• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

comp.hh

00001 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_TRAIT_VALUE_INTERNAL_COMP_HH
00027 # define MLN_TRAIT_VALUE_INTERNAL_COMP_HH
00028 
00035 
00036 # include <mln/metal/bool.hh>
00037 # include <mln/metal/if.hh>
00038 
00039 
00040 
00041 
00042 namespace mln
00043 {
00044 
00045   namespace trait
00046   {
00047 
00048 
00049     // Forward declaration.
00050     template <typename V> struct value_;
00051 
00052 
00053     namespace value
00054     {
00055 
00056       namespace internal
00057       {
00058 
00059         // bind_comp< T, i >
00060 
00061         template <typename T, typename Tr, unsigned i>
00062         struct bind_comp;
00063 
00064         template <typename T, typename Tr>
00065         struct bind_comp< T, Tr, 0 >
00066         {
00067           typedef typename Tr::comp_0 ret;
00068           static ret on(const T& v)
00069           {
00070             return Tr::get_comp_0(v);
00071           }
00072         };
00073 
00074         template <typename T, typename Tr>
00075         struct bind_comp< T, Tr, 1 >
00076         {
00077           typedef typename Tr::comp_1 ret;
00078           static ret on(const T& v)
00079           {
00080             return Tr::get_comp_1(v);
00081           }
00082         };
00083 
00084         template <typename T, typename Tr>
00085         struct bind_comp< T, Tr, 2 >
00086         {
00087           typedef typename Tr::comp_2 ret;
00088           static ret on(const T& v)
00089           {
00090             return Tr::get_comp_2(v);
00091           }
00092         };
00093 
00094         template <typename T, typename Tr>
00095         struct bind_comp< T, Tr, 3 >
00096         {
00097           typedef typename Tr::comp_3 ret;
00098           static ret on(const T& v)
00099           {
00100             return Tr::get_comp_3(v);
00101           }
00102         };
00103 
00104         template <typename T, typename Tr>
00105         struct bind_comp< T, Tr, 4 >
00106         {
00107           typedef typename Tr::comp_4 ret;
00108           static ret on(const T& v)
00109           {
00110             return Tr::get_comp_4(v);
00111           }
00112         };
00113 
00114         template <typename T, typename Tr>
00115         struct bind_comp< T, Tr, 5 >
00116         {
00117           typedef typename Tr::comp_5 ret;
00118           static ret on(const T& v)
00119           {
00120             return Tr::get_comp_5(v);
00121           }
00122         };
00123 
00124         template <typename T, typename Tr>
00125         struct bind_comp< T, Tr, 6 >
00126         {
00127           typedef typename Tr::comp_6 ret;
00128           static ret on(const T& v)
00129           {
00130             return Tr::get_comp_6(v);
00131           }
00132         };
00133 
00134         template <typename T, typename Tr>
00135         struct bind_comp< T, Tr, 7 >
00136         {
00137           typedef typename Tr::comp_7 ret;
00138           static ret on(const T& v)
00139           {
00140             return Tr::get_comp_7(v);
00141           }
00142         };
00143 
00144         template <typename T, typename Tr>
00145         struct bind_comp< T, Tr, 8 >
00146         {
00147           typedef typename Tr::comp_8 ret;
00148           static ret on(const T& v)
00149           {
00150             return Tr::get_comp_8(v);
00151           }
00152         };
00153 
00154         template <typename T, typename Tr>
00155         struct bind_comp< T, Tr, 9 >
00156         {
00157           typedef typename Tr::comp_9 ret;
00158           static ret on(const T& v)
00159           {
00160             return Tr::get_comp_9(v);
00161           }
00162         };
00163 
00164 
00165         // get_comp< T, i, dim >
00166 
00167         template <typename T, typename C, typename Tr, unsigned i>
00168         struct get_comp_helper
00169         {
00170           typedef C ret;
00171           static ret on(const T& v)
00172           {
00173             return v[i];
00174           }
00175         };
00176 
00177         template <typename T, typename Tr, unsigned i>
00178         struct get_comp_helper< T, void, Tr, i >
00179         {
00180           typedef bind_comp<T, Tr, i> helper;
00181           typedef typename helper::ret ret;
00182           static ret on(const T& v)
00183           {
00184             return helper::on(v);
00185           }
00186         };
00187 
00188 
00189         // Technical note:
00190         //
00191         // We distinguish between a type T being a C-array type (T =
00192         // U[dim]) and T a "regular" type (meaning "not a C-array
00193         // type").  We have two stages to help g++-3.3 which has
00194         // difficulty in solving such partial specializations.
00195 
00196         // Regular case.
00197 
00198         template <typename T, unsigned i, unsigned dim>
00199         struct get_comp_with_regular_
00200         {
00201           typedef mln::trait::value_<T> Tr;
00202           typedef typename Tr::comp C;
00203           typedef get_comp_helper<T, C, Tr, i> helper;
00204           typedef typename helper::ret ret;
00205 
00206           static ret on(const T& v)
00207           {
00208             return helper::on(v);
00209           }
00210         };
00211 
00212         template <typename T>
00213         struct get_comp_with_regular_< T, 0, 1 >
00214         {
00215           typedef T ret;
00216 
00217           static ret on(const T& v)
00218           {
00219             return v;
00220           }
00221         };
00222 
00223         template <typename T, unsigned i, unsigned dim>
00224         struct get_comp : get_comp_with_regular_<T, i, dim>
00225         {
00226         };
00227 
00228         // C-array case.
00229 
00230         template <typename T, unsigned i, unsigned dim>
00231         struct get_comp_with_C_array
00232         {
00233           typedef T ret;
00234 
00235           static ret on(const T (&v)[dim])
00236           {
00237             return v[i];
00238           }
00239         };
00240         
00241         template <typename T, unsigned i, unsigned dim>
00242         struct get_comp< T[dim], i, dim > : get_comp_with_C_array<T, i, dim>
00243         {
00244         };
00245 
00246 
00247 
00248         // comp< T, i >
00249 
00250         template <typename T, unsigned i>
00251         struct comp
00252           : private metal::bool_< (i < mln::trait::value_<T>::dim) >::check_t
00253         {
00254           enum { dim = mln::trait::value_<T>::dim };
00255           typedef get_comp<T, i, dim> helper;
00256           typedef typename helper::ret ret;
00257 
00258           static ret on(const T& v)
00259           {
00260             return helper::on(v);
00261           }
00262         };
00263 
00264       } // end of namespace mln::trait::value::internal
00265 
00266     } // end of namespace mln::trait::value
00267 
00268   } // end of namespace mln::trait
00269 
00270 } // end of namespace mln
00271 
00272 
00273 
00274 #endif // ! MLN_TRAIT_VALUE_INTERNAL_COMP_HH

Generated on Tue Oct 4 2011 15:23:37 for Milena (Olena) by  doxygen 1.7.1