1 #ifndef DATE_DURATION_TYPES_HPP___ 2 #define DATE_DURATION_TYPES_HPP___ 3 4 /* Copyright (c) 2004 CrystalClear Software, Inc. 5 * Subject to the Boost Software License, Version 1.0. 6 * (See accompanying file LICENSE_1_0.txt or 7 * http://www.boost.org/LICENSE_1_0.txt) 8 * Author: Jeff Garland, Bart Garst 9 * $Date$ 10 */ 11 12 #include <boost/date_time/compiler_config.hpp> 13 #include <boost/date_time/int_adapter.hpp> 14 #include <boost/date_time/special_defs.hpp> 15 #include <boost/date_time/date_duration.hpp> 16 17 namespace boost { 18 namespace date_time { 19 20 21 //! Additional duration type that represents a number of n*7 days 22 template <class duration_config> 23 class BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration<duration_config> { 24 public: weeks_duration(typename duration_config::impl_type w)25 BOOST_CXX14_CONSTEXPR weeks_duration(typename duration_config::impl_type w) 26 : date_duration<duration_config>(w * 7) {} weeks_duration(special_values sv)27 BOOST_CXX14_CONSTEXPR weeks_duration(special_values sv) 28 : date_duration<duration_config>(sv) {} 29 }; 30 31 // predeclare 32 template<class t> 33 class BOOST_SYMBOL_VISIBLE years_duration; 34 35 //! additional duration type that represents a logical month 36 /*! A logical month enables things like: "date(2002,Mar,2) + months(2) -> 37 * 2002-May2". If the date is a last day-of-the-month, the result will 38 * also be a last-day-of-the-month. 39 */ 40 template<class base_config> 41 class BOOST_SYMBOL_VISIBLE months_duration 42 { 43 private: 44 typedef typename base_config::int_rep int_rep; 45 typedef typename int_rep::int_type int_type; 46 typedef typename base_config::date_type date_type; 47 typedef typename date_type::duration_type duration_type; 48 typedef typename base_config::month_adjustor_type month_adjustor_type; 49 typedef months_duration<base_config> months_type; 50 typedef years_duration<base_config> years_type; 51 public: months_duration(int_rep num)52 BOOST_CXX14_CONSTEXPR months_duration(int_rep num) : _m(num) {} months_duration(special_values sv)53 BOOST_CXX14_CONSTEXPR months_duration(special_values sv) : _m(sv) 54 { 55 _m = int_rep::from_special(sv); 56 } number_of_months() const57 int_rep number_of_months() const { return _m; } 58 //! returns a negative duration get_neg_offset(const date_type & d) const59 BOOST_CXX14_CONSTEXPR duration_type get_neg_offset(const date_type& d) const 60 { 61 month_adjustor_type m_adj(_m.as_number()); 62 return duration_type(m_adj.get_neg_offset(d)); 63 } get_offset(const date_type & d) const64 BOOST_CXX14_CONSTEXPR duration_type get_offset(const date_type& d) const 65 { 66 month_adjustor_type m_adj(_m.as_number()); 67 return duration_type(m_adj.get_offset(d)); 68 } operator ==(const months_type & rhs) const69 BOOST_CONSTEXPR bool operator==(const months_type& rhs) const 70 { 71 return(_m == rhs._m); 72 } operator !=(const months_type & rhs) const73 BOOST_CONSTEXPR bool operator!=(const months_type& rhs) const 74 { 75 return(_m != rhs._m); 76 } operator +(const months_type & rhs) const77 BOOST_CXX14_CONSTEXPR months_type operator+(const months_type& rhs)const 78 { 79 return months_type(_m + rhs._m); 80 } operator +=(const months_type & rhs)81 BOOST_CXX14_CONSTEXPR months_type& operator+=(const months_type& rhs) 82 { 83 _m = _m + rhs._m; 84 return *this; 85 } operator -(const months_type & rhs) const86 BOOST_CXX14_CONSTEXPR months_type operator-(const months_type& rhs)const 87 { 88 return months_type(_m - rhs._m); 89 } operator -=(const months_type & rhs)90 BOOST_CXX14_CONSTEXPR months_type& operator-=(const months_type& rhs) 91 { 92 _m = _m - rhs._m; 93 return *this; 94 } operator *(const int_type rhs) const95 BOOST_CXX14_CONSTEXPR months_type operator*(const int_type rhs)const 96 { 97 return months_type(_m * rhs); 98 } operator *=(const int_type rhs)99 BOOST_CXX14_CONSTEXPR months_type& operator*=(const int_type rhs) 100 { 101 _m = _m * rhs; 102 return *this; 103 } operator /(const int_type rhs) const104 BOOST_CXX14_CONSTEXPR months_type operator/(const int_type rhs)const 105 { 106 return months_type(_m / rhs); 107 } operator /=(const int_type rhs)108 BOOST_CXX14_CONSTEXPR months_type& operator/=(const int_type rhs) 109 { 110 _m = _m / rhs; 111 return *this; 112 } operator +(const years_type & y) const113 BOOST_CXX14_CONSTEXPR months_type operator+(const years_type& y)const 114 { 115 return months_type(y.number_of_years() * 12 + _m); 116 } operator +=(const years_type & y)117 BOOST_CXX14_CONSTEXPR months_type& operator+=(const years_type& y) 118 { 119 _m = y.number_of_years() * 12 + _m; 120 return *this; 121 } operator -(const years_type & y) const122 BOOST_CXX14_CONSTEXPR months_type operator-(const years_type& y) const 123 { 124 return months_type(_m - y.number_of_years() * 12); 125 } operator -=(const years_type & y)126 BOOST_CXX14_CONSTEXPR months_type& operator-=(const years_type& y) 127 { 128 _m = _m - y.number_of_years() * 12; 129 return *this; 130 } 131 // operator +(const date_type & d,const months_type & m)132 BOOST_CXX14_CONSTEXPR friend date_type operator+(const date_type& d, const months_type& m) 133 { 134 return d + m.get_offset(d); 135 } operator +=(date_type & d,const months_type & m)136 BOOST_CXX14_CONSTEXPR friend date_type operator+=(date_type& d, const months_type& m) 137 { 138 return d += m.get_offset(d); 139 } operator -(const date_type & d,const months_type & m)140 BOOST_CXX14_CONSTEXPR friend date_type operator-(const date_type& d, const months_type& m) 141 { 142 // get_neg_offset returns a negative duration, so we add 143 return d + m.get_neg_offset(d); 144 } operator -=(date_type & d,const months_type & m)145 BOOST_CXX14_CONSTEXPR friend date_type operator-=(date_type& d, const months_type& m) 146 { 147 // get_neg_offset returns a negative duration, so we add 148 return d += m.get_neg_offset(d); 149 } 150 private: 151 int_rep _m; 152 }; 153 154 //! additional duration type that represents a logical year 155 /*! A logical year enables things like: "date(2002,Mar,2) + years(2) -> 156 * 2004-Mar-2". If the date is a last day-of-the-month, the result will 157 * also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) -> 158 * 2004-Feb-29). 159 */ 160 template<class base_config> 161 class BOOST_SYMBOL_VISIBLE years_duration 162 { 163 private: 164 typedef typename base_config::int_rep int_rep; 165 typedef typename int_rep::int_type int_type; 166 typedef typename base_config::date_type date_type; 167 typedef typename date_type::duration_type duration_type; 168 typedef typename base_config::month_adjustor_type month_adjustor_type; 169 typedef years_duration<base_config> years_type; 170 typedef months_duration<base_config> months_type; 171 public: years_duration(int_rep num)172 BOOST_CXX14_CONSTEXPR years_duration(int_rep num) : _y(num) {} years_duration(special_values sv)173 BOOST_CXX14_CONSTEXPR years_duration(special_values sv) : _y(sv) 174 { 175 _y = int_rep::from_special(sv); 176 } number_of_years() const177 BOOST_CXX14_CONSTEXPR int_rep number_of_years() const { return _y; } 178 //! returns a negative duration get_neg_offset(const date_type & d) const179 BOOST_CXX14_CONSTEXPR duration_type get_neg_offset(const date_type& d) const 180 { 181 month_adjustor_type m_adj(_y.as_number() * 12); 182 return duration_type(m_adj.get_neg_offset(d)); 183 } get_offset(const date_type & d) const184 BOOST_CXX14_CONSTEXPR duration_type get_offset(const date_type& d) const 185 { 186 month_adjustor_type m_adj(_y.as_number() * 12); 187 return duration_type(m_adj.get_offset(d)); 188 } operator ==(const years_type & rhs) const189 BOOST_CXX14_CONSTEXPR bool operator==(const years_type& rhs) const 190 { 191 return(_y == rhs._y); 192 } operator !=(const years_type & rhs) const193 bool operator!=(const years_type& rhs) const 194 { 195 return(_y != rhs._y); 196 } operator +(const years_type & rhs) const197 BOOST_CXX14_CONSTEXPR years_type operator+(const years_type& rhs)const 198 { 199 return years_type(_y + rhs._y); 200 } operator +=(const years_type & rhs)201 BOOST_CXX14_CONSTEXPR years_type& operator+=(const years_type& rhs) 202 { 203 _y = _y + rhs._y; 204 return *this; 205 } operator -(const years_type & rhs) const206 BOOST_CXX14_CONSTEXPR years_type operator-(const years_type& rhs)const 207 { 208 return years_type(_y - rhs._y); 209 } operator -=(const years_type & rhs)210 BOOST_CXX14_CONSTEXPR years_type& operator-=(const years_type& rhs) 211 { 212 _y = _y - rhs._y; 213 return *this; 214 } operator *(const int_type rhs) const215 BOOST_CXX14_CONSTEXPR years_type operator*(const int_type rhs)const 216 { 217 return years_type(_y * rhs); 218 } operator *=(const int_type rhs)219 BOOST_CXX14_CONSTEXPR years_type& operator*=(const int_type rhs) 220 { 221 _y = _y * rhs; 222 return *this; 223 } operator /(const int_type rhs) const224 BOOST_CXX14_CONSTEXPR years_type operator/(const int_type rhs)const 225 { 226 return years_type(_y / rhs); 227 } operator /=(const int_type rhs)228 BOOST_CXX14_CONSTEXPR years_type& operator/=(const int_type rhs) 229 { 230 _y = _y / rhs; 231 return *this; 232 } operator +(const months_type & m) const233 BOOST_CXX14_CONSTEXPR months_type operator+(const months_type& m) const 234 { 235 return(months_type(_y * 12 + m.number_of_months())); 236 } operator -(const months_type & m) const237 BOOST_CXX14_CONSTEXPR months_type operator-(const months_type& m) const 238 { 239 return(months_type(_y * 12 - m.number_of_months())); 240 } 241 // operator +(const date_type & d,const years_type & y)242 BOOST_CXX14_CONSTEXPR friend date_type operator+(const date_type& d, const years_type& y) 243 { 244 return d + y.get_offset(d); 245 } operator +=(date_type & d,const years_type & y)246 BOOST_CXX14_CONSTEXPR friend date_type operator+=(date_type& d, const years_type& y) 247 { 248 return d += y.get_offset(d); 249 } operator -(const date_type & d,const years_type & y)250 BOOST_CXX14_CONSTEXPR friend date_type operator-(const date_type& d, const years_type& y) 251 { 252 // get_neg_offset returns a negative duration, so we add 253 return d + y.get_neg_offset(d); 254 } operator -=(date_type & d,const years_type & y)255 BOOST_CXX14_CONSTEXPR friend date_type operator-=(date_type& d, const years_type& y) 256 { 257 // get_neg_offset returns a negative duration, so we add 258 return d += y.get_neg_offset(d); 259 } 260 private: 261 int_rep _y; 262 }; 263 }} // namespace boost::date_time 264 265 #endif // DATE_DURATION_TYPES_HPP___ 266