Boost logo

Boost :

From: christopher diggins (cdiggins_at_[hidden])
Date: 2004-05-15 21:37:43


Here is my latest range.hpp file, I should probably change the name back to
constrained_value because of the conflict with iterator ranges? I am a first
time boost contributor , so I would appreciate comments on my style, and
whether this file overextends its intended scope.

To Jeff Garland: do you want me to be fully compatible with your existing
constrained_value type, so that you can link this in without rewriting a
thing?

Thanks to all in advance.

/*
  range.hpp
  Boost range type mini-library
  based on the constrained_value type by Jeff Garland,
http://www.crystalclearsoftware.com/
  modified and enhanced by Christopher Diggins http://www.cdiggins.com
  license available at http://www.boost.org/LICENSE_1_0.txt
*/

#ifndef BOOST_RANGE_HPP
#define BOOST_RANGE_HPP

// TEMP: my preference is to disallow silent casts to range
// the default will have to decided upon by consensus
#define BOOST_RANGE_SILENT_CASTS 1

// you can explicitly turn off range_checking
#ifdef BOOST_RANGE_CHECKING_OFF
#define BOOST_RANGE_CHECKING_ON 0
#else
#define BOOST_RANGE_CHECKING_ON 1
#endif

#include <limits>

namespace boost
{
  namespace range
  {
    using namespace std;

    namespace policies
    {
      // some common policies for range types

      static inline double less_than(double d) {
        return (1.0 - numeric_limits<double>::epsilon()) * d;
      }

      template<typename T>
      struct root {
        typedef T value;
        static void on_error(T value, T min, T max) {
          cerr << "range violation: " << value << " outside of range " <<
min << " to " << max << endl;
        }
      };

      struct unsigned_double : root<double> {
        static const value min() { return 0.0; };
      };

      struct zero_to_one_inclusive : public unsigned_double {
        static const value max() { return 1.0; };
      };

      struct zero_to_one_exclusive : public unsigned_double {
        static const value max() { return less_than(1.0); };
      };

      struct percent : public unsigned_double {
        static const value max() { return 100.0; };
      };

      struct degrees : public unsigned_double {
        static const value max() { return less_than(360.0); };
      };

      const double PI = 3.1415926535897;
      struct radians : public unsigned_double {
        static const value max() { return less_than(2 * PI); };
      };

      template <typename T, T min_T, T max_T>
      struct simple : root<T> {
        static const value min() { return min_T; };
        static const value max() { return max_T; };
      };

      template<int base>
      struct whole_number : simple<unsigned short int, 0, base - 1> {
      };
    };

    // a simple range class
    template<class policy>
    class range {
      public:
        typedef range<policy> self;
        typedef typename policy::value value;
        range() : m(min()) { }
        range(const self& x) { m = x.get_value(); }
        #ifdef BOOST_RANGE_SILENT_CASTS
          range(value x) { assign(x); }
        #endif
        static const value min() { return policy::min(); }
        static const value max() { return policy::max(); }
        const value get_value() const { return m; }
        operator value() { return m; }
        self& operator=(const self& x) { m = x; return *this; }
        #ifdef BOOST_RANGE_SILENT_CASTS
          self& operator=(value x) { assign(x); return *this; }
        #endif
        void assign(const value& x)
        {
          #ifdef BOOST_RANGE_CHECKING_ON
          {
            if (x+1 < min()+1) {
              policy::on_error(x, min(), max());
              return;
            }
            if (x > max()) {
              policy::on_error(x, min(), max());
              return;
            }
          }
          #endif
          m = x;
        }
      private:
        value m;
    };

    // some common types expressed as ranges
    typedef range<policies::zero_to_one_inclusive> probability;
    typedef range<policies::zero_to_one_exclusive> distribution;
    typedef range<policies::percent> percent;
    typedef range<policies::degrees> degrees;
    typedef range<policies::radians> radians;
    typedef range<policies::whole_number<24> > hour;
    typedef range<policies::whole_number<60> > minute;
    typedef range<policies::whole_number<60> > second;
    typedef range<policies::whole_number<10> > decimal_digit;
    typedef range<policies::whole_number<16> > hex_digit;
    typedef range<policies::whole_number<8> > octal_digit;
    typedef range<policies::whole_number<7> > day_of_week;
    typedef range<policies::whole_number<12> > greg_month;
    typedef range<policies::whole_number<365> > greg_day_of_year;

  };
};

#endif // BOOST_RANGE_HPP

Christopher Diggins
http://www.cdiggins.com
http://www.heron-language.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk