00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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 }
00072
00073
00074
00075
00076
00078
00079
00080
00081
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
00121 stream << (ntg_largest_type(T))(rhs.val());
00122 return stream;
00123 }
00124
00125 namespace internal {
00126
00127
00128
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
00171
00172
00173
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
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
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 }
00194
00195 }
00196
00197 #endif // !NTG_REAL_RANGE_HH