Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-12-16 18:10:39


>From: "David A. Greene" <greened_at_[hidden]>
>
> Rozental, Gennadiy wrote:
> >>Which example is that? Is inherit_linearly documented somewhere?
> >>
> >
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/libs/mpl/example/
> > inherit_linearly.cpp?rev=1.1&content-type=text/vnd.viewcvs-markup
>
> Well, that's not creating a boost::tuple. :) I could certainly use
> mpl::fold or some similar algorithm to create boost::tuple<int,
> boost::tuple<...> > > > but I'm not sure that "really" a boost::tuple
> either. cons<int, cons<...> > > > might be closer.

Here's one way. This handles tuples of up to three elements, but can easily
be extended.

It requires partial specialisation, but it could also be rewritten without
it. In fact, I wrote a more complex version without it first, using
compile-time if-else, but then realised I could use specialisations for
this.

This is tested on Intel C++ 7.0, and it works.

--- Start ---

// For sequence_to_tuple

#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>
#include <boost/tuple/tuple.hpp>

// For test

#include <boost/mpl/list.hpp>
#include <boost/type_traits/same_traits.hpp>
#include <boost/static_assert.hpp>

#include <boost/mpl/alias.hpp>

template<class Sequence,int N = mpl::size<Sequence>::type::value>
struct sequence_to_tuple;

template<class Sequence>
struct sequence_to_tuple<Sequence,1>
{
  typedef boost::tuple<typename mpl::at_c<Sequence,0>::type> type;
};

template<class Sequence>
struct sequence_to_tuple<Sequence,2>
{
  typedef boost::tuple<typename mpl::at_c<Sequence,0>::type,
                       typename mpl::at_c<Sequence,1>::type> type;
};

template<class Sequence>
struct sequence_to_tuple<Sequence,3>
{
  typedef boost::tuple<typename mpl::at_c<Sequence,0>::type,
                       typename mpl::at_c<Sequence,1>::type,
                       typename mpl::at_c<Sequence,2>::type> type;
};

int main()
{
  typedef mpl::list<char> List1;
  typedef mpl::list<char,int> List2;
  typedef mpl::list<char,int,double> List3;

  typedef boost::tuple<char> Tuple1;
  typedef boost::tuple<char,int> Tuple2;
  typedef boost::tuple<char,int,double> Tuple3;

  typedef sequence_to_tuple<List1>::type NewTuple1;
  typedef sequence_to_tuple<List2>::type NewTuple2;
  typedef sequence_to_tuple<List3>::type NewTuple3;

  BOOST_STATIC_ASSERT((boost::is_same<Tuple1,NewTuple1>::value));
  BOOST_STATIC_ASSERT((boost::is_same<Tuple2,NewTuple2>::value));
  BOOST_STATIC_ASSERT((boost::is_same<Tuple3,NewTuple3>::value));
}

--- End ---

By the way, when making the above, I found that the docs for at/at_c
specifies <N, Sequence>, while the library has <Sequence, N>. Could this be
fixed?

> And I still don't completely "get" inherit_linearly. I assume it is
> supposed to be something like Loki's GenLinearHierarchy.

It seems so.

Regards,

Terje


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk