YouCompleteMe/cpp/BoostParts/boost/date_time/wrapping_int.hpp

170 lines
5.4 KiB
C++
Raw Normal View History

2012-05-10 00:45:30 -04:00
#ifndef _DATE_TIME_WRAPPING_INT_HPP__
#define _DATE_TIME_WRAPPING_INT_HPP__
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
2013-01-13 17:38:19 -05:00
* Use, modification and distribution is subject to the
2012-05-10 00:45:30 -04:00
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
2013-01-13 17:38:19 -05:00
* $Date: 2012-09-22 15:33:33 -0700 (Sat, 22 Sep 2012) $
2012-05-10 00:45:30 -04:00
*/
namespace boost {
namespace date_time {
//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type)
/*! In composite date and time types this type is used to
* wrap at the day boundary.
2013-01-13 17:38:19 -05:00
* Ex:
* A wrapping_int<short, 10> will roll over after nine, and
2012-05-10 00:45:30 -04:00
* roll under below zero. This gives a range of [0,9]
*
2013-01-13 17:38:19 -05:00
* NOTE: it is strongly recommended that wrapping_int2 be used
* instead of wrapping_int as wrapping_int is to be depricated
2012-05-10 00:45:30 -04:00
* at some point soon.
*
2013-01-13 17:38:19 -05:00
* Also Note that warnings will occur if instantiated with an
2012-05-10 00:45:30 -04:00
* unsigned type. Only a signed type should be used!
*/
template<typename int_type_, int_type_ wrap_val>
class wrapping_int {
public:
typedef int_type_ int_type;
//typedef overflow_type_ overflow_type;
static int_type wrap_value() {return wrap_val;}
//!Add, return true if wrapped
2013-01-13 17:38:19 -05:00
wrapping_int(int_type v) : value_(v) {}
2012-05-10 00:45:30 -04:00
//! Explicit converion method
int_type as_int() const {return value_;}
operator int_type() const {return value_;}
//!Add, return number of wraps performed
2013-01-13 17:38:19 -05:00
/*! The sign of the returned value will indicate which direction the
2012-05-10 00:45:30 -04:00
* wraps went. Ex: add a negative number and wrapping under could occur,
2013-01-13 17:38:19 -05:00
* this would be indicated by a negative return value. If wrapping over
2012-05-10 00:45:30 -04:00
* took place, a positive value would be returned */
template< typename IntT >
2013-01-13 17:38:19 -05:00
IntT add(IntT v)
2012-05-10 00:45:30 -04:00
{
int_type remainder = static_cast<int_type>(v % (wrap_val));
IntT overflow = static_cast<IntT>(v / (wrap_val));
value_ = static_cast<int_type>(value_ + remainder);
return calculate_wrap(overflow);
}
//! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps)
/*! The sign of the returned value will indicate which direction the
2013-01-13 17:38:19 -05:00
* wraps went (positive indicates wrap under, negative indicates wrap over).
* Ex: subtract a negative number and wrapping over could
* occur, this would be indicated by a negative return value. If
2012-05-10 00:45:30 -04:00
* wrapping under took place, a positive value would be returned. */
template< typename IntT >
2013-01-13 17:38:19 -05:00
IntT subtract(IntT v)
2012-05-10 00:45:30 -04:00
{
int_type remainder = static_cast<int_type>(v % (wrap_val));
IntT underflow = static_cast<IntT>(-(v / (wrap_val)));
value_ = static_cast<int_type>(value_ - remainder);
return calculate_wrap(underflow) * -1;
}
private:
int_type value_;
template< typename IntT >
IntT calculate_wrap(IntT wrap)
{
2013-01-13 17:38:19 -05:00
if ((value_) >= wrap_val)
2012-05-10 00:45:30 -04:00
{
++wrap;
value_ -= (wrap_val);
}
2013-01-13 17:38:19 -05:00
else if(value_ < 0)
2012-05-10 00:45:30 -04:00
{
--wrap;
value_ += (wrap_val);
}
return wrap;
}
2013-01-13 17:38:19 -05:00
2012-05-10 00:45:30 -04:00
};
//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type)
/*! Bad name, quick impl to fix a bug -- fix later!!
* This allows the wrap to restart at a value other than 0.
*/
template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
class wrapping_int2 {
public:
typedef int_type_ int_type;
static int_type wrap_value() {return wrap_max;}
static int_type min_value() {return wrap_min;}
/*! If initializing value is out of range of [wrap_min, wrap_max],
* value will be initialized to closest of min or max */
wrapping_int2(int_type v) : value_(v) {
if(value_ < wrap_min)
{
value_ = wrap_min;
}
if(value_ > wrap_max)
{
value_ = wrap_max;
}
}
//! Explicit converion method
int_type as_int() const {return value_;}
operator int_type() const {return value_;}
//!Add, return number of wraps performed
2013-01-13 17:38:19 -05:00
/*! The sign of the returned value will indicate which direction the
2012-05-10 00:45:30 -04:00
* wraps went. Ex: add a negative number and wrapping under could occur,
2013-01-13 17:38:19 -05:00
* this would be indicated by a negative return value. If wrapping over
2012-05-10 00:45:30 -04:00
* took place, a positive value would be returned */
template< typename IntT >
2013-01-13 17:38:19 -05:00
IntT add(IntT v)
2012-05-10 00:45:30 -04:00
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
IntT overflow = static_cast<IntT>(v / (wrap_max - wrap_min + 1));
value_ = static_cast<int_type>(value_ + remainder);
return calculate_wrap(overflow);
}
//! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps)
/*! The sign of the returned value will indicate which direction the
2013-01-13 17:38:19 -05:00
* wraps went. Ex: subtract a negative number and wrapping over could
* occur, this would be indicated by a positive return value. If
2012-05-10 00:45:30 -04:00
* wrapping under took place, a negative value would be returned */
template< typename IntT >
2013-01-13 17:38:19 -05:00
IntT subtract(IntT v)
2012-05-10 00:45:30 -04:00
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
IntT underflow = static_cast<IntT>(-(v / (wrap_max - wrap_min + 1)));
value_ = static_cast<int_type>(value_ - remainder);
return calculate_wrap(underflow);
}
2013-01-13 17:38:19 -05:00
2012-05-10 00:45:30 -04:00
private:
int_type value_;
template< typename IntT >
IntT calculate_wrap(IntT wrap)
{
2013-01-13 17:38:19 -05:00
if ((value_) > wrap_max)
2012-05-10 00:45:30 -04:00
{
++wrap;
value_ -= (wrap_max - wrap_min + 1);
}
2013-01-13 17:38:19 -05:00
else if((value_) < wrap_min)
2012-05-10 00:45:30 -04:00
{
--wrap;
value_ += (wrap_max - wrap_min + 1);
}
return wrap;
}
};
} } //namespace date_time
#endif