Go to the documentation of this file.00001 #ifndef VIENNAMATH_COMPILETIME_VARIABLE_HPP
00002 #define VIENNAMATH_COMPILETIME_VARIABLE_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
00059 template <typename VectorType,
00060 long id>
00061 struct variable_traits
00062 {
00063 typedef default_numeric_type return_type;
00064
00065
00066 static return_type get(VectorType const & v)
00067 {
00068 return v[id];
00069 }
00070 };
00071
00072
00073
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
00083 static return_type get(ct_vector_1<T0> const & v)
00084 {
00085 return v[ct_index<id>()];
00086 }
00087 };
00088
00089
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
00099 static return_type get(ct_vector_2<T0, T1> const & v)
00100 {
00101 return v[ct_index<id>()];
00102 }
00103 };
00104
00105
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
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
00126 template <long value_>
00127 struct variable_traits <ct_constant<value_>,
00128 0>
00129 {
00130 typedef viennamath::ct_constant<value_> return_type;
00131
00132
00133 static return_type get(viennamath::ct_constant<value_> const & v)
00134 {
00135 return v;
00136 }
00137 };
00138
00139
00141 template <long value_, long id>
00142 struct variable_traits <ct_constant<value_>,
00143 id>
00144 {
00145
00146 typedef typename ct_constant<value_>::ERROR_PROVIDED_NOT_ENOUGH_ARGUMENTS_TO_EXPRESSION error_type;
00147
00148
00149 };
00150
00151
00152
00153
00154
00159 template <id_type id >
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
00174
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
00193 template <typename VectorType>
00194 typename variable_traits<VectorType, id>::return_type
00195
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 };
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