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_FUNCTIONAL_HPP 00025 #define IVL_CORE_DETAILS_TYPES_FUNCTIONAL_HPP 00026 00027 namespace ivl { 00028 00029 namespace types { 00030 00031 // --------------------------------------------------- 00032 00033 // functional 00034 00035 namespace types_details { 00036 00037 template <class COND> 00038 struct r_if_result { }; 00039 00040 template<> 00041 struct r_if_result<t_true> 00042 { 00043 template <class THEN, class ELSE> 00044 static inline THEN& operate(THEN& t, ELSE& e) { return t; } 00045 }; 00046 00047 template<> 00048 struct r_if_result<t_false> 00049 { 00050 template <class THEN, class ELSE> 00051 static inline ELSE& operate(THEN& t, ELSE& e) { return e; } 00052 }; 00053 00054 } /* namespace types_details */ 00055 00056 // r_if returns the requested type 00057 template <class COND, class THEN, class ELSE> 00058 inline 00059 typename t_if<COND, THEN&, ELSE&>::type r_if(THEN& t, ELSE& e) 00060 { 00061 return types_details::r_if_result<typename COND::type>::operate(t, e); 00062 } 00063 00064 template <class COND, class THEN, class ELSE> 00065 inline 00066 typename t_if<COND, const THEN&, ELSE&>::type r_if(const THEN& t, ELSE& e) 00067 { 00068 return types_details::r_if_result<typename COND::type> 00069 ::template operate<const THEN, ELSE>(t, e); 00070 } 00071 00072 template <class COND, class THEN, class ELSE> 00073 inline 00074 typename t_if<COND, THEN&, const ELSE&>::type r_if(THEN& t, const ELSE& e) 00075 { 00076 return types_details::r_if_result<typename COND::type> 00077 ::template operate<THEN, const ELSE>(t, e); 00078 } 00079 00080 template <class COND, class THEN, class ELSE> 00081 inline 00082 typename t_if<COND, const THEN&, const ELSE&>:: 00083 type r_if(const THEN& t, const ELSE& e) 00084 { 00085 return types_details::r_if_result<typename COND::type> 00086 ::template operate<const THEN, const ELSE>(t, e); 00087 } 00088 00089 // ---------------------------------------------------------------------- 00090 00091 namespace types_details { 00092 00093 template <class A, class IS_RESIZEABLE> 00094 class r_resize_details { }; 00095 00096 template <class A> 00097 class r_resize_details<A, t_true> 00098 { 00099 template <class SZ> 00100 static inline bool operate(A& a, const SZ& l) 00101 { 00102 a.resize(l); 00103 return true; 00104 } 00105 template <class SZ, class T> 00106 static inline bool operate(A& a, const SZ& l, const T& s) 00107 { 00108 a.resize(l, s); 00109 return true; 00110 } 00111 template <class SZ> 00112 static inline bool reshape(A& a, const SZ& s) 00113 { 00114 a.reshape(s); 00115 return true; 00116 } 00117 }; 00118 00119 template <class A> 00120 class r_resize_details<A, t_false> 00121 { 00122 template <class SZ> 00123 static inline bool operate(A& a, const SZ& l) 00124 { 00125 return (a.size() == l); 00126 } 00127 template <class SZ, class T> 00128 static inline bool operate(A& a, const SZ& l, const T& s) 00129 { 00130 return (a.size() == l); 00131 } 00132 template <class SZ> 00133 static inline bool reshape(A& a, const SZ& s) 00134 { 00135 return (a.size() == s); 00136 } 00137 }; 00138 00139 } /* namespace types_details */ 00140 00142 template <class A, class SZ> 00143 bool r_resize(A& a, const SZ& sz) 00144 { 00145 return types_details::r_resize_details<A, 00146 t_and<typename A::is_resizeable, t_not<is_const<A> > > 00147 >::operate(a, sz); 00148 } 00149 00150 template <class A, class SZ, class T> 00151 bool r_resize(A& a, const SZ& sz, const T& s) 00152 { 00153 return types_details::r_resize_details<A, 00154 t_and<typename A::is_resizeable, t_not<is_const<A> > > 00155 >::operate(a, sz, s); 00156 } 00157 00158 template <class A, class SZ, class T> 00159 bool r_reshape(A& a, const SZ& sz, const T& s) 00160 { 00161 return types_details::r_resize_details<A, 00162 t_and<typename A::is_resizeable, t_not<is_const<A> > > 00163 >::reshape(a, sz, s); 00164 } 00165 00166 }; /*namespace types*/ 00167 00168 }; /*namespace ivl*/ 00169 00170 #endif // IVL_CORE_DETAILS_TYPES_FUNCTIONAL_HPP