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 #ifndef MLN_METAL_ARRAY2D_HH
00027 # define MLN_METAL_ARRAY2D_HH
00028
00029 # include <mln/core/concept/object.hh>
00030
00031 # include <mln/trait/all.hh>
00032 # include <mln/trait/value_.hh>
00033
00034 # include <mln/value/ops.hh>
00035
00036 namespace mln
00037 {
00038
00039
00040 namespace metal {
00041 template <typename T, unsigned r, unsigned c> struct array2d;
00042 }
00043
00044 namespace trait
00045 {
00046
00047 template <typename T, unsigned r, unsigned c>
00048 struct value_< mln::metal::array2d<T, r, c> >
00049 {
00050 typedef trait::value::nature::vectorial nature;
00051 typedef trait::value::kind::data kind;
00052
00053 enum {
00054 nbits = r * c * mln_nbits(T),
00055 card = r * c * mln_card(T)
00056 };
00057 typedef mln_value_quant_from_(card) quant;
00058
00059 typedef metal::array2d<mln_sum(T),r, c> sum;
00060 };
00061
00062 }
00063
00064
00065 namespace metal
00066 {
00067
00068 template <typename T, unsigned r, unsigned c>
00069 struct array2d : public Object< array2d<T, r, c> >
00070 {
00071
00072
00073
00074
00075
00076 array2d();
00077 array2d(T* ptr);
00078
00079
00080
00081 array2d(const array2d<T, r, c>& rhs);
00082
00083 array2d<T, r, c>& operator=(const array2d<T, r, c>& rhs);
00084
00085
00086
00087 template <class U>
00088 array2d<T, r, c> operator*(U w);
00089
00090 template <class U>
00091 array2d<mln_trait_op_div(T,U), r, c>
00092 operator/(U w);
00093
00094 template <typename U>
00095 array2d<mln_trait_op_plus(T,U), r, c>
00096 operator+(const array2d<U, r, c>& rhs) const;
00097 array2d<T, r, c>& operator+=(const array2d<T, r, c>& rhs);
00098
00099 template <typename U>
00100 array2d<mln_trait_op_minus(T,U), r, c>
00101 operator-(const array2d<U, r, c>& rhs) const;
00102 array2d<T, r, c>&
00103 operator-=(const array2d<T, r, c>& rhs);
00104
00105
00106
00107 T operator()(unsigned row, unsigned col) const {
00108 mln_precondition(row < r * c);
00109 return buffer_[col * r + row];
00110 }
00111 T& operator()(unsigned row, unsigned col) {
00112 mln_precondition(row < r * c);
00113 return buffer_[col * r + row];
00114 }
00115
00116
00117
00118 template<unsigned row, unsigned col>
00119 T get() const {
00120 return buffer_[col * r + row];
00121 }
00122 template<unsigned row, unsigned col>
00123 T& get() {
00124 return buffer_[col * r + row];
00125 }
00126
00127 template<unsigned row, unsigned col>
00128 T get_at() const {
00129 mln_precondition(col * r + row < r *c);
00130 return buffer_[col * r + row];
00131 }
00132 template<unsigned row, unsigned col>
00133 T& get_at() {
00134 mln_precondition(col * r + row < r *c);
00135 return buffer_[col * r + row];
00136 }
00137
00138 enum { length = r * c };
00139 protected:
00140
00141 T buffer_[r * c];
00142 };
00143
00144 }
00145
00146 namespace trait
00147 {
00148
00149
00150
00151 template < template <class> class Name,
00152 unsigned r, unsigned c, typename T >
00153 struct set_precise_unary_< Name, metal::array2d<T, r, c> >
00154 {
00155 typedef mln_trait_unary(Name, T) V;
00156 typedef metal::array2d<V, r, c> ret;
00157 };
00158
00159
00160
00161 template < template <class, class> class Name,
00162 unsigned r, unsigned c, typename T,
00163 typename U >
00164 struct set_precise_binary_< Name,
00165 metal::array2d<T, r, c>, metal::array2d<U, r, c> >
00166 {
00167 typedef mln_trait_binary(Name, T, U) V;
00168 typedef metal::array2d<V, r, c> ret;
00169 };
00170
00171 template < unsigned r, unsigned c, typename T,
00172 typename U >
00173 struct set_precise_binary_< op::times,
00174 metal::array2d<T, r, c>, metal::array2d<U, r, c> >
00175 {
00176 typedef mln_sum_product(T,U) ret;
00177 };
00178
00179 template < template <class, class> class Name,
00180 unsigned r, unsigned c, typename T,
00181 typename S >
00182 struct set_precise_binary_< Name,
00183 metal::array2d<T, r, c>, mln::value::scalar_<S> >
00184 {
00185 typedef mln_trait_binary(Name, T, S) V;
00186 typedef metal::array2d<V, r, c> ret;
00187 };
00188
00189 template < template<class, class> class Name,
00190 unsigned r, unsigned c, typename T,
00191 typename S >
00192 struct set_binary_< Name,
00193 mln::Object, metal::array2d<T, r, c>,
00194 mln::value::Scalar, S >
00195 {
00196 typedef mln_trait_binary(Name, T, S) V;
00197 typedef metal::array2d<T, r, c> ret;
00198 };
00199
00200 }
00201
00202
00203 namespace metal
00204 {
00205
00206
00207
00208
00209
00210 template <typename T, unsigned r, unsigned c>
00211 array2d<T, r, c>::array2d()
00212 {
00213 }
00214
00215 template <typename T, unsigned r, unsigned c>
00216 array2d<T, r, c>::array2d(T* ptr)
00217 {
00218 for (unsigned i = 0; i < r * c; ++i)
00219 buffer_[i] = *ptr++;
00220 }
00221
00222
00223
00224 template <typename T, unsigned r, unsigned c>
00225 array2d<T, r, c>::array2d(const array2d<T, r, c>& rhs)
00226 {
00227 for (unsigned i = 0; i < r * c; ++i)
00228 buffer_[i] = rhs[i];
00229 }
00230 template <typename T, unsigned r, unsigned c>
00231 array2d<T, r, c>&
00232 array2d<T, r, c>::operator=(const array2d<T, r, c>& rhs)
00233 {
00234 for (unsigned i = 0; i < r * c; ++i)
00235 buffer_[i] = rhs[i];
00236 return *this;
00237 }
00238
00239
00240
00241 template <typename T, unsigned r, unsigned c>
00242 template <class U>
00243 array2d<T, r, c>
00244 array2d<T, r, c>::operator*(U w)
00245 {
00246
00247 array2d<T, r, c> tmp;
00248 for (unsigned i = 0; i < r * c; ++i)
00249 tmp[i] = this->buffer_[i] * w;
00250 return tmp;
00251 }
00252
00253 template <typename T, unsigned r, unsigned c>
00254 template <class U>
00255 array2d<mln_trait_op_div(T,U), r, c>
00256 array2d<T,r, c>::operator/(U w)
00257 {
00258 array2d<T, r, c> tmp;
00259 for (unsigned i = 0; i < r * c; ++i)
00260 tmp[i] = this->buffer_[i] / w;
00261 return tmp;
00262 }
00263
00264 template <typename T, unsigned r, unsigned c>
00265 template <typename U>
00266 array2d<mln_trait_op_plus(T,U), r, c>
00267 array2d<T,r, c>::operator+(const array2d<U, r, c>& rhs) const
00268 {
00269 array2d<T, r, c> tmp;
00270 for (unsigned i = 0; i < r * c; ++i)
00271 tmp[i] = this->buffer_[i] + rhs.buffer_[i];
00272 return tmp;
00273 }
00274 template <typename T, unsigned r, unsigned c>
00275 array2d<T, r, c>&
00276 array2d<T, r, c>::operator+=(const array2d<T, r, c>& rhs)
00277 {
00278 for (unsigned i = 0; i < r * c; ++i)
00279 this->buffer_[i] += rhs.buffer_[i];
00280 return *this;
00281 }
00282
00283 template <typename T, unsigned r, unsigned c>
00284 template <typename U>
00285 array2d<mln_trait_op_minus(T,U), r, c>
00286 array2d<T,r, c>::operator-(const array2d<U, r, c>& rhs) const
00287 {
00288 array2d<T, r, c> tmp;
00289 for (unsigned i = 0; i < r * c; ++i)
00290 tmp[i] = this->buffer_[i] - rhs.buffer_[i];
00291 return tmp;
00292 }
00293 template <typename T, unsigned r, unsigned c>
00294 array2d<T, r, c>&
00295 array2d<T, r, c>::operator-=(const array2d<T, r, c>& rhs)
00296 {
00297 for (unsigned i = 0; i < r * c; ++i)
00298 this->buffer_[i] -= rhs.buffer_[i];
00299 return *this;
00300 }
00301
00302 }
00303
00304 }
00305
00306 #endif // ! MLN_METAL_ARRAY2D_HH