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_CYCLE_HH
00029 # define NTG_REAL_CYCLE_HH
00030
00031 # include <ntg/basics.hh>
00032 # include <ntg/core/internal/macros.hh>
00033 # include <ntg/core/interval.hh>
00034
00035 # include <mlc/is_a.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>
00049 struct typetraits<cycle<T, interval> > : public typetraits<T>
00050 {
00051 typedef cycle<T, interval> self;
00052 typedef typename typetraits<T>::abstract_type abstract_type;
00053 typedef self ntg_type;
00054 typedef optraits<self> optraits_type;
00055 typedef cycle_behavior::get<self> behavior_type;
00056 typedef cycle_behavior abstract_behavior_type;
00057
00058 typedef typename typetraits<T>::base_type base_type;
00059 typedef T storage_type;
00060 typedef typename typetraits<T>::signed_type signed_type;
00061 typedef typename typetraits<T>::unsigned_type unsigned_type;
00062 typedef self cumul_type;
00063 typedef self largest_type;
00064 typedef self signed_largest_type;
00065 typedef self signed_cumul_type;
00066 typedef self unsigned_largest_type;
00067 typedef self unsigned_cumul_type;
00068 typedef typename typetraits<T>::integer_type integer_type;
00069 };
00070
00071 }
00072
00073
00074
00075
00076
00077 template <class T,
00078 class interval>
00079 class cycle :
00080 public type_traits<T>::template build_value_type<cycle<T, interval> >::ret
00081 {
00082 public:
00083 typedef cycle<T, interval> self;
00084
00085 private:
00086 typedef ntgi_optraits_type(self) optraits_type;
00087 typedef ntg_base_type(self) base_type;
00088 typedef ntgi_storage_type(base_type) base_storage_type;
00089
00090 public:
00091 cycle () { this->val_ = 0; }
00092
00093 template <class U>
00094 cycle (const U& u)
00095 {
00096 ntg_is_a(U, real)::ensure();
00097 this->val_ = optraits_type::check(u);
00098 }
00099 template <class U>
00100 self&
00101 operator=(const U& u)
00102 {
00103 this->val_ = optraits_type::check(u);
00104 return *this;
00105 }
00106
00107 operator base_storage_type() const { return this->val_; }
00108 };
00109
00110 template<class T, class interval>
00111 inline std::ostream&
00112 operator<<(std::ostream& stream, const cycle<T, interval>& rhs)
00113 {
00114
00115 stream << (ntg_largest_type(T))(rhs.val());
00116 return stream;
00117 }
00118
00119 namespace internal {
00120
00121
00122
00123
00124
00125 template<class T,
00126 class interval>
00127 struct optraits<cycle<T, interval> > : public optraits<T>
00128 {
00129 public:
00130 typedef cycle<T, interval> self;
00131
00132 private:
00133 typedef typename typetraits<self>::storage_type storage_type_;
00134 typedef typename interval::storage_type interval_type_;
00135 typedef typename typetraits<self>::behavior_type behavior_type_;
00136
00137 public:
00138 static interval_type_ min()
00139 { return interval::min(); }
00140
00141 static interval_type_ max()
00142 { return interval::max(); }
00143
00144 static interval_type_ inf()
00145 { return interval::inf(); }
00146
00147 static interval_type_ sup()
00148 { return interval::sup(); }
00149
00150 template <class P>
00151 static storage_type_
00152 check(const P& rhs)
00153 { return behavior_type_::check(rhs); }
00154
00155 static std::string
00156 name()
00157 {
00158 std::ostringstream out;
00159 out << "cycle<" << optraits<T>::name() << ", "
00160 << interval::name() << ">"<< std::ends;
00161 return out.str();
00162 }
00163 };
00164
00165
00166 template <class Op, class T, class I, class U>
00167 struct operator_traits<Op, cycle<T, I>, U>
00168 : public deduce_from_traits<Op, T, U>::deduced_traits
00169 {};
00170
00171
00172 template <class Op, class T, class I, class U>
00173 struct operator_traits<Op, U, cycle<T, I> >
00174 : public deduce_from_traits<Op, U, T>::deduced_traits
00175 {};
00176
00177
00178 template <class Op, class T1, class I1, class T2, class I2>
00179 struct operator_traits<Op, cycle<T1, I1>, cycle<T2, I2> >
00180 : public deduce_from_traits<Op, T1, T2>::deduced_traits
00181 {};
00182
00183 }
00184
00185 }
00186
00187 #endif // !NTG_REAL_CYCLE_HH