source: vendor/nemo/current/NEMOGCM/EXTERNAL/XIOS/extern/boost/include/boost/date_time/wrapping_int.hpp @ 44

Last change on this file since 44 was 44, checked in by cholod, 12 years ago

Load NEMO_TMP into vendor/nemo/current.

File size: 5.5 KB
Line 
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: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
10 */
11
12
13namespace boost {
14namespace 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 */
30template<typename int_type_, int_type_ wrap_val>
31class wrapping_int {
32public:
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  }
68private:
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 */
94template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
95class wrapping_int2 {
96public:
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           
142private:
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
Note: See TracBrowser for help on using the repository browser.