ivl 679
ivl/details/core/types/derive.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations