epoc32/include/stdapis/boost/compressed_pair.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
parent 2 epoc32/include/stdapis/boost/detail/compressed_pair.hpp@2fe1408b6811
child 4 837f303aceeb
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     1 //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
     2 //  Use, modification and distribution are subject to the Boost Software License,
     3 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     4 //  http://www.boost.org/LICENSE_1_0.txt).
     5 //
     6 //  See http://www.boost.org/libs/utility for most recent version including documentation.
     7 
     8 // compressed_pair: pair that "compresses" empty members
     9 // (see libs/utility/compressed_pair.htm)
    10 //
    11 // JM changes 25 Jan 2004:
    12 // For the case where T1 == T2 and both are empty, then first() and second()
    13 // should return different objects.
    14 // JM changes 25 Jan 2000:
    15 // Removed default arguments from compressed_pair_switch to get
    16 // C++ Builder 4 to accept them
    17 // rewriten swap to get gcc and C++ builder to compile.
    18 // added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
    19 
    20 #ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
    21 #define BOOST_DETAIL_COMPRESSED_PAIR_HPP
    22 
    23 #include <algorithm>
    24 
    25 #include <boost/type_traits/remove_cv.hpp>
    26 #include <boost/type_traits/is_empty.hpp>
    27 #include <boost/type_traits/is_same.hpp>
    28 #include <boost/call_traits.hpp>
    29 
    30 #ifdef BOOST_MSVC
    31 # pragma warning(push)
    32 # pragma warning(disable:4512)
    33 #endif 
    34 namespace boost
    35 {
    36 
    37 template <class T1, class T2>
    38 class compressed_pair;
    39 
    40 
    41 // compressed_pair
    42 
    43 namespace details
    44 {
    45    // JM altered 26 Jan 2000:
    46    template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
    47    struct compressed_pair_switch;
    48 
    49    template <class T1, class T2>
    50    struct compressed_pair_switch<T1, T2, false, false, false>
    51       {static const int value = 0;};
    52 
    53    template <class T1, class T2>
    54    struct compressed_pair_switch<T1, T2, false, true, true>
    55       {static const int value = 3;};
    56 
    57    template <class T1, class T2>
    58    struct compressed_pair_switch<T1, T2, false, true, false>
    59       {static const int value = 1;};
    60 
    61    template <class T1, class T2>
    62    struct compressed_pair_switch<T1, T2, false, false, true>
    63       {static const int value = 2;};
    64 
    65    template <class T1, class T2>
    66    struct compressed_pair_switch<T1, T2, true, true, true>
    67       {static const int value = 4;};
    68 
    69    template <class T1, class T2>
    70    struct compressed_pair_switch<T1, T2, true, false, false>
    71       {static const int value = 5;};
    72 
    73    template <class T1, class T2, int Version> class compressed_pair_imp;
    74 
    75 #ifdef __GNUC__
    76    // workaround for GCC (JM):
    77    using std::swap;
    78 #endif
    79    //
    80    // can't call unqualified swap from within classname::swap
    81    // as Koenig lookup rules will find only the classname::swap
    82    // member function not the global declaration, so use cp_swap
    83    // as a forwarding function (JM):
    84    template <typename T>
    85    inline void cp_swap(T& t1, T& t2)
    86    {
    87 #ifndef __GNUC__
    88       using std::swap;
    89 #endif
    90       swap(t1, t2);
    91    }
    92 
    93    // 0    derive from neither
    94 
    95    template <class T1, class T2>
    96    class compressed_pair_imp<T1, T2, 0>
    97    {
    98    public:
    99       typedef T1                                                 first_type;
   100       typedef T2                                                 second_type;
   101       typedef typename call_traits<first_type>::param_type       first_param_type;
   102       typedef typename call_traits<second_type>::param_type      second_param_type;
   103       typedef typename call_traits<first_type>::reference        first_reference;
   104       typedef typename call_traits<second_type>::reference       second_reference;
   105       typedef typename call_traits<first_type>::const_reference  first_const_reference;
   106       typedef typename call_traits<second_type>::const_reference second_const_reference;
   107 
   108       compressed_pair_imp() {} 
   109 
   110       compressed_pair_imp(first_param_type x, second_param_type y)
   111          : first_(x), second_(y) {}
   112 
   113       compressed_pair_imp(first_param_type x)
   114          : first_(x) {}
   115 
   116       compressed_pair_imp(second_param_type y)
   117          : second_(y) {}
   118 
   119       first_reference       first()       {return first_;}
   120       first_const_reference first() const {return first_;}
   121 
   122       second_reference       second()       {return second_;}
   123       second_const_reference second() const {return second_;}
   124 
   125       void swap(::boost::compressed_pair<T1, T2>& y)
   126       {
   127          cp_swap(first_, y.first());
   128          cp_swap(second_, y.second());
   129       }
   130    private:
   131       first_type first_;
   132       second_type second_;
   133    };
   134 
   135    // 1    derive from T1
   136 
   137    template <class T1, class T2>
   138    class compressed_pair_imp<T1, T2, 1>
   139       : protected ::boost::remove_cv<T1>::type
   140    {
   141    public:
   142       typedef T1                                                 first_type;
   143       typedef T2                                                 second_type;
   144       typedef typename call_traits<first_type>::param_type       first_param_type;
   145       typedef typename call_traits<second_type>::param_type      second_param_type;
   146       typedef typename call_traits<first_type>::reference        first_reference;
   147       typedef typename call_traits<second_type>::reference       second_reference;
   148       typedef typename call_traits<first_type>::const_reference  first_const_reference;
   149       typedef typename call_traits<second_type>::const_reference second_const_reference;
   150 
   151       compressed_pair_imp() {}
   152 
   153       compressed_pair_imp(first_param_type x, second_param_type y)
   154          : first_type(x), second_(y) {}
   155 
   156       compressed_pair_imp(first_param_type x)
   157          : first_type(x) {}
   158 
   159       compressed_pair_imp(second_param_type y)
   160          : second_(y) {}
   161 
   162       first_reference       first()       {return *this;}
   163       first_const_reference first() const {return *this;}
   164 
   165       second_reference       second()       {return second_;}
   166       second_const_reference second() const {return second_;}
   167 
   168       void swap(::boost::compressed_pair<T1,T2>& y)
   169       {
   170          // no need to swap empty base class:
   171          cp_swap(second_, y.second());
   172       }
   173    private:
   174       second_type second_;
   175    };
   176 
   177    // 2    derive from T2
   178 
   179    template <class T1, class T2>
   180    class compressed_pair_imp<T1, T2, 2>
   181       : protected ::boost::remove_cv<T2>::type
   182    {
   183    public:
   184       typedef T1                                                 first_type;
   185       typedef T2                                                 second_type;
   186       typedef typename call_traits<first_type>::param_type       first_param_type;
   187       typedef typename call_traits<second_type>::param_type      second_param_type;
   188       typedef typename call_traits<first_type>::reference        first_reference;
   189       typedef typename call_traits<second_type>::reference       second_reference;
   190       typedef typename call_traits<first_type>::const_reference  first_const_reference;
   191       typedef typename call_traits<second_type>::const_reference second_const_reference;
   192 
   193       compressed_pair_imp() {}
   194 
   195       compressed_pair_imp(first_param_type x, second_param_type y)
   196          : second_type(y), first_(x) {}
   197 
   198       compressed_pair_imp(first_param_type x)
   199          : first_(x) {}
   200 
   201       compressed_pair_imp(second_param_type y)
   202          : second_type(y) {}
   203 
   204       first_reference       first()       {return first_;}
   205       first_const_reference first() const {return first_;}
   206 
   207       second_reference       second()       {return *this;}
   208       second_const_reference second() const {return *this;}
   209 
   210       void swap(::boost::compressed_pair<T1,T2>& y)
   211       {
   212          // no need to swap empty base class:
   213          cp_swap(first_, y.first());
   214       }
   215 
   216    private:
   217       first_type first_;
   218    };
   219 
   220    // 3    derive from T1 and T2
   221 
   222    template <class T1, class T2>
   223    class compressed_pair_imp<T1, T2, 3>
   224       : protected ::boost::remove_cv<T1>::type,
   225         protected ::boost::remove_cv<T2>::type
   226    {
   227    public:
   228       typedef T1                                                 first_type;
   229       typedef T2                                                 second_type;
   230       typedef typename call_traits<first_type>::param_type       first_param_type;
   231       typedef typename call_traits<second_type>::param_type      second_param_type;
   232       typedef typename call_traits<first_type>::reference        first_reference;
   233       typedef typename call_traits<second_type>::reference       second_reference;
   234       typedef typename call_traits<first_type>::const_reference  first_const_reference;
   235       typedef typename call_traits<second_type>::const_reference second_const_reference;
   236 
   237       compressed_pair_imp() {}
   238 
   239       compressed_pair_imp(first_param_type x, second_param_type y)
   240          : first_type(x), second_type(y) {}
   241 
   242       compressed_pair_imp(first_param_type x)
   243          : first_type(x) {}
   244 
   245       compressed_pair_imp(second_param_type y)
   246          : second_type(y) {}
   247 
   248       first_reference       first()       {return *this;}
   249       first_const_reference first() const {return *this;}
   250 
   251       second_reference       second()       {return *this;}
   252       second_const_reference second() const {return *this;}
   253       //
   254       // no need to swap empty bases:
   255       void swap(::boost::compressed_pair<T1,T2>&) {}
   256    };
   257 
   258    // JM
   259    // 4    T1 == T2, T1 and T2 both empty
   260    //      Originally this did not store an instance of T2 at all
   261    //      but that led to problems beause it meant &x.first() == &x.second()
   262    //      which is not true for any other kind of pair, so now we store an instance
   263    //      of T2 just in case the user is relying on first() and second() returning
   264    //      different objects (albeit both empty).
   265    template <class T1, class T2>
   266    class compressed_pair_imp<T1, T2, 4>
   267       : protected ::boost::remove_cv<T1>::type
   268    {
   269    public:
   270       typedef T1                                                 first_type;
   271       typedef T2                                                 second_type;
   272       typedef typename call_traits<first_type>::param_type       first_param_type;
   273       typedef typename call_traits<second_type>::param_type      second_param_type;
   274       typedef typename call_traits<first_type>::reference        first_reference;
   275       typedef typename call_traits<second_type>::reference       second_reference;
   276       typedef typename call_traits<first_type>::const_reference  first_const_reference;
   277       typedef typename call_traits<second_type>::const_reference second_const_reference;
   278 
   279       compressed_pair_imp() {}
   280 
   281       compressed_pair_imp(first_param_type x, second_param_type y)
   282          : first_type(x), m_second(y) {}
   283 
   284       compressed_pair_imp(first_param_type x)
   285          : first_type(x), m_second(x) {}
   286 
   287       first_reference       first()       {return *this;}
   288       first_const_reference first() const {return *this;}
   289 
   290       second_reference       second()       {return m_second;}
   291       second_const_reference second() const {return m_second;}
   292 
   293       void swap(::boost::compressed_pair<T1,T2>&) {}
   294    private:
   295       T2 m_second;
   296    };
   297 
   298    // 5    T1 == T2 and are not empty:   //JM
   299 
   300    template <class T1, class T2>
   301    class compressed_pair_imp<T1, T2, 5>
   302    {
   303    public:
   304       typedef T1                                                 first_type;
   305       typedef T2                                                 second_type;
   306       typedef typename call_traits<first_type>::param_type       first_param_type;
   307       typedef typename call_traits<second_type>::param_type      second_param_type;
   308       typedef typename call_traits<first_type>::reference        first_reference;
   309       typedef typename call_traits<second_type>::reference       second_reference;
   310       typedef typename call_traits<first_type>::const_reference  first_const_reference;
   311       typedef typename call_traits<second_type>::const_reference second_const_reference;
   312 
   313       compressed_pair_imp() {}
   314 
   315       compressed_pair_imp(first_param_type x, second_param_type y)
   316          : first_(x), second_(y) {}
   317 
   318       compressed_pair_imp(first_param_type x)
   319          : first_(x), second_(x) {}
   320 
   321       first_reference       first()       {return first_;}
   322       first_const_reference first() const {return first_;}
   323 
   324       second_reference       second()       {return second_;}
   325       second_const_reference second() const {return second_;}
   326 
   327       void swap(::boost::compressed_pair<T1, T2>& y)
   328       {
   329          cp_swap(first_, y.first());
   330          cp_swap(second_, y.second());
   331       }
   332    private:
   333       first_type first_;
   334       second_type second_;
   335    };
   336 
   337 }  // details
   338 
   339 template <class T1, class T2>
   340 class compressed_pair
   341    : private ::boost::details::compressed_pair_imp<T1, T2,
   342              ::boost::details::compressed_pair_switch<
   343                     T1,
   344                     T2,
   345                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
   346                     ::boost::is_empty<T1>::value,
   347                     ::boost::is_empty<T2>::value>::value>
   348 {
   349 private:
   350    typedef details::compressed_pair_imp<T1, T2,
   351              ::boost::details::compressed_pair_switch<
   352                     T1,
   353                     T2,
   354                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
   355                     ::boost::is_empty<T1>::value,
   356                     ::boost::is_empty<T2>::value>::value> base;
   357 public:
   358    typedef T1                                                 first_type;
   359    typedef T2                                                 second_type;
   360    typedef typename call_traits<first_type>::param_type       first_param_type;
   361    typedef typename call_traits<second_type>::param_type      second_param_type;
   362    typedef typename call_traits<first_type>::reference        first_reference;
   363    typedef typename call_traits<second_type>::reference       second_reference;
   364    typedef typename call_traits<first_type>::const_reference  first_const_reference;
   365    typedef typename call_traits<second_type>::const_reference second_const_reference;
   366 
   367             compressed_pair() : base() {}
   368             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
   369    explicit compressed_pair(first_param_type x) : base(x) {}
   370    explicit compressed_pair(second_param_type y) : base(y) {}
   371 
   372    first_reference       first()       {return base::first();}
   373    first_const_reference first() const {return base::first();}
   374 
   375    second_reference       second()       {return base::second();}
   376    second_const_reference second() const {return base::second();}
   377 
   378    void swap(compressed_pair& y) { base::swap(y); }
   379 };
   380 
   381 // JM
   382 // Partial specialisation for case where T1 == T2:
   383 //
   384 template <class T>
   385 class compressed_pair<T, T>
   386    : private details::compressed_pair_imp<T, T,
   387              ::boost::details::compressed_pair_switch<
   388                     T,
   389                     T,
   390                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
   391                     ::boost::is_empty<T>::value,
   392                     ::boost::is_empty<T>::value>::value>
   393 {
   394 private:
   395    typedef details::compressed_pair_imp<T, T,
   396              ::boost::details::compressed_pair_switch<
   397                     T,
   398                     T,
   399                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
   400                     ::boost::is_empty<T>::value,
   401                     ::boost::is_empty<T>::value>::value> base;
   402 public:
   403    typedef T                                                  first_type;
   404    typedef T                                                  second_type;
   405    typedef typename call_traits<first_type>::param_type       first_param_type;
   406    typedef typename call_traits<second_type>::param_type      second_param_type;
   407    typedef typename call_traits<first_type>::reference        first_reference;
   408    typedef typename call_traits<second_type>::reference       second_reference;
   409    typedef typename call_traits<first_type>::const_reference  first_const_reference;
   410    typedef typename call_traits<second_type>::const_reference second_const_reference;
   411 
   412             compressed_pair() : base() {}
   413             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
   414 #if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
   415    explicit 
   416 #endif
   417       compressed_pair(first_param_type x) : base(x) {}
   418 
   419    first_reference       first()       {return base::first();}
   420    first_const_reference first() const {return base::first();}
   421 
   422    second_reference       second()       {return base::second();}
   423    second_const_reference second() const {return base::second();}
   424 
   425    void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
   426 };
   427 
   428 template <class T1, class T2>
   429 inline
   430 void
   431 swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
   432 {
   433    x.swap(y);
   434 }
   435 
   436 } // boost
   437 
   438 #ifdef BOOST_MSVC
   439 # pragma warning(pop)
   440 #endif 
   441 
   442 #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
   443