tuples.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,330 行 · 第 1/3 页

HPP
1,330
字号
/*=============================================================================    Phoenix V1.2.1    Copyright (c) 2001-2002 Joel de Guzman  Distributed under 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////      This class wraps an integer in a type to be used for indexing

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?