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

tuple.hh

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

Generated on Tue Oct 4 2011 15:24:45 for Milena (Olena) by  doxygen 1.7.1