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 METALIC_ARRAY_1D_HH
00029 # define METALIC_ARRAY_1D_HH
00030
00031 # include <mlc/contract.hh>
00032 # include <mlc/cmp.hh>
00033 # include <mlc/array/objs.hh>
00034 # include <ntg/basics.hh>
00035 # include <iostream>
00036
00037
00038
00039 # include <mlc/array/1d.hxx>
00040
00041 namespace mlc
00042 {
00043
00044 template<class Info_, class T_>
00045 struct array1d
00046 {
00047 typedef array1d self;
00048 typedef T_ T;
00049 typedef Info_ Info;
00050
00051
00052
00053
00054
00055
00056 array1d()
00057 {
00058 }
00059
00060 array1d(T* ptr)
00061 {
00062 less<0, Info_::card>::ensure();
00063 less< Info_::card, internal::max_card_ >::ensure();
00064 for (unsigned i = 0; i < Info_::card; ++i)
00065 buffer_[i] = *ptr++;
00066 }
00067
00068
00069
00070 array1d(const self& rhs)
00071 {
00072 for (unsigned i = 0; i < Info_::card; ++i)
00073 buffer_[i] = rhs[i];
00074 }
00075 self& operator=(const self& rhs)
00076 {
00077 for (unsigned i = 0; i < Info_::card; ++i)
00078 buffer_[i] = rhs[i];
00079 return *this;
00080 }
00081
00082
00083
00084
00085 static std::string
00086 name()
00087 {
00088 return std::string("array1d< Info, ") + ntg_name(T) + " >";
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 array1d<Info_, ntg::float_s>
00100 normalize()
00101 {
00102 array1d<Info_, ntg::float_s> tmp;
00103 ntg::float_s sum = 0.f;
00104 const ntg::float_s epsilon = 0.01f;
00105 unsigned i;
00106 for (i = 0; i < Info_::card; ++i)
00107 sum += this->buffer_[i];
00108 for (i = 0; i < Info_::card; ++i)
00109 tmp[i] = this->buffer_[i] / sum;
00110
00111 sum = 0.f;
00112 for (i = 0; i < Info_::card; ++i)
00113 sum += tmp[i];
00114 postcondition(std::abs(sum - 1) <= epsilon);
00115 return tmp;
00116 }
00117
00118
00119
00120 array1d<array1d_info<Info_::card,
00121 Info_::card - Info_::center - 1,
00122 Info_::i>, T>
00123 operator-() const
00124 {
00125 enum { new_center = Info_::card - Info_::center - 1 };
00126 array1d<array1d_info< Info_::card, new_center, Info_::i>,T> tmp;
00127
00128 for (unsigned i = 0; i < Info_::card; ++i)
00129 tmp[Info_::card - i - 1] = this->operator[](i);
00130 return tmp;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 template <class U>
00140 array1d< Info, ntg_return_type(times, T, U) >
00141 operator*(U w)
00142 {
00143 array1d< Info, ntg_return_type(times, T, U) > tmp;
00144 for (unsigned i = 0; i < Info::card; ++i)
00145 tmp[i] = this->buffer_[i] * w;
00146 return tmp;
00147 }
00148
00149 template <class U>
00150 array1d< Info, ntg_return_type(div, T, U) >
00151 operator/(U w)
00152 {
00153 array1d< Info, ntg_return_type(div, T, U) > tmp;
00154 for (unsigned i = 0; i < Info::card; ++i)
00155 tmp[i] = this->buffer_[i] / w;
00156 return tmp;
00157 }
00158
00159 self operator+(const self& rhs) const
00160 {
00161 self tmp;
00162 for (unsigned i = 0; i < Info::card; ++i)
00163 tmp[i] = this->buffer_[i] + rhs.buffer_[i];
00164 return tmp;
00165 }
00166 self& operator+=(const self& rhs)
00167 {
00168 for (unsigned i = 0; i < Info::card; ++i)
00169 this->buffer_[i] += rhs.buffer_[i];
00170 return *this;
00171 }
00172
00173 self operator-(const self& rhs) const
00174 {
00175 self tmp;
00176 for (unsigned i = 0; i < Info::card; ++i)
00177 tmp[i] = this->buffer_[i] - rhs.buffer_[i];
00178 return tmp;
00179 }
00180 self& operator-=(const self& rhs)
00181 {
00182 for (unsigned i = 0; i < Info::card; ++i)
00183 this->buffer_[i] -= rhs.buffer_[i];
00184 return *this;
00185 }
00186
00187
00188
00189
00190
00191
00192 unsigned size() const
00193 {
00194 return Info_::card;
00195 }
00196
00197 const T* buffer() const
00198 {
00199 return buffer_;
00200 }
00201
00202
00203
00204 T operator[](unsigned i) const
00205 {
00206 precondition(i < Info_::card);
00207 return *(buffer_ + i);
00208 }
00209 T& operator[](unsigned i)
00210 {
00211 precondition(i < Info_::card);
00212 return *(buffer_ + i);
00213 }
00214
00215 T operator()(int i) const
00216 {
00217 precondition(-Info_::center <= i);
00218 precondition(i <= Info_::card - Info_::center - 1);
00219 return *(buffer_ + Info_::center + i);
00220 }
00221 T& operator()(int i)
00222 {
00223 precondition(-Info_::center <= i);
00224 precondition(i <= Info_::card - Info_::center - 1);
00225 return *(buffer_ + Info_::center + i);
00226 }
00227
00228
00229
00230
00231 template<unsigned i>
00232 T get_at_() const {
00233 lesseq<i, Info_::card>::ensure();
00234 return *(buffer_ + i);
00235 }
00236
00237 template<int i>
00238 T get_() const {
00239 lesseq<-Info_::center, i>::ensure();
00240 lesseq<i, Info_::card - Info_::center - 1>::ensure();
00241 return *(buffer_ + Info_::center + i);
00242 }
00243
00244 protected:
00245
00246 T buffer_[Info_::card];
00247 };
00248
00249
00250
00251
00252 template<unsigned i, class Info, class T> inline
00253 T get_at(const array1d<Info, T>& arr)
00254 {
00255 return arr.template get_at_<i>();
00256 }
00257
00258 template<int i, class Info, class T> inline
00259 T get(const array1d<Info, T>& arr)
00260 {
00261 return arr.template get_<i>();
00262 }
00263
00264
00265
00266
00267
00268
00269 # define array1d_starter(T) \
00270 static internal::array1d_start_<T > T##s_1d = internal::array1d_start_<T >()
00271
00272 array1d_starter(int);
00273 array1d_starter(float);
00274
00275
00276
00277
00278
00279 template<class Info, class T>
00280 std::ostream& operator<<(std::ostream& ostr, const array1d<Info, T>& rhs)
00281 {
00282 for (int i = 0; i < Info::card; ++i)
00283 if (i == Info::center)
00284 ostr << "<" << rhs[i] << "> ";
00285 else
00286 ostr << rhs[i] << " ";
00287 ostr << std::endl;
00288
00289 return ostr;
00290 }
00291
00292 }
00293
00294 #endif // ! METALIC_ARRAY_1D_HH