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