Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:27

0001 //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
0002 //  Use, modification and distribution are subject to the Boost Software License,
0003 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt).
0005 //
0006 //  See http://www.boost.org/libs/utility for most recent version including documentation.
0007 
0008 // compressed_pair: pair that "compresses" empty members
0009 // (see libs/utility/doc/html/compressed_pair.html)
0010 //
0011 // JM changes 25 Jan 2004:
0012 // For the case where T1 == T2 and both are empty, then first() and second()
0013 // should return different objects.
0014 // JM changes 25 Jan 2000:
0015 // Removed default arguments from compressed_pair_switch to get
0016 // C++ Builder 4 to accept them
0017 // rewriten swap to get gcc and C++ builder to compile.
0018 // added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
0019 
0020 #ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
0021 #define BOOST_DETAIL_COMPRESSED_PAIR_HPP
0022 
0023 #include <algorithm>
0024 
0025 #include <boost/type_traits/remove_cv.hpp>
0026 #include <boost/type_traits/is_empty.hpp>
0027 #include <boost/type_traits/is_final.hpp>
0028 #include <boost/type_traits/is_same.hpp>
0029 #include <boost/call_traits.hpp>
0030 
0031 #ifdef BOOST_MSVC
0032 # pragma warning(push)
0033 # pragma warning(disable:4512)
0034 #endif 
0035 namespace boost
0036 {
0037 
0038 template <class T1, class T2>
0039 class compressed_pair;
0040 
0041 
0042 // compressed_pair
0043 
0044 namespace details
0045 {
0046    template<class T, bool E = boost::is_final<T>::value>
0047    struct compressed_pair_empty
0048       : ::boost::false_type { };
0049 
0050    template<class T>
0051    struct compressed_pair_empty<T, false>
0052       : ::boost::is_empty<T> { };
0053 
0054    // JM altered 26 Jan 2000:
0055    template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
0056    struct compressed_pair_switch;
0057 
0058    template <class T1, class T2>
0059    struct compressed_pair_switch<T1, T2, false, false, false>
0060       {static const int value = 0;};
0061 
0062    template <class T1, class T2>
0063    struct compressed_pair_switch<T1, T2, false, true, true>
0064       {static const int value = 3;};
0065 
0066    template <class T1, class T2>
0067    struct compressed_pair_switch<T1, T2, false, true, false>
0068       {static const int value = 1;};
0069 
0070    template <class T1, class T2>
0071    struct compressed_pair_switch<T1, T2, false, false, true>
0072       {static const int value = 2;};
0073 
0074    template <class T1, class T2>
0075    struct compressed_pair_switch<T1, T2, true, true, true>
0076       {static const int value = 4;};
0077 
0078    template <class T1, class T2>
0079    struct compressed_pair_switch<T1, T2, true, false, false>
0080       {static const int value = 5;};
0081 
0082    template <class T1, class T2, int Version> class compressed_pair_imp;
0083 
0084 #ifdef __GNUC__
0085    // workaround for GCC (JM):
0086    using std::swap;
0087 #endif
0088    //
0089    // can't call unqualified swap from within classname::swap
0090    // as Koenig lookup rules will find only the classname::swap
0091    // member function not the global declaration, so use cp_swap
0092    // as a forwarding function (JM):
0093    template <typename T>
0094    inline void cp_swap(T& t1, T& t2)
0095    {
0096 #ifndef __GNUC__
0097       using std::swap;
0098 #endif
0099       swap(t1, t2);
0100    }
0101 
0102    // 0    derive from neither
0103 
0104    template <class T1, class T2>
0105    class compressed_pair_imp<T1, T2, 0>
0106    {
0107    public:
0108       typedef T1                                                 first_type;
0109       typedef T2                                                 second_type;
0110       typedef typename call_traits<first_type>::param_type       first_param_type;
0111       typedef typename call_traits<second_type>::param_type      second_param_type;
0112       typedef typename call_traits<first_type>::reference        first_reference;
0113       typedef typename call_traits<second_type>::reference       second_reference;
0114       typedef typename call_traits<first_type>::const_reference  first_const_reference;
0115       typedef typename call_traits<second_type>::const_reference second_const_reference;
0116 
0117       compressed_pair_imp() {} 
0118 
0119       compressed_pair_imp(first_param_type x, second_param_type y)
0120          : first_(x), second_(y) {}
0121 
0122       compressed_pair_imp(first_param_type x)
0123          : first_(x) {}
0124 
0125       compressed_pair_imp(second_param_type y)
0126          : second_(y) {}
0127 
0128       first_reference       first()       {return first_;}
0129       first_const_reference first() const {return first_;}
0130 
0131       second_reference       second()       {return second_;}
0132       second_const_reference second() const {return second_;}
0133 
0134       void swap(::boost::compressed_pair<T1, T2>& y)
0135       {
0136          cp_swap(first_, y.first());
0137          cp_swap(second_, y.second());
0138       }
0139    private:
0140       first_type first_;
0141       second_type second_;
0142    };
0143 
0144    // 1    derive from T1
0145 
0146    template <class T1, class T2>
0147    class compressed_pair_imp<T1, T2, 1>
0148       : protected ::boost::remove_cv<T1>::type
0149    {
0150    public:
0151       typedef T1                                                 first_type;
0152       typedef T2                                                 second_type;
0153       typedef typename call_traits<first_type>::param_type       first_param_type;
0154       typedef typename call_traits<second_type>::param_type      second_param_type;
0155       typedef typename call_traits<first_type>::reference        first_reference;
0156       typedef typename call_traits<second_type>::reference       second_reference;
0157       typedef typename call_traits<first_type>::const_reference  first_const_reference;
0158       typedef typename call_traits<second_type>::const_reference second_const_reference;
0159 
0160       compressed_pair_imp() {}
0161 
0162       compressed_pair_imp(first_param_type x, second_param_type y)
0163          : first_type(x), second_(y) {}
0164 
0165       compressed_pair_imp(first_param_type x)
0166          : first_type(x) {}
0167 
0168       compressed_pair_imp(second_param_type y)
0169          : second_(y) {}
0170 
0171       first_reference       first()       {return *this;}
0172       first_const_reference first() const {return *this;}
0173 
0174       second_reference       second()       {return second_;}
0175       second_const_reference second() const {return second_;}
0176 
0177       void swap(::boost::compressed_pair<T1,T2>& y)
0178       {
0179          // no need to swap empty base class:
0180          cp_swap(second_, y.second());
0181       }
0182    private:
0183       second_type second_;
0184    };
0185 
0186    // 2    derive from T2
0187 
0188    template <class T1, class T2>
0189    class compressed_pair_imp<T1, T2, 2>
0190       : protected ::boost::remove_cv<T2>::type
0191    {
0192    public:
0193       typedef T1                                                 first_type;
0194       typedef T2                                                 second_type;
0195       typedef typename call_traits<first_type>::param_type       first_param_type;
0196       typedef typename call_traits<second_type>::param_type      second_param_type;
0197       typedef typename call_traits<first_type>::reference        first_reference;
0198       typedef typename call_traits<second_type>::reference       second_reference;
0199       typedef typename call_traits<first_type>::const_reference  first_const_reference;
0200       typedef typename call_traits<second_type>::const_reference second_const_reference;
0201 
0202       compressed_pair_imp() {}
0203 
0204       compressed_pair_imp(first_param_type x, second_param_type y)
0205          : second_type(y), first_(x) {}
0206 
0207       compressed_pair_imp(first_param_type x)
0208          : first_(x) {}
0209 
0210       compressed_pair_imp(second_param_type y)
0211          : second_type(y) {}
0212 
0213       first_reference       first()       {return first_;}
0214       first_const_reference first() const {return first_;}
0215 
0216       second_reference       second()       {return *this;}
0217       second_const_reference second() const {return *this;}
0218 
0219       void swap(::boost::compressed_pair<T1,T2>& y)
0220       {
0221          // no need to swap empty base class:
0222          cp_swap(first_, y.first());
0223       }
0224 
0225    private:
0226       first_type first_;
0227    };
0228 
0229    // 3    derive from T1 and T2
0230 
0231    template <class T1, class T2>
0232    class compressed_pair_imp<T1, T2, 3>
0233       : protected ::boost::remove_cv<T1>::type,
0234         protected ::boost::remove_cv<T2>::type
0235    {
0236    public:
0237       typedef T1                                                 first_type;
0238       typedef T2                                                 second_type;
0239       typedef typename call_traits<first_type>::param_type       first_param_type;
0240       typedef typename call_traits<second_type>::param_type      second_param_type;
0241       typedef typename call_traits<first_type>::reference        first_reference;
0242       typedef typename call_traits<second_type>::reference       second_reference;
0243       typedef typename call_traits<first_type>::const_reference  first_const_reference;
0244       typedef typename call_traits<second_type>::const_reference second_const_reference;
0245 
0246       compressed_pair_imp() {}
0247 
0248       compressed_pair_imp(first_param_type x, second_param_type y)
0249          : first_type(x), second_type(y) {}
0250 
0251       compressed_pair_imp(first_param_type x)
0252          : first_type(x) {}
0253 
0254       compressed_pair_imp(second_param_type y)
0255          : second_type(y) {}
0256 
0257       first_reference       first()       {return *this;}
0258       first_const_reference first() const {return *this;}
0259 
0260       second_reference       second()       {return *this;}
0261       second_const_reference second() const {return *this;}
0262       //
0263       // no need to swap empty bases:
0264       void swap(::boost::compressed_pair<T1,T2>&) {}
0265    };
0266 
0267    // JM
0268    // 4    T1 == T2, T1 and T2 both empty
0269    //      Originally this did not store an instance of T2 at all
0270    //      but that led to problems beause it meant &x.first() == &x.second()
0271    //      which is not true for any other kind of pair, so now we store an instance
0272    //      of T2 just in case the user is relying on first() and second() returning
0273    //      different objects (albeit both empty).
0274    template <class T1, class T2>
0275    class compressed_pair_imp<T1, T2, 4>
0276       : protected ::boost::remove_cv<T1>::type
0277    {
0278    public:
0279       typedef T1                                                 first_type;
0280       typedef T2                                                 second_type;
0281       typedef typename call_traits<first_type>::param_type       first_param_type;
0282       typedef typename call_traits<second_type>::param_type      second_param_type;
0283       typedef typename call_traits<first_type>::reference        first_reference;
0284       typedef typename call_traits<second_type>::reference       second_reference;
0285       typedef typename call_traits<first_type>::const_reference  first_const_reference;
0286       typedef typename call_traits<second_type>::const_reference second_const_reference;
0287 
0288       compressed_pair_imp() {}
0289 
0290       compressed_pair_imp(first_param_type x, second_param_type y)
0291          : first_type(x), m_second(y) {}
0292 
0293       compressed_pair_imp(first_param_type x)
0294          : first_type(x), m_second(x) {}
0295 
0296       first_reference       first()       {return *this;}
0297       first_const_reference first() const {return *this;}
0298 
0299       second_reference       second()       {return m_second;}
0300       second_const_reference second() const {return m_second;}
0301 
0302       void swap(::boost::compressed_pair<T1,T2>&) {}
0303    private:
0304       T2 m_second;
0305    };
0306 
0307    // 5    T1 == T2 and are not empty:   //JM
0308 
0309    template <class T1, class T2>
0310    class compressed_pair_imp<T1, T2, 5>
0311    {
0312    public:
0313       typedef T1                                                 first_type;
0314       typedef T2                                                 second_type;
0315       typedef typename call_traits<first_type>::param_type       first_param_type;
0316       typedef typename call_traits<second_type>::param_type      second_param_type;
0317       typedef typename call_traits<first_type>::reference        first_reference;
0318       typedef typename call_traits<second_type>::reference       second_reference;
0319       typedef typename call_traits<first_type>::const_reference  first_const_reference;
0320       typedef typename call_traits<second_type>::const_reference second_const_reference;
0321 
0322       compressed_pair_imp() {}
0323 
0324       compressed_pair_imp(first_param_type x, second_param_type y)
0325          : first_(x), second_(y) {}
0326 
0327       compressed_pair_imp(first_param_type x)
0328          : first_(x), second_(x) {}
0329 
0330       first_reference       first()       {return first_;}
0331       first_const_reference first() const {return first_;}
0332 
0333       second_reference       second()       {return second_;}
0334       second_const_reference second() const {return second_;}
0335 
0336       void swap(::boost::compressed_pair<T1, T2>& y)
0337       {
0338          cp_swap(first_, y.first());
0339          cp_swap(second_, y.second());
0340       }
0341    private:
0342       first_type first_;
0343       second_type second_;
0344    };
0345 
0346 }  // details
0347 
0348 template <class T1, class T2>
0349 class compressed_pair
0350 #ifndef BOOST_UTILITY_DOCS
0351     : private ::boost::details::compressed_pair_imp<T1, T2,
0352              ::boost::details::compressed_pair_switch<
0353                     T1,
0354                     T2,
0355                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
0356                     ::boost::details::compressed_pair_empty<T1>::value,
0357                     ::boost::details::compressed_pair_empty<T2>::value>::value>
0358 #endif // BOOST_UTILITY_DOCS
0359 {
0360 private:
0361    typedef details::compressed_pair_imp<T1, T2,
0362              ::boost::details::compressed_pair_switch<
0363                     T1,
0364                     T2,
0365                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
0366                     ::boost::details::compressed_pair_empty<T1>::value,
0367                     ::boost::details::compressed_pair_empty<T2>::value>::value> base;
0368 public:
0369    typedef T1                                                 first_type;
0370    typedef T2                                                 second_type;
0371    typedef typename call_traits<first_type>::param_type       first_param_type;
0372    typedef typename call_traits<second_type>::param_type      second_param_type;
0373    typedef typename call_traits<first_type>::reference        first_reference;
0374    typedef typename call_traits<second_type>::reference       second_reference;
0375    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0376    typedef typename call_traits<second_type>::const_reference second_const_reference;
0377 
0378             compressed_pair() : base() {}
0379             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
0380    explicit compressed_pair(first_param_type x) : base(x) {}
0381    explicit compressed_pair(second_param_type y) : base(y) {}
0382 
0383    first_reference       first()       {return base::first();}
0384    first_const_reference first() const {return base::first();}
0385 
0386    second_reference       second()       {return base::second();}
0387    second_const_reference second() const {return base::second();}
0388 
0389    void swap(compressed_pair& y) { base::swap(y); }
0390 };
0391 
0392 // JM
0393 // Partial specialisation for case where T1 == T2:
0394 //
0395 template <class T>
0396 class compressed_pair<T, T>
0397 #ifndef BOOST_UTILITY_DOCS
0398    : private details::compressed_pair_imp<T, T,
0399              ::boost::details::compressed_pair_switch<
0400                     T,
0401                     T,
0402                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
0403                     ::boost::details::compressed_pair_empty<T>::value,
0404                     ::boost::details::compressed_pair_empty<T>::value>::value>
0405 #endif // BOOST_UTILITY_DOCS
0406 {
0407 private:
0408    typedef details::compressed_pair_imp<T, T,
0409              ::boost::details::compressed_pair_switch<
0410                     T,
0411                     T,
0412                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
0413                     ::boost::details::compressed_pair_empty<T>::value,
0414                     ::boost::details::compressed_pair_empty<T>::value>::value> base;
0415 public:
0416    typedef T                                                  first_type;
0417    typedef T                                                  second_type;
0418    typedef typename call_traits<first_type>::param_type       first_param_type;
0419    typedef typename call_traits<second_type>::param_type      second_param_type;
0420    typedef typename call_traits<first_type>::reference        first_reference;
0421    typedef typename call_traits<second_type>::reference       second_reference;
0422    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0423    typedef typename call_traits<second_type>::const_reference second_const_reference;
0424 
0425             compressed_pair() : base() {}
0426             compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
0427 #if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
0428    explicit 
0429 #endif
0430       compressed_pair(first_param_type x) : base(x) {}
0431 
0432    first_reference       first()       {return base::first();}
0433    first_const_reference first() const {return base::first();}
0434 
0435    second_reference       second()       {return base::second();}
0436    second_const_reference second() const {return base::second();}
0437 
0438    void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
0439 };
0440 
0441 template <class T1, class T2>
0442 inline
0443 void
0444 swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
0445 {
0446    x.swap(y);
0447 }
0448 
0449 } // boost
0450 
0451 #ifdef BOOST_MSVC
0452 # pragma warning(pop)
0453 #endif 
0454 
0455 #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
0456