| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 | //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.//  Use, modification and distribution are subject to 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).////  See http://www.boost.org/libs/utility for most recent version including documentation.// compressed_pair: pair that "compresses" empty members// (see libs/utility/doc/html/compressed_pair.html)//// JM changes 25 Jan 2004:// For the case where T1 == T2 and both are empty, then first() and second()// should return different objects.// JM changes 25 Jan 2000:// Removed default arguments from compressed_pair_switch to get// C++ Builder 4 to accept them// rewriten swap to get gcc and C++ builder to compile.// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP#define BOOST_DETAIL_COMPRESSED_PAIR_HPP#include <algorithm>#include <boost/type_traits/remove_cv.hpp>#include <boost/type_traits/is_empty.hpp>#include <boost/type_traits/is_final.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/call_traits.hpp>#ifdef BOOST_MSVC# pragma warning(push)# pragma warning(disable:4512)#endif namespace boost{template <class T1, class T2>class compressed_pair;// compressed_pairnamespace details{   template<class T, bool E = boost::is_final<T>::value>   struct compressed_pair_empty      : ::boost::false_type { };   template<class T>   struct compressed_pair_empty<T, false>      : ::boost::is_empty<T> { };   // JM altered 26 Jan 2000:   template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>   struct compressed_pair_switch;   template <class T1, class T2>   struct compressed_pair_switch<T1, T2, false, false, false>      {static const int value = 0;};   template <class T1, class T2>   struct compressed_pair_switch<T1, T2, false, true, true>      {static const int value = 3;};   template <class T1, class T2>   struct compressed_pair_switch<T1, T2, false, true, false>      {static const int value = 1;};   template <class T1, class T2>   struct compressed_pair_switch<T1, T2, false, false, true>      {static const int value = 2;};   template <class T1, class T2>   struct compressed_pair_switch<T1, T2, true, true, true>      {static const int value = 4;};   template <class T1, class T2>   struct compressed_pair_switch<T1, T2, true, false, false>      {static const int value = 5;};   template <class T1, class T2, int Version> class compressed_pair_imp;#ifdef __GNUC__   // workaround for GCC (JM):   using std::swap;#endif   //   // can't call unqualified swap from within classname::swap   // as Koenig lookup rules will find only the classname::swap   // member function not the global declaration, so use cp_swap   // as a forwarding function (JM):   template <typename T>   inline void cp_swap(T& t1, T& t2)   {#ifndef __GNUC__      using std::swap;#endif      swap(t1, t2);   }   // 0    derive from neither   template <class T1, class T2>   class compressed_pair_imp<T1, T2, 0>   {   public:      typedef T1                                                 first_type;      typedef T2                                                 second_type;      typedef typename call_traits<first_type>::param_type       first_param_type;      typedef typename call_traits<second_type>::param_type      second_param_type;      typedef typename call_traits<first_type>::reference        first_reference;      typedef typename call_traits<second_type>::reference       second_reference;      typedef typename call_traits<first_type>::const_reference  first_const_reference;      typedef typename call_traits<second_type>::const_reference second_const_reference;      compressed_pair_imp() {}       compressed_pair_imp(first_param_type x, second_param_type y)         : first_(x), second_(y) {}      compressed_pair_imp(first_param_type x)         : first_(x) {}      compressed_pair_imp(second_param_type y)         : second_(y) {}      first_reference       first()       {return first_;}      first_const_reference first() const {return first_;}      second_reference       second()       {return second_;}      second_const_reference second() const {return second_;}      void swap(::boost::compressed_pair<T1, T2>& y)      {         cp_swap(first_, y.first());         cp_swap(second_, y.second());      }   private:      first_type first_;      second_type second_;   };   // 1    derive from T1   template <class T1, class T2>   class compressed_pair_imp<T1, T2, 1>      : protected ::boost::remove_cv<T1>::type   {   public:      typedef T1                                                 first_type;      typedef T2                                                 second_type;      typedef typename call_traits<first_type>::param_type       first_param_type;      typedef typename call_traits<second_type>::param_type      second_param_type;      typedef typename call_traits<first_type>::reference        first_reference;      typedef typename call_traits<second_type>::reference       second_reference;      typedef typename call_traits<first_type>::const_reference  first_const_reference;      typedef typename call_traits<second_type>::const_reference second_const_reference;      compressed_pair_imp() {}      compressed_pair_imp(first_param_type x, second_param_type y)         : first_type(x), second_(y) {}      compressed_pair_imp(first_param_type x)         : first_type(x) {}      compressed_pair_imp(second_param_type y)         : second_(y) {}      first_reference       first()       {return *this;}      first_const_reference first() const {return *this;}      second_reference       second()       {return second_;}      second_const_reference second() const {return second_;}      void swap(::boost::compressed_pair<T1,T2>& y)      {         // no need to swap empty base class:         cp_swap(second_, y.second());      }   private:      second_type second_;   };   // 2    derive from T2   template <class T1, class T2>   class compressed_pair_imp<T1, T2, 2>      : protected ::boost::remove_cv<T2>::type   {   public:      typedef T1                                                 first_type;      typedef T2                                                 second_type;      typedef typename call_traits<first_type>::param_type       first_param_type;      typedef typename call_traits<second_type>::param_type      second_param_type;      typedef typename call_traits<first_type>::reference        first_reference;      typedef typename call_traits<second_type>::reference       second_reference;      typedef typename call_traits<first_type>::const_reference  first_const_reference;      typedef typename call_traits<second_type>::const_reference second_const_reference;      compressed_pair_imp() {}      compressed_pair_imp(first_param_type x, second_param_type y)         : second_type(y), first_(x) {}      compressed_pair_imp(first_param_type x)         : first_(x) {}      compressed_pair_imp(second_param_type y)         : second_type(y) {}      first_reference       first()       {return first_;}      first_const_reference first() const {return first_;}      second_reference       second()       {return *this;}      second_const_reference second() const {return *this;}      void swap(::boost::compressed_pair<T1,T2>& y)      {         // no need to swap empty base class:         cp_swap(first_, y.first());      }   private:      first_type first_;   };   // 3    derive from T1 and T2   template <class T1, class T2>   class compressed_pair_imp<T1, T2, 3>      : protected ::boost::remove_cv<T1>::type,        protected ::boost::remove_cv<T2>::type   {   public:      typedef T1                                                 first_type;      typedef T2                                                 second_type;      typedef typename call_traits<first_type>::param_type       first_param_type;      typedef typename call_traits<second_type>::param_type      second_param_type;      typedef typename call_traits<first_type>::reference        first_reference;      typedef typename call_traits<second_type>::reference       second_reference;      typedef typename call_traits<first_type>::const_reference  first_const_reference;      typedef typename call_traits<second_type>::const_reference second_const_reference;      compressed_pair_imp() {}      compressed_pair_imp(first_param_type x, second_param_type y)         : first_type(x), second_type(y) {}      compressed_pair_imp(first_param_type x)         : first_type(x) {}      compressed_pair_imp(second_param_type y)         : second_type(y) {}      first_reference       first()       {return *this;}      first_const_reference first() const {return *this;}      second_reference       second()       {return *this;}      second_const_reference second() const {return *this;}      //      // no need to swap empty bases:      void swap(::boost::compressed_pair<T1,T2>&) {}   };   // JM   // 4    T1 == T2, T1 and T2 both empty   //      Originally this did not store an instance of T2 at all   //      but that led to problems beause it meant &x.first() == &x.second()   //      which is not true for any other kind of pair, so now we store an instance   //      of T2 just in case the user is relying on first() and second() returning   //      different objects (albeit both empty).   template <class T1, class T2>   class compressed_pair_imp<T1, T2, 4>      : protected ::boost::remove_cv<T1>::type   {   public:      typedef T1                                                 first_type;      typedef T2                                                 second_type;      typedef typename call_traits<first_type>::param_type       first_param_type;      typedef typename call_traits<second_type>::param_type      second_param_type;      typedef typename call_traits<first_type>::reference        first_reference;      typedef typename call_traits<second_type>::reference       second_reference;      typedef typename call_traits<first_type>::const_reference  first_const_reference;      typedef typename call_traits<second_type>::const_reference second_const_reference;      compressed_pair_imp() {}      compressed_pair_imp(first_param_type x, second_param_type y)         : first_type(x), m_second(y) {}      compressed_pair_imp(first_param_type x)         : first_type(x), m_second(x) {}      first_reference       first()       {return *this;}      first_const_reference first() const {return *this;}      second_reference       second()       {return m_second;}      second_const_reference second() const {return m_second;}      void swap(::boost::compressed_pair<T1,T2>&) {}   private:      T2 m_second;   };   // 5    T1 == T2 and are not empty:   //JM   template <class T1, class T2>   class compressed_pair_imp<T1, T2, 5>   {   public:      typedef T1                                                 first_type;      typedef T2                                                 second_type;      typedef typename call_traits<first_type>::param_type       first_param_type;      typedef typename call_traits<second_type>::param_type      second_param_type;      typedef typename call_traits<first_type>::reference        first_reference;      typedef typename call_traits<second_type>::reference       second_reference;      typedef typename call_traits<first_type>::const_reference  first_const_reference;      typedef typename call_traits<second_type>::const_reference second_const_reference;      compressed_pair_imp() {}      compressed_pair_imp(first_param_type x, second_param_type y)         : first_(x), second_(y) {}      compressed_pair_imp(first_param_type x)         : first_(x), second_(x) {}      first_reference       first()       {return first_;}      first_const_reference first() const {return first_;}      second_reference       second()       {return second_;}      second_const_reference second() const {return second_;}      void swap(::boost::compressed_pair<T1, T2>& y)      {         cp_swap(first_, y.first());         cp_swap(second_, y.second());      }   private:      first_type first_;      second_type second_;   };}  // detailstemplate <class T1, class T2>class compressed_pair   : private ::boost::details::compressed_pair_imp<T1, T2,             ::boost::details::compressed_pair_switch<                    T1,                    T2,                    ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,                    ::boost::details::compressed_pair_empty<T1>::value,                    ::boost::details::compressed_pair_empty<T2>::value>::value>{private:   typedef details::compressed_pair_imp<T1, T2,             ::boost::details::compressed_pair_switch<                    T1,                    T2,                    ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,                    ::boost::details::compressed_pair_empty<T1>::value,                    ::boost::details::compressed_pair_empty<T2>::value>::value> base;public:   typedef T1                                                 first_type;   typedef T2                                                 second_type;   typedef typename call_traits<first_type>::param_type       first_param_type;   typedef typename call_traits<second_type>::param_type      second_param_type;   typedef typename call_traits<first_type>::reference        first_reference;   typedef typename call_traits<second_type>::reference       second_reference;   typedef typename call_traits<first_type>::const_reference  first_const_reference;   typedef typename call_traits<second_type>::const_reference second_const_reference;            compressed_pair() : base() {}            compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}   explicit compressed_pair(first_param_type x) : base(x) {}   explicit compressed_pair(second_param_type y) : base(y) {}   first_reference       first()       {return base::first();}   first_const_reference first() const {return base::first();}   second_reference       second()       {return base::second();}   second_const_reference second() const {return base::second();}   void swap(compressed_pair& y) { base::swap(y); }};// JM// Partial specialisation for case where T1 == T2://template <class T>class compressed_pair<T, T>   : private details::compressed_pair_imp<T, T,             ::boost::details::compressed_pair_switch<                    T,                    T,                    ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,                    ::boost::details::compressed_pair_empty<T>::value,                    ::boost::details::compressed_pair_empty<T>::value>::value>{private:   typedef details::compressed_pair_imp<T, T,             ::boost::details::compressed_pair_switch<                    T,                    T,                    ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,                    ::boost::details::compressed_pair_empty<T>::value,                    ::boost::details::compressed_pair_empty<T>::value>::value> base;public:   typedef T                                                  first_type;   typedef T                                                  second_type;   typedef typename call_traits<first_type>::param_type       first_param_type;   typedef typename call_traits<second_type>::param_type      second_param_type;   typedef typename call_traits<first_type>::reference        first_reference;   typedef typename call_traits<second_type>::reference       second_reference;   typedef typename call_traits<first_type>::const_reference  first_const_reference;   typedef typename call_traits<second_type>::const_reference second_const_reference;            compressed_pair() : base() {}            compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))   explicit #endif      compressed_pair(first_param_type x) : base(x) {}   first_reference       first()       {return base::first();}   first_const_reference first() const {return base::first();}   second_reference       second()       {return base::second();}   second_const_reference second() const {return base::second();}   void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }};template <class T1, class T2>inlinevoidswap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y){   x.swap(y);}} // boost#ifdef BOOST_MSVC# pragma warning(pop)#endif #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
 |