Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_ACCU_TUPLE_HH 00028 # define MLN_ACCU_TUPLE_HH 00029 00033 00034 00035 # include <utility> 00036 00037 # include <mln/core/concept/meta_accumulator.hh> 00038 00039 # include <mln/accu/internal/base.hh> 00040 # include <mln/metal/is_a.hh> 00041 # include <mln/metal/unqualif.hh> 00042 00043 # include <boost/tuple/tuple.hpp> 00044 # include <boost/preprocessor/iteration/local.hpp> 00045 # include <boost/preprocessor/repetition/repeat.hpp> 00046 # include <boost/preprocessor/repetition/enum_params.hpp> 00047 # include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> 00048 00049 # define RESULT_ACCU(z, n, data) BOOST_PP_COMMA_IF(n) typename internal::tuplehelper_<T ## n>::result 00050 # define ARG(z, n, data) BOOST_PP_COMMA_IF(n) const T ## n& p ## n = T ## n() 00051 # define BOOST_PP_LOCAL_MACRO(n) typedef mln_accu_with(T ## n, A) AT ## n; 00052 # define BOOST_PP_LOCAL_LIMITS (0, 9) 00053 00054 namespace mln 00055 { 00056 00057 namespace accu 00058 { 00059 00060 namespace internal 00061 { 00062 // Fwd decl. 00063 template <typename T> struct tuplehelper_; 00064 template <unsigned n, typename T> struct tuplehelper; 00065 } 00066 00068 00073 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(10, typename T, boost::tuples::null_type)> 00074 struct tuple 00075 : public mln::accu::internal::base< boost::tuple< BOOST_PP_REPEAT(10, RESULT_ACCU, Le Ricard ya que ca de vrai !) >, tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)> > 00076 { 00077 typedef A argument; 00078 00079 typedef boost::tuple< BOOST_PP_REPEAT(10, RESULT_ACCU, Le Ricard ya que ca de vrai !)> res; 00080 typedef boost::tuple< BOOST_PP_ENUM_PARAMS(10, T)> intern; 00081 typedef tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)> self; 00082 00083 tuple(); 00084 00087 void init(); 00088 void take_as_init_(const argument& t); 00089 void take(const argument& t); 00090 void take(const tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)>& other); 00092 00094 res to_result() const; 00095 00098 bool is_valid() const; 00099 00100 protected: 00101 00102 intern a_; 00103 }; 00104 00105 namespace meta 00106 { 00107 00109 00110 template <unsigned n, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(10, typename T, boost::tuples::null_type)> 00111 struct tuple : public Meta_Accumulator< tuple<n, BOOST_PP_ENUM_PARAMS(10, T)> > 00112 { 00113 template <typename A> 00114 struct with 00115 { 00116 # include BOOST_PP_LOCAL_ITERATE() 00117 00118 typedef accu::tuple<A, n, BOOST_PP_ENUM_PARAMS(10, AT)> ret; 00119 }; 00120 }; 00121 00122 } 00123 00124 00125 # ifndef MLN_INCLUDE_ONLY 00126 00127 namespace internal 00128 { 00129 00130 template <typename T> 00131 struct tuplehelper_ 00132 { 00133 typedef typename T::result result; 00134 }; 00135 00136 template <> 00137 struct tuplehelper_<boost::tuples::null_type> 00138 { 00139 typedef boost::tuples::null_type result; 00140 }; 00141 00142 template <unsigned n, typename T> 00143 struct tuplehelper 00144 { 00145 static void init(typename T::intern& a) 00146 { 00147 boost::get<n - 1>(a).init(); 00148 tuplehelper<n - 1, T>::init(a); 00149 } 00150 00151 static void take_as_init_(typename T::intern& a, const typename T::argument& argument) 00152 { 00153 boost::get<n - 1>(a).take_as_init_(argument); 00154 tuplehelper<n - 1, T>::take_as_init_(a, argument); 00155 } 00156 00157 static void take(typename T::intern& a, const typename T::argument& argument) 00158 { 00159 boost::get<n - 1>(a).take(argument); 00160 tuplehelper<n - 1, T>::take(a, argument); 00161 } 00162 00163 static void take(typename T::intern& a, const typename T::intern& other) 00164 { 00165 boost::get<n - 1>(a).take(boost::get<n - 1>(other)); 00166 tuplehelper<n - 1, T>::take(a, other); 00167 } 00168 00169 static void to_result(const typename T::intern& a, typename T::result& res) 00170 { 00171 boost::get<n - 1>(res) = boost::get<n - 1>(a).to_result(); 00172 tuplehelper<n - 1, T>::to_result(a, res); 00173 } 00174 }; 00175 00176 template <typename T> 00177 struct tuplehelper<0, T> 00178 { 00179 static void init(typename T::intern&) {} 00180 static void take_as_init_(typename T::intern&, const typename T::argument&) {} 00181 static void take(typename T::intern&, const typename T::argument) {} 00182 static void take(typename T::intern&, const typename T::intern&) {} 00183 static void to_result(const typename T::intern&, typename T::result&) {} 00184 }; 00185 } 00186 00187 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)> 00188 inline 00189 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::tuple() 00190 { 00191 init(); 00192 } 00193 00194 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)> 00195 inline 00196 void 00197 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::init() 00198 { 00199 internal::tuplehelper<n, self>::init(this->a_); 00200 } 00201 00202 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)> 00203 inline 00204 void 00205 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take_as_init_(const argument& t) 00206 { 00207 internal::tuplehelper<n, self>::take_as_init_(this->a_, t); 00208 } 00209 00210 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)> 00211 inline 00212 void 00213 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take(const argument& t) 00214 { 00215 internal::tuplehelper<n, self>::take(this->a_, t); 00216 } 00217 00218 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)> 00219 inline 00220 void 00221 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take(const tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >& other) 00222 { 00223 internal::tuplehelper<n, self>::take(this->a_, other.a_); 00224 } 00225 00226 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)> 00227 inline 00228 typename tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::res 00229 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::to_result() const 00230 { 00231 res tmp; 00232 internal::tuplehelper<n, self>::to_result(this->a_, tmp); 00233 return tmp; 00234 } 00235 00236 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)> 00237 inline 00238 bool 00239 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::is_valid() const 00240 { 00241 return true; 00242 } 00243 00244 # endif // ! MLN_INCLUDE_ONLY 00245 00246 } // end of namespace mln::accu 00247 00248 } // end of namespace mln 00249 00250 00251 #endif // ! MLN_ACCU_TUPLE_HH