range.hh

00001 // Copyright (C) 2001, 2002, 2003  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef NTG_REAL_RANGE_HH
00029 # define NTG_REAL_RANGE_HH
00030 
00031 # include <mlc/is_a.hh>
00032 
00033 # include <ntg/basics.hh>
00034 # include <ntg/core/internal/macros.hh>
00035 # include <ntg/real/optraits_real.hh>
00036 
00037 # include <string>
00038 # include <sstream>
00039 
00040 namespace ntg {
00041 
00042   namespace internal {
00043 
00044     /*------------------.
00045     | typetraits<range> |
00046     `------------------*/
00047 
00048     template <class T, class interval, class behavior>
00049     struct typetraits<range<T, interval, behavior> > : public typetraits<T>
00050     {
00051       typedef range<T, interval, behavior>      self;
00052       typedef ntgi_abstract_type(T)             abstract_type;
00053       typedef self                              ntg_type;
00054       typedef optraits<self>                    optraits_type;
00055       typedef typename behavior::template get<self>     behavior_type;
00056       typedef behavior                          abstract_behavior_type;
00057 
00058       typedef ntgi_base_type(T)                 base_type;
00059       typedef T                                 storage_type;
00060       typedef ntgi_signed_type(T)               signed_type;
00061       typedef ntgi_unsigned_type(T)             unsigned_type;
00062       typedef ntgi_cumul_type(T)                cumul_type;
00063       typedef ntgi_largest_type(T)              largest_type;
00064       typedef ntgi_signed_largest_type(T)       signed_largest_type;
00065       typedef ntgi_signed_cumul_type(T)         signed_cumul_type;
00066       typedef ntgi_unsigned_largest_type(T)     unsigned_largest_type;
00067       typedef ntgi_unsigned_cumul_type(T)       unsigned_cumul_type;
00068       typedef ntgi_integer_type(T)              integer_type;
00069     };
00070 
00071   } // end of internal.
00072 
00073   /*-----------------------------.
00074   | range<T, Interval, Behavior> |
00075   `-----------------------------*/
00076 
00078   /*
00079     Range is a decorator. Thanks to the build_value_type helper in
00080     typetraits, it can insert into a precise place of the hierarchy,
00081     depending on T.
00082   */
00083   template <class T, class interval, class behavior>
00084   class range : 
00085     public type_traits<T>::template build_value_type<range<T, interval, behavior> >::ret
00086   {
00087   public:
00088     typedef range<T, interval, behavior> self;
00089 
00090   private:
00091     typedef ntgi_optraits_type(self)    optraits_type;
00092     typedef ntg_base_type(self)         base_type;
00093     typedef ntg_storage_type(base_type) base_storage_type;
00094 
00095   public:
00096     range () { this->val_ = 0; }
00097 
00098     template <class U>
00099     range (const U& u)
00100     {
00101       ntg_is_a(U, real)::ensure();
00102       this->val_ = optraits_type::check(u);
00103     }
00104     template <class U>
00105     self&
00106     operator=(const U& u)
00107     {
00108       this->val_ = optraits_type::check(u);
00109       return *this;
00110     }
00111 
00112     template <class U>
00113     operator U() const { return this->val_; }
00114   };
00115 
00116   template<class T, class interval, class behavior>
00117   inline std::ostream&
00118   operator<<(std::ostream& stream, const range<T, interval, behavior>& rhs)
00119   {
00120     // Cast useful for range<unsigned char, ...>
00121     stream << (ntg_largest_type(T))(rhs.val());
00122     return stream;
00123   }
00124 
00125   namespace internal {
00126 
00127     /*----------------.
00128     | optraits<range> |
00129     `----------------*/
00130 
00131     template<class T, class interval, class behavior>
00132     struct optraits<range<T, interval, behavior> > : public optraits<T>
00133     {
00134     public:
00135       typedef range<T, interval, behavior> self;
00136 
00137     private:
00138       typedef typename typetraits<self>::storage_type   storage_type_;
00139       typedef typename behavior::template get<self>             behavior_type_;
00140       typedef typename interval::storage_type           interval_type_;
00141 
00142     public:
00143       template <class P>
00144       static storage_type_ check(const P& rhs)
00145       { return behavior_type_::check(rhs); }
00146 
00147       static interval_type_ min()
00148       { return interval::min(); }
00149     
00150       static interval_type_ max()
00151       { return interval::max(); }
00152 
00153       static interval_type_ inf()
00154       { return interval::inf(); }
00155     
00156       static interval_type_ sup()
00157       { return interval::sup(); }
00158     
00159       static std::string
00160       name() 
00161       {
00162         std::ostringstream out;
00163         out << "range<" << optraits<T>::name() << ", " << interval::name() 
00164             << ", " << behavior::name() << ">"<< std::ends;
00165         return out.str();
00166       }
00167     };
00168 
00169     /*----------------.
00170     | operator traits |
00171     `----------------*/
00172 
00173     // Inherit operator traits from the base type.
00174     template <class Op, class T, class I, class B, class U>
00175     struct operator_traits<Op, range<T, I, B>, U> 
00176       : public deduce_from_traits<Op, T, U>::deduced_traits
00177     {}; 
00178 
00179     // Inherit operator traits from the base type.
00180     template <class Op, class T, class I, class B, class U>
00181     struct operator_traits<Op, U, range<T, I, B> >
00182       : public deduce_from_traits<Op, U, T>::deduced_traits
00183     {};
00184 
00185     // Inherit operator traits from the base type.
00186     template <class Op, 
00187               class T1, class I1, class B1, 
00188               class T2, class I2, class B2>
00189     struct operator_traits<Op, range<T1, I1, B1>, range<T2, I2, B2> >
00190       : public deduce_from_traits<Op, T1, T2>::deduced_traits
00191     {};
00192  
00193   } // end of internal.
00194   
00195 } // end of ntg.
00196 
00197 #endif // !NTG_REAL_RANGE_HH

Generated on Thu Apr 15 20:13:14 2004 for Olena by doxygen 1.3.6-20040222