MongoDB  2.7.0
safe_num.h
1 /* Copyright 2012 10gen Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <iosfwd>
19 #include <string>
20 
21 #include "mongo/bson/bsonelement.h"
22 #include "mongo/bson/bsonobj.h"
23 
24 namespace mongo {
25 
26 namespace mutablebson {
27  class Element;
28  class Document;
29 }
30 
56  class SafeNum {
57  public:
58  SafeNum();
59  ~SafeNum();
60 
61  //
62  // construction support
63  //
64 
65  // Copy ctor and assignment are allowed.
66  SafeNum(const SafeNum& rhs);
67  SafeNum& operator=(const SafeNum& rhs);
68 
69  // Implicit conversions are allowed.
70  SafeNum(const BSONElement& element);
71  SafeNum(int num);
72  SafeNum(long long int num);
73  SafeNum(double num);
74  // TODO: add Paul's mutablebson::Element ctor
75 
76  //
77  // comparison support
78  //
79 
85  bool isEquivalent(const SafeNum& rhs) const;
86  bool operator==(const SafeNum& rhs) const;
87  bool operator!=(const SafeNum& rhs) const;
88 
94  bool isIdentical(const SafeNum& rhs) const;
95 
96  //
97  // arithmetic support
98  //
99 
104  SafeNum operator+(const SafeNum& rhs) const;
105  SafeNum& operator+=(const SafeNum& rhs);
106 
111  SafeNum operator*(const SafeNum& rhs) const;
112  SafeNum& operator*=(const SafeNum& rhs);
113 
114  //
115  // logical operation support. Note that these operations are only supported for
116  // integral types. Attempts to apply with either side holding a double value
117  // will result in an EOO typed safenum.
118  //
119 
120  // Bitwise 'and' support
121  SafeNum bitAnd(const SafeNum& rhs) const;
122  SafeNum operator&(const SafeNum& rhs) const;
123  SafeNum& operator&=(const SafeNum& rhs);
124 
125  // Bitwise 'or' support
126  SafeNum bitOr(const SafeNum& rhs) const;
127  SafeNum operator|(const SafeNum& rhs) const;
128  SafeNum& operator|=(const SafeNum& rhs);
129 
130  // Bitwise 'xor' support
131  SafeNum bitXor(const SafeNum& rhs) const;
132  SafeNum operator^(const SafeNum& rhs) const;
133  SafeNum& operator^=(const SafeNum& rhs);
134 
135 
136  //
137  // output support
138  //
139 
140  friend class mutablebson::Element;
141  friend class mutablebson::Document;
142 
143  // TODO: output to builder
144 
145  //
146  // accessors
147  //
148  bool isValid() const;
149  BSONType type() const;
150  std::string debugString() const;
151 
152  //
153  // Below exposed for testing purposes. Treat as private.
154  //
155 
156  // Maximum integer that can be converted accuratelly into a double, assuming a
157  // double precission IEEE 754 representation.
158  // TODO use numeric_limits to make this portable
159  static const long long maxIntInDouble = 9007199254740992LL; // 2^53
160 
161  private:
162  // One of the following: NumberInt, NumberLong, NumberDouble, or EOO.
163  BSONType _type;
164 
165  // Value of the safe num. Indeterminate if _type is EOO.
166  union {
167  int int32Val;
168  long long int int64Val;
169  double doubleVal;
170  } _value;
171 
177  static SafeNum addInternal(const SafeNum& lhs, const SafeNum& rhs);
178 
184  static SafeNum mulInternal(const SafeNum& lhs, const SafeNum& rhs);
185 
189  static SafeNum andInternal(const SafeNum& lhs, const SafeNum& rhs);
190 
194  static SafeNum orInternal(const SafeNum& lhs, const SafeNum& rhs);
195 
199  static SafeNum xorInternal(const SafeNum& lhs, const SafeNum& rhs);
200 
205  static long long getLongLong(const SafeNum& snum);
206 
211  static double getDouble(const SafeNum& snum);
212  };
213 
214  // Convenience method for unittest code. Please use accessors otherwise.
215  std::ostream& operator<<(std::ostream& os, const SafeNum& snum);
216 
217 } // namespace mongo
218 
219 #include "mongo/util/safe_num-inl.h"
220 
SafeNum operator*(const SafeNum &rhs) const
Multiplies the 'rhs' – right-hand side – safe num with this, taking care of upconversions and overflo...
Definition: safe_num-inl.h:63
BSONType
the complete list of valid BSON types see also bsonspec.org
Definition: bsontypes.h:43
bool isIdentical(const SafeNum &rhs) const
Returns true if 'rsh' is equivalent to 'this' (see isEquivalent) and both types are exactly the same...
Definition: safe_num.cpp:111
SafeNum holds and does arithmetic on a number in a safe way, handling overflow and casting for the us...
Definition: safe_num.h:56
Element represents a BSON value or object in a mutable BSON Document.
Definition: element.h:99
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:62
Mutable BSON Overview.
Definition: document.h:221
bool isEquivalent(const SafeNum &rhs) const
Returns true if the numeric quantity of 'rhs' and 'this' are the same.
Definition: safe_num.cpp:75
SafeNum operator+(const SafeNum &rhs) const
Sums the 'rhs' – right-hand side – safe num with this, taking care of upconversions and overflow (see...
Definition: safe_num-inl.h:55