3d.hxx

00001 // Copyright (C) 2001, 2002, 2003  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef METALIC_ARRAY_3D_HXX
00029 # define METALIC_ARRAY_3D_HXX
00030 
00031 # include <mlc/array/nd.hh>
00032 
00033 namespace mlc
00034 {
00035 
00036   //
00037   //  mlc::array3d_info
00038   //
00040     
00041 
00042   // nrows_     -> total number of rows (1-indexed)
00043   // ncols_     -> total number of columns (1-indexed)
00044   // nplanes_   -> total number of planes (1-indexed)
00045 
00046   // center_    -> position of the central element (0-indexed)
00047   //               domain : [ 0, card [
00048 
00049   // i_ -> number of elements that have been eaten yet (0-indexed)
00050   //               domain : [ 0, card ] -> watch out !!
00051 
00052   // Center is user-defined
00053 
00054   template < unsigned nplanes_,
00055              unsigned nrows_, 
00056              unsigned ncols_,
00057              unsigned center_ = (ncols_ * nrows_) * (nplanes_ / 2) + ncols_ * (nrows_ / 2) + (ncols_ / 2),
00058              unsigned i_ = nplanes_ * nrows_ * ncols_>
00059   struct array3d_info
00060   {
00061     enum {
00062       nplanes = nplanes_,
00063       nrows = nrows_,
00064       ncols = ncols_,
00065       center = center_,
00066       center_plane = center_ / (nrows_ * ncols_),
00067       center_row = (center_ % (nrows_ * ncols_)) / ncols_,
00068       center_col = (center_ % (nrows_ * ncols_)) % ncols_,
00069       i = i_,
00070       card = nplanes_ * nrows_ * ncols_,
00071       well_formed = (i_ % (ncols_ * nrows) == 0),
00072       get_real_center = center_
00073     };
00074 
00075     typedef array3d_info< nplanes_, nrows_, ncols_, center_, i + 1 > next_elt;
00076 
00077   };
00078     
00079   // Center is defined automatically, if nrows and ncols are both odd
00080 
00081   template < unsigned nplanes_, unsigned nrows_, unsigned ncols_, unsigned i_ >
00082   struct array3d_info < nplanes_, nrows_, ncols_, internal::unknown_, i_ >
00083   {
00084     enum {
00085       nplanes = nplanes_,
00086       nrows = nrows_,
00087       ncols = ncols_,
00088       center = internal::unknown_,
00089       i = i_,
00090       card = nplanes_ * nrows_ * ncols_,
00091       well_formed = (i_ % (ncols_ * nrows_) == 0),
00092       get_real_center = i_ / 2
00093     };
00094 
00095     typedef array3d_info< nplanes_, nrows_, ncols_, internal::unknown_, i + 1 > next_elt;
00096 
00097   };
00098 
00099   // fwd decl
00100   template<class, class> struct array3d;
00101 
00102   namespace internal 
00103   {
00104 
00105     // fwd decl
00106 
00107     template<class T, class Info>
00108     struct array3d_elt_;
00109 
00110     // for error messages
00111 
00112     template<class U>
00113     struct here_a_value_is_not_of_type_;
00114 
00115 
00116     //
00117     //  mlc::internal::array3d_start_ decl
00118     //
00120 
00121     template<class T>
00122     struct array3d_start_ {
00123 
00124       array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, unknown_, 1 > > 
00125       operator=(T val);
00126         
00127       array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > > 
00128       operator=(x_<T> val);
00129         
00130       array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > > 
00131       operator=(x_<void> val);
00132 
00133       T ptr[max_card_]; // could be static
00134     };
00135 
00136     //
00137     //  mlc::internal::array3d_elt_
00138     //
00140 
00141     template<class T, class Info>
00142     struct array3d_elt_
00143     {
00144       typedef array3d_elt_< T, typename Info::next_elt >
00145       next_elt_t_;
00146 
00147       typedef array3d_elt_< T, array3d_info< Info::nplanes, Info::nrows, Info::ncols, Info::i, Info::i + 1> >
00148       eat_center_t_;
00149 
00150       typedef array3d_elt_< T, array3d_info< Info::nplanes, Info::nrows, Info::i, Info::center, Info::i > >
00151       eat_lbrk_t_;
00152 
00153       typedef array3d_elt_< T, array3d_info< Info::nplanes, Info::i / Info::ncols, Info::ncols, Info::center, Info::i > >
00154       eat_pbrk_t_;
00155 
00156       typedef array3d< array3d_info< Info::i / (Info::ncols * Info::nrows), Info::nrows, Info::ncols, Info::get_real_center, Info::i > , T>
00157       array3d_t_;
00158 
00159     public:
00160         
00161       // Constructor
00162 
00163       array3d_elt_(T* ptr, array3d_start_<T>* arr) : ptr(ptr), arr(arr)
00164       {
00165       }
00166 
00167 
00168       //
00169       // Overloading "operator,"
00170       //
00171 
00172 
00173       // elt, elt
00174 
00175       next_elt_t_ operator,(T val)
00176       {
00177         is_true<Info::nplanes == unknown_>::ensure();
00178         *ptr = val;
00179         return next_elt_t_(ptr + 1, arr);
00180       }
00181 
00182 
00183       // elt, x(elt)            -> center
00184 
00185       eat_center_t_ operator,(x_<T> val)
00186       {
00187         is_true<Info::center == unknown_>::ensure();
00188         *ptr = val.ue; // FIXME : give a *name* to this variable !!
00189         return eat_center_t_(ptr + 1, arr);
00190       }
00191 
00192 
00193       // elt, x()               -> center
00194 
00195       eat_center_t_ operator,(x_<void>)
00196       {
00197         is_true<Info::center == unknown_>::ensure();
00198         *ptr = T(0);
00199         return eat_center_t_(ptr + 1, arr);
00200       }
00201 
00202 
00203       // elt, lbrk
00204 
00205       eat_lbrk_t_ operator,(lbrk_)
00206       {
00207         is_true<Info::ncols == unknown_>::ensure();
00208         return eat_lbrk_t_(ptr, arr);
00209       }
00210 
00211 
00212       // elt, pbrk
00213       eat_pbrk_t_ operator,(pbrk_)
00214       {
00215         is_true<Info::nplanes == unknown_>::ensure();
00216         return eat_pbrk_t_(ptr, arr);
00217       }
00218 
00219       // elt, end
00220         
00221       array3d_t_ operator,(end_type)
00222       {
00223         enum { nplanes = (Info::i / (Info::ncols * Info::nrows)) };
00224           
00225         // array is well-formed :
00226         is_true<Info::well_formed>::ensure();
00227         // centering is automatic or user-defined :
00228 
00229         is_true<Info::ncols != unknown_>::ensure();
00230         is_true<Info::nrows != unknown_>::ensure();
00231 
00232         // all of nplanes, nrows and ncols are odd
00233         // or the center is user-defined
00234 
00235         is_true<            
00236           (Info::ncols % 2 == 1 && Info::nrows % 2 == 1 && nplanes % 2 == 1)
00237           || (Info::center != unknown_)
00238           >::ensure();
00239           
00240         return array3d_t_(arr->ptr);
00241       }
00242         
00243 
00244       // else -> error
00245 
00246       template<class U>
00247       void operator,(array3d< Info, U >);
00248 
00249       template<class U>
00250       here_a_value_is_not_of_type_<T> operator,(U u) const;
00251 
00252       T* ptr;
00253       array3d_start_<T>* arr;
00254     };
00255 
00256 
00257     //
00258     //  mlc::internal::array3d_start_  impl
00259     //
00261 
00262     template<class T> inline 
00263     array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, unknown_, 1 > >
00264     array3d_start_<T>::operator=(T val)
00265     {
00266       ptr[0] = val;
00267       return array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, unknown_, 1 > >(ptr+1,this);
00268     }
00269 
00270     template<class T> inline 
00271     array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >
00272     array3d_start_<T>::operator=(x_<T> val)
00273     {
00274       ptr[0] = val.ue;
00275       // center <- 0
00276       return array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >(ptr+1,this);
00277     }
00278 
00279     template<class T> inline 
00280     array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >
00281     array3d_start_<T>::operator=(x_<void> val)
00282     {
00283       ptr[0] = T(0);
00284       // center <- 0
00285       return array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >(ptr+1,this);
00286     }
00287 
00288   } // end of internal
00289 
00290 } // end of mlc
00291 
00292 
00293 #endif // ! METALIC_ARRAY_3D_HXX

Generated on Thu Apr 15 20:13:04 2004 for Olena by doxygen 1.3.6-20040222