]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/date_time/include/boost/date_time/wrapping_int.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / date_time / include / boost / date_time / wrapping_int.hpp
1 #ifndef _DATE_TIME_WRAPPING_INT_HPP__
2 #define _DATE_TIME_WRAPPING_INT_HPP__
3
4 /* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
5 * Use, modification and distribution is subject to the
6 * Boost Software License, Version 1.0. (See accompanying
7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
8 * Author: Jeff Garland, Bart Garst
9 * $Date$
10 */
11
12
13 namespace boost {
14 namespace date_time {
15
16 //! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type)
17 /*! In composite date and time types this type is used to
18 * wrap at the day boundary.
19 * Ex:
20 * A wrapping_int<short, 10> will roll over after nine, and
21 * roll under below zero. This gives a range of [0,9]
22 *
23 * NOTE: it is strongly recommended that wrapping_int2 be used
24 * instead of wrapping_int as wrapping_int is to be depricated
25 * at some point soon.
26 *
27 * Also Note that warnings will occur if instantiated with an
28 * unsigned type. Only a signed type should be used!
29 */
30 template<typename int_type_, int_type_ wrap_val>
31 class wrapping_int {
32 public:
33 typedef int_type_ int_type;
34 //typedef overflow_type_ overflow_type;
35 static int_type wrap_value() {return wrap_val;}
36 //!Add, return true if wrapped
37 wrapping_int(int_type v) : value_(v) {}
38 //! Explicit converion method
39 int_type as_int() const {return value_;}
40 operator int_type() const {return value_;}
41 //!Add, return number of wraps performed
42 /*! The sign of the returned value will indicate which direction the
43 * wraps went. Ex: add a negative number and wrapping under could occur,
44 * this would be indicated by a negative return value. If wrapping over
45 * took place, a positive value would be returned */
46 template< typename IntT >
47 IntT add(IntT v)
48 {
49 int_type remainder = static_cast<int_type>(v % (wrap_val));
50 IntT overflow = static_cast<IntT>(v / (wrap_val));
51 value_ = static_cast<int_type>(value_ + remainder);
52 return calculate_wrap(overflow);
53 }
54 //! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps)
55 /*! The sign of the returned value will indicate which direction the
56 * wraps went (positive indicates wrap under, negative indicates wrap over).
57 * Ex: subtract a negative number and wrapping over could
58 * occur, this would be indicated by a negative return value. If
59 * wrapping under took place, a positive value would be returned. */
60 template< typename IntT >
61 IntT subtract(IntT v)
62 {
63 int_type remainder = static_cast<int_type>(v % (wrap_val));
64 IntT underflow = static_cast<IntT>(-(v / (wrap_val)));
65 value_ = static_cast<int_type>(value_ - remainder);
66 return calculate_wrap(underflow) * -1;
67 }
68 private:
69 int_type value_;
70
71 template< typename IntT >
72 IntT calculate_wrap(IntT wrap)
73 {
74 if ((value_) >= wrap_val)
75 {
76 ++wrap;
77 value_ -= (wrap_val);
78 }
79 else if(value_ < 0)
80 {
81 --wrap;
82 value_ += (wrap_val);
83 }
84 return wrap;
85 }
86
87 };
88
89
90 //! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type)
91 /*! Bad name, quick impl to fix a bug -- fix later!!
92 * This allows the wrap to restart at a value other than 0.
93 */
94 template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
95 class wrapping_int2 {
96 public:
97 typedef int_type_ int_type;
98 static int_type wrap_value() {return wrap_max;}
99 static int_type min_value() {return wrap_min;}
100 /*! If initializing value is out of range of [wrap_min, wrap_max],
101 * value will be initialized to closest of min or max */
102 wrapping_int2(int_type v) : value_(v) {
103 if(value_ < wrap_min)
104 {
105 value_ = wrap_min;
106 }
107 if(value_ > wrap_max)
108 {
109 value_ = wrap_max;
110 }
111 }
112 //! Explicit converion method
113 int_type as_int() const {return value_;}
114 operator int_type() const {return value_;}
115 //!Add, return number of wraps performed
116 /*! The sign of the returned value will indicate which direction the
117 * wraps went. Ex: add a negative number and wrapping under could occur,
118 * this would be indicated by a negative return value. If wrapping over
119 * took place, a positive value would be returned */
120 template< typename IntT >
121 IntT add(IntT v)
122 {
123 int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
124 IntT overflow = static_cast<IntT>(v / (wrap_max - wrap_min + 1));
125 value_ = static_cast<int_type>(value_ + remainder);
126 return calculate_wrap(overflow);
127 }
128 //! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps)
129 /*! The sign of the returned value will indicate which direction the
130 * wraps went. Ex: subtract a negative number and wrapping over could
131 * occur, this would be indicated by a positive return value. If
132 * wrapping under took place, a negative value would be returned */
133 template< typename IntT >
134 IntT subtract(IntT v)
135 {
136 int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
137 IntT underflow = static_cast<IntT>(-(v / (wrap_max - wrap_min + 1)));
138 value_ = static_cast<int_type>(value_ - remainder);
139 return calculate_wrap(underflow);
140 }
141
142 private:
143 int_type value_;
144
145 template< typename IntT >
146 IntT calculate_wrap(IntT wrap)
147 {
148 if ((value_) > wrap_max)
149 {
150 ++wrap;
151 value_ -= (wrap_max - wrap_min + 1);
152 }
153 else if((value_) < wrap_min)
154 {
155 --wrap;
156 value_ += (wrap_max - wrap_min + 1);
157 }
158 return wrap;
159 }
160 };
161
162
163
164 } } //namespace date_time
165
166
167
168 #endif
169