Chris@16
|
1 #ifndef _DATE_TIME_INT_ADAPTER_HPP__
|
Chris@16
|
2 #define _DATE_TIME_INT_ADAPTER_HPP__
|
Chris@16
|
3
|
Chris@16
|
4 /* Copyright (c) 2002,2003 CrystalClear Software, Inc.
|
Chris@16
|
5 * Use, modification and distribution is subject to the
|
Chris@16
|
6 * Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 * Author: Jeff Garland, Bart Garst
|
Chris@101
|
9 * $Date$
|
Chris@16
|
10 */
|
Chris@16
|
11
|
Chris@16
|
12
|
Chris@16
|
13 #include "boost/config.hpp"
|
Chris@16
|
14 #include "boost/limits.hpp" //work around compilers without limits
|
Chris@16
|
15 #include "boost/date_time/special_defs.hpp"
|
Chris@16
|
16 #include "boost/date_time/locale_config.hpp"
|
Chris@16
|
17 #ifndef BOOST_DATE_TIME_NO_LOCALE
|
Chris@16
|
18 # include <ostream>
|
Chris@16
|
19 #endif
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost {
|
Chris@16
|
22 namespace date_time {
|
Chris@16
|
23
|
Chris@16
|
24
|
Chris@16
|
25 //! Adapter to create integer types with +-infinity, and not a value
|
Chris@16
|
26 /*! This class is used internally in counted date/time representations.
|
Chris@16
|
27 * It adds the floating point like features of infinities and
|
Chris@16
|
28 * not a number. It also provides mathmatical operations with
|
Chris@16
|
29 * consideration to special values following these rules:
|
Chris@16
|
30 *@code
|
Chris@16
|
31 * +infinity - infinity == Not A Number (NAN)
|
Chris@16
|
32 * infinity * non-zero == infinity
|
Chris@16
|
33 * infinity * zero == NAN
|
Chris@16
|
34 * +infinity * -integer == -infinity
|
Chris@16
|
35 * infinity / infinity == NAN
|
Chris@16
|
36 * infinity * infinity == infinity
|
Chris@16
|
37 *@endcode
|
Chris@16
|
38 */
|
Chris@16
|
39 template<typename int_type_>
|
Chris@16
|
40 class int_adapter {
|
Chris@16
|
41 public:
|
Chris@16
|
42 typedef int_type_ int_type;
|
Chris@16
|
43 int_adapter(int_type v) :
|
Chris@16
|
44 value_(v)
|
Chris@16
|
45 {}
|
Chris@16
|
46 static bool has_infinity()
|
Chris@16
|
47 {
|
Chris@16
|
48 return true;
|
Chris@16
|
49 }
|
Chris@16
|
50 static const int_adapter pos_infinity()
|
Chris@16
|
51 {
|
Chris@16
|
52 return (::std::numeric_limits<int_type>::max)();
|
Chris@16
|
53 }
|
Chris@16
|
54 static const int_adapter neg_infinity()
|
Chris@16
|
55 {
|
Chris@16
|
56 return (::std::numeric_limits<int_type>::min)();
|
Chris@16
|
57 }
|
Chris@16
|
58 static const int_adapter not_a_number()
|
Chris@16
|
59 {
|
Chris@16
|
60 return (::std::numeric_limits<int_type>::max)()-1;
|
Chris@16
|
61 }
|
Chris@16
|
62 static int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
Chris@16
|
63 {
|
Chris@16
|
64 return (::std::numeric_limits<int_type>::max)()-2;
|
Chris@16
|
65 }
|
Chris@16
|
66 static int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
Chris@16
|
67 {
|
Chris@16
|
68 return (::std::numeric_limits<int_type>::min)()+1;
|
Chris@16
|
69 }
|
Chris@16
|
70 static int_adapter from_special(special_values sv)
|
Chris@16
|
71 {
|
Chris@16
|
72 switch (sv) {
|
Chris@16
|
73 case not_a_date_time: return not_a_number();
|
Chris@16
|
74 case neg_infin: return neg_infinity();
|
Chris@16
|
75 case pos_infin: return pos_infinity();
|
Chris@16
|
76 case max_date_time: return (max)();
|
Chris@16
|
77 case min_date_time: return (min)();
|
Chris@16
|
78 default: return not_a_number();
|
Chris@16
|
79 }
|
Chris@16
|
80 }
|
Chris@16
|
81 static bool is_inf(int_type v)
|
Chris@16
|
82 {
|
Chris@16
|
83 return (v == neg_infinity().as_number() ||
|
Chris@16
|
84 v == pos_infinity().as_number());
|
Chris@16
|
85 }
|
Chris@16
|
86 static bool is_neg_inf(int_type v)
|
Chris@16
|
87 {
|
Chris@16
|
88 return (v == neg_infinity().as_number());
|
Chris@16
|
89 }
|
Chris@16
|
90 static bool is_pos_inf(int_type v)
|
Chris@16
|
91 {
|
Chris@16
|
92 return (v == pos_infinity().as_number());
|
Chris@16
|
93 }
|
Chris@16
|
94 static bool is_not_a_number(int_type v)
|
Chris@16
|
95 {
|
Chris@16
|
96 return (v == not_a_number().as_number());
|
Chris@16
|
97 }
|
Chris@16
|
98 //! Returns either special value type or is_not_special
|
Chris@16
|
99 static special_values to_special(int_type v)
|
Chris@16
|
100 {
|
Chris@16
|
101 if (is_not_a_number(v)) return not_a_date_time;
|
Chris@16
|
102 if (is_neg_inf(v)) return neg_infin;
|
Chris@16
|
103 if (is_pos_inf(v)) return pos_infin;
|
Chris@16
|
104 return not_special;
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107 //-3 leaves room for representations of infinity and not a date
|
Chris@16
|
108 static int_type maxcount()
|
Chris@16
|
109 {
|
Chris@16
|
110 return (::std::numeric_limits<int_type>::max)()-3;
|
Chris@16
|
111 }
|
Chris@16
|
112 bool is_infinity() const
|
Chris@16
|
113 {
|
Chris@16
|
114 return (value_ == neg_infinity().as_number() ||
|
Chris@16
|
115 value_ == pos_infinity().as_number());
|
Chris@16
|
116 }
|
Chris@16
|
117 bool is_pos_infinity()const
|
Chris@16
|
118 {
|
Chris@16
|
119 return(value_ == pos_infinity().as_number());
|
Chris@16
|
120 }
|
Chris@16
|
121 bool is_neg_infinity()const
|
Chris@16
|
122 {
|
Chris@16
|
123 return(value_ == neg_infinity().as_number());
|
Chris@16
|
124 }
|
Chris@16
|
125 bool is_nan() const
|
Chris@16
|
126 {
|
Chris@16
|
127 return (value_ == not_a_number().as_number());
|
Chris@16
|
128 }
|
Chris@16
|
129 bool is_special() const
|
Chris@16
|
130 {
|
Chris@16
|
131 return(is_infinity() || is_nan());
|
Chris@16
|
132 }
|
Chris@16
|
133 bool operator==(const int_adapter& rhs) const
|
Chris@16
|
134 {
|
Chris@16
|
135 return (compare(rhs) == 0);
|
Chris@16
|
136 }
|
Chris@16
|
137 bool operator==(const int& rhs) const
|
Chris@16
|
138 {
|
Chris@16
|
139 // quiets compiler warnings
|
Chris@16
|
140 bool is_signed = std::numeric_limits<int_type>::is_signed;
|
Chris@16
|
141 if(!is_signed)
|
Chris@16
|
142 {
|
Chris@16
|
143 if(is_neg_inf(value_) && rhs == 0)
|
Chris@16
|
144 {
|
Chris@16
|
145 return false;
|
Chris@16
|
146 }
|
Chris@16
|
147 }
|
Chris@16
|
148 return (compare(rhs) == 0);
|
Chris@16
|
149 }
|
Chris@16
|
150 bool operator!=(const int_adapter& rhs) const
|
Chris@16
|
151 {
|
Chris@16
|
152 return (compare(rhs) != 0);
|
Chris@16
|
153 }
|
Chris@16
|
154 bool operator!=(const int& rhs) const
|
Chris@16
|
155 {
|
Chris@16
|
156 // quiets compiler warnings
|
Chris@16
|
157 bool is_signed = std::numeric_limits<int_type>::is_signed;
|
Chris@16
|
158 if(!is_signed)
|
Chris@16
|
159 {
|
Chris@16
|
160 if(is_neg_inf(value_) && rhs == 0)
|
Chris@16
|
161 {
|
Chris@16
|
162 return true;
|
Chris@16
|
163 }
|
Chris@16
|
164 }
|
Chris@16
|
165 return (compare(rhs) != 0);
|
Chris@16
|
166 }
|
Chris@16
|
167 bool operator<(const int_adapter& rhs) const
|
Chris@16
|
168 {
|
Chris@16
|
169 return (compare(rhs) == -1);
|
Chris@16
|
170 }
|
Chris@16
|
171 bool operator<(const int& rhs) const
|
Chris@16
|
172 {
|
Chris@16
|
173 // quiets compiler warnings
|
Chris@16
|
174 bool is_signed = std::numeric_limits<int_type>::is_signed;
|
Chris@16
|
175 if(!is_signed)
|
Chris@16
|
176 {
|
Chris@16
|
177 if(is_neg_inf(value_) && rhs == 0)
|
Chris@16
|
178 {
|
Chris@16
|
179 return true;
|
Chris@16
|
180 }
|
Chris@16
|
181 }
|
Chris@16
|
182 return (compare(rhs) == -1);
|
Chris@16
|
183 }
|
Chris@16
|
184 bool operator>(const int_adapter& rhs) const
|
Chris@16
|
185 {
|
Chris@16
|
186 return (compare(rhs) == 1);
|
Chris@16
|
187 }
|
Chris@16
|
188 int_type as_number() const
|
Chris@16
|
189 {
|
Chris@16
|
190 return value_;
|
Chris@16
|
191 }
|
Chris@16
|
192 //! Returns either special value type or is_not_special
|
Chris@16
|
193 special_values as_special() const
|
Chris@16
|
194 {
|
Chris@16
|
195 return int_adapter::to_special(value_);
|
Chris@16
|
196 }
|
Chris@16
|
197 //creates nasty ambiguities
|
Chris@16
|
198 // operator int_type() const
|
Chris@16
|
199 // {
|
Chris@16
|
200 // return value_;
|
Chris@16
|
201 // }
|
Chris@16
|
202
|
Chris@16
|
203 /*! Operator allows for adding dissimilar int_adapter types.
|
Chris@16
|
204 * The return type will match that of the the calling object's type */
|
Chris@16
|
205 template<class rhs_type>
|
Chris@16
|
206 inline
|
Chris@16
|
207 int_adapter operator+(const int_adapter<rhs_type>& rhs) const
|
Chris@16
|
208 {
|
Chris@16
|
209 if(is_special() || rhs.is_special())
|
Chris@16
|
210 {
|
Chris@16
|
211 if (is_nan() || rhs.is_nan())
|
Chris@16
|
212 {
|
Chris@16
|
213 return int_adapter::not_a_number();
|
Chris@16
|
214 }
|
Chris@16
|
215 if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ||
|
Chris@16
|
216 (is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) )
|
Chris@16
|
217 {
|
Chris@16
|
218 return int_adapter::not_a_number();
|
Chris@16
|
219 }
|
Chris@16
|
220 if (is_infinity())
|
Chris@16
|
221 {
|
Chris@16
|
222 return *this;
|
Chris@16
|
223 }
|
Chris@16
|
224 if (rhs.is_pos_inf(rhs.as_number()))
|
Chris@16
|
225 {
|
Chris@16
|
226 return int_adapter::pos_infinity();
|
Chris@16
|
227 }
|
Chris@16
|
228 if (rhs.is_neg_inf(rhs.as_number()))
|
Chris@16
|
229 {
|
Chris@16
|
230 return int_adapter::neg_infinity();
|
Chris@16
|
231 }
|
Chris@16
|
232 }
|
Chris@16
|
233 return int_adapter<int_type>(value_ + rhs.as_number());
|
Chris@16
|
234 }
|
Chris@16
|
235
|
Chris@16
|
236 int_adapter operator+(const int_type rhs) const
|
Chris@16
|
237 {
|
Chris@16
|
238 if(is_special())
|
Chris@16
|
239 {
|
Chris@16
|
240 if (is_nan())
|
Chris@16
|
241 {
|
Chris@16
|
242 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
243 }
|
Chris@16
|
244 if (is_infinity())
|
Chris@16
|
245 {
|
Chris@16
|
246 return *this;
|
Chris@16
|
247 }
|
Chris@16
|
248 }
|
Chris@16
|
249 return int_adapter<int_type>(value_ + rhs);
|
Chris@16
|
250 }
|
Chris@16
|
251
|
Chris@16
|
252 /*! Operator allows for subtracting dissimilar int_adapter types.
|
Chris@16
|
253 * The return type will match that of the the calling object's type */
|
Chris@16
|
254 template<class rhs_type>
|
Chris@16
|
255 inline
|
Chris@16
|
256 int_adapter operator-(const int_adapter<rhs_type>& rhs)const
|
Chris@16
|
257 {
|
Chris@16
|
258 if(is_special() || rhs.is_special())
|
Chris@16
|
259 {
|
Chris@16
|
260 if (is_nan() || rhs.is_nan())
|
Chris@16
|
261 {
|
Chris@16
|
262 return int_adapter::not_a_number();
|
Chris@16
|
263 }
|
Chris@16
|
264 if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ||
|
Chris@16
|
265 (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) )
|
Chris@16
|
266 {
|
Chris@16
|
267 return int_adapter::not_a_number();
|
Chris@16
|
268 }
|
Chris@16
|
269 if (is_infinity())
|
Chris@16
|
270 {
|
Chris@16
|
271 return *this;
|
Chris@16
|
272 }
|
Chris@16
|
273 if (rhs.is_pos_inf(rhs.as_number()))
|
Chris@16
|
274 {
|
Chris@16
|
275 return int_adapter::neg_infinity();
|
Chris@16
|
276 }
|
Chris@16
|
277 if (rhs.is_neg_inf(rhs.as_number()))
|
Chris@16
|
278 {
|
Chris@16
|
279 return int_adapter::pos_infinity();
|
Chris@16
|
280 }
|
Chris@16
|
281 }
|
Chris@16
|
282 return int_adapter<int_type>(value_ - rhs.as_number());
|
Chris@16
|
283 }
|
Chris@16
|
284 int_adapter operator-(const int_type rhs) const
|
Chris@16
|
285 {
|
Chris@16
|
286 if(is_special())
|
Chris@16
|
287 {
|
Chris@16
|
288 if (is_nan())
|
Chris@16
|
289 {
|
Chris@16
|
290 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
291 }
|
Chris@16
|
292 if (is_infinity())
|
Chris@16
|
293 {
|
Chris@16
|
294 return *this;
|
Chris@16
|
295 }
|
Chris@16
|
296 }
|
Chris@16
|
297 return int_adapter<int_type>(value_ - rhs);
|
Chris@16
|
298 }
|
Chris@16
|
299
|
Chris@16
|
300 // should templatize this to be consistant with op +-
|
Chris@16
|
301 int_adapter operator*(const int_adapter& rhs)const
|
Chris@16
|
302 {
|
Chris@16
|
303 if(this->is_special() || rhs.is_special())
|
Chris@16
|
304 {
|
Chris@16
|
305 return mult_div_specials(rhs);
|
Chris@16
|
306 }
|
Chris@16
|
307 return int_adapter<int_type>(value_ * rhs.value_);
|
Chris@16
|
308 }
|
Chris@16
|
309 /*! Provided for cases when automatic conversion from
|
Chris@16
|
310 * 'int' to 'int_adapter' causes incorrect results. */
|
Chris@16
|
311 int_adapter operator*(const int rhs) const
|
Chris@16
|
312 {
|
Chris@16
|
313 if(is_special())
|
Chris@16
|
314 {
|
Chris@16
|
315 return mult_div_specials(rhs);
|
Chris@16
|
316 }
|
Chris@16
|
317 return int_adapter<int_type>(value_ * rhs);
|
Chris@16
|
318 }
|
Chris@16
|
319
|
Chris@16
|
320 // should templatize this to be consistant with op +-
|
Chris@16
|
321 int_adapter operator/(const int_adapter& rhs)const
|
Chris@16
|
322 {
|
Chris@16
|
323 if(this->is_special() || rhs.is_special())
|
Chris@16
|
324 {
|
Chris@16
|
325 if(is_infinity() && rhs.is_infinity())
|
Chris@16
|
326 {
|
Chris@16
|
327 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
328 }
|
Chris@16
|
329 if(rhs != 0)
|
Chris@16
|
330 {
|
Chris@16
|
331 return mult_div_specials(rhs);
|
Chris@16
|
332 }
|
Chris@16
|
333 else { // let divide by zero blow itself up
|
Chris@16
|
334 return int_adapter<int_type>(value_ / rhs.value_);
|
Chris@16
|
335 }
|
Chris@16
|
336 }
|
Chris@16
|
337 return int_adapter<int_type>(value_ / rhs.value_);
|
Chris@16
|
338 }
|
Chris@16
|
339 /*! Provided for cases when automatic conversion from
|
Chris@16
|
340 * 'int' to 'int_adapter' causes incorrect results. */
|
Chris@16
|
341 int_adapter operator/(const int rhs) const
|
Chris@16
|
342 {
|
Chris@16
|
343 if(is_special() && rhs != 0)
|
Chris@16
|
344 {
|
Chris@16
|
345 return mult_div_specials(rhs);
|
Chris@16
|
346 }
|
Chris@16
|
347 return int_adapter<int_type>(value_ / rhs);
|
Chris@16
|
348 }
|
Chris@16
|
349
|
Chris@16
|
350 // should templatize this to be consistant with op +-
|
Chris@16
|
351 int_adapter operator%(const int_adapter& rhs)const
|
Chris@16
|
352 {
|
Chris@16
|
353 if(this->is_special() || rhs.is_special())
|
Chris@16
|
354 {
|
Chris@16
|
355 if(is_infinity() && rhs.is_infinity())
|
Chris@16
|
356 {
|
Chris@16
|
357 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
358 }
|
Chris@16
|
359 if(rhs != 0)
|
Chris@16
|
360 {
|
Chris@16
|
361 return mult_div_specials(rhs);
|
Chris@16
|
362 }
|
Chris@16
|
363 else { // let divide by zero blow itself up
|
Chris@16
|
364 return int_adapter<int_type>(value_ % rhs.value_);
|
Chris@16
|
365 }
|
Chris@16
|
366 }
|
Chris@16
|
367 return int_adapter<int_type>(value_ % rhs.value_);
|
Chris@16
|
368 }
|
Chris@16
|
369 /*! Provided for cases when automatic conversion from
|
Chris@16
|
370 * 'int' to 'int_adapter' causes incorrect results. */
|
Chris@16
|
371 int_adapter operator%(const int rhs) const
|
Chris@16
|
372 {
|
Chris@16
|
373 if(is_special() && rhs != 0)
|
Chris@16
|
374 {
|
Chris@16
|
375 return mult_div_specials(rhs);
|
Chris@16
|
376 }
|
Chris@16
|
377 return int_adapter<int_type>(value_ % rhs);
|
Chris@16
|
378 }
|
Chris@16
|
379 private:
|
Chris@16
|
380 int_type value_;
|
Chris@16
|
381
|
Chris@16
|
382 //! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs
|
Chris@16
|
383 int compare(const int_adapter& rhs)const
|
Chris@16
|
384 {
|
Chris@16
|
385 if(this->is_special() || rhs.is_special())
|
Chris@16
|
386 {
|
Chris@16
|
387 if(this->is_nan() || rhs.is_nan()) {
|
Chris@16
|
388 if(this->is_nan() && rhs.is_nan()) {
|
Chris@16
|
389 return 0; // equal
|
Chris@16
|
390 }
|
Chris@16
|
391 else {
|
Chris@16
|
392 return 2; // nan
|
Chris@16
|
393 }
|
Chris@16
|
394 }
|
Chris@16
|
395 if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) ||
|
Chris@16
|
396 (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) )
|
Chris@16
|
397 {
|
Chris@16
|
398 return -1; // less than
|
Chris@16
|
399 }
|
Chris@16
|
400 if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) ||
|
Chris@16
|
401 (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) {
|
Chris@16
|
402 return 1; // greater than
|
Chris@16
|
403 }
|
Chris@16
|
404 }
|
Chris@16
|
405 if(value_ < rhs.value_) return -1;
|
Chris@16
|
406 if(value_ > rhs.value_) return 1;
|
Chris@16
|
407 // implied-> if(value_ == rhs.value_)
|
Chris@16
|
408 return 0;
|
Chris@16
|
409 }
|
Chris@16
|
410 /* When multiplying and dividing with at least 1 special value
|
Chris@16
|
411 * very simmilar rules apply. In those cases where the rules
|
Chris@16
|
412 * are different, they are handled in the respective operator
|
Chris@16
|
413 * function. */
|
Chris@16
|
414 //! Assumes at least 'this' or 'rhs' is a special value
|
Chris@16
|
415 int_adapter mult_div_specials(const int_adapter& rhs)const
|
Chris@16
|
416 {
|
Chris@16
|
417 int min_value;
|
Chris@16
|
418 // quiets compiler warnings
|
Chris@16
|
419 bool is_signed = std::numeric_limits<int_type>::is_signed;
|
Chris@16
|
420 if(is_signed) {
|
Chris@16
|
421 min_value = 0;
|
Chris@16
|
422 }
|
Chris@16
|
423 else {
|
Chris@16
|
424 min_value = 1;// there is no zero with unsigned
|
Chris@16
|
425 }
|
Chris@16
|
426 if(this->is_nan() || rhs.is_nan()) {
|
Chris@16
|
427 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
428 }
|
Chris@16
|
429 if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) {
|
Chris@16
|
430 return int_adapter<int_type>(pos_infinity());
|
Chris@16
|
431 }
|
Chris@16
|
432 if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) {
|
Chris@16
|
433 return int_adapter<int_type>(neg_infinity());
|
Chris@16
|
434 }
|
Chris@16
|
435 //implied -> if(this->value_ == 0 || rhs.value_ == 0)
|
Chris@16
|
436 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
437 }
|
Chris@16
|
438 /* Overloaded function necessary because of special
|
Chris@16
|
439 * situation where int_adapter is instantiated with
|
Chris@16
|
440 * 'unsigned' and func is called with negative int.
|
Chris@16
|
441 * It would produce incorrect results since 'unsigned'
|
Chris@16
|
442 * wraps around when initialized with a negative value */
|
Chris@16
|
443 //! Assumes 'this' is a special value
|
Chris@16
|
444 int_adapter mult_div_specials(const int& rhs) const
|
Chris@16
|
445 {
|
Chris@16
|
446 int min_value;
|
Chris@16
|
447 // quiets compiler warnings
|
Chris@16
|
448 bool is_signed = std::numeric_limits<int_type>::is_signed;
|
Chris@16
|
449 if(is_signed) {
|
Chris@16
|
450 min_value = 0;
|
Chris@16
|
451 }
|
Chris@16
|
452 else {
|
Chris@16
|
453 min_value = 1;// there is no zero with unsigned
|
Chris@16
|
454 }
|
Chris@16
|
455 if(this->is_nan()) {
|
Chris@16
|
456 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
457 }
|
Chris@16
|
458 if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) {
|
Chris@16
|
459 return int_adapter<int_type>(pos_infinity());
|
Chris@16
|
460 }
|
Chris@16
|
461 if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) {
|
Chris@16
|
462 return int_adapter<int_type>(neg_infinity());
|
Chris@16
|
463 }
|
Chris@16
|
464 //implied -> if(this->value_ == 0 || rhs.value_ == 0)
|
Chris@16
|
465 return int_adapter<int_type>(not_a_number());
|
Chris@16
|
466 }
|
Chris@16
|
467
|
Chris@16
|
468 };
|
Chris@16
|
469
|
Chris@16
|
470 #ifndef BOOST_DATE_TIME_NO_LOCALE
|
Chris@16
|
471 /*! Expected output is either a numeric representation
|
Chris@16
|
472 * or a special values representation.<BR>
|
Chris@16
|
473 * Ex. "12", "+infinity", "not-a-number", etc. */
|
Chris@16
|
474 //template<class charT = char, class traits = std::traits<charT>, typename int_type>
|
Chris@16
|
475 template<class charT, class traits, typename int_type>
|
Chris@16
|
476 inline
|
Chris@16
|
477 std::basic_ostream<charT, traits>&
|
Chris@16
|
478 operator<<(std::basic_ostream<charT, traits>& os, const int_adapter<int_type>& ia)
|
Chris@16
|
479 {
|
Chris@16
|
480 if(ia.is_special()) {
|
Chris@16
|
481 // switch copied from date_names_put.hpp
|
Chris@16
|
482 switch(ia.as_special())
|
Chris@16
|
483 {
|
Chris@16
|
484 case not_a_date_time:
|
Chris@16
|
485 os << "not-a-number";
|
Chris@16
|
486 break;
|
Chris@16
|
487 case pos_infin:
|
Chris@16
|
488 os << "+infinity";
|
Chris@16
|
489 break;
|
Chris@16
|
490 case neg_infin:
|
Chris@16
|
491 os << "-infinity";
|
Chris@16
|
492 break;
|
Chris@16
|
493 default:
|
Chris@16
|
494 os << "";
|
Chris@16
|
495 }
|
Chris@16
|
496 }
|
Chris@16
|
497 else {
|
Chris@16
|
498 os << ia.as_number();
|
Chris@16
|
499 }
|
Chris@16
|
500 return os;
|
Chris@16
|
501 }
|
Chris@16
|
502 #endif
|
Chris@16
|
503
|
Chris@16
|
504
|
Chris@16
|
505 } } //namespace date_time
|
Chris@16
|
506
|
Chris@16
|
507
|
Chris@16
|
508
|
Chris@16
|
509 #endif
|