00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_ACCU_TUPLE_HH
00027 # define MLN_ACCU_TUPLE_HH
00028
00032
00033
00034 # include <utility>
00035
00036 # include <mln/core/concept/meta_accumulator.hh>
00037
00038 # include <mln/accu/internal/base.hh>
00039 # include <mln/metal/is_a.hh>
00040 # include <mln/metal/unqualif.hh>
00041
00042 # include "boost/tuple/tuple.hpp"
00043 # include "boost/preprocessor/iteration/local.hpp"
00044 # include "boost/preprocessor/repetition/repeat.hpp"
00045 # include "boost/preprocessor/repetition/enum_params.hpp"
00046 # include "boost/preprocessor/repetition/enum_params_with_a_default.hpp"
00047
00048 # define RESULT_ACCU(z, n, data) BOOST_PP_COMMA_IF(n) typename internal::tuplehelper_<T ## n>::result
00049 # define ARG(z, n, data) BOOST_PP_COMMA_IF(n) const T ## n& p ## n = T ## n()
00050 # define BOOST_PP_LOCAL_MACRO(n) typedef mln_accu_with(T ## n, A) AT ## n;
00051 # define BOOST_PP_LOCAL_LIMITS (0, 9)
00052
00053 namespace mln
00054 {
00055
00056 namespace accu
00057 {
00058
00059 namespace internal
00060 {
00061
00062 template <typename T> struct tuplehelper_;
00063 template <unsigned n, typename T> struct tuplehelper;
00064 }
00065
00067
00072 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(10, typename T, boost::tuples::null_type)>
00073 struct tuple
00074 : 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)> >
00075 {
00076 typedef A argument;
00077
00078 typedef boost::tuple< BOOST_PP_REPEAT(10, RESULT_ACCU, Le Ricard ya que ca de vrai !)> res;
00079 typedef boost::tuple< BOOST_PP_ENUM_PARAMS(10, T)> intern;
00080 typedef tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)> self;
00081
00082 tuple();
00083
00086 void init();
00087 void take_as_init_(const argument& t);
00088 void take(const argument& t);
00089 void take(const tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)>& other);
00091
00093 res to_result() const;
00094
00097 bool is_valid() const;
00098
00099 protected:
00100
00101 intern a_;
00102 };
00103
00104 namespace meta
00105 {
00106
00108
00109 template <unsigned n, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(10, typename T, boost::tuples::null_type)>
00110 struct tuple : public Meta_Accumulator< tuple<n, BOOST_PP_ENUM_PARAMS(10, T)> >
00111 {
00112 template <typename A>
00113 struct with
00114 {
00115 # include BOOST_PP_LOCAL_ITERATE()
00116
00117 typedef accu::tuple<A, n, BOOST_PP_ENUM_PARAMS(10, AT)> ret;
00118 };
00119 };
00120
00121 }
00122
00123
00124 # ifndef MLN_INCLUDE_ONLY
00125
00126 namespace internal
00127 {
00128
00129 template <typename T>
00130 struct tuplehelper_
00131 {
00132 typedef typename T::result result;
00133 };
00134
00135 template <>
00136 struct tuplehelper_<boost::tuples::null_type>
00137 {
00138 typedef boost::tuples::null_type result;
00139 };
00140
00141 template <unsigned n, typename T>
00142 struct tuplehelper
00143 {
00144 static void init(typename T::intern& a)
00145 {
00146 boost::get<n - 1>(a).init();
00147 tuplehelper<n - 1, T>::init(a);
00148 }
00149
00150 static void take_as_init_(typename T::intern& a, const typename T::argument& argument)
00151 {
00152 boost::get<n - 1>(a).take_as_init_(argument);
00153 tuplehelper<n - 1, T>::take_as_init_(a, argument);
00154 }
00155
00156 static void take(typename T::intern& a, const typename T::argument& argument)
00157 {
00158 boost::get<n - 1>(a).take(argument);
00159 tuplehelper<n - 1, T>::take(a, argument);
00160 }
00161
00162 static void take(typename T::intern& a, const typename T::intern& other)
00163 {
00164 boost::get<n - 1>(a).take(boost::get<n - 1>(other));
00165 tuplehelper<n - 1, T>::take(a, other);
00166 }
00167
00168 static void to_result(const typename T::intern& a, typename T::result& res)
00169 {
00170 boost::get<n - 1>(res) = boost::get<n - 1>(a).to_result();
00171 tuplehelper<n - 1, T>::to_result(a, res);
00172 }
00173 };
00174
00175 template <typename T>
00176 struct tuplehelper<0, T>
00177 {
00178 static void init(typename T::intern&) {}
00179 static void take_as_init_(typename T::intern&, const typename T::argument&) {}
00180 static void take(typename T::intern&, const typename T::argument) {}
00181 static void take(typename T::intern&, const typename T::intern&) {}
00182 static void to_result(const typename T::intern&, typename T::result&) {}
00183 };
00184 }
00185
00186 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
00187 inline
00188 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::tuple()
00189 {
00190 init();
00191 }
00192
00193 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
00194 inline
00195 void
00196 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::init()
00197 {
00198 internal::tuplehelper<n, self>::init(this->a_);
00199 }
00200
00201 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
00202 inline
00203 void
00204 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take_as_init_(const argument& t)
00205 {
00206 internal::tuplehelper<n, self>::take_as_init_(this->a_, t);
00207 }
00208
00209 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
00210 inline
00211 void
00212 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take(const argument& t)
00213 {
00214 internal::tuplehelper<n, self>::take(this->a_, t);
00215 }
00216
00217 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
00218 inline
00219 void
00220 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take(const tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >& other)
00221 {
00222 internal::tuplehelper<n, self>::take(this->a_, other.a_);
00223 }
00224
00225 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
00226 inline
00227 typename tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::res
00228 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::to_result() const
00229 {
00230 res tmp;
00231 internal::tuplehelper<n, self>::to_result(this->a_, tmp);
00232 return tmp;
00233 }
00234
00235 template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
00236 inline
00237 bool
00238 tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::is_valid() const
00239 {
00240 return true;
00241 }
00242
00243 # endif // ! MLN_INCLUDE_ONLY
00244
00245 }
00246
00247 }
00248
00249
00250 #endif // ! MLN_ACCU_TUPLE_HH