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