imgtools/imglib/boostlibrary/boost/detail/compressed_pair.hpp
changeset 0 044383f39525
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     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