• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

tuple.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
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       // Fwd decl.
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   } // end of namespace mln::accu
00246 
00247 } // end of namespace mln
00248 
00249 
00250 #endif // ! MLN_ACCU_TUPLE_HH

Generated on Thu Sep 8 2011 18:32:43 for Milena (Olena) by  doxygen 1.7.1