glue_cube_metaprog.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup glue_cube_metaprog
00017 //! @{
00018 
00019 
00020 
00021 //! \brief
00022 //! Template metaprogram depth_lhs_cube
00023 //! calculates the number of GlueCube<Tx,Ty, glue_type> instances on the left hand side argument of GlueCube<Tx,Ty, glue_cube_type>
00024 //! i.e. it recursively expands each Tx, until the type of Tx is not "GlueCube<..,.., glue_cube_type>"  (i.e the "glue_cube_type" changes)
00025 
00026 template<typename glue_cube_type, typename T1>
00027 struct depth_lhs_cube
00028   {
00029   static const u32 num = 0;
00030   };
00031 
00032 template<typename glue_cube_type, typename T1, typename T2>
00033 struct depth_lhs_cube< glue_cube_type, GlueCube<T1,T2,glue_cube_type> >
00034   {
00035   static const u32 num = 1 + depth_lhs_cube<glue_cube_type, T1>::num;
00036   };
00037 
00038 
00039 
00040 //! \brief
00041 //! Template metaprogram cube_ptrs
00042 //! fills a given array with addresses of cubes from a recursive instance of GlueCube<Tx,Ty, glue_cube_type>.
00043 //! While parsing the recursive instance, if encountered objects are of type OpCube<..>,
00044 //! they are converted to type 'Cube' first
00045 
00046 template<typename glue_type, typename T1>
00047 struct cube_ptrs
00048   {
00049   typedef typename T1::elem_type elem_type;
00050   
00051   static const u32 num = 0;
00052 
00053   inline
00054   static
00055   void
00056   get_ptrs
00057     (
00058     const Cube<elem_type>** ptrs,
00059           bool*             del,
00060     const T1&               X
00061     )
00062     {
00063     ptrs[0] = 
00064       (
00065       is_Cube<T1>::value ?
00066         reinterpret_cast<const Cube<elem_type>*>(&X)
00067       :
00068         new Cube<elem_type>(X)
00069       );
00070 
00071     del[0] = 
00072       (
00073       is_Cube<T1>::value ?
00074         false
00075       :
00076         true
00077       );
00078 
00079     
00080     }
00081   
00082   };
00083 
00084 
00085 
00086 template<typename glue_type, typename T1, typename T2>
00087 struct cube_ptrs<glue_type, GlueCube<T1,T2,glue_type> >
00088   {
00089   typedef typename T1::elem_type elem_type;
00090   
00091   static const u32 num = 1 + cube_ptrs<glue_type, T1>::num;
00092   
00093   inline
00094   static
00095   void
00096   get_ptrs
00097     (
00098     const Cube<elem_type>**          in_ptrs,
00099           bool*                      del,
00100     const GlueCube<T1,T2,glue_type>& X
00101     )
00102     {
00103     isnt_same_type<typename T1::elem_type, typename T2::elem_type>::check();
00104     
00105     cube_ptrs<glue_type, T1>::get_ptrs(in_ptrs, del, X.A);
00106     
00107     in_ptrs[num]  = 
00108       (
00109       is_Cube<T2>::value ?
00110         reinterpret_cast<const Cube<elem_type>*>(&X.B)
00111       :
00112         new Cube<elem_type>(X.B)
00113       );
00114     
00115     del[num] = 
00116       (
00117       is_Cube<T2>::value ?
00118         false
00119       :
00120         true
00121       );
00122     }
00123   
00124   };
00125 
00126 
00127 
00128 //! template metaprogram cube_ptrs_outcheck
00129 //! builds on 'cube_ptrs' by also checking whether any of the input cubes are aliases of the output cube
00130 
00131 template<typename glue_type, typename T1>
00132 struct cube_ptrs_outcheck
00133   {
00134   typedef typename T1::elem_type elem_type;
00135   
00136   static const u32 num = 0;
00137 
00138   inline
00139   static
00140   void
00141   get_ptrs
00142     (
00143     const Cube<elem_type>** ptrs,
00144           bool*             del,
00145     const T1&               X,
00146     const Cube<elem_type>*  out_ptr
00147     )
00148     {
00149 
00150     const bool same_ptr = 
00151       (
00152       is_Cube<T1>::value ?
00153         (
00154         (out_ptr == reinterpret_cast<const Cube<elem_type>*>(&X)) ?
00155           true
00156         :
00157           false
00158         )
00159       :
00160         false
00161       );
00162 
00163     
00164     ptrs[0] = 
00165       (
00166       same_ptr ?
00167         new Cube<elem_type>(X)
00168       :
00169         (
00170         is_Cube<T1>::value ?
00171           reinterpret_cast<const Cube<elem_type>*>(&X)
00172         :
00173           new Cube<elem_type>(X)
00174         )
00175       );
00176 
00177     
00178     del[0] = 
00179       (
00180       same_ptr ?
00181         true
00182       :
00183         (
00184         is_Cube<T1>::value ?
00185           false
00186         :
00187           true
00188         )
00189       );
00190 
00191     
00192     }
00193   
00194   };
00195 
00196 
00197 
00198 template<typename glue_type, typename T1, typename T2>
00199 struct cube_ptrs_outcheck<glue_type, GlueCube<T1,T2,glue_type> >
00200   {
00201   typedef typename T1::elem_type elem_type;
00202   
00203   static const u32 num = 1 + cube_ptrs_outcheck<glue_type, T1>::num;
00204   
00205   inline
00206   static
00207   void
00208   get_ptrs
00209     (
00210     const Cube<elem_type>**          ptrs,
00211           bool*                      del,
00212     const GlueCube<T1,T2,glue_type>& X,
00213     const Cube<elem_type>*           out_ptr
00214     )
00215     {
00216     isnt_same_type<typename T1::elem_type, typename T2::elem_type>::check();
00217     
00218     cube_ptrs_outcheck<glue_type, T1>::get_ptrs(ptrs, del, X.A, out_ptr);
00219     
00220     const bool same_ptr =
00221       (
00222       is_Cube<T2>::value ?
00223         (
00224         (out_ptr == reinterpret_cast<const Cube<elem_type>*>(&X.B)) ?
00225           true
00226         :
00227           false
00228         )
00229       :
00230         false
00231       );
00232     
00233     
00234     ptrs[num]  = 
00235       (
00236       same_ptr ?
00237         new Cube<elem_type>(X.B)
00238       :
00239         (
00240         is_Cube<T2>::value ?
00241           reinterpret_cast<const Cube<elem_type>*>(&X.B)
00242         :
00243           new Cube<elem_type>(X.B)
00244         )
00245       );
00246     
00247     
00248     del[num] = 
00249       (
00250       same_ptr ?
00251         true
00252       :
00253         (
00254         is_Cube<T2>::value ?
00255           false
00256         :
00257           true
00258         )
00259       );
00260     }
00261 
00262   };
00263 
00264 
00265 
00266 //! @}