1d.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_1D_HXX
00029 # define METALIC_ARRAY_1D_HXX
00030 
00031 # include <mlc/array/nd.hh>
00032 
00033 namespace mlc
00034 {
00035 
00036   //
00037   //  mlc::array1d_info
00038   //
00040     
00041 
00042   // card_      -> total number of elements (1-indexed)
00043 
00044   // center_    -> position of the central element (0-indexed)
00045   //               domain : [ 0, card [
00046 
00047   // i_ -> number of elements that have been eaten yet (0-indexed)
00048   //               domain : [ 0, card ] -> watch out !!
00049 
00050 
00051   template < unsigned card_, unsigned center_ = card_ / 2, unsigned i_ = card_>
00052   struct array1d_info
00053   {
00054     enum {
00055       card = card_,
00056       center = center_,
00057       i = i_,
00058       well_formed = true,
00059       get_real_center = center_
00060     };
00061 
00062     typedef array1d_info< card_, center_, i + 1 > next_elt;
00063 
00064   };
00065     
00066   template < unsigned card_, unsigned i_ >
00067   struct array1d_info <card_, internal::unknown_, i_ >
00068   {
00069     enum {
00070       card = card_,
00071       center = internal::unknown_,
00072       i = i_,
00073       well_formed = true,
00074       get_real_center = i_ / 2
00075     };
00076 
00077     typedef array1d_info< card_, internal::unknown_, i + 1 > next_elt;
00078 
00079   };
00080 
00081   // fwd decl
00082   template<class, class> struct array1d;
00083 
00084 
00085   namespace internal 
00086   {
00087 
00088     // fwd decl
00089 
00090     template<class T, class Info>
00091     struct array1d_elt_;
00092 
00093     // for error messages
00094 
00095     template<class U>
00096     struct here_a_value_is_not_of_type_;
00097 
00098 
00099     //
00100     //  mlc::internal::array1d_start_ decl
00101     //
00103 
00104     template<class T>
00105     struct array1d_start_ {
00106 
00107       array1d_elt_< T, array1d_info< unknown_, unknown_, 1 > > operator=(T val);
00108       array1d_elt_< T, array1d_info< unknown_, 0, 1 > > operator=(x_<T> val);
00109       array1d_elt_< T, array1d_info< unknown_, 0, 1 > > operator=(x_<void> val);
00110 
00111       T ptr[max_card_]; // could be static
00112     };
00113 
00114 
00115 
00116     //
00117     //  mlc::internal::array1d_elt_
00118     //
00120 
00121     template<class T, class Info>
00122     struct array1d_elt_
00123     {
00124       typedef array1d_elt_<T, typename Info::next_elt> next_elt_t_;
00125 
00126       typedef array1d_elt_< T, array1d_info< Info::card, Info::i, Info::i + 1> > eat_center_t_;
00127 
00128       typedef array1d< array1d_info< Info::i, Info::get_real_center, Info::i > , T> array1d_t_;
00129 
00130     public:
00131         
00132       // Constructor
00133 
00134       array1d_elt_(T* ptr, array1d_start_<T>* arr) : ptr(ptr), arr(arr)
00135       {
00136       }
00137 
00138 
00139 
00140       //
00141       // Overloading "operator,"
00142       //
00143 
00144 
00145       // elt, elt
00146 
00147       next_elt_t_ operator,(T val)
00148       {
00149         is_true<Info::card == unknown_>::ensure();
00150         *ptr = val;
00151         return next_elt_t_(ptr + 1, arr);
00152       }
00153 
00154 
00155       // elt, x(elt)            -> center
00156 
00157       eat_center_t_ operator,(x_<T> val)
00158       {
00159         is_true<Info::center == unknown_>::ensure();
00160         *ptr = val.ue; // FIXME : give a *name* to this variable !!
00161         return eat_center_t_(ptr+1, arr);
00162       }
00163 
00164 
00165       // elt, x()               -> center
00166 
00167       eat_center_t_ operator,(x_<void>)
00168       {
00169         is_true<Info::center == unknown_>::ensure();
00170         *ptr = T(0);
00171         return eat_center_t_(ptr+1, arr);
00172       }
00173 
00174 
00175       // elt, end
00176         
00177       array1d_t_ operator,(end_type)
00178       {
00179         // array is well-formed :
00180         is_true<Info::well_formed>::ensure();
00181         // centering is automatic or user-defined :
00182         // (commented out to allow automatic centering on even sized arrays)
00183         // mlc::logical_or< mlc::eq< Info::i % 2, 1 >::ret, mlc::neq< Info::center, unknown_ >::ret >::ensure();
00184         return array1d_t_(arr->ptr);
00185       }
00186         
00187 
00188       // else -> error
00189 
00190       template<class U>
00191       void operator,(array1d< Info, U >);
00192 
00193       template<class U>
00194       here_a_value_is_not_of_type_<T> operator,(U u) const;
00195 
00196       T* ptr;
00197       array1d_start_<T>* arr;
00198     };
00199 
00200 
00201 
00202     //
00203     //  mlc::internal::array1d_start_  impl
00204     //
00206 
00207     template<class T> inline 
00208     array1d_elt_< T, array1d_info< unknown_, unknown_, 1 > >
00209     array1d_start_<T>::operator=(T val)
00210     {
00211       ptr[0] = val;
00212       return array1d_elt_< T, array1d_info< unknown_, unknown_, 1 > >(ptr+1, this);
00213     }
00214 
00215     template<class T> inline 
00216     array1d_elt_< T, array1d_info< unknown_, 0, 1 > >
00217     array1d_start_<T>::operator=(x_<T> val)
00218     {
00219       ptr[0] = val.ue;
00220       // center <- 0
00221       return array1d_elt_< T, array1d_info< unknown_, 0, 1 > >(ptr+1, this);
00222     }
00223 
00224     template<class T> inline 
00225     array1d_elt_< T, array1d_info< unknown_, 0, 1 > >
00226     array1d_start_<T>::operator=(x_<void> val)
00227     {
00228       ptr[0] = T(0);
00229       // center <- 0
00230       return array1d_elt_< T, array1d_info< unknown_, 0, 1 > >(ptr+1,this);
00231     }
00232 
00233   } // end of internal
00234 
00235 } // end of mlc
00236 
00237 #endif // ! METALIC_ARRAY_1D_HXX

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