⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tuples.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 3 页
字号:
/*=============================================================================
    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 + -