~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/mongo/db/pipeline/value.h

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
#pragma once
18
18
 
19
 
#include "mongo/pch.h"
20
 
#include "bson/bsontypes.h"
21
 
#include "bson/oid.h"
22
 
#include "util/intrusive_counter.h"
23
 
#include "util/optime.h"
 
19
#include "mongo/db/pipeline/value_internal.h"
24
20
 
25
21
namespace mongo {
26
22
    class BSONElement;
27
23
    class Builder;
28
 
    class Document;
29
 
    class Value;
30
 
 
31
 
    class ValueIterator :
32
 
        public IntrusiveCounterUnsigned {
33
 
    public:
34
 
        virtual ~ValueIterator();
35
 
 
36
 
        /*
37
 
          Ask if there are more fields to return.
38
 
 
39
 
          @returns true if there are more fields, false otherwise
40
 
        */
41
 
        virtual bool more() const = 0;
42
 
 
43
 
        /*
44
 
          Move the iterator to point to the next field and return it.
45
 
 
46
 
          @returns the next field's <name, Value>
47
 
        */
48
 
        virtual intrusive_ptr<const Value> next() = 0;
49
 
    };
50
 
 
51
 
 
52
 
    /*
53
 
      Values are immutable, so these are passed around as
54
 
      intrusive_ptr<const Value>.
 
24
 
 
25
    /** A variant type that can hold any type of data representable in BSON
 
26
     *
 
27
     *  Small values are stored inline, but some values, such as large strings,
 
28
     *  are heap allocated. It has smart pointer capabilities built-in so it is
 
29
     *  safe and recommended to pass these around and return them by value.
 
30
     *
 
31
     *  Values are immutable, but can be assigned. This means that once you have
 
32
     *  a Value, you can be assured that none of the data in that Value will
 
33
     *  change. However if you have a non-const Value you replace it with
 
34
     *  operator=. These rules are the same as BSONObj, and similar to
 
35
     *  shared_ptr<const Object> with stronger guarantees of constness. This is
 
36
     *  also the same as Java's String type.
 
37
     *
 
38
     *  Thread-safety: A single Value instance can be safely shared between
 
39
     *  threads as long as there are no writers while other threads are
 
40
     *  accessing the object. Any number of threads can read from a Value
 
41
     *  concurrently. There are no restrictions on how threads access Value
 
42
     *  instances exclusively owned by them, even if they reference the same
 
43
     *  storage as Value in other threads.
55
44
     */
56
 
    class Value :
57
 
        public IntrusiveCounterUnsigned {
 
45
    class Value {
58
46
    public:
59
 
        ~Value();
60
 
 
61
 
        /*
62
 
          Construct a Value from a BSONElement.
63
 
 
64
 
          This ignores the name of the element, and only uses the value,
65
 
          whatever type it is.
66
 
 
67
 
          @returns a new Value initialized from the bsonElement
68
 
        */
69
 
        static intrusive_ptr<const Value> createFromBsonElement(
70
 
            BSONElement *pBsonElement);
71
 
 
72
 
        /*
73
 
          Construct an integer-valued Value.
74
 
 
75
 
          For commonly used values, consider using one of the singleton
76
 
          instances defined below.
77
 
 
78
 
          @param value the value
79
 
          @returns a Value with the given value
80
 
        */
81
 
        static intrusive_ptr<const Value> createInt(int value);
82
 
 
83
 
        /*
84
 
          Construct a long or interger-valued Value.
85
 
          Used when preforming arithmetic operations with int where the result may be too large
86
 
          and need to be stored as long. The Value will be an int if value fits, otherwise it
87
 
          will be a long.
88
 
 
89
 
          @param value the value
90
 
          @returns a Value with the given value
91
 
        */
92
 
        static intrusive_ptr<const Value> createIntOrLong(long long value);
93
 
 
94
 
        /*
95
 
          Construct an long(long)-valued Value.
96
 
 
97
 
          For commonly used values, consider using one of the singleton
98
 
          instances defined below.
99
 
 
100
 
          @param value the value
101
 
          @returns a Value with the given value
102
 
        */
103
 
        static intrusive_ptr<const Value> createLong(long long value);
104
 
 
105
 
        /*
106
 
          Construct a double-valued Value.
107
 
 
108
 
          @param value the value
109
 
          @returns a Value with the given value
110
 
        */
111
 
        static intrusive_ptr<const Value> createDouble(double value);
112
 
 
113
 
        /*
114
 
          Construct a string-valued Value.
115
 
 
116
 
          @param value the value
117
 
          @returns a Value with the given value
118
 
        */
119
 
        static intrusive_ptr<const Value> createString(const string &value);
120
 
 
121
 
        /*
122
 
          Construct a date-valued Value.
123
 
 
124
 
          @param value the value
125
 
          @returns a Value with the given value
126
 
        */
127
 
        static intrusive_ptr<const Value> createDate(const long long &value);
128
 
 
129
 
        static intrusive_ptr<const Value> createTimestamp(const OpTime& value);
130
 
 
131
 
        /*
132
 
          Construct a document-valued Value.
133
 
 
134
 
          @param value the value
135
 
          @returns a Value with the given value
136
 
        */
137
 
        static intrusive_ptr<const Value> createDocument(
138
 
            const intrusive_ptr<Document> &pDocument);
139
 
 
140
 
        /*
141
 
          Construct an array-valued Value.
142
 
 
143
 
          @param value the value
144
 
          @returns a Value with the given value
145
 
        */
146
 
        static intrusive_ptr<const Value> createArray(
147
 
            const vector<intrusive_ptr<const Value> > &vpValue);
148
 
 
149
 
        /*
150
 
          Get the BSON type of the field.
151
 
 
152
 
          If the type is jstNULL, no value getter will work.
153
 
 
154
 
          @return the BSON type of the field.
155
 
        */
156
 
        BSONType getType() const;
157
 
 
158
 
        /*
159
 
          Getters.
160
 
 
161
 
          @returns the Value's value; asserts if the requested value type is
162
 
          incorrect.
163
 
        */
 
47
        /** Construct a Value
 
48
         *
 
49
         *  All types not listed will be rejected rather than converted (see private for why)
 
50
         *
 
51
         *  Note: Currently these are all explicit conversions.
 
52
         *        I'm not sure if we want implicit or not.
 
53
         *  //TODO decide
 
54
         */
 
55
 
 
56
        Value(): _storage() {} // "Missing" value
 
57
        explicit Value(bool value)                : _storage(Bool, value) {}
 
58
        explicit Value(int value)                 : _storage(NumberInt, value) {}
 
59
        explicit Value(long long value)           : _storage(NumberLong, value) {}
 
60
        explicit Value(double value)              : _storage(NumberDouble, value) {}
 
61
        explicit Value(const OpTime& value)       : _storage(Timestamp, value.asDate()) {}
 
62
        explicit Value(const OID& value)          : _storage(jstOID, value) {}
 
63
        explicit Value(const StringData& value)   : _storage(String, value) {}
 
64
        explicit Value(const string& value)       : _storage(String, StringData(value)) {}
 
65
        explicit Value(const char* value)         : _storage(String, StringData(value)) {}
 
66
        explicit Value(const Document& doc)       : _storage(Object, doc) {}
 
67
        explicit Value(const BSONObj& obj);//     : _storage(Object, Document(obj)) {} // in cpp
 
68
        explicit Value(const vector<Value>& vec)  : _storage(Array, new RCVector(vec)) {}
 
69
        explicit Value(const BSONBinData& bd)     : _storage(BinData, bd) {}
 
70
        explicit Value(const BSONRegEx& re)       : _storage(RegEx, re) {}
 
71
        explicit Value(const BSONCodeWScope& cws) : _storage(CodeWScope, cws) {}
 
72
        explicit Value(const BSONDBRef& dbref)    : _storage(DBRef, dbref) {}
 
73
        explicit Value(const BSONSymbol& sym)     : _storage(Symbol, sym.symbol) {}
 
74
        explicit Value(const BSONCode& code)      : _storage(Code, code.code) {}
 
75
        explicit Value(const NullLabeler&)        : _storage(jstNULL) {}   // BSONNull
 
76
        explicit Value(const UndefinedLabeler&)   : _storage(Undefined) {} // BSONUndefined
 
77
        explicit Value(const MinKeyLabeler&)      : _storage(MinKey) {}    // MINKEY
 
78
        explicit Value(const MaxKeyLabeler&)      : _storage(MaxKey) {}    // MAXKEY
 
79
        explicit Value(const Date_t& date)
 
80
            : _storage(Date, static_cast<long long>(date.millis)) // millis really signed
 
81
        {}
 
82
 
 
83
        /** Creates an empty or zero value of specified type.
 
84
         *  This is currently the only way to create Undefined or Null Values.
 
85
         */
 
86
        explicit Value(BSONType type);
 
87
 
 
88
        // TODO: add an unsafe version that can share storage with the BSONElement
 
89
        /// Deep-convert from BSONElement to Value
 
90
        explicit Value(const BSONElement& elem);
 
91
 
 
92
        /** Construct a long or integer-valued Value.
 
93
         *
 
94
         *  Used when preforming arithmetic operations with int where the
 
95
         *  result may be too large and need to be stored as long. The Value
 
96
         *  will be an int if value fits, otherwise it will be a long.
 
97
        */
 
98
        static Value createIntOrLong(long long value);
 
99
 
 
100
        /** A "missing" value indicates the lack of a Value.
 
101
         *  This is similar to undefined/null but should not appear in output to BSON.
 
102
         *  Missing Values are returned by Document when accessing non-existent fields.
 
103
         */
 
104
        bool missing() const { return _storage.type == EOO; }
 
105
 
 
106
        /// true if missing() or type is jstNULL or Undefined
 
107
        bool nullish() const {
 
108
            return missing()
 
109
                || _storage.type == jstNULL
 
110
                || _storage.type == Undefined;
 
111
        }
 
112
 
 
113
        /// true if type represents a number
 
114
        bool numeric() const {
 
115
            return _storage.type == NumberDouble
 
116
                || _storage.type == NumberLong
 
117
                || _storage.type == NumberInt;
 
118
        }
 
119
 
 
120
        /// Get the BSON type of the field.
 
121
        BSONType getType() const { return _storage.bsonType(); }
 
122
 
 
123
        /** Exact type getters.
 
124
         *  Asserts if the requested value type is not exactly correct.
 
125
         *  See coerceTo methods below for a more type-flexible alternative.
 
126
         */
164
127
        double getDouble() const;
165
128
        string getString() const;
166
 
        intrusive_ptr<Document> getDocument() const;
167
 
        intrusive_ptr<ValueIterator> getArray() const;
 
129
        Document getDocument() const;
168
130
        OID getOid() const;
169
131
        bool getBool() const;
170
 
        long long getDate() const;
 
132
        long long getDate() const; // in milliseconds
171
133
        OpTime getTimestamp() const;
172
 
        string getRegex() const;
 
134
        const char* getRegex() const;
 
135
        const char* getRegexFlags() const;
173
136
        string getSymbol() const;
 
137
        string getCode() const;
174
138
        int getInt() const;
175
139
        long long getLong() const;
176
 
 
177
 
        /*
178
 
          Get the length of an array value.
179
 
 
180
 
          @returns the length of the array, if this is array-valued; otherwise
181
 
             throws an error
182
 
        */
 
140
        const vector<Value>& getArray() const { return _storage.getArray(); }
183
141
        size_t getArrayLength() const;
184
142
 
185
 
        /*
186
 
          Add this value to the BSON object under construction.
187
 
        */
188
 
        void addToBsonObj(BSONObjBuilder *pBuilder, string fieldName) const;
189
 
 
190
 
        /*
191
 
          Add this field to the BSON array under construction.
192
 
 
193
 
          As part of an array, the Value's name will be ignored.
194
 
        */
195
 
        void addToBsonArray(BSONArrayBuilder *pBuilder) const;
196
 
 
197
 
        /*
198
 
          Get references to singleton instances of commonly used field values.
199
 
         */
200
 
        static intrusive_ptr<const Value> getUndefined();
201
 
        static intrusive_ptr<const Value> getNull();
202
 
        static intrusive_ptr<const Value> getTrue();
203
 
        static intrusive_ptr<const Value> getFalse();
204
 
        static intrusive_ptr<const Value> getMinusOne();
205
 
        static intrusive_ptr<const Value> getZero();
206
 
        static intrusive_ptr<const Value> getOne();
207
 
 
208
 
        /**
209
 
         * Coerce (cast) a value to a native bool using BSONElement::trueValue() rules, but with
210
 
         * some types unsupported.  SERVER-6120
211
 
         * @return the bool value
 
143
        /// Access an element of a subarray. Returns Value() if missing or getType() != Array
 
144
        Value operator[] (size_t index) const;
 
145
 
 
146
        /// Access a field of a subdocument. Returns Value() if missing or getType() != Object
 
147
        Value operator[] (StringData name) const;
 
148
 
 
149
        /// Add this value to the BSON object under construction.
 
150
        void addToBsonObj(BSONObjBuilder* pBuilder, StringData fieldName) const;
 
151
 
 
152
        /// Add this field to the BSON array under construction.
 
153
        void addToBsonArray(BSONArrayBuilder* pBuilder) const;
 
154
 
 
155
        // Support BSONObjBuilder and BSONArrayBuilder "stream" API
 
156
        friend BSONObjBuilder& operator << (BSONObjBuilderValueStream& builder, const Value& val);
 
157
 
 
158
        /** Coerce a value to a bool using BSONElement::trueValue() rules.
 
159
         *  Some types unsupported.  SERVER-6120
212
160
         */
213
161
        bool coerceToBool() const;
214
162
 
215
 
        /*
216
 
          Coerce (cast) a value to an int, using JSON rules.
217
 
 
218
 
          @returns the int value
219
 
        */
 
163
        /** Coercion operators to extract values with fuzzy type logic.
 
164
         *
 
165
         *  These currently assert if called on an unconvertible type.
 
166
         *  TODO: decided how to handle unsupported types.
 
167
         */
 
168
        string coerceToString() const;
220
169
        int coerceToInt() const;
221
 
 
222
 
        /*
223
 
          Coerce (cast) a value to a long long, using JSON rules.
224
 
 
225
 
          @returns the long value
226
 
        */
227
170
        long long coerceToLong() const;
228
 
 
229
 
        /*
230
 
          Coerce (cast) a value to a double, using JSON rules.
231
 
 
232
 
          @returns the double value
233
 
        */
234
171
        double coerceToDouble() const;
235
 
 
236
 
        /*
237
 
          Coerce (cast) a value to a date, using JSON rules.
238
 
 
239
 
          @returns the date value
240
 
        */
 
172
        OpTime coerceToTimestamp() const;
241
173
        long long coerceToDate() const;
242
174
        time_t coerceToTimeT() const;
243
175
        tm coerceToTm() const; // broken-out time struct (see man gmtime)
244
176
 
245
 
        OpTime coerceToTimestamp() const;
246
 
 
247
 
        /*
248
 
          Coerce (cast) a value to a string, using JSON rules.
249
 
 
250
 
          @returns the date value
251
 
        */
252
 
        string coerceToString() const;
253
 
 
254
 
        /*
255
 
          Compare two Values.
256
 
 
257
 
          @param rL left value
258
 
          @param rR right value
259
 
          @returns an integer less than zero, zero, or an integer greater than
260
 
            zero, depending on whether rL < rR, rL == rR, or rL > rR
261
 
         */
262
 
        static int compare(const intrusive_ptr<const Value> &rL,
263
 
                           const intrusive_ptr<const Value> &rR);
264
 
 
265
 
 
266
 
        /*
267
 
          Figure out what the widest of two numeric types is.
268
 
 
269
 
          Widest can be thought of as "most capable," or "able to hold the
270
 
          largest or most precise value."  The progression is Int, Long, Double.
271
 
 
272
 
          @param rL left value
273
 
          @param rR right value
274
 
          @returns a BSONType of NumberInt, NumberLong, or NumberDouble
275
 
        */
 
177
 
 
178
        /** Compare two Values.
 
179
         *  @returns an integer less than zero, zero, or an integer greater than
 
180
         *           zero, depending on whether lhs < rhs, lhs == rhs, or lhs > rhs
 
181
         *  Warning: may return values other than -1, 0, or 1
 
182
         */
 
183
        static int compare(const Value& lhs, const Value& rhs);
 
184
 
 
185
        friend
 
186
        bool operator==(const Value& v1, const Value& v2) {
 
187
            if (v1._storage.identical(v2._storage)) {
 
188
                // Simple case
 
189
                return true;
 
190
            }
 
191
            return (Value::compare(v1, v2) == 0);
 
192
        }
 
193
 
 
194
        /// This is for debugging, logging, etc. See getString() for how to extract a string.
 
195
        string toString() const;
 
196
        friend ostream& operator << (ostream& out, const Value& v);
 
197
 
 
198
        void swap(Value& rhs) {
 
199
            _storage.swap(rhs._storage);
 
200
        }
 
201
 
 
202
        /** Figure out what the widest of two numeric types is.
 
203
         *
 
204
         *  Widest can be thought of as "most capable," or "able to hold the
 
205
         *  largest or most precise value."  The progression is Int, Long, Double.
 
206
         */
276
207
        static BSONType getWidestNumeric(BSONType lType, BSONType rType);
277
208
 
278
 
        /*
279
 
          Get the approximate storage size of the value, in bytes.
280
 
 
281
 
          @returns approximate storage size of the value.
282
 
         */
 
209
        /// Get the approximate memory size of the value, in bytes. Includes sizeof(Value)
283
210
        size_t getApproximateSize() const;
284
211
 
285
 
        /*
286
 
          Calculate a hash value.
287
 
 
288
 
          Meant to be used to create composite hashes suitable for
289
 
          boost classes such as unordered_map<>.
290
 
 
291
 
          @param seed value to augment with this' hash
292
 
        */
293
 
        void hash_combine(size_t &seed) const;
294
 
 
295
 
        /*
296
 
          struct Hash is defined to enable the use of Values as
297
 
          keys in boost::unordered_map<>.
298
 
 
299
 
          Values are always referenced as immutables in the form
300
 
          intrusive_ptr<const Value>, so these operate on that construction.
301
 
        */
302
 
        struct Hash :
303
 
            unary_function<intrusive_ptr<const Value>, size_t> {
304
 
            size_t operator()(const intrusive_ptr<const Value> &rV) const;
 
212
        /** Calculate a hash value.
 
213
         *
 
214
         *  Meant to be used to create composite hashes suitable for
 
215
         *  hashed container classes such as unordered_map<>.
 
216
         */
 
217
        void hash_combine(size_t& seed) const;
 
218
 
 
219
        /// struct Hash is defined to enable the use of Values as keys in unordered_map.
 
220
        struct Hash : unary_function<const Value&, size_t> {
 
221
            size_t operator()(const Value& rV) const;
305
222
        };
306
223
 
307
 
    protected:
308
 
        Value(); // creates null value
309
 
        Value(BSONType type); // creates an empty (unitialized value) of type
310
 
                                                // mostly useful for Undefined
311
 
        Value(bool boolValue);
312
 
        Value(int intValue);
 
224
        /// Call this after memcpying to update ref counts if needed
 
225
        void memcpyed() const { _storage.memcpyed(); }
 
226
 
 
227
        // LEGACY creation functions
 
228
        static Value createFromBsonElement(const BSONElement* pBsonElement);
 
229
        static Value createInt(int value) { return Value(value); }
 
230
        static Value createLong(long long value) { return Value(value); }
 
231
        static Value createDouble(double value) { return Value(value); }
 
232
        static Value createTimestamp(const OpTime& value) { return Value(value); }
 
233
        static Value createString(const string& value) { return Value(value); }
 
234
        static Value createDocument(const Document& doc) { return Value(doc); }
 
235
        static Value createArray(const vector<Value>& vec) { return Value(vec); }
 
236
        static Value createDate(const long long value);
313
237
 
314
238
    private:
315
 
        Value(BSONElement *pBsonElement);
316
 
 
317
 
        Value(long long longValue);
318
 
        Value(double doubleValue);
319
 
        Value(const OpTime& timestampValue);
320
 
        Value(const string &stringValue);
321
 
        Value(const intrusive_ptr<Document> &pDocument);
322
 
        Value(const vector<intrusive_ptr<const Value> > &vpValue);
323
 
 
324
 
        void addToBson(Builder *pBuilder) const;
325
 
 
326
 
        BSONType type;
327
 
 
328
 
        // store values that don't need a ctor/dtor in one of these
329
 
        union {
330
 
            double doubleValue;
331
 
            bool boolValue;
332
 
            int intValue;
333
 
            long long longValue;
334
 
            ReplTime timestampValue;
335
 
            unsigned char oidValue[12];
336
 
            // The member below is redundant, but useful for clarity and searchability.
337
 
            long long dateValue;
338
 
        };
339
 
 
340
 
        string stringValue; // String, Regex, Symbol
341
 
        intrusive_ptr<Document> pDocumentValue;
342
 
        vector<intrusive_ptr<const Value> > vpValue; // for arrays
343
 
 
344
 
        /*
345
 
        These are often used as the result of boolean or comparison
346
 
        expressions.
347
 
 
348
 
        These are obtained via public static getters defined above.
349
 
        */
350
 
        static const intrusive_ptr<const Value> pFieldUndefined;
351
 
        static const intrusive_ptr<const Value> pFieldNull;
352
 
        static const intrusive_ptr<const Value> pFieldTrue;
353
 
        static const intrusive_ptr<const Value> pFieldFalse;
354
 
        static const intrusive_ptr<const Value> pFieldMinusOne;
355
 
        static const intrusive_ptr<const Value> pFieldZero;
356
 
        static const intrusive_ptr<const Value> pFieldOne;
357
 
 
358
 
        /* this implementation is used for getArray() */
359
 
        class vi :
360
 
            public ValueIterator {
361
 
        public:
362
 
            // virtuals from ValueIterator
363
 
            virtual ~vi();
364
 
            virtual bool more() const;
365
 
            virtual intrusive_ptr<const Value> next();
366
 
 
367
 
        private:
368
 
            friend class Value;
369
 
            vi(const intrusive_ptr<const Value> &pSource,
370
 
               const vector<intrusive_ptr<const Value> > *pvpValue);
371
 
 
372
 
            size_t size;
373
 
            size_t nextIndex;
374
 
            const vector<intrusive_ptr<const Value> > *pvpValue;
375
 
        }; /* class vi */
376
 
 
377
 
    };
378
 
 
379
 
    /*
380
 
      Equality operator for values.
381
 
 
382
 
      Useful for unordered_map<>, etc.
383
 
     */
384
 
    inline bool operator==(const intrusive_ptr<const Value> &v1,
385
 
                    const intrusive_ptr<const Value> &v2) {
386
 
        return (Value::compare(v1, v2) == 0);
387
 
    }
388
 
 
389
 
    /*
390
 
      For performance reasons, there are various sharable static values
391
 
      defined in class Value, obtainable by methods such as getUndefined(),
392
 
      getTrue(), getOne(), etc.  We don't want these to go away as they are
393
 
      used by a multitude of threads evaluating pipelines.  In order to avoid
394
 
      having to use atomic integers in the intrusive reference counter, this
395
 
      class overrides the reference counting methods to do nothing, making it
396
 
      safe to use for static Values.
397
 
 
398
 
      At this point, only the constructors necessary for the static Values in
399
 
      common use have been defined.  The remainder can be defined if necessary.
400
 
     */
401
 
    class ValueStatic :
402
 
        public Value {
403
 
    public:
404
 
        // virtuals from IntrusiveCounterUnsigned
405
 
        virtual void addRef() const;
406
 
        virtual void release() const;
407
 
 
408
 
        // constructors
409
 
        ValueStatic();
410
 
        ValueStatic(BSONType type);
411
 
        ValueStatic(bool boolValue);
412
 
        ValueStatic(int intValue);
413
 
    };
 
239
        /** This is a "honeypot" to prevent unexpected implicit conversions to the accepted argument
 
240
         *  types. bool is especially bad since without this it will accept any pointer.
 
241
         *
 
242
         *  Template argument name was chosen to make produced error easier to read.
 
243
         */
 
244
        template <typename InvalidArgumentType>
 
245
        explicit Value(const InvalidArgumentType& invalidArgument);
 
246
 
 
247
        // does no type checking
 
248
        StringData getStringData() const; // May contain embedded NUL bytes
 
249
 
 
250
        ValueStorage _storage;
 
251
        friend class MutableValue; // gets and sets _storage.genericRCPtr
 
252
    };
 
253
    BOOST_STATIC_ASSERT(sizeof(Value) == 16);
 
254
}
 
255
 
 
256
namespace std {
 
257
    // This is used by std::sort and others
 
258
    template <>
 
259
    inline void swap(mongo::Value& lhs, mongo::Value& rhs) { lhs.swap(rhs); }
414
260
}
415
261
 
416
262
/* ======================= INLINED IMPLEMENTATIONS ========================== */
417
263
 
418
264
namespace mongo {
419
265
 
420
 
    inline BSONType Value::getType() const {
421
 
        return type;
422
 
    }
423
 
 
424
266
    inline size_t Value::getArrayLength() const {
425
267
        verify(getType() == Array);
426
 
        return vpValue.size();
427
 
    }
428
 
 
429
 
    inline intrusive_ptr<const Value> Value::getUndefined() {
430
 
        return pFieldUndefined;
431
 
    }
432
 
 
433
 
    inline intrusive_ptr<const Value> Value::getNull() {
434
 
        return pFieldNull;
435
 
    }
436
 
 
437
 
    inline intrusive_ptr<const Value> Value::getTrue() {
438
 
        return pFieldTrue;
439
 
    }
440
 
 
441
 
    inline intrusive_ptr<const Value> Value::getFalse() {
442
 
        return pFieldFalse;
443
 
    }
444
 
 
445
 
    inline intrusive_ptr<const Value> Value::getMinusOne() {
446
 
        return pFieldMinusOne;
447
 
    }
448
 
 
449
 
    inline intrusive_ptr<const Value> Value::getZero() {
450
 
        return pFieldZero;
451
 
    }
452
 
 
453
 
    inline intrusive_ptr<const Value> Value::getOne() {
454
 
        return pFieldOne;
455
 
    }
456
 
 
457
 
    inline size_t Value::Hash::operator()(
458
 
        const intrusive_ptr<const Value> &rV) const {
 
268
        return getArray().size();
 
269
    }
 
270
 
 
271
    inline size_t Value::Hash::operator()(const Value& v) const {
459
272
        size_t seed = 0xf0afbeef;
460
 
        rV->hash_combine(seed);
 
273
        v.hash_combine(seed);
461
274
        return seed;
462
275
    }
463
276
 
464
 
    inline ValueStatic::ValueStatic():
465
 
        Value() {
466
 
    }
467
 
 
468
 
    inline ValueStatic::ValueStatic(BSONType type):
469
 
        Value(type) {
470
 
    }
471
 
 
472
 
    inline ValueStatic::ValueStatic(bool boolValue):
473
 
        Value(boolValue) {
474
 
    }
475
 
 
476
 
    inline ValueStatic::ValueStatic(int intValue):
477
 
        Value(intValue) {
478
 
    }
479
 
 
 
277
    inline StringData Value::getStringData() const {
 
278
        return _storage.getString();
 
279
    }
 
280
 
 
281
    inline string Value::getString() const {
 
282
        verify(getType() == String);
 
283
        return _storage.getString().toString();
 
284
    }
 
285
 
 
286
    inline OID Value::getOid() const {
 
287
        verify(getType() == jstOID);
 
288
        return OID(_storage.oid);
 
289
    }
 
290
 
 
291
    inline bool Value::getBool() const {
 
292
        verify(getType() == Bool);
 
293
        return _storage.boolValue;
 
294
    }
 
295
 
 
296
    inline long long Value::getDate() const {
 
297
        verify(getType() == Date);
 
298
        return _storage.dateValue;
 
299
    }
 
300
 
 
301
    inline OpTime Value::getTimestamp() const {
 
302
        verify(getType() == Timestamp);
 
303
        return _storage.timestampValue;
 
304
    }
 
305
 
 
306
    inline const char* Value::getRegex() const {
 
307
        verify(getType() == RegEx);
 
308
        return _storage.getString().rawData(); // this is known to be NUL terminated
 
309
    }
 
310
    inline const char* Value::getRegexFlags() const {
 
311
        verify(getType() == RegEx);
 
312
        const char* pattern = _storage.getString().rawData(); // this is known to be NUL terminated
 
313
        const char* flags = pattern + strlen(pattern) + 1; // first byte after pattern's NUL
 
314
        dassert(flags + strlen(flags) == pattern + _storage.getString().size());
 
315
        return flags;
 
316
    }
 
317
 
 
318
    inline string Value::getSymbol() const {
 
319
        verify(getType() == Symbol);
 
320
        return _storage.getString().toString();
 
321
    }
 
322
    inline string Value::getCode() const {
 
323
        verify(getType() == Code);
 
324
        return _storage.getString().toString();
 
325
    }
 
326
 
 
327
    inline int Value::getInt() const {
 
328
        verify(getType() == NumberInt);
 
329
        return _storage.intValue;
 
330
    }
 
331
 
 
332
    inline long long Value::getLong() const {
 
333
        BSONType type = getType();
 
334
        if (type == NumberInt)
 
335
            return _storage.intValue;
 
336
 
 
337
        verify(type == NumberLong);
 
338
        return _storage.longValue;
 
339
    }
480
340
};