2009-06-16 12:07:49 +02:00
|
|
|
/*
|
|
|
|
|
TUPLE.hpp - metaprogramming utilities for type tuples and data tuples
|
|
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2009, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 of the
|
|
|
|
|
License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @file tuple.hpp
|
2009-06-22 06:05:32 +02:00
|
|
|
** Metaprogramming with tuples-of-types and a simple Tuple (record) datatype.
|
2009-06-16 12:07:49 +02:00
|
|
|
** The metaprogramming part of this header complements typelist.hpp and allows
|
2009-06-30 04:54:50 +02:00
|
|
|
** some additional manipulations on type sequences. Such a finite sequence or
|
|
|
|
|
** tuple of types can at times be more handy than a typelist, especially when
|
|
|
|
|
** capturing specific types to use as template parameter.
|
2009-06-16 12:07:49 +02:00
|
|
|
**
|
2009-06-22 06:05:32 +02:00
|
|
|
** Additionally, this header augments the Tuple template into a simple Tuple
|
2009-06-16 12:07:49 +02:00
|
|
|
** (run time) datatype. This isn't meant as competing with std::tr1::tuple, which is
|
|
|
|
|
** much more capable, but also has the downside of pulling in a lot of other headers.
|
|
|
|
|
** But when all we need is to define a generic typed record of N data elements and
|
|
|
|
|
** later re-accessing them (but no further advanced processing), the Tuple template
|
|
|
|
|
** might come in handy.
|
|
|
|
|
**
|
|
|
|
|
** @see control::CommandDef usage example
|
2009-06-20 18:06:07 +02:00
|
|
|
** @see tuple-test.cpp
|
2009-06-16 12:07:49 +02:00
|
|
|
** @see typelist.hpp
|
|
|
|
|
** @see function.hpp
|
|
|
|
|
** @see generator.hpp
|
|
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef LUMIERA_META_TUPLE_H
|
|
|
|
|
#define LUMIERA_META_TUPLE_H
|
|
|
|
|
|
|
|
|
|
#include "lib/meta/typelist.hpp"
|
2009-06-30 04:54:50 +02:00
|
|
|
#include "lib/meta/typelist-util.hpp"
|
|
|
|
|
#include "lib/meta/typeseq-util.hpp"
|
2009-06-20 23:18:02 +02:00
|
|
|
#include "lib/meta/util.hpp"
|
2009-06-16 12:07:49 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace lumiera {
|
|
|
|
|
namespace typelist{
|
2009-06-22 06:05:32 +02:00
|
|
|
|
|
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
/**
|
|
|
|
|
* simple generic Tuple datatype.
|
|
|
|
|
* Usable both for metaprogramming and as a generic record.
|
|
|
|
|
* The types within this tuple can either be specified
|
2009-06-22 06:05:32 +02:00
|
|
|
* as Type sequence or as typelist. Default and canonical
|
|
|
|
|
* is the type-sequence based tuple form \c Tuple<Types<T1,T2,...>>
|
|
|
|
|
* The secondary from of specifying a tuple is based on a typelist
|
|
|
|
|
* (and this form is used actually to implement the storage, while
|
|
|
|
|
* the plain-flat (type sequence based) form acts as interface.
|
|
|
|
|
*
|
|
|
|
|
* Irrespective of the flavour actually used, you can always
|
|
|
|
|
* - get the canonical TupleType (sequence based)
|
|
|
|
|
* - get the types of head and tail, and a list version of the types
|
|
|
|
|
* - access the head element and the tail tuple
|
|
|
|
|
* - access the Nth element and a shifted-b-N sub (tail) tuple
|
2009-06-17 06:55:18 +02:00
|
|
|
*/
|
2009-06-16 12:07:49 +02:00
|
|
|
template<class TYPES>
|
|
|
|
|
struct Tuple;
|
2009-06-17 06:55:18 +02:00
|
|
|
|
|
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
template<>
|
|
|
|
|
struct Tuple<NullType>
|
|
|
|
|
{
|
|
|
|
|
typedef NullType HeadType;
|
|
|
|
|
typedef Types<> TailType;
|
|
|
|
|
typedef Types<> Type;
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef NullType ArgList;
|
2009-06-21 19:52:33 +02:00
|
|
|
typedef Tuple<Type> TupleType;
|
|
|
|
|
typedef Tuple<NullType> ThisType;
|
2009-06-16 12:07:49 +02:00
|
|
|
typedef Tuple<NullType> Tail;
|
2009-06-17 06:55:18 +02:00
|
|
|
enum { SIZE = 0 };
|
2009-06-16 12:07:49 +02:00
|
|
|
|
|
|
|
|
NullType getHead() { return NullType(); }
|
|
|
|
|
Tail& getTail() { return *this; }
|
|
|
|
|
|
|
|
|
|
Tuple (HeadType const&, Tail const&) { }
|
|
|
|
|
Tuple () { }
|
2009-06-21 19:52:33 +02:00
|
|
|
|
2009-06-28 20:41:33 +02:00
|
|
|
template<uint> struct ShiftedTuple { typedef Tail Type;};
|
|
|
|
|
template<uint> Tail& getShifted () { return *this; }
|
|
|
|
|
template<uint> NullType& getAt () { return getHead(); }
|
|
|
|
|
|
|
|
|
|
const NullType getHead_const() const { return NullType();}
|
|
|
|
|
const Tail& getTail_const() const { return *this; }
|
2009-06-21 19:52:33 +02:00
|
|
|
|
|
|
|
|
TupleType&
|
|
|
|
|
tupleCast ()
|
|
|
|
|
{
|
|
|
|
|
return reinterpret_cast<TupleType&> (*this);
|
|
|
|
|
}
|
2009-06-16 12:07:49 +02:00
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
template<class TY, class TYPES>
|
|
|
|
|
struct Tuple<Node<TY,TYPES> >
|
|
|
|
|
: Tuple<TYPES>
|
|
|
|
|
{
|
2009-06-30 04:54:50 +02:00
|
|
|
typedef TY HeadType;
|
|
|
|
|
typedef typename Tuple<TYPES>::Type TailType;
|
|
|
|
|
typedef typename Prepend<TY,TailType>::Seq Type;
|
2009-06-16 12:07:49 +02:00
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef Node<TY,TYPES> ArgList;
|
2009-06-21 19:52:33 +02:00
|
|
|
typedef Tuple<Type> TupleType;
|
|
|
|
|
typedef Tuple<ArgList> ThisType;
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef Tuple<TYPES> Tail;
|
|
|
|
|
enum { SIZE = count<ArgList>::value };
|
2009-06-16 12:07:49 +02:00
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
Tuple ( TY a1 =TY()
|
2009-06-16 12:07:49 +02:00
|
|
|
, Tail tail =Tail()
|
|
|
|
|
)
|
2009-06-21 19:52:33 +02:00
|
|
|
: Tail (tail.getHead(), tail.getTail()),
|
2009-06-16 12:07:49 +02:00
|
|
|
val_(a1)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
TY & getHead() { return val_; }
|
|
|
|
|
Tail& getTail() { return static_cast<Tail&> (*this); }
|
|
|
|
|
|
2009-06-28 20:41:33 +02:00
|
|
|
TY const& getHead_const() const { return val_; }
|
|
|
|
|
Tail const& getTail_const() const { return static_cast<const Tail&> (*this); }
|
|
|
|
|
|
2009-06-21 19:52:33 +02:00
|
|
|
|
|
|
|
|
template<uint i>
|
|
|
|
|
class ShiftedTuple
|
|
|
|
|
{
|
|
|
|
|
typedef typename Tuple::Type OurType_;
|
|
|
|
|
typedef typename Shifted<OurType_,i>::Type ShiftedTypes_;
|
|
|
|
|
public:
|
|
|
|
|
typedef Tuple<typename ShiftedTypes_::List> Type;
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-22 06:05:32 +02:00
|
|
|
|
2009-06-21 19:52:33 +02:00
|
|
|
template<uint i>
|
|
|
|
|
typename ShiftedTuple<i>::Type&
|
|
|
|
|
getShifted ()
|
|
|
|
|
{
|
|
|
|
|
typedef typename ShiftedTuple<i>::Type Tail_I;
|
|
|
|
|
return static_cast<Tail_I&> (*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TupleType&
|
|
|
|
|
tupleCast () ///< note makes this List-style Tuple appear as plain-flat Tuple
|
|
|
|
|
{
|
|
|
|
|
return reinterpret_cast<TupleType&> (*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<uint i>
|
|
|
|
|
typename Shifted<Type,i>::Head&
|
|
|
|
|
getAt ()
|
|
|
|
|
{
|
|
|
|
|
return getShifted<i>().getHead();
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
private:
|
|
|
|
|
TY val_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
, typename T4
|
|
|
|
|
, typename T5
|
2009-06-17 06:55:18 +02:00
|
|
|
, typename T6
|
|
|
|
|
, typename T7
|
|
|
|
|
, typename T8
|
|
|
|
|
, typename T9
|
2009-06-16 12:07:49 +02:00
|
|
|
>
|
2009-06-17 06:55:18 +02:00
|
|
|
struct Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> >
|
|
|
|
|
: Tuple<typename Types<T1,T2,T3,T4,T5,T6,T7,T8,T9>::List>
|
2009-06-16 12:07:49 +02:00
|
|
|
{
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef T1 HeadType;
|
|
|
|
|
typedef Types<T2,T3,T4,T5,T6,T7,T8,T9,NullType> TailType;
|
|
|
|
|
typedef Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> Type;
|
2009-06-16 12:07:49 +02:00
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef typename Type::List ArgList;
|
2009-06-21 19:52:33 +02:00
|
|
|
typedef Tuple<Type> TupleType;
|
|
|
|
|
typedef Tuple<Type> ThisType;
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef Tuple<TailType> Tail;
|
|
|
|
|
enum { SIZE = count<ArgList>::value };
|
2009-06-16 12:07:49 +02:00
|
|
|
|
2009-06-21 02:03:22 +02:00
|
|
|
/** standard ctor: create from values */
|
2009-06-16 12:07:49 +02:00
|
|
|
Tuple ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
, T4 a4 =T4()
|
|
|
|
|
, T5 a5 =T5()
|
2009-06-17 06:55:18 +02:00
|
|
|
, T6 a6 =T6()
|
|
|
|
|
, T7 a7 =T7()
|
|
|
|
|
, T8 a8 =T8()
|
|
|
|
|
, T9 a9 =T9()
|
2009-06-16 12:07:49 +02:00
|
|
|
)
|
2009-06-17 06:55:18 +02:00
|
|
|
: Tuple<ArgList>(a1, Tuple<TailType>(a2,a3,a4,a5,a6,a7,a8,a9))
|
2009-06-16 12:07:49 +02:00
|
|
|
{ }
|
|
|
|
|
|
2009-06-21 02:03:22 +02:00
|
|
|
/** shortcut: allow copy construction from a tuple
|
|
|
|
|
* which is rather defined by a list type */
|
|
|
|
|
Tuple (Tuple<ArgList> const& listTuple)
|
|
|
|
|
: Tuple<ArgList> (listTuple)
|
|
|
|
|
{ }
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
using Tuple<ArgList>::getHead;
|
2009-06-16 12:07:49 +02:00
|
|
|
|
2009-06-21 19:52:33 +02:00
|
|
|
Tail& getTail() ///< note makes the Tail appear as plain-flat shifted tuple
|
2009-06-16 12:07:49 +02:00
|
|
|
{
|
2009-06-21 19:52:33 +02:00
|
|
|
return Tuple<ArgList>::getTail().tupleCast();
|
2009-06-16 12:07:49 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-06-20 23:17:22 +02:00
|
|
|
template<>
|
|
|
|
|
struct Tuple<Types<> >
|
|
|
|
|
: Tuple<NullType>
|
|
|
|
|
{
|
|
|
|
|
enum { SIZE = 0 };
|
2009-06-21 19:52:33 +02:00
|
|
|
typedef Tuple<NullType> TupNilList;
|
|
|
|
|
typedef Tuple<Types<> > ThisType;
|
|
|
|
|
typedef ThisType Tail;
|
|
|
|
|
|
2009-06-20 23:17:22 +02:00
|
|
|
|
|
|
|
|
Tuple ( NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
, NullType =NullType()
|
|
|
|
|
)
|
|
|
|
|
{ } ///< end recursion of chained ctor calls
|
|
|
|
|
|
2009-06-21 08:38:24 +02:00
|
|
|
/** shortcut: allow copy construction from a tuple
|
|
|
|
|
* which is rather defined by a list type */
|
2009-06-21 19:52:33 +02:00
|
|
|
Tuple (TupNilList const&)
|
2009-06-21 08:38:24 +02:00
|
|
|
{ }
|
2009-06-20 23:17:22 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-21 08:38:24 +02:00
|
|
|
|
|
|
|
|
/** specialisation to shift plain tuple types */
|
|
|
|
|
template<class TYPES, uint i>
|
|
|
|
|
struct Shifted<Tuple<TYPES>,i>
|
|
|
|
|
{
|
|
|
|
|
typedef typename Shifted<TYPES,i>::Type Type;
|
|
|
|
|
typedef typename Shifted<TYPES,i>::Head Head;
|
2009-06-21 19:52:33 +02:00
|
|
|
typedef Tuple<Type> TupleType;
|
2009-06-21 08:38:24 +02:00
|
|
|
};
|
|
|
|
|
template<class TYPES>
|
|
|
|
|
struct Shifted<Tuple<TYPES>, 0>
|
|
|
|
|
{
|
|
|
|
|
typedef typename Tuple<TYPES>::Type Type;
|
|
|
|
|
typedef typename Tuple<TYPES>::HeadType Head;
|
2009-06-21 19:52:33 +02:00
|
|
|
typedef Tuple<Type> TupleType;
|
2009-06-21 08:38:24 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-06-22 06:05:32 +02:00
|
|
|
/* ====== Helpers for working with Tuples ========= */
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
namespace tuple { // some convenience access functions
|
|
|
|
|
|
|
|
|
|
template<uint n, class TUP>
|
2009-06-21 08:38:24 +02:00
|
|
|
typename Shifted<TUP,n>::Head&
|
2009-06-17 06:55:18 +02:00
|
|
|
element (TUP& tup)
|
|
|
|
|
{
|
|
|
|
|
return tup.template getAt<n>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-06-19 19:11:33 +02:00
|
|
|
inline
|
|
|
|
|
Tuple< Types<> >
|
2009-06-17 06:55:18 +02:00
|
|
|
makeNullTuple ()
|
|
|
|
|
{
|
|
|
|
|
return Tuple<Types<> > ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-06-19 19:11:33 +02:00
|
|
|
template<typename T1>
|
|
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1> >
|
2009-06-17 06:55:18 +02:00
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return Tuple<Types<T1> > (a1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
>
|
2009-06-19 19:11:33 +02:00
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2> >
|
2009-06-17 06:55:18 +02:00
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return Tuple<Types<T1,T2> > (a1,a2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
>
|
2009-06-19 19:11:33 +02:00
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2,T3> >
|
2009-06-17 06:55:18 +02:00
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return Tuple<Types<T1,T2,T3> > (a1,a2,a3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
, typename T4
|
|
|
|
|
>
|
2009-06-19 19:11:33 +02:00
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2,T3,T4> >
|
2009-06-17 06:55:18 +02:00
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
, T4 a4 =T4()
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return Tuple<Types<T1,T2,T3,T4> > (a1,a2,a3,a4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
, typename T4
|
|
|
|
|
, typename T5
|
|
|
|
|
>
|
2009-06-19 19:11:33 +02:00
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2,T3,T4,T5> >
|
2009-06-17 06:55:18 +02:00
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
, T4 a4 =T4()
|
|
|
|
|
, T5 a5 =T5()
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return Tuple<Types<T1,T2,T3,T4,T5> > (a1,a2,a3,a4,a5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-07-25 17:51:59 +02:00
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
, typename T4
|
|
|
|
|
, typename T5
|
|
|
|
|
, typename T6
|
|
|
|
|
>
|
|
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2,T3,T4,T5,T6> >
|
|
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
, T4 a4 =T4()
|
|
|
|
|
, T5 a5 =T5()
|
|
|
|
|
, T6 a6 =T6()
|
|
|
|
|
)
|
|
|
|
|
{
|
2009-07-25 19:21:50 +02:00
|
|
|
return Tuple<Types<T1,T2,T3,T4,T5,T6> > (a1,a2,a3,a4,a5,a6);
|
2009-07-25 17:51:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
, typename T4
|
|
|
|
|
, typename T5
|
|
|
|
|
, typename T6
|
|
|
|
|
, typename T7
|
|
|
|
|
>
|
|
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2,T3,T4,T5,T6,T7> >
|
|
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
, T4 a4 =T4()
|
|
|
|
|
, T5 a5 =T5()
|
|
|
|
|
, T6 a6 =T6()
|
|
|
|
|
, T7 a7 =T7()
|
|
|
|
|
)
|
|
|
|
|
{
|
2009-07-25 19:21:50 +02:00
|
|
|
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7> > (a1,a2,a3,a4,a5,a6,a7);
|
2009-07-25 17:51:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
, typename T4
|
|
|
|
|
, typename T5
|
|
|
|
|
, typename T6
|
|
|
|
|
, typename T7
|
|
|
|
|
, typename T8
|
|
|
|
|
>
|
|
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2,T3,T4,T5,T6,T7,T8> >
|
|
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
, T4 a4 =T4()
|
|
|
|
|
, T5 a5 =T5()
|
|
|
|
|
, T6 a6 =T6()
|
|
|
|
|
, T7 a7 =T7()
|
|
|
|
|
, T8 a8 =T8()
|
|
|
|
|
)
|
|
|
|
|
{
|
2009-07-25 19:21:50 +02:00
|
|
|
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8> > (a1,a2,a3,a4,a5,a6,a7,a8);
|
2009-07-25 17:51:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
template< typename T1
|
|
|
|
|
, typename T2
|
|
|
|
|
, typename T3
|
|
|
|
|
, typename T4
|
|
|
|
|
, typename T5
|
|
|
|
|
, typename T6
|
|
|
|
|
, typename T7
|
|
|
|
|
, typename T8
|
|
|
|
|
, typename T9
|
|
|
|
|
>
|
2009-06-19 19:11:33 +02:00
|
|
|
inline
|
|
|
|
|
Tuple< Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> >
|
2009-06-17 06:55:18 +02:00
|
|
|
make ( T1 a1 =T1()
|
|
|
|
|
, T2 a2 =T2()
|
|
|
|
|
, T3 a3 =T3()
|
|
|
|
|
, T4 a4 =T4()
|
|
|
|
|
, T5 a5 =T5()
|
|
|
|
|
, T6 a6 =T6()
|
|
|
|
|
, T7 a7 =T7()
|
|
|
|
|
, T8 a8 =T8()
|
|
|
|
|
, T9 a9 =T9()
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > (a1,a2,a3,a4,a5,a6,a7,a8,a9);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-28 20:41:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper to construct a new tuple, partially using provided argument values.
|
|
|
|
|
* Arguments are expected as a tuple, which is assumed to be a sub-tuple of
|
|
|
|
|
* the target type to be created. The start index of this sub-tuple may be
|
|
|
|
|
* provided as additional parameter, otherwise it is assumed to be zero,
|
|
|
|
|
* (i.e. the sub tuple starting left aligned). Any further arguments
|
|
|
|
|
* of the target type, which aren't covered by the argument tuple,
|
|
|
|
|
* are default initialised.
|
|
|
|
|
* @param TYPES type sequence or type list denoting the target tuple type
|
|
|
|
|
* @param ARGS type sequence of type list denoting the argument tuple type
|
|
|
|
|
* @param pos start index of the ARGS sequence within the TYPES sequence
|
|
|
|
|
*
|
|
|
|
|
* @note call the embedded #create function to invoke
|
|
|
|
|
* @note when types or positions disagree, argument tuple will be ignored
|
|
|
|
|
* @see TypeTuple_test#check_build_from_subTuple
|
|
|
|
|
*/
|
|
|
|
|
template<typename TYPES, typename ARGS, uint pos=0>
|
|
|
|
|
struct BuildTuple
|
|
|
|
|
{
|
|
|
|
|
typedef typename Tuple<TYPES>::TupleType ThisTuple;
|
|
|
|
|
typedef typename Tuple<TYPES>::ArgList TypeList;
|
|
|
|
|
typedef typename Tuple<ARGS>::ArgList ArgTypeList;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param the argument values, contained in a list or flat- tuple
|
|
|
|
|
* of the type denoted by ARGS
|
|
|
|
|
* @return a plain-flat Tuple<TYPES> instance, initialised with
|
|
|
|
|
* the values found within arg
|
|
|
|
|
*/
|
|
|
|
|
static ThisTuple
|
|
|
|
|
create (Tuple<ArgTypeList> const& arg)
|
|
|
|
|
{
|
|
|
|
|
return BuildTuple<TypeList,ArgTypeList,pos>
|
|
|
|
|
::create(arg)
|
|
|
|
|
.tupleCast();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename TYPES, typename ARGS, uint pos>
|
|
|
|
|
struct BuildTuple<Tuple<TYPES>, Tuple<ARGS>, pos> ///< tuples allowed instead of plain type sequences/lists
|
|
|
|
|
: BuildTuple<TYPES,ARGS,pos>
|
|
|
|
|
{ };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T
|
|
|
|
|
, typename TS
|
|
|
|
|
, typename A
|
|
|
|
|
, typename AS
|
|
|
|
|
, uint pos
|
|
|
|
|
>
|
|
|
|
|
struct BuildTuple<Node<T,TS>, Node<A,AS>, pos> ///< case: recursion \em before start of arg tuple
|
|
|
|
|
{
|
|
|
|
|
typedef Tuple<Node<T,TS> > ThisTuple;
|
|
|
|
|
typedef Tuple<Node<A,AS> > ThisArg;
|
|
|
|
|
|
|
|
|
|
static ThisTuple
|
|
|
|
|
create (ThisArg const& arg)
|
|
|
|
|
{
|
|
|
|
|
return ThisTuple( T()
|
|
|
|
|
, BuildTuple<TS, Node<A,AS>, pos-1>::create(arg)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename A
|
|
|
|
|
, typename TS
|
|
|
|
|
, typename AS
|
|
|
|
|
>
|
|
|
|
|
struct BuildTuple<Node<A,TS>, Node<A,AS>, 0> ///< case: start of argument tuple detected
|
|
|
|
|
{
|
|
|
|
|
typedef Tuple<Node<A,TS> > ThisTuple;
|
|
|
|
|
typedef Tuple<Node<A,AS> > ThisArg;
|
|
|
|
|
|
|
|
|
|
static ThisTuple
|
|
|
|
|
create (ThisArg const& arg)
|
|
|
|
|
{
|
|
|
|
|
return ThisTuple( arg.getHead_const()
|
|
|
|
|
, BuildTuple<TS, AS, 0>::create (arg.getTail_const())
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename ARGS
|
|
|
|
|
, uint i
|
|
|
|
|
>
|
|
|
|
|
struct BuildTuple<NullType, ARGS, i> ///< case: hit end of target typelist
|
|
|
|
|
{
|
|
|
|
|
typedef Tuple<NullType> ThisTuple;
|
|
|
|
|
typedef Tuple<ARGS> ThisArg;
|
|
|
|
|
|
|
|
|
|
static ThisTuple
|
|
|
|
|
create (ThisArg const&)
|
|
|
|
|
{
|
|
|
|
|
return ThisTuple();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename T
|
|
|
|
|
, typename TS
|
|
|
|
|
, uint i
|
|
|
|
|
>
|
|
|
|
|
struct BuildTuple<Node<T,TS>, NullType, i> ///< case: hit end of argument tuple
|
|
|
|
|
{
|
|
|
|
|
typedef Tuple<Node<T,TS> > ThisTuple;
|
|
|
|
|
typedef Tuple<NullType> ThisArg;
|
|
|
|
|
|
|
|
|
|
static ThisTuple
|
|
|
|
|
create (ThisArg const&)
|
|
|
|
|
{
|
|
|
|
|
return ThisTuple();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-06-22 06:05:32 +02:00
|
|
|
} // (END) access / tuple building helper functions (namespace tuple)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-06-20 23:18:02 +02:00
|
|
|
/** Trait template for detecting a type tuple */
|
|
|
|
|
template<typename TUP>
|
|
|
|
|
class is_Tuple
|
|
|
|
|
{
|
|
|
|
|
template<class X> struct Check { typedef No_t It; };
|
|
|
|
|
template<class TY> struct Check<Tuple<TY> > { typedef Yes_t It; };
|
|
|
|
|
|
2009-06-22 06:05:32 +02:00
|
|
|
public:
|
2009-06-20 23:18:02 +02:00
|
|
|
static const bool value = (sizeof(Yes_t)==sizeof(typename Check<TUP>::It));
|
|
|
|
|
};
|
2009-06-21 02:03:22 +02:00
|
|
|
|
|
|
|
|
/** Trait template detecting especially tuples
|
|
|
|
|
* built directly on top of a Typelist */
|
|
|
|
|
template<typename TUP>
|
|
|
|
|
class is_TupleListType
|
|
|
|
|
{
|
2009-06-22 06:05:32 +02:00
|
|
|
template<class X>
|
2009-06-21 02:03:22 +02:00
|
|
|
struct Check
|
|
|
|
|
{
|
|
|
|
|
enum{ result = sizeof(No_t)};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class N>
|
|
|
|
|
struct Check<Tuple<N> >
|
|
|
|
|
{
|
|
|
|
|
template<class H, class T>
|
|
|
|
|
Yes_t static check(Node<H,T>*);
|
|
|
|
|
Yes_t static check(NullType*);
|
|
|
|
|
No_t static check(...);
|
|
|
|
|
|
|
|
|
|
enum{ result = sizeof(check( (N*)0)) };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static const bool value = (sizeof(Yes_t)== Check<TUP>::result);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Trait template to discern plain tuples and list-type tuples */
|
|
|
|
|
template<typename TUP>
|
|
|
|
|
struct is_TuplePlain
|
|
|
|
|
{
|
|
|
|
|
static const bool value = is_Tuple<TUP>::value
|
|
|
|
|
&& !is_TupleListType<TUP>::value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Trait template detecting an empty tuple type */
|
|
|
|
|
template<typename TUP>
|
|
|
|
|
class is_NullTuple
|
|
|
|
|
{
|
2009-06-22 06:05:32 +02:00
|
|
|
template<class X>
|
2009-06-21 02:03:22 +02:00
|
|
|
struct Check
|
|
|
|
|
{
|
|
|
|
|
enum{ result = sizeof(No_t)};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class TY>
|
|
|
|
|
struct Check<Tuple<TY> >
|
|
|
|
|
{
|
2009-06-22 06:05:32 +02:00
|
|
|
Yes_t static check(Types<>*);
|
|
|
|
|
Yes_t static check(NullType*);
|
|
|
|
|
No_t static check(...);
|
2009-06-21 02:03:22 +02:00
|
|
|
|
|
|
|
|
enum{ result = sizeof(check( (TY*)0)) };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static const bool value = (sizeof(Yes_t)== Check<TUP>::result);
|
|
|
|
|
};
|
2009-06-22 06:05:32 +02:00
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
/**
|
|
|
|
|
* Decorating a tuple type with auxiliary data access operations.
|
|
|
|
|
* This helper template builds up a subclass of the given BASE type
|
|
|
|
|
* (which is assumed to be a Tuple or at least need to be copy constructible
|
|
|
|
|
* from \c Tuple<TYPES> ). The purpose is to use the Tuple as storage, but
|
|
|
|
|
* to add a layer of access functions, which in turn might rely on the exact
|
|
|
|
|
* type of the individual elements within the Tuple. To achieve this, for each
|
|
|
|
|
* type within the Tuple, the BASE type is decorated with an instance of the
|
|
|
|
|
* template passed in as template template parameter _X_. Each of these
|
2009-06-22 06:05:32 +02:00
|
|
|
* decorating instances is provided with a index allowing to access "his"
|
2009-06-16 12:07:49 +02:00
|
|
|
* specific element within the underlying tuple.
|
|
|
|
|
*
|
|
|
|
|
* The decorating template _X_ need to take its own base class as template
|
|
|
|
|
* parameter. Typically, operations on _X_ will be defined in a recursive fashion,
|
|
|
|
|
* calling down into this templated base class. To support this, an instantiation
|
2009-06-22 06:05:32 +02:00
|
|
|
* of _X_ with the empty type sequence is generated for detecting recursion end
|
2009-06-16 12:07:49 +02:00
|
|
|
* (built as innermost decorator, i.e. immediate subclass of BASE)
|
|
|
|
|
*/
|
|
|
|
|
template
|
2009-06-17 06:55:18 +02:00
|
|
|
< typename TYPES ///< Type sequence to use within the Accessor (usually the Tuple Types)
|
|
|
|
|
, template<class,class,class, uint> class _X_ ///< user provided template<Type, Base, TupleType, arg-No>
|
|
|
|
|
, class TUP =Tuple<TYPES> ///< the tuple type to build on
|
|
|
|
|
, uint i = 0 ///< tuple element index counter
|
2009-06-16 12:07:49 +02:00
|
|
|
>
|
|
|
|
|
class BuildTupleAccessor
|
|
|
|
|
{
|
|
|
|
|
typedef Tuple<TYPES> ArgTuple;
|
|
|
|
|
typedef typename ArgTuple::HeadType Head;
|
|
|
|
|
typedef typename ArgTuple::TailType Tail;
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef BuildTupleAccessor<Tail,_X_,TUP, i+1> NextBuilder;
|
2009-06-16 12:07:49 +02:00
|
|
|
typedef typename NextBuilder::Accessor NextAccessor;
|
|
|
|
|
|
2009-06-19 19:11:33 +02:00
|
|
|
ArgTuple const& argData_;
|
2009-06-16 12:07:49 +02:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
/** type of the product created by this template.
|
2009-06-17 06:55:18 +02:00
|
|
|
* Will be a subclass of TUP */
|
|
|
|
|
typedef _X_< Head // the type to use for this accessor
|
|
|
|
|
, NextAccessor // the base type to inherit from
|
|
|
|
|
, TUP // the tuple type we build upon
|
|
|
|
|
, i // current element index
|
|
|
|
|
> Accessor;
|
|
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
|
2009-06-19 19:11:33 +02:00
|
|
|
BuildTupleAccessor (ArgTuple const& tup)
|
2009-06-16 12:07:49 +02:00
|
|
|
: argData_(tup)
|
|
|
|
|
{ }
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
/** used to get the product of this builder template... */
|
2009-06-16 12:07:49 +02:00
|
|
|
operator Accessor() { return Accessor(argData_); }
|
|
|
|
|
|
|
|
|
|
};
|
2009-06-17 06:55:18 +02:00
|
|
|
|
|
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
template
|
2009-06-17 06:55:18 +02:00
|
|
|
< template<class,class,class, uint> class _X_
|
|
|
|
|
, class TUP
|
2009-06-16 12:07:49 +02:00
|
|
|
, uint i
|
|
|
|
|
>
|
2009-06-17 06:55:18 +02:00
|
|
|
class BuildTupleAccessor<Types<>, _X_, TUP, i>
|
2009-06-16 12:07:49 +02:00
|
|
|
{
|
|
|
|
|
typedef Tuple<Types<> > ArgTuple;
|
2009-06-19 19:11:33 +02:00
|
|
|
ArgTuple const& argData_;
|
2009-06-16 12:07:49 +02:00
|
|
|
|
|
|
|
|
public:
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef _X_<NullType, TUP, TUP, 0> Accessor;
|
2009-06-19 19:11:33 +02:00
|
|
|
|
|
|
|
|
BuildTupleAccessor (ArgTuple const& tup)
|
|
|
|
|
: argData_(tup)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
/** used to get the product of this builder template... */
|
|
|
|
|
operator Accessor() { return Accessor(argData_); }
|
|
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-06-22 06:05:32 +02:00
|
|
|
|
2009-06-16 12:07:49 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
}} // namespace lumiera::typelist
|
|
|
|
|
#endif
|