• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List

/export/development/ViennaMath/viennamath/compiletime/ct_variable.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_COMPILETIME_VARIABLE_HPP
00002 #define VIENNAMATH_COMPILETIME_VARIABLE_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2012, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008                              -----------------
00009                ViennaMath - Symbolic and Numerical Math in C++
00010                              -----------------
00011 
00012    Author:     Karl Rupp                          rupp@iue.tuwien.ac.at
00013 
00014    License:    MIT (X11), see file LICENSE in the ViennaMath base directory
00015 ======================================================================= */
00016 
00017 
00018 
00019 
00020 #include "viennamath/compiletime/ct_vector.hpp"
00021 #include "viennamath/exception.hpp"
00022 
00023 #include <assert.h>
00024 
00029 namespace viennamath
00030 {
00031   /********** evaluation at ViennaMath vector types ***************/
00033   template <typename vmath_vector, long id>
00034   struct type_by_index {};
00035   
00037   template <typename vmath_vector>
00038   struct type_by_index <vmath_vector, 0>
00039   {
00040     typedef typename vmath_vector::type_0   type; 
00041   };
00042   
00044   template <typename vmath_vector>
00045   struct type_by_index <vmath_vector, 1>
00046   {
00047     typedef typename vmath_vector::type_1   type; 
00048   };
00049   
00051   template <typename vmath_vector>
00052   struct type_by_index <vmath_vector, 2>
00053   {
00054     typedef typename vmath_vector::type_2   type; 
00055   };
00056 
00057   /********** evaluation at STL vector types ***************/
00059   template <typename VectorType,
00060             long id>
00061   struct variable_traits
00062   {
00063     typedef default_numeric_type          return_type;
00064     
00065     //per default, access id-th element;
00066     static return_type get(VectorType const & v)
00067     {
00068       return v[id];
00069     }
00070   };
00071   
00072   
00073   //vector_1:
00075   template <typename T0,
00076             long id>
00077   struct variable_traits <ct_vector_1<T0>, 
00078                           id>
00079   {
00080     typedef typename type_by_index<ct_vector_1<T0>, id>::type   return_type;
00081     
00082     //per default, access id-th element;
00083     static return_type get(ct_vector_1<T0> const & v)
00084     {
00085       return v[ct_index<id>()];
00086     }
00087   };
00088   
00089   //vector_2:
00091   template <typename T0, typename T1,
00092             long id>
00093   struct variable_traits <ct_vector_2<T0, T1>, 
00094                           id>
00095   {
00096     typedef typename type_by_index<ct_vector_2<T0, T1>, id>::type   return_type;
00097     
00098     //per default, access id-th element;
00099     static return_type get(ct_vector_2<T0, T1> const & v)
00100     {
00101       return v[ct_index<id>()];
00102     }
00103   };
00104 
00105   //vector_3:
00107   template <typename T0, typename T1, typename T2,
00108             long id>
00109   struct variable_traits <ct_vector_3<T0, T1, T2>, 
00110                           id>
00111   {
00112     typedef typename type_by_index<ct_vector_3<T0, T1, T2>, id>::type   return_type;
00113     
00114     //per default, access id-th element;
00115     static return_type get(ct_vector_3<T0, T1, T2> const & v)
00116     {
00117       return v[ct_index<id>()];
00118     }
00119   };
00120 
00121   
00122 
00123   
00124   /************* evaluation of a compile time constant *****************/
00126   template <long value_>
00127   struct variable_traits <ct_constant<value_>,
00128                           0>
00129   {
00130     typedef viennamath::ct_constant<value_>   return_type;
00131     
00132     //per default, access id-th element;
00133     static return_type get(viennamath::ct_constant<value_> const & v)
00134     {
00135       return v;
00136     }
00137   };
00138 
00139   //guard: something like (x*y - z)(constant<long, ct_constant<4> >()) is not allowed
00141   template <long value_, long id>
00142   struct variable_traits <ct_constant<value_>, 
00143                           id>
00144   {
00145     //try to provide a good compiler error message:
00146     typedef typename ct_constant<value_>::ERROR_PROVIDED_NOT_ENOUGH_ARGUMENTS_TO_EXPRESSION   error_type;
00147     
00148     //providing a non-vector type is bogus -> force linker error!
00149   };
00150   
00151   // further specialize variable_traits::get() here as required.
00152   
00153   
00154   
00159   template <id_type id /* see forwards.h for default argument */>
00160   struct ct_variable
00161   {
00162     typedef default_numeric_type   numeric_type;
00163     
00164     explicit ct_variable() {};
00165 
00166     std::ostream & operator<<(std::ostream & stream) const
00167     {
00168       stream << "variable<" << id << ">";
00169       return stream;
00170     }
00171 
00173     //template <typename NumericT>
00174     //NumericT operator()(NumericT value) const { return value; }
00175 
00176     template <typename ScalarType>
00177     rt_constant<ScalarType> operator()(rt_constant<ScalarType> const & other) const
00178     {
00179       if (id > 0)
00180         throw variable_index_out_of_bounds_exception(id, 0);
00181       return rt_constant<ScalarType>(static_cast<ScalarType>(other));
00182     }
00183 
00184     template <long value>
00185     long operator()(ct_constant<value> const & other) const
00186     {
00187       if (id > 0)
00188         throw variable_index_out_of_bounds_exception(id, 0);
00189       return value;
00190     }
00191 
00192     //Vector argument (can be of type std::vector)
00193     template <typename VectorType>
00194     typename variable_traits<VectorType, id>::return_type 
00195     //numeric_type 
00196     operator()(VectorType const & v) const
00197     {
00198       if(id >= v.size())
00199         throw variable_index_out_of_bounds_exception(id, v.size());
00200       return variable_traits<VectorType, id>::get(v);
00201     }
00202     
00203   }; //variable
00204 
00205 
00207   template <id_type id>
00208   std::ostream& operator<<(std::ostream & stream, ct_variable<id> const & u)
00209   {
00210     stream << "ct_variable<" << id << ">";
00211     return stream;
00212   }
00213 
00214 
00215 }
00216 
00217 #endif

Generated on Wed Feb 29 2012 21:50:43 for ViennaMath by  doxygen 1.7.1