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