ivl 679
|
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>. 00002 A C++ template library extending syntax towards mathematical notation. 00003 00004 Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr> 00005 Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr> 00006 00007 ivl is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License 00009 version 3 as published by the Free Software Foundation. 00010 00011 Alternatively, you can redistribute it and/or modify it under the terms 00012 of the GNU General Public License version 2 as published by the Free 00013 Software Foundation. 00014 00015 ivl is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 See the GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 and a copy of the GNU Lesser General Public License along 00022 with ivl. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 #ifndef IVL_CORE_DETAILS_TYPES_DERIVE_HPP 00025 #define IVL_CORE_DETAILS_TYPES_DERIVE_HPP 00026 00027 00028 namespace ivl { 00029 00030 //forward declaration 00031 //template <class T, int N, class S, class K> class image; 00032 00033 namespace data { 00034 00035 //forward declaration 00036 //template <int N> struct normal_image; 00037 00038 // forward declarations 00039 /* 00040 template <class T, template <typename, typename, typename> class A, class Derived> 00041 class data_base; 00042 00043 template <class T, template <typename, typename, typename> class A, class DI> 00044 class data_base_inst; 00045 00046 template <class T, template <typename, typename, typename> class A, class DI> 00047 class iactset; 00048 */ 00049 00050 }// namespace data 00051 00052 namespace types { 00053 00054 /* These structs allow the compile-time translation from one 00055 * template type to another. Or otherwise said, they perform 00056 ** type promotion for template types */ 00057 00058 //-------------------------------------------------------------- 00059 00060 template<class T> 00061 class enable_if : public enable_if<typename T::type> 00062 { 00063 public: 00064 enable_if(int x) : enable_if<typename T::type>(x) {} 00065 }; 00066 00067 template<> 00068 class enable_if<types::t_false> 00069 { 00070 private: 00071 enable_if(int) {} 00072 }; 00073 00074 template<> 00075 class enable_if<types::t_true> 00076 { 00077 public: 00078 enable_if(int) {} 00079 }; 00080 00081 // used to validate that a class is of a certain class type 00082 // has a private constructor if class A != class B which wont allow construction 00083 // of the class that contains that type 00084 template<class A, class B> 00085 class validate_class 00086 { 00087 private: 00088 validate_class() { } 00089 }; 00090 00091 template<class A> 00092 class validate_class<A, A> 00093 { 00094 public: 00095 validate_class() { } 00096 }; 00097 00098 00099 // struct that 00100 //typedef <template<typename, typename, typename> class D, class T, class DERIVED_CLASS> 00101 00102 00103 namespace types_details 00104 { 00105 00106 00107 00108 00109 template <class PRIMARY, class DERINFO> 00110 struct derive_logic 00111 { 00112 typedef DERINFO type; 00113 }; 00114 00115 template <class PRIMARY> 00116 struct derive_logic <PRIMARY, term> 00117 { 00118 typedef PRIMARY type; 00119 }; 00120 00121 }// namespace types_details 00122 00123 00124 template <class T> 00125 struct derive_opts { }; 00126 00127 template <template <typename, typename> class A, class T, class DS> 00128 struct derive_opts<A<T, DS> > 00129 { 00130 typedef typename t_if<t_eq<typename DS::derived_param, term>, 00131 typename DS::template change_derived_param<A<T, DS> >::type, DS> 00132 ::type type; 00133 }; 00134 00135 template <class PRIMARY> 00136 struct derive 00137 { 00138 typedef PRIMARY type; 00139 }; 00140 00141 // opts parameter class 00142 template <template <typename, typename> class A, 00143 class T, class DS> 00144 struct derive <A <T, DS> > 00145 { 00146 typedef typename types_details::derive_logic <A <T, DS>, 00147 typename DS::derived_param>::type type; 00148 }; 00149 00150 00151 // ------------------------------------------------------------- 00152 00153 template <class DERIVED_CLASS, class X> 00154 struct change_derived_class { }; 00155 // spec parameter class 00156 template <class DERIVED_CLASS, template <typename, typename> class A, 00157 class T, class DS> 00158 struct change_derived_class <DERIVED_CLASS, A <T, DS> > 00159 { 00160 typedef A <T, typename DS::template 00161 change_derived_param<DERIVED_CLASS>::type> type; 00162 }; 00163 00164 // ------------------------------------------------------------- 00165 00166 // returns an array type with the data class changed to DATA. 00167 // X has to be the derived class. 00168 template <class DATA, class X> 00169 struct change_data_class_set 00170 { 00171 // TODO: fix better, @@@, for high classes e.g. point<DATA> 00172 typedef typename change_data_class_set<DATA, typename X::derived_type>::type type; 00173 }; 00174 00175 namespace types_details { 00176 00177 template <class DATA, class X, class REPL, class IS_TERM> 00178 struct change_data_class_set_tool 00179 { 00180 // if the class is below the array-hierarchy classes 00181 // we get the lowest possible ancestor that is. 00182 //TODO: revise this 00183 typedef typename change_data_class_set<DATA, 00184 typename change_derived_class<types::term, 00185 typename X::container_type>::type>::type type; 00186 }; 00187 00188 template <class DATA, class X, class REPL> 00189 struct change_data_class_set_tool<DATA, X, REPL, t_true> 00190 { 00191 typedef REPL type; 00192 }; 00193 00194 } /* namespace types_details */ 00195 00196 // 00197 // spec parameter class 00198 template <class DATA, template <typename, typename> class A, 00199 class T, class DS> 00200 struct change_data_class_set <DATA, A <T, DS> > 00201 { 00202 typedef typename types_details:: 00203 change_data_class_set_tool<DATA, A<T, DS>, A<T, DATA>, 00204 typename t_eq<typename DS::derived_param, term>::type>::type 00205 type; 00206 }; 00207 00208 00209 // ------------------------------------------------------------- 00210 00211 template <class ELEM_TYPE, class X> 00212 struct change_elem_type { }; 00213 00214 // this is a new approach 00215 template <class E> 00216 struct change_elem_type<E, term> 00217 { 00218 typedef term type; 00219 }; 00220 00221 // 00222 // opts parameter class 00223 template <class ELEM_TYPE, template <typename, typename> class A, 00224 class T, class DS> 00225 struct change_elem_type <ELEM_TYPE, A <T, DS> > 00226 { 00227 typedef A <ELEM_TYPE, typename DS::template change_derived_param< 00228 typename change_elem_type<ELEM_TYPE, typename DS::derived_param> 00229 ::type>::type> type; 00230 }; 00231 00232 00233 // -------------------------- TODO : style ------------- 00234 00235 template <class A> 00236 struct normal_type 00237 { 00238 //Note: for now, change_data_class_set also resets the derived_type to 00239 //types::term. However this could change. 00240 //An idea is to allow only change data class and change_elem_type to 00241 //classes that end with term (are derived). 00242 //However, normal_type will certainly reset the derived_type to term... 00243 // 00244 // so for backup reasons I place here the valid implementation of 00245 // change_data_class_set 00246 // 00247 // // if the class is below the array-hierarchy classes 00248 // // we get the lowest possible ancestor that is. 00249 // typedef typename change_data_class_set<DATA, 00250 // typename change_derived_class<types::term, 00251 // typename X::array_type>::type>::type type; 00252 // 00253 // 00254 typedef typename change_data_class_set<data::mem<>, A>::type type; 00255 }; 00256 00257 namespace types_details { 00258 00259 template <class DATA, class A, class IS_ARRAY> 00260 struct change_data_class_set_rec_tool { }; 00261 00262 template <class DATA, class T> 00263 struct change_data_class_set_rec_tool<DATA, T, t_false> 00264 { 00265 typedef T type; 00266 }; 00267 00268 template <class DATA, class A> 00269 struct change_data_class_set_rec_tool<DATA, A, t_true> 00270 { 00271 typedef typename change_elem_type< 00272 typename change_data_class_set_rec_tool<DATA, typename A::elem_type, 00273 typename is_ivl_array<typename A::elem_type>::type>::type, 00274 typename change_data_class_set<DATA, A>::type>::type type; 00275 }; 00276 00277 } /* namespace types_details */ 00278 00279 template <class DATA, class A> 00280 struct change_data_class_set_rec : 00281 public types_details:: 00282 change_data_class_set_rec_tool<DATA, A, typename is_ivl_array<A>::type> 00283 { 00284 }; 00285 00286 } /* namespace types */ 00287 } /* namespace ivl */ 00288 00289 #endif // IVL_CORE_DETAILS_TYPES_DERIVE_HPP