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_2D_HXX
00029 # define METALIC_ARRAY_2D_HXX
00030
00031 # include <mlc/array/nd.hh>
00032
00033 namespace mlc
00034 {
00035
00036
00037
00038
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 template < unsigned nrows_,
00056 unsigned ncols_,
00057 unsigned center_ = ncols_ * (nrows_ / 2) + (ncols_ / 2),
00058 unsigned i_ = nrows_ * ncols_>
00059 struct array2d_info
00060 {
00061 enum {
00062 nrows = nrows_,
00063 ncols = ncols_,
00064 center = center_,
00065 center_row = center_ / ncols_,
00066 center_col = center_ % ncols_,
00067 card = nrows_ * ncols_,
00068 i = i_,
00069 well_formed = ((i_ % ncols_) == 0),
00070 get_real_center = center_
00071 };
00072
00073 typedef array2d_info< nrows_, ncols_, center_, i + 1 > next_elt;
00074
00075 };
00076
00077
00078
00079 template < unsigned nrows_, unsigned ncols_, unsigned i_ >
00080 struct array2d_info <nrows_, ncols_, internal::unknown_, i_ >
00081 {
00082 enum {
00083 nrows = nrows_,
00084 ncols = ncols_,
00085 center = internal::unknown_,
00086 i = i_,
00087 card = nrows_ * ncols_,
00088 well_formed = ((i_ % ncols_) == 0),
00089 get_real_center = i_ / 2
00090 };
00091
00092 typedef array2d_info< nrows_, ncols_, internal::unknown_, i + 1 > next_elt;
00093
00094 };
00095
00096
00097 template<class, class> struct array2d;
00098
00099
00100 namespace internal
00101 {
00102
00103
00104
00105 template<class T, class Info>
00106 struct array2d_elt_;
00107
00108
00109
00110 template<class U>
00111 struct here_a_value_is_not_of_type_;
00112
00113
00114
00115
00116
00118
00119 template<class T>
00120 struct array2d_start_ {
00121
00122 array2d_elt_< T, array2d_info< unknown_, unknown_, unknown_, 1 > >
00123 operator=(T val);
00124
00125 array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
00126 operator=(x_<T> val);
00127
00128 array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
00129 operator=(x_<void> val);
00130
00131 T ptr[max_card_];
00132 };
00133
00134
00135
00136
00137
00139
00140 template<class T, class Info>
00141 struct array2d_elt_
00142 {
00143 typedef array2d_elt_< T, typename Info::next_elt >
00144 next_elt_t_;
00145
00146 typedef array2d_elt_< T, array2d_info< Info::nrows, Info::ncols, Info::i, Info::i + 1> >
00147 eat_center_t_;
00148
00149 typedef array2d_elt_< T, array2d_info< Info::nrows, Info::i, Info::center, Info::i > >
00150 eat_lbrk_t_;
00151
00152 typedef array2d< array2d_info< Info::i / Info::ncols, Info::ncols, Info::get_real_center, Info::i > , T>
00153 array2d_t_;
00154
00155 public:
00156
00157
00158
00159 array2d_elt_(T* ptr, array2d_start_<T>* arr) : ptr(ptr), arr(arr)
00160 {
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 next_elt_t_ operator,(T val)
00172 {
00173 is_true<Info::nrows == unknown_>::ensure();
00174 *ptr = val;
00175 return next_elt_t_(ptr + 1, arr);
00176 }
00177
00178
00179
00180
00181 eat_center_t_ operator,(x_<T> val)
00182 {
00183 is_true<Info::center == unknown_>::ensure();
00184 *ptr = val.ue;
00185 return eat_center_t_(ptr + 1, arr);
00186 }
00187
00188
00189
00190
00191 eat_center_t_ operator,(x_<void>)
00192 {
00193 is_true<Info::center == unknown_>::ensure();
00194 *ptr = T(0);
00195 return eat_center_t_(ptr + 1, arr);
00196 }
00197
00198
00199
00200
00201 eat_lbrk_t_ operator,(lbrk_)
00202 {
00203 is_true<Info::ncols == unknown_>::ensure();
00204 is_true<Info::ncols != 0>::ensure();
00205 return eat_lbrk_t_(ptr, arr);
00206 }
00207
00208
00209
00210
00211 array2d_t_ operator,(end_type)
00212 {
00213 enum { nrows = Info::i / Info::ncols };
00214
00215
00216 is_true<Info::well_formed == true>::ensure();
00217
00218
00219 is_true<Info::ncols != unknown_>::ensure();
00220
00221
00222
00223
00224
00225 is_true<
00226 ((Info::ncols % 2 == 1) && (nrows % 2 == 1))
00227 || (Info::center != unknown_)
00228 >::ensure();
00229
00230 return array2d_t_(arr->ptr);
00231 }
00232
00233
00234
00235
00236 template<class U>
00237 void operator,(array2d< Info, U >);
00238
00239 template<class U>
00240 here_a_value_is_not_of_type_<T> operator,(U u) const;
00241
00242 T* ptr;
00243 array2d_start_<T>* arr;
00244 };
00245
00246
00247
00248
00249
00250
00252
00253 template<class T> inline
00254 array2d_elt_< T, array2d_info< unknown_, unknown_, unknown_, 1 > >
00255 array2d_start_<T>::operator=(T val)
00256 {
00257 ptr[0] = val;
00258 return array2d_elt_< T, array2d_info< unknown_, unknown_, unknown_, 1 > >(ptr+1,this);
00259 }
00260
00261 template<class T> inline
00262 array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
00263 array2d_start_<T>::operator=(x_<T> val)
00264 {
00265 ptr[0] = val.ue;
00266
00267 return array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >(ptr+1,this);
00268 }
00269
00270 template<class T> inline
00271 array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
00272 array2d_start_<T>::operator=(x_<void> val)
00273 {
00274 ptr[0] = T(0);
00275
00276 return array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >(ptr+1,this);
00277 }
00278
00279 }
00280
00281 }
00282
00283 #endif // ! METALIC_ARRAY_2D_HXX