Milena (Olena)
User documentation 2.0a Id
|
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