Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:40

0001 #ifndef _DATE_TIME_WRAPPING_INT_HPP__
0002 #define _DATE_TIME_WRAPPING_INT_HPP__
0003 
0004 /* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
0005  * Use, modification and distribution is subject to the
0006  * Boost Software License, Version 1.0. (See accompanying
0007  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
0008  * Author: Jeff Garland, Bart Garst
0009  * $Date$
0010  */
0011 
0012 #include "boost/config.hpp"
0013 
0014 namespace boost {
0015 namespace date_time {
0016 
0017 //! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type)
0018 /*! In composite date and time types this type is used to
0019  *  wrap at the day boundary.
0020  *  Ex:
0021  *  A wrapping_int<short, 10> will roll over after nine, and
0022  *  roll under below zero. This gives a range of [0,9]
0023  *
0024  * NOTE: it is strongly recommended that wrapping_int2 be used
0025  * instead of wrapping_int as wrapping_int is to be depricated
0026  * at some point soon.
0027  *
0028  * Also Note that warnings will occur if instantiated with an
0029  * unsigned type. Only a signed type should be used!
0030  */
0031 template<typename int_type_, int_type_ wrap_val>
0032 class wrapping_int {
0033 public:
0034   typedef int_type_ int_type;
0035   //typedef overflow_type_ overflow_type;
0036   static BOOST_CONSTEXPR int_type wrap_value() {return wrap_val;}
0037   //!Add, return true if wrapped
0038   BOOST_CXX14_CONSTEXPR wrapping_int(int_type v) : value_(v) {}
0039   //! Explicit converion method
0040   BOOST_CONSTEXPR int_type as_int()   const   {return value_;}
0041   BOOST_CONSTEXPR operator int_type() const   {return value_;}
0042   //!Add, return number of wraps performed
0043   /*! The sign of the returned value will indicate which direction the
0044    * wraps went. Ex: add a negative number and wrapping under could occur,
0045    * this would be indicated by a negative return value. If wrapping over
0046    * took place, a positive value would be returned */
0047   template< typename IntT >
0048   BOOST_CXX14_CONSTEXPR IntT add(IntT v)
0049   {
0050     int_type remainder = static_cast<int_type>(v % (wrap_val));
0051     IntT overflow = static_cast<IntT>(v / (wrap_val));
0052     value_ = static_cast<int_type>(value_ + remainder);
0053     return calculate_wrap(overflow);
0054   }
0055   //! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps)
0056   /*! The sign of the returned value will indicate which direction the
0057    * wraps went (positive indicates wrap under, negative indicates wrap over).
0058    * Ex: subtract a negative number and wrapping over could
0059    * occur, this would be indicated by a negative return value. If
0060    * wrapping under took place, a positive value would be returned. */
0061   template< typename IntT >
0062   BOOST_CXX14_CONSTEXPR IntT subtract(IntT v)
0063   {
0064     int_type remainder = static_cast<int_type>(v % (wrap_val));
0065     IntT underflow = static_cast<IntT>(-(v / (wrap_val)));
0066     value_ = static_cast<int_type>(value_ - remainder);
0067     return calculate_wrap(underflow) * -1;
0068   }
0069 private:
0070   int_type value_;
0071 
0072   template< typename IntT >
0073   BOOST_CXX14_CONSTEXPR IntT calculate_wrap(IntT wrap)
0074   {
0075     if ((value_) >= wrap_val)
0076     {
0077       ++wrap;
0078       value_ -= (wrap_val);
0079     }
0080     else if(value_ < 0)
0081     {
0082       --wrap;
0083       value_ += (wrap_val);
0084     }
0085     return wrap;
0086   }
0087 
0088 };
0089 
0090 
0091 //! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type)
0092 /*! Bad name, quick impl to fix a bug -- fix later!!
0093  *  This allows the wrap to restart at a value other than 0.
0094  */
0095 template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
0096 class wrapping_int2 {
0097 public:
0098   typedef int_type_ int_type;
0099   static BOOST_CONSTEXPR int_type wrap_value() {return wrap_max;}
0100   static BOOST_CONSTEXPR int_type min_value()  {return wrap_min;}
0101   /*! If initializing value is out of range of [wrap_min, wrap_max],
0102    * value will be initialized to closest of min or max */
0103   BOOST_CXX14_CONSTEXPR wrapping_int2(int_type v) : value_(v) {
0104     if(value_ < wrap_min)
0105     {
0106       value_ = wrap_min;
0107     }
0108     if(value_ > wrap_max)
0109     {
0110       value_ = wrap_max;
0111     }
0112   }
0113   //! Explicit converion method
0114   BOOST_CONSTEXPR int_type as_int()   const   {return value_;}
0115   BOOST_CONSTEXPR operator int_type() const {return value_;}
0116   //!Add, return number of wraps performed
0117   /*! The sign of the returned value will indicate which direction the
0118    * wraps went. Ex: add a negative number and wrapping under could occur,
0119    * this would be indicated by a negative return value. If wrapping over
0120    * took place, a positive value would be returned */
0121   template< typename IntT >
0122   BOOST_CXX14_CONSTEXPR IntT add(IntT v)
0123   {
0124     int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
0125     IntT overflow = static_cast<IntT>(v / (wrap_max - wrap_min + 1));
0126     value_ = static_cast<int_type>(value_ + remainder);
0127     return calculate_wrap(overflow);
0128   }
0129   //! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps)
0130   /*! The sign of the returned value will indicate which direction the
0131    * wraps went. Ex: subtract a negative number and wrapping over could
0132    * occur, this would be indicated by a positive return value. If
0133    * wrapping under took place, a negative value would be returned */
0134   template< typename IntT >
0135   BOOST_CXX14_CONSTEXPR IntT subtract(IntT v)
0136   {
0137     int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
0138     IntT underflow = static_cast<IntT>(-(v / (wrap_max - wrap_min + 1)));
0139     value_ = static_cast<int_type>(value_ - remainder);
0140     return calculate_wrap(underflow);
0141   }
0142 
0143 private:
0144   int_type value_;
0145 
0146   template< typename IntT >
0147   BOOST_CXX14_CONSTEXPR IntT calculate_wrap(IntT wrap)
0148   {
0149     if ((value_) > wrap_max)
0150     {
0151       ++wrap;
0152       value_ -= (wrap_max - wrap_min + 1);
0153     }
0154     else if((value_) < wrap_min)
0155     {
0156       --wrap;
0157       value_ += (wrap_max - wrap_min + 1);
0158     }
0159     return wrap;
0160   }
0161 };
0162 
0163 
0164 
0165 } } //namespace date_time
0166 
0167 
0168 
0169 #endif
0170