boost/date_time/wrapping_int.hpp
#ifndef _DATE_TIME_WRAPPING_INT_HPP__
#define _DATE_TIME_WRAPPING_INT_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
* Author: Jeff Garland, Bart Garst
* $Date: 2003/12/03 03:14:07 $
*/
namespace boost {
namespace date_time {
//! A wrapping integer used to support time durations
/*! In composite date and time types this type is used to
* wrap at the day boundary.
*
*/
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
wrapping_int(int_type v) : value_(v) {};
//! Explicit converion method
int_type as_int() const {return value_;}
operator int_type() const {return value_;}
int_type add(int_type v)
{
//take the mod here and assign it....
int_type remainder = static_cast<int_type>(v % wrap_val);
int_type overflow = static_cast<int_type>(v / wrap_val);
value_ = static_cast<int_type>(value_ + remainder);
if ((value_) >= wrap_val) {
value_ -= wrap_val;
overflow++;
}
return overflow;
}
int_type subtract(int_type v)
{
//take the mod here and assign it....
int_type remainder = v % wrap_val;
int_type underflow = v / wrap_val;
// std::cout << "wi :" << value_ << "|"
// << v << "|"
// << underflow << "|"
// << remainder << "|"
// << wrap_val << std::endl;
if (remainder > value_) {
underflow++;
// value_ = remainder - value_;
value_ = wrap_val - (remainder-value_);
}
else {
value_ -= remainder;
//value_ = wrap_val-(remainder-value_);
// value_ = wrap_val -(value_-remainder);
}
// std::cout << "wi final uf: " << underflow
// << " value: " << value_ << std::endl;
return underflow;
}
private:
int_type value_;
};
//! A wrapping integer used to wrap around at the top
/*! Bad name, quick impl to fix a bug -- fix later!!
* This allows the wrap to restart at a value other than 0.
* Currently this only works if wrap_min == 1
*/
template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
class wrapping_int2 {
public:
typedef int_type_ int_type;
static unsigned long wrap_value() {return wrap_max;}
static unsigned long 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
int_type add(int_type v)
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
int_type overflow = static_cast<int_type>(v / (wrap_max - wrap_min + 1));
value_ = static_cast<int_type>(value_ + remainder);
if ((value_) > wrap_max)
{
overflow++;
value_ -= (wrap_max - wrap_min + 1);
}
return overflow;
}
//! Subtract will return '-d' if wrapping took place ('d' is the number of wraps)
int_type subtract(int_type v)
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
int_type underflow = static_cast<int_type>(-(v / (wrap_max - wrap_min + 1)));
value_ = static_cast<int_type>(value_ - remainder);
if ((value_) < wrap_min)
{
underflow--;
value_ += (wrap_max - wrap_min + 1);
}
return underflow;
}
private:
int_type value_;
};
} } //namespace date_time
#endif