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
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
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 }
00247
00248 }
00249
00250
00251 #endif // ! MLN_ACCU_TUPLE_HH