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