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_LAZY_HPP 00025 #define IVL_CORE_DETAILS_TYPES_LAZY_HPP 00026 00027 namespace ivl { 00028 namespace types { 00029 00030 // This struct is inherited by all expression classes which are lazy. 00031 // A lazy expression E is computed with typename E::type but is written as E. 00032 struct lazy_expr { }; 00033 00034 // 00035 template <int N> 00036 struct arg { }; 00037 00038 template <class T> 00039 struct lazy_stop { }; 00040 00041 namespace types_details { 00042 00043 template <class T, class IS_LAZY_EXPR> 00044 struct lazy_run_op 00045 { 00046 typedef T type; 00047 }; 00048 00049 template <class T> 00050 struct lazy_run_op<T, t_true> 00051 { 00052 typedef typename T::type type; 00053 }; 00054 00055 } /* namespace types_details */ 00056 00057 template <class T> 00058 struct lazy_run 00059 { 00060 typedef types_details::lazy_run_op lazy_run_op; 00061 typedef typename lazy_run_op<T, typename is_base<lazy_expr, T>::type>::type 00062 type; 00063 }; 00064 00065 // 00066 template <class T> 00067 struct lazy_type : public lazy_expr { }; 00068 00069 template <class T> 00070 struct lazy_run<lazy_type<T> > 00071 { 00072 typedef typename T::type type; 00073 }; 00074 00075 // This type is used to define a lazy expression 00076 template <class E> 00077 struct lazy 00078 { 00079 template <class T> 00080 struct eval 00081 { 00082 typedef typename lazy_run<E>::type type; 00083 }; 00084 }; 00085 00086 template <template <typename> class C, class T1> 00087 struct lazy<lazy_stop<T1> > 00088 { 00089 typedef T1 type; 00090 }; 00091 00092 template <template <typename> class C, class T1> 00093 struct lazy<C<T1> > 00094 { 00095 template <class T> 00096 struct eval 00097 { 00098 typedef typename lazy_run<C<typename lazy<T1>::eval<T>::type> >:: 00099 type type; 00100 }; 00101 }; 00102 00103 template <template <typename, typename> class C, class T1, class T2> 00104 struct lazy<C<T1, T2> > 00105 { 00106 template <class T> 00107 struct eval 00108 { 00109 typedef typename lazy_run<C< 00110 typename lazy<T1>::eval<T>::type, 00111 typename lazy<T2>::eval<T>::type> >:: 00112 type type; 00113 }; 00114 }; 00115 00116 template <template <typename, typename, typename> class C, 00117 class T1, class T2, class T3> 00118 struct lazy<C<T1, T2, T3> > 00119 { 00120 template <class T> 00121 struct eval 00122 { 00123 typedef typename lazy_run<C< 00124 typename lazy<T1>::eval<T>::type, 00125 typename lazy<T2>::eval<T>::type, 00126 typename lazy<T3>::eval<T>::type> >:: 00127 type type; 00128 }; 00129 }; 00130 00131 template <int N> 00132 struct lazy<arg<N> > 00133 { 00134 template <class TPL> 00135 struct eval 00136 { 00137 typedef typename TPL::template val_t<N>::type type; 00138 }; 00139 }; 00140 00141 lazy<T<1> >::eval<TPL> => typename lazy_run<T<lazy<1>::eval<TPL> >> >::type 00142 lazy<T<1,2> >::eval<TPL> => typename lazy_run<T<lazy<1>::eval<TPL> >> >::type 00143 lazy<T<1..> >::eval<TPL> => typename lazy_run<T<lazy<1>::eval<TPL> >>>::type 00144 lazy<T<1..,10> >::eval<TPL> => typename lazy_run<T<lazy<1>::eval<TPL> >>>::type 00145 00146 lazy<arg<1> >::eval<TPL> => TPL::t1 00147 lazy<arg<2> >::eval<TPL> => TPL::t2 00148 lazy<arg<..> >::eval<TPL> => TPL::.. 00149 lazy<arg<10> >::eval<TPL> => TPL::t10 00150 00151 lazy<E> : typename lazy_run<E>::type 00152 00153 lazy_run<E> 00154 cases: 00155 is_base<E, lazy_expr>, 00156 typename E::type, 00157 E 00158 00159 00160 lazy<lazy_stop<E> >::eval<TPL> => E 00161 00162 is_ivl_array<arg<0> > 00163 00164 A::elem_type 00165 00166 l_elem_type<A> 00167 l_... 00168 00169 lazy<T<2> > => lazy<T<lazy<2> >> 00170 00171 00172 } /* namespace types */ 00173 } /* namespace ivl */ 00174 00175 #endif // IVL_CORE_DETAILS_TYPES_LAZY_HPP