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_DETECT_HPP 00025 #define IVL_CORE_DETAILS_TYPES_DETECT_HPP 00026 00027 namespace ivl { 00028 namespace types { 00029 00030 template <class T> 00031 class is_integer : public t_false { }; 00032 00033 #include "platform_specific/is_integer_impl.hpp" 00034 00035 template <class T> 00036 class is_bool : public t_false { }; 00037 00038 template <> 00039 class is_bool<bool> : public t_true { }; 00040 00041 template <class T> 00042 class is_floating : public t_false { }; 00043 00044 template <> 00045 class is_floating<float> : public t_true { }; 00046 00047 template <> 00048 class is_floating<double> : public t_true { }; 00049 00050 template <class T> 00051 class is_builtin : 00052 public t_or_3<is_integer<T>, is_bool<T>, is_floating<T> >::type {}; 00053 00054 // --------- 00055 00056 template <class T> 00057 class is_ptr : public t_false { }; 00058 00059 template <class T> 00060 class is_ptr<T*> : public t_true { }; 00061 00062 template <class T> 00063 class is_ptr<const T*> : public t_true { }; 00064 00065 template <class T> 00066 class is_ref : public t_false { }; 00067 00068 template <class T> 00069 class is_ref<T&> : public t_true { }; 00070 00071 template <class T> 00072 class is_ref<const T&> : public t_true { }; 00073 00074 template <class T> 00075 class is_c_array : public t_false { }; 00076 00077 template <int N, class T> 00078 class is_c_array<T[N]> : public t_true { }; 00079 00080 template <int N, class T> 00081 class is_c_array<const T[N]> : public t_true { }; 00082 00083 // --------- 00084 00085 template <class T> 00086 class is_complex : public t_false { }; 00087 00088 template <class T> 00089 class is_complex<std::complex<T> > : public t_true { }; 00090 00091 template <class T> 00092 class is_num_value : 00093 public t_or<is_builtin<T>, is_complex<T> >::type {}; 00094 00095 // --------- 00096 00097 namespace types_details { 00098 00099 template <class B, class D> 00100 struct is_base_match 00101 { 00102 template <class T> 00103 static inline t_detect<t_true> check(const D& , T) ; 00104 static inline t_detect<t_false> check(const B& , int) ; 00105 }; 00106 00107 template <class B, class D> 00108 struct is_base_struct 00109 { 00110 struct convert 00111 { 00112 operator const B& () const; 00113 operator const D& (); 00114 }; 00115 00116 enum { 00117 is_base_value = (sizeof(is_base_match<B, D>:: 00118 check(convert(), 0)) == sizeof(t_detect<t_true>)) 00119 }; 00120 00121 typedef typename t_expr<is_base_value>::type type; 00122 }; 00123 00124 }; /* namespace types_details */ 00125 00126 template <class B, class D> 00127 struct is_base 00128 : public types_details::is_base_struct<B, D>::type 00129 { 00130 }; 00131 00132 // Note: Added this specialization to remove problems with references checked. 00133 // TODO: needs proper thought. 00134 template <class B, class D> 00135 struct is_base<B, D&> 00136 : public types::t_false 00137 { 00138 }; 00139 00140 template <class B, class D> 00141 struct is_base_eq 00142 : public types_details::is_base_struct<B, D>::type 00143 { 00144 }; 00145 00146 // Note: Added this specialization to remove problems with references checked. 00147 // TODO: needs proper thought. 00148 template <class B, class D> 00149 struct is_base_eq<B, D&> 00150 : public types::t_false 00151 { 00152 }; 00153 00154 // Note: Added this specialization to remove problems with references checked. 00155 // TODO: needs proper thought. 00156 template <class D> 00157 struct is_base_eq<D&, D&> 00158 : public types::t_true 00159 { 00160 }; 00161 00162 00163 template <class A> 00164 struct is_base_eq<A, A> : public t_true { }; 00165 00166 template <class A, class B> 00167 struct is_related 00168 : public t_or<is_base_eq<A, B>, is_base_eq<B, A> > { }; 00169 00170 template <class A> 00171 struct is_ivl_array 00172 : public t_and_3<typename is_base<array_identifier, A>::type, 00173 t_not<typename is_base_eq<scalar_identifier, A>::type>, 00174 t_not<typename is_base_eq<index_array, A>::type > >::type 00175 { 00176 }; 00177 00179 template <class T, class S> 00180 struct is_ivl_array<array<T, S> > : public t_true { }; 00181 00182 00183 namespace types_details { 00184 00185 template <class T, class IS_ARRAY> 00186 struct get_value_t {}; 00187 00188 template <class T> 00189 struct get_value_t<T, t_false> 00190 { 00191 typedef term subtype; 00192 typedef T type; 00193 typedef T inner_type; 00194 }; 00195 /* 00196 template <class T> 00197 struct get_value_t<T, t_true> 00198 : public get_value_t<typename T::elem_type, 00199 typename types::is_array<typename T::elem_type>::type> 00200 { 00201 };*/ 00202 template <class T> 00203 struct get_value_t<T, t_true> 00204 { 00205 typedef typename T::elem_type type; 00206 typedef typename T::elem_type subtype; 00207 typedef typename get_value_t<typename T::elem_type, 00208 typename is_ivl_array<typename T::elem_type>::type> 00209 ::inner_type inner_type; 00210 }; 00211 00212 } /* namespace types_details */ 00213 00214 template <class T> 00215 class get_value 00216 : public 00217 types_details::get_value_t<T, typename types::is_ivl_array<T>::type> 00218 { 00219 }; 00220 00221 template <class T> 00222 struct get_inner_value 00223 { 00224 typedef typename types_details:: 00225 get_value_t<T, typename types::is_ivl_array<T>::type>::inner_type type; 00226 }; 00227 00228 template <class T> 00229 struct subtype 00230 { 00231 typedef typename types_details:: 00232 get_value_t<T, typename types::is_ivl_array<T>::type>::subtype type; 00233 }; 00234 00235 } /* namespace types */ 00236 } /* namespace ivl */ 00237 00238 #endif // IVL_CORE_DETAILS_TYPES_DETECT_HPP