📄 tuples.hpp
字号:
/*=============================================================================
Phoenix V1.2.1
Copyright (c) 2001-2002 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef PHOENIX_TUPLES_HPP
#define PHOENIX_TUPLES_HPP
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
#error "Sorry, Phoenix does not support VC6 and VC7. Please upgrade to at least VC7.1"
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Phoenix predefined maximum limit. This limit defines the maximum
// number of elements a tuple can hold. This number defaults to 3. The
// actual maximum is rounded up in multiples of 3. Thus, if this value
// is 4, the actual limit is 6. The ultimate maximum limit in this
// implementation is 15.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef PHOENIX_LIMIT
#define PHOENIX_LIMIT 3
#endif
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x561)
namespace phoenix { namespace borland_only
{
namespace ftors
{
// We define these dummy template functions. Borland complains when
// a template class has the same name as a template function,
// regardless if they are in different namespaces.
template <typename T> void if_(T) {}
template <typename T> void for_(T) {}
template <typename T> void while_(T) {}
template <typename T> void do_(T) {}
}
namespace tmpls
{
// We define these dummy template functions. Borland complains when
// a template class has the same name as a template function,
// regardless if they are in different namespaces.
template <typename T> struct if_ {};
template <typename T> struct for_ {};
template <typename T> struct while_ {};
template <typename T> struct do_ {};
}
}} // namespace phoenix::borland_only
#endif
///////////////////////////////////////////////////////////////////////////////
#include <boost/static_assert.hpp>
#include <boost/call_traits.hpp>
#include <boost/type_traits/remove_reference.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace phoenix {
///////////////////////////////////////////////////////////////////////////////
//
// tuple
//
// Tuples hold heterogeneous types up to a predefined maximum. Only
// the most basic functionality needed is provided. Unlike other
// recursive list-like tuple implementations, this tuple
// implementation uses simple structs similar to std::pair with
// specialization for 0 to N tuple elements.
//
// 1) Construction
// Here are examples on how to construct tuples:
//
// typedef tuple<int, char> t1_t;
// typedef tuple<int, std::string, double> t2_t;
//
// // this tuple has an int and char members
// t1_t t1(3, 'c');
//
// // this tuple has an int, std::string and double members
// t2_t t2(3, "hello", 3.14);
//
// Tuples can also be constructed from other tuples. The
// source and destination tuples need not have exactly the
// same element types. The only requirement is that the
// source tuple have the same number of elements as the
// destination and that each element slot in the
// destination can be copy constructed from the source
// element. For example:
//
// tuple<double, double> t3(t1); // OK. Compatible tuples
// tuple<double, double> t4(t2); // Error! Incompatible tuples
//
// 2) Member access
// A member in a tuple can be accessed using the
// tuple's [] operator by specifying the Nth
// tuple_index. Here are some examples:
//
// tuple_index<0> ix0; // 0th index == 1st item
// tuple_index<1> ix1; // 1st index == 2nd item
// tuple_index<2> ix2; // 2nd index == 3rd item
//
// t1[ix0] = 33; // sets the int member of the tuple t1
// t2[ix2] = 6e6; // sets the double member of the tuple t2
// t1[ix1] = 'a'; // sets the char member of the tuple t1
//
// There are some predefined names are provided in sub-
// namespace tuple_index_names:
//
// tuple_index<0> _1;
// tuple_index<1> _2;
// ...
// tuple_index<N> _N;
//
// These indexes may be used by 'using' namespace
// phoenix::tuple_index_names.
//
// Access to out of bound indexes returns a nil_t value.
//
// 3) Member type inquiry
// The type of an individual member can be queried.
// Example:
//
// tuple_element<1, t2_t>::type
//
// Refers to the type of the second member (note zero based,
// thus 0 = 1st item, 1 = 2nd item) of the tuple.
//
// Aside from tuple_element<N, T>::type, there are two
// more types that tuple_element provides: rtype and
// crtype. While 'type' is the plain underlying type,
// 'rtype' is the reference type, or type& and 'crtype'
// is the constant reference type or type const&. The
// latter two are provided to make it easy for the
// client in dealing with the possibility of reference
// to reference when type is already a reference, which
// is illegal in C++.
//
// Access to out of bound indexes returns a nil_t type.
//
// 4) Tuple length
// The number of elements in a tuple can be queried.
// Example:
//
// int n = t1.length;
//
// gets the number of elements in tuple t1.
//
// length is a static constant. Thus, TupleT::length
// also works. Example:
//
// int n = t1_t::length;
//
///////////////////////////////////////////////////////////////////////////////
struct nil_t {};
using boost::remove_reference;
using boost::call_traits;
//////////////////////////////////
namespace impl {
template <typename T>
struct access {
typedef const T& ctype;
typedef T& type;
};
template <typename T>
struct access<T&> {
typedef T& ctype;
typedef T& type;
};
}
///////////////////////////////////////////////////////////////////////////////
//
// tuple_element
//
// A query class that gets the Nth element inside a tuple.
// Examples:
//
// tuple_element<1, tuple<int, char, void*> >::type // plain
// tuple_element<1, tuple<int, char, void*> >::rtype // ref
// tuple_element<1, tuple<int, char, void*> >::crtype // const ref
//
// Has type char which is the 2nd type in the tuple
// (note zero based, thus 0 = 1st item, 1 = 2nd item).
//
// Given a tuple object, the static function tuple_element<N,
// TupleT>::get(tuple) gets the Nth element in the tuple. The
// tuple class' tuple::operator[] uses this to get its Nth
// element.
//
///////////////////////////////////////////////////////////////////////////////
template <int N, typename TupleT>
struct tuple_element
{
typedef nil_t type;
typedef nil_t& rtype;
typedef nil_t const& crtype;
static nil_t get(TupleT const& t) { return nil_t(); }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<0, TupleT>
{
typedef typename TupleT::a_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.a; }
static crtype get(TupleT const& t) { return t.a; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<1, TupleT>
{
typedef typename TupleT::b_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.b; }
static crtype get(TupleT const& t) { return t.b; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<2, TupleT>
{
typedef typename TupleT::c_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.c; }
static crtype get(TupleT const& t) { return t.c; }
};
#if PHOENIX_LIMIT > 3
//////////////////////////////////
template <typename TupleT>
struct tuple_element<3, TupleT>
{
typedef typename TupleT::d_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.d; }
static crtype get(TupleT const& t) { return t.d; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<4, TupleT>
{
typedef typename TupleT::e_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.e; }
static crtype get(TupleT const& t) { return t.e; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<5, TupleT>
{
typedef typename TupleT::f_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.f; }
static crtype get(TupleT const& t) { return t.f; }
};
#if PHOENIX_LIMIT > 6
//////////////////////////////////
template <typename TupleT>
struct tuple_element<6, TupleT>
{
typedef typename TupleT::g_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.g; }
static crtype get(TupleT const& t) { return t.g; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<7, TupleT>
{
typedef typename TupleT::h_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.h; }
static crtype get(TupleT const& t) { return t.h; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<8, TupleT>
{
typedef typename TupleT::i_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.i; }
static crtype get(TupleT const& t) { return t.i; }
};
#if PHOENIX_LIMIT > 9
//////////////////////////////////
template <typename TupleT>
struct tuple_element<9, TupleT>
{
typedef typename TupleT::j_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.j; }
static crtype get(TupleT const& t) { return t.j; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<10, TupleT>
{
typedef typename TupleT::k_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.k; }
static crtype get(TupleT const& t) { return t.k; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<11, TupleT>
{
typedef typename TupleT::l_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.l; }
static crtype get(TupleT const& t) { return t.l; }
};
#if PHOENIX_LIMIT > 12
//////////////////////////////////
template <typename TupleT>
struct tuple_element<12, TupleT>
{
typedef typename TupleT::m_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.m; }
static crtype get(TupleT const& t) { return t.m; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<13, TupleT>
{
typedef typename TupleT::n_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.n; }
static crtype get(TupleT const& t) { return t.n; }
};
//////////////////////////////////
template <typename TupleT>
struct tuple_element<14, TupleT>
{
typedef typename TupleT::o_type type;
typedef typename impl::access<type>::type rtype;
typedef typename impl::access<type>::ctype crtype;
static rtype get(TupleT& t) { return t.o; }
static crtype get(TupleT const& t) { return t.o; }
};
#endif
#endif
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
//
// tuple forward declaration.
//
///////////////////////////////////////////////////////////////////////////////
template <
typename A = nil_t
, typename B = nil_t
, typename C = nil_t
#if PHOENIX_LIMIT > 3
, typename D = nil_t
, typename E = nil_t
, typename F = nil_t
#if PHOENIX_LIMIT > 6
, typename G = nil_t
, typename H = nil_t
, typename I = nil_t
#if PHOENIX_LIMIT > 9
, typename J = nil_t
, typename K = nil_t
, typename L = nil_t
#if PHOENIX_LIMIT > 12
, typename M = nil_t
, typename N = nil_t
, typename O = nil_t
#endif
#endif
#endif
#endif
, typename NU = nil_t // Not used
>
struct tuple;
///////////////////////////////////////////////////////////////////////////////
//
// tuple_index
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -