compressed_pair.hpp
Go to the documentation of this file.
00001 //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
00002 //  Use, modification and distribution are subject to the Boost Software License,
00003 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00004 //  http://www.boost.org/LICENSE_1_0.txt).
00005 //
00006 //  See http://www.boost.org/libs/utility for most recent version including documentation.
00007 
00008 // compressed_pair: pair that "compresses" empty members
00009 // (see libs/utility/compressed_pair.htm)
00010 //
00011 // JM changes 25 Jan 2004:
00012 // For the case where T1 == T2 and both are empty, then first() and second()
00013 // should return different objects.
00014 // JM changes 25 Jan 2000:
00015 // Removed default arguments from compressed_pair_switch to get
00016 // C++ Builder 4 to accept them
00017 // rewriten swap to get gcc and C++ builder to compile.
00018 // added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
00019 
00020 #ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
00021 #define BOOST_DETAIL_COMPRESSED_PAIR_HPP
00022 
00023 #include <algorithm>
00024 
00025 #include <boost/type_traits/remove_cv.hpp>
00026 #include <boost/type_traits/is_empty.hpp>
00027 #include <boost/type_traits/is_same.hpp>
00028 #include <boost/call_traits.hpp>
00029 
00030 #ifdef BOOST_MSVC
00031 # pragma warning(push)
00032 # pragma warning(disable:4512)
00033 #endif 
00034 namespace boost
00035 {
00036 
00037 template <class T1, class T2>
00038 class compressed_pair;
00039 
00040 
00041 // compressed_pair
00042 
00043 namespace details
00044 {
00045    // JM altered 26 Jan 2000:
00046    template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
00047    struct compressed_pair_switch;
00048 
00049    template <class T1, class T2>
00050    struct compressed_pair_switch<T1, T2, false, false, false>
00051       {static const int value = 0;};
00052 
00053    template <class T1, class T2>
00054    struct compressed_pair_switch<T1, T2, false, true, true>
00055       {static const int value = 3;};
00056 
00057    template <class T1, class T2>
00058    struct compressed_pair_switch<T1, T2, false, true, false>
00059       {static const int value = 1;};
00060 
00061    template <class T1, class T2>
00062    struct compressed_pair_switch<T1, T2, false, false, true>
00063       {static const int value = 2;};
00064 
00065    template <class T1, class T2>
00066    struct compressed_pair_switch<T1, T2, true, true, true>
00067       {static const int value = 4;};
00068 
00069    template <class T1, class T2>
00070    struct compressed_pair_switch<T1, T2, true, false, false>
00071       {static const int value = 5;};
00072 
00073    template <class T1, class T2, int Version> class compressed_pair_imp;
00074 
00075 #ifdef __GNUC__
00076    // workaround for GCC (JM):
00077    using std::swap;
00078 #endif
00079    //
00080    // can't call unqualified swap from within classname::swap
00081    // as Koenig lookup rules will find only the classname::swap
00082    // member function not the global declaration, so use cp_swap
00083    // as a forwarding function (JM):
00084    template <typename T>
00085    inline void cp_swap(T& t1, T& t2)
00086    {
00087 #ifndef __GNUC__
00088       using std::swap;
00089 #endif
00090       swap(t1, t2);
00091    }
00092 
00093    // 0    derive from neither
00094 
00095    template <class T1, class T2>
00096    class compressed_pair_imp<T1, T2, 0>
00097    {
00098    public:
00099       typedef T1                                                 first_type;
00100       typedef T2                                                 second_type;
00101       typedef typename call_traits<first_type>::param_type       first_param_type;
00102       typedef typename call_traits<second_type>::param_type      second_param_type;
00103       typedef typename call_traits<first_type>::reference        first_reference;
00104       typedef typename call_traits<second_type>::reference       second_reference;
00105       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00106       typedef typename call_traits<second_type>::const_reference second_const_reference;
00107 
00108       compressed_pair_imp() {} 
00109 
00110       compressed_pair_imp(first_param_type x, second_param_type y)
00111          : first_(x), second_(y) {}
00112 
00113       compressed_pair_imp(first_param_type x)
00114          : first_(x) {}
00115 
00116       compressed_pair_imp(second_param_type y)
00117          : second_(y) {}
00118 
00119       first_reference       first()       {return first_;}
00120       first_const_reference first() const {return first_;}
00121 
00122       second_reference       second()       {return second_;}
00123       second_const_reference second() const {return second_;}
00124 
00125       void swap(::boost::compressed_pair<T1, T2>& y)
00126       {
00127          cp_swap(first_, y.first());
00128          cp_swap(second_, y.second());
00129       }
00130    private:
00131       first_type first_;
00132       second_type second_;
00133    };
00134 
00135    // 1    derive from T1
00136 
00137    template <class T1, class T2>
00138    class compressed_pair_imp<T1, T2, 1>
00139       : protected ::boost::remove_cv<T1>::type
00140    {
00141    public:
00142       typedef T1                                                 first_type;
00143       typedef T2                                                 second_type;
00144       typedef typename call_traits<first_type>::param_type       first_param_type;
00145       typedef typename call_traits<second_type>::param_type      second_param_type;
00146       typedef typename call_traits<first_type>::reference        first_reference;
00147       typedef typename call_traits<second_type>::reference       second_reference;
00148       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00149       typedef typename call_traits<second_type>::const_reference second_const_reference;
00150 
00151       compressed_pair_imp() {}
00152 
00153       compressed_pair_imp(first_param_type x, second_param_type y)
00154          : first_type(x), second_(y) {}
00155 
00156       compressed_pair_imp(first_param_type x)
00157          : first_type(x) {}
00158 
00159       compressed_pair_imp(second_param_type y)
00160          : second_(y) {}
00161 
00162       first_reference       first()       {return *this;}
00163       first_const_reference first() const {return *this;}
00164 
00165       second_reference       second()       {return second_;}
00166       second_const_reference second() const {return second_;}
00167 
00168       void swap(::boost::compressed_pair<T1,T2>& y)
00169       {
00170          // no need to swap empty base class:
00171          cp_swap(second_, y.second());
00172       }
00173    private:
00174       second_type second_;
00175    };
00176 
00177    // 2    derive from T2
00178 
00179    template <class T1, class T2>
00180    class compressed_pair_imp<T1, T2, 2>
00181       : protected ::boost::remove_cv<T2>::type
00182    {
00183    public:
00184       typedef T1                                                 first_type;
00185       typedef T2                                                 second_type;
00186       typedef typename call_traits<first_type>::param_type       first_param_type;
00187       typedef typename call_traits<second_type>::param_type      second_param_type;
00188       typedef typename call_traits<first_type>::reference        first_reference;
00189       typedef typename call_traits<second_type>::reference       second_reference;
00190       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00191       typedef typename call_traits<second_type>::const_reference second_const_reference;
00192 
00193       compressed_pair_imp() {}
00194 
00195       compressed_pair_imp(first_param_type x, second_param_type y)
00196          : second_type(y), first_(x) {}
00197 
00198       compressed_pair_imp(first_param_type x)
00199          : first_(x) {}
00200 
00201       compressed_pair_imp(second_param_type y)
00202          : second_type(y) {}
00203 
00204       first_reference       first()       {return first_;}
00205       first_const_reference first() const {return first_;}
00206 
00207       second_reference       second()       {return *this;}
00208       second_const_reference second() const {return *this;}
00209 
00210       void swap(::boost::compressed_pair<T1,T2>& y)
00211       {
00212          // no need to swap empty base class:
00213          cp_swap(first_, y.first());
00214       }
00215 
00216    private:
00217       first_type first_;
00218    };
00219 
00220    // 3    derive from T1 and T2
00221 
00222    template <class T1, class T2>
00223    class compressed_pair_imp<T1, T2, 3>
00224       : protected ::boost::remove_cv<T1>::type,
00225         protected ::boost::remove_cv<T2>::type
00226    {
00227    public:
00228       typedef T1                                                 first_type;
00229       typedef T2                                                 second_type;
00230       typedef typename call_traits<first_type>::param_type       first_param_type;
00231       typedef typename call_traits<second_type>::param_type      second_param_type;
00232       typedef typename call_traits<first_type>::reference        first_reference;
00233       typedef typename call_traits<second_type>::reference       second_reference;
00234       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00235       typedef typename call_traits<second_type>::const_reference second_const_reference;
00236 
00237       compressed_pair_imp() {}
00238 
00239       compressed_pair_imp(first_param_type x, second_param_type y)
00240          : first_type(x), second_type(y) {}
00241 
00242       compressed_pair_imp(first_param_type x)
00243          : first_type(x) {}
00244 
00245       compressed_pair_imp(second_param_type y)
00246          : second_type(y) {}
00247 
00248       first_reference       first()       {return *this;}
00249       first_const_reference first() const {return *this;}
00250 
00251       second_reference       second()       {return *this;}
00252       second_const_reference second() const {return *this;}
00253       //
00254       // no need to swap empty bases:
00255       void swap(::boost::compressed_pair<T1,T2>&) {}
00256    };
00257 
00258    // JM
00259    // 4    T1 == T2, T1 and T2 both empty
00260    //      Originally this did not store an instance of T2 at all
00261    //      but that led to problems beause it meant &x.first() == &x.second()
00262    //      which is not true for any other kind of pair, so now we store an instance
00263    //      of T2 just in case the user is relying on first() and second() returning
00264    //      different objects (albeit both empty).
00265    template <class T1, class T2>
00266    class compressed_pair_imp<T1, T2, 4>
00267       : protected ::boost::remove_cv<T1>::type
00268    {
00269    public:
00270       typedef T1                                                 first_type;
00271       typedef T2                                                 second_type;
00272       typedef typename call_traits<first_type>::param_type       first_param_type;
00273       typedef typename call_traits<second_type>::param_type      second_param_type;
00274       typedef typename call_traits<first_type>::reference        first_reference;
00275       typedef typename call_traits<second_type>::reference       second_reference;
00276       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00277       typedef typename call_traits<second_type>::const_reference second_const_reference;
00278 
00279       compressed_pair_imp() {}
00280 
00281       compressed_pair_imp(first_param_type x, second_param_type y)
00282          : first_type(x), m_second(y) {}
00283 
00284       compressed_pair_imp(first_param_type x)
00285          : first_type(x), m_second(x) {}
00286 
00287       first_reference       first()       {return *this;}
00288       first_const_reference first() const {return *this;}
00289 
00290       second_reference       second()       {return m_second;}
00291       second_const_reference second() const {return m_second;}
00292 
00293       void swap(::boost::compressed_pair<T1,T2>&) {}
00294    private:
00295       T2 m_second;
00296    };
00297 
00298    // 5    T1 == T2 and are not empty:   //JM
00299 
00300    template <class T1, class T2>
00301    class compressed_pair_imp<T1, T2, 5>
00302    {
00303    public:
00304       typedef T1                                                 first_type;
00305       typedef T2                                                 second_type;
00306       typedef typename call_traits<first_type>::param_type       first_param_type;
00307       typedef typename call_traits<second_type>::param_type      second_param_type;
00308       typedef typename call_traits<first_type>::reference        first_reference;
00309       typedef typename call_traits<second_type>::reference       second_reference;
00310       typedef typename call_traits<first_type>::const_reference  first_const_reference;
00311       typedef typename call_traits<second_type>::const_reference second_const_reference;
00312 
00313       compressed_pair_imp() {}
00314 
00315       compressed_pair_imp(first_param_type x, second_param_type y)
00316          : first_(x), second_(y) {}
00317 
00318       compressed_pair_imp(first_param_type x)
00319          : first_(x), second_(x) {}
00320 
00321       first_reference       first()       {return first_;}
00322       first_const_reference first() const {return first_;}
00323 
00324       second_reference       second()       {return second_;}
00325       second_const_reference second() const {return second_;}
00326 
00327       void swap(::boost::compressed_pair<T1, T2>& y)
00328       {
00329          cp_swap(first_, y.first());
00330          cp_swap(second_, y.second());
00331       }
00332    private:
00333       first_type first_;
00334       second_type second_;
00335    };
00336 
00337 }  // details
00338 
00339 template <class T1, class T2>
00340 class compressed_pair
00341    : private ::boost::details::compressed_pair_imp<T1, T2,
00342              ::boost::details::compressed_pair_switch<
00343                     T1,
00344                     T2,
00345                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
00346                     ::boost::is_empty<T1>::value,
00347                     ::boost::is_empty<T2>::value>::value>
00348 {
00349 private:
00350    typedef details::compressed_pair_imp<T1, T2,
00351              ::boost::details::compressed_pair_switch<
00352                     T1,
00353                     T2,
00354                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
00355                     ::boost::is_empty<T1>::value,
00356                     ::boost::is_empty<T2>::value>::value> base;
00357 public:
00358    typedef T1                                                 first_type;
00359    typedef T2                                                 second_type;
00360    typedef typename call_traits<first_type>::param_type       first_param_type;
00361    typedef typename call_traits<second_type>::param_type      second_param_type;
00362    typedef typename call_traits<first_type>::reference        first_reference;
00363    typedef typename call_traits<second_type>::reference       second_reference;
00364    typedef typename call_traits<first_type>::const_reference  first_const_reference;
00365    typedef typename call_traits<second_type>::const_reference second_const_reference;
00366 
00367             compressed_pair() : base() {}
00368             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
00369    explicit compressed_pair(first_param_type x) : base(x) {}
00370    explicit compressed_pair(second_param_type y) : base(y) {}
00371 
00372    first_reference       first()       {return base::first();}
00373    first_const_reference first() const {return base::first();}
00374 
00375    second_reference       second()       {return base::second();}
00376    second_const_reference second() const {return base::second();}
00377 
00378    void swap(compressed_pair& y) { base::swap(y); }
00379 };
00380 
00381 // JM
00382 // Partial specialisation for case where T1 == T2:
00383 //
00384 template <class T>
00385 class compressed_pair<T, T>
00386    : private details::compressed_pair_imp<T, T,
00387              ::boost::details::compressed_pair_switch<
00388                     T,
00389                     T,
00390                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
00391                     ::boost::is_empty<T>::value,
00392                     ::boost::is_empty<T>::value>::value>
00393 {
00394 private:
00395    typedef details::compressed_pair_imp<T, T,
00396              ::boost::details::compressed_pair_switch<
00397                     T,
00398                     T,
00399                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
00400                     ::boost::is_empty<T>::value,
00401                     ::boost::is_empty<T>::value>::value> base;
00402 public:
00403    typedef T                                                  first_type;
00404    typedef T                                                  second_type;
00405    typedef typename call_traits<first_type>::param_type       first_param_type;
00406    typedef typename call_traits<second_type>::param_type      second_param_type;
00407    typedef typename call_traits<first_type>::reference        first_reference;
00408    typedef typename call_traits<second_type>::reference       second_reference;
00409    typedef typename call_traits<first_type>::const_reference  first_const_reference;
00410    typedef typename call_traits<second_type>::const_reference second_const_reference;
00411 
00412             compressed_pair() : base() {}
00413             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
00414 #if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
00415    explicit 
00416 #endif
00417       compressed_pair(first_param_type x) : base(x) {}
00418 
00419    first_reference       first()       {return base::first();}
00420    first_const_reference first() const {return base::first();}
00421 
00422    second_reference       second()       {return base::second();}
00423    second_const_reference second() const {return base::second();}
00424 
00425    void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
00426 };
00427 
00428 template <class T1, class T2>
00429 inline
00430 void
00431 swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
00432 {
00433    x.swap(y);
00434 }
00435 
00436 } // boost
00437 
00438 #ifdef BOOST_MSVC
00439 # pragma warning(pop)
00440 #endif 
00441 
00442 #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
00443 


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:28