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_ARRAY_HPP 00025 #define IVL_CORE_DETAILS_TYPES_ARRAY_HPP 00026 00027 namespace ivl { 00028 00029 namespace types { 00030 00031 00032 00033 namespace types_details 00034 { 00035 /* 00036 template <class F> struct base_class {}; 00037 // 3 parameter template 00038 template <template<typename, typename, typename> class CC> struct class_container 00039 { 00040 template <class A, class B, class C> 00041 struct instance 00042 { 00043 typedef CC <A, B, C> type; 00044 }; 00045 }; 00046 */ 00047 00048 } /* namespace types_details */ 00049 00050 00051 00052 namespace types_details 00053 { 00054 00055 template <class A, class B> 00056 struct is_hierarchy_base_eq_tool 00057 : public is_hierarchy_base_eq_tool <A, typename B::base_class> { }; 00058 00059 template <class A> 00060 struct is_hierarchy_base_eq_tool<A, A> : public t_true { }; 00061 00062 template <class X, class Y> 00063 struct is_hierarchy_base_eq_tool<ivl::array<X, Y>, ivl::array<X, Y> > 00064 : public t_true { }; 00065 00066 // Note: used to be X, P, Q, however this restriction was relaxed since 00067 // we are going to allow 'affairs' between different data-type arrays. 00068 template <class X, class Y, class J, class P> 00069 struct is_hierarchy_base_eq_tool<ivl::array<X, Y>, ivl::array<J, P> > 00070 : public t_true { }; 00071 00072 template <class A, class X, class Y> 00073 struct is_hierarchy_base_eq_tool<A, ivl::array<X, Y> > 00074 : public t_false { }; 00075 00076 } /* namespace types_details */ 00077 00078 // A and B must be ivl arrays. returns A base or equal to B in the ivl 00079 // hierarchy tree, only in the matter of the array type (array, array_nd ...). 00080 template <class A, class B> 00081 struct is_hierarchy_base_eq 00082 : public types_details::is_hierarchy_base_eq_tool< 00083 typename change_data_class_set<data::mem<>, A>::type, 00084 typename change_data_class_set<data::mem<>, B>::type> { }; 00085 00086 // A and B must be ivl arrays. returns A is equal to B in the ivl 00087 // hierarchy tree, only in the matter of the array type (array != array_nd ...). 00088 // another name could be is_same_level 00089 template <class A, class B> 00090 struct is_hierarchy_eq 00091 : public t_and<is_hierarchy_base_eq<A, B>, is_hierarchy_base_eq<B, A> > { }; 00092 00093 00094 template <class A, class B> 00095 struct highest_common; 00096 00097 namespace types_details { 00098 00099 template <class A, class B, class A_ISBASEOF_B, class B_ISBASEOF_A> 00100 struct hc {}; 00101 00102 template <class A, class B> 00103 struct hc<A, B, t_true, t_true> 00104 { 00105 typedef A type_a; 00106 typedef B type_b; 00107 }; 00108 00109 template <class A, class B> 00110 struct hc<A, B, t_false, t_true> : 00111 public highest_common<typename A::base_class, B> {}; 00112 00113 template <class A, class B> 00114 struct hc<A, B, t_true, t_false> : 00115 public highest_common<A, typename B::base_class> {}; 00116 00117 template <class A, class B> 00118 struct hc<A, B, t_false, t_false> : 00119 public highest_common<A, typename B::base_class> {}; 00120 00121 } /* namespace types_details */ 00122 00123 00126 template <class A, class B> 00127 struct highest_common : 00128 public types_details::hc<A, B, 00129 typename is_hierarchy_base_eq<A, B>::type, 00130 typename is_hierarchy_base_eq<B, A>::type> 00131 { 00132 typedef typename highest_common::type_a type_a; 00133 typedef typename highest_common::type_b type_b; 00134 }; 00135 /* todo:wipe 00143 template <class A, class B> 00144 struct highest_common_template 00145 { 00146 typedef typename highest_common< 00147 typename change_data_class_set<data::normal, A>::type, 00148 typename change_data_class_set<data::normal, B>::type> 00149 ::type type_normal; 00150 00151 typedef typename change_data_class_set< 00152 typename A::data_type, type_normal>::type type_a; 00153 00154 00155 typedef typename change_data_class_set< 00156 typename B::data_type, type_normal>::type type_b; 00157 00158 00159 }; 00160 */ 00161 00162 00163 00164 00165 namespace types_details { 00166 00167 template <class A, class B, class A_IS_ARRAY, class B_IS_ARRAY> 00168 struct is_kind_base_eq_tool { }; 00169 00170 template <class A, class B> 00171 struct is_kind_base_eq_tool <A, B, t_true, t_true> 00172 : public is_hierarchy_base_eq<A, B> 00173 { 00174 typedef is_kind_base_eq_tool< 00175 typename get_value<A>::type, typename get_value<B>::type, 00176 typename is_ivl_array<typename get_value<A>::type>::type, 00177 typename is_ivl_array<typename get_value<B>::type>::type> rec; 00178 00179 typedef typename t_and<is_hierarchy_base_eq<A, B>, 00180 typename rec::base_eq_recurse>::type base_eq_recurse; 00181 00182 typedef typename t_and<is_hierarchy_eq<A, B>, 00183 typename rec::eq_recurse>::type eq_recurse; 00184 }; 00185 00186 // and the big question is: should this yield true? B element is convertible 00187 // to array A with 1 element! Making it true would also not affect equality. 00188 template <class A, class B> 00189 struct is_kind_base_eq_tool <A, B, t_true, t_false> 00190 : public t_false 00191 { 00192 typedef t_false base_eq_recurse; 00193 typedef t_false eq_recurse; 00194 }; 00195 00196 template <class A, class B> 00197 struct is_kind_base_eq_tool <A, B, t_false, t_true> 00198 : public t_false 00199 { 00200 typedef t_false base_eq_recurse; 00201 typedef t_false eq_recurse; 00202 }; 00203 00204 // TODO: actually should be only true if B is convertible to A. 00205 // which is kind of possible to detect. 00206 // However the 'any type by any type' array data relaxation is decided to be 00207 // the rule for the situations that is_kind_base_eq_tool will be needed. 00208 // for the same reason, is_kind_eq will not check at all for data type equality. 00209 template <class A, class B> 00210 struct is_kind_base_eq_tool <A, B, t_false, t_false> 00211 : public t_true 00212 { 00213 typedef t_true base_eq_recurse; 00214 typedef t_true eq_recurse; 00215 }; 00216 00217 } /* namespace types_details */ 00218 00219 template <class A, class B> 00220 struct is_kind_base_eq 00221 : public types_details::is_kind_base_eq_tool<A, B, 00222 typename is_ivl_array<A>::type, typename is_ivl_array<B>::type>::type { }; 00223 00224 template <class A, class B> 00225 struct is_kind_eq 00226 : public t_and<is_kind_base_eq<A, B>, is_kind_base_eq<B, A> > { }; 00227 00228 // Need some decent naming here: 00229 // The struct below does the following: Checks if a class A is base or equal 00230 // of class B, only in hierarchy terms, e.g. array <= array_nd, but also 00231 // looking at the data type. e.g. array<array> <= array<array_nd> 00232 // and array<array> <= array_nd<array>. etc. 00233 template <class A, class B> 00234 struct is_kind_base_eq_recurse 00235 : public types_details::is_kind_base_eq_tool<A, B, 00236 typename is_ivl_array<A>::type, typename is_ivl_array<B>::type> 00237 ::base_eq_recurse { }; 00238 00239 template <class A, class B> 00240 struct is_kind_eq_recurse 00241 : public types_details::is_kind_base_eq_tool<A, B, 00242 typename is_ivl_array<A>::type, typename is_ivl_array<B>::type> 00243 ::eq_recurse { }; 00244 00245 // --------------------------------------------------------------------- 00246 00247 template <class J> 00248 struct single_element : public internal::reference_face<J> { }; 00249 00250 namespace types_details { 00251 00252 template <class T, class IS_ARRAY> 00253 struct create_new_tool { }; 00254 00255 template <class T> 00256 struct create_new_tool<T, t_true> 00257 { 00258 typedef typename T::create_new create_new; 00259 typedef typename T::create_similar create_similar; 00260 }; 00261 00262 template <class T> 00263 struct create_new_tool<T, t_false> 00264 { 00265 typedef T create_new; 00266 typedef T create_similar; 00267 }; 00268 00269 } /* namespace types_details */ 00270 00271 template <class T> 00272 struct create_new 00273 { 00274 typedef typename types_details::create_new_tool<T, 00275 typename is_ivl_array<T>::type>::create_new type; 00276 }; 00277 00278 template <class T> 00279 struct create_similar 00280 { 00281 typedef typename types_details::create_new_tool<T, 00282 typename is_ivl_array<T>::type>::create_similar type; 00283 }; 00284 00285 // --------------------------------------------------------------------- 00286 00287 00288 } /* namespace types */ 00289 00290 } /* namespace ivl */ 00291 00292 00293 #endif // CORE_DETAILS_TYPES_ARRAY_HPP