Back to home page

EIC code displayed by LXR

 
 

    


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

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 //  see libs/utility/compressed_pair.hpp
0008 //
0009 /* Release notes:
0010    20 Jan 2001:
0011         Fixed obvious bugs (David Abrahams)
0012    07 Oct 2000:
0013       Added better single argument constructor support.
0014    03 Oct 2000:
0015       Added VC6 support (JM).
0016    23rd July 2000:
0017       Additional comments added. (JM)
0018    Jan 2000:
0019       Original version: this version crippled for use with crippled compilers
0020       - John Maddock Jan 2000.
0021 */
0022 
0023 #ifndef BOOST_UTILITY_DOCS
0024 #ifndef BOOST_OB_COMPRESSED_PAIR_HPP
0025 #define BOOST_OB_COMPRESSED_PAIR_HPP
0026 
0027 
0028 #include <algorithm>
0029 #ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
0030 #include <boost/type_traits/object_traits.hpp>
0031 #endif
0032 #ifndef BOOST_SAME_TRAITS_HPP
0033 #include <boost/type_traits/same_traits.hpp>
0034 #endif
0035 #ifndef BOOST_CALL_TRAITS_HPP
0036 #include <boost/call_traits.hpp>
0037 #endif
0038 
0039 namespace boost
0040 {
0041 #ifdef BOOST_MSVC6_MEMBER_TEMPLATES
0042 //
0043 // use member templates to emulate
0044 // partial specialisation.  Note that due to
0045 // problems with overload resolution with VC6
0046 // each of the compressed_pair versions that follow
0047 // have one template single-argument constructor
0048 // in place of two specific constructors:
0049 //
0050 
0051 template <class T1, class T2>
0052 class compressed_pair;
0053 
0054 namespace detail{
0055 
0056 template <class A, class T1, class T2>
0057 struct best_conversion_traits
0058 {
0059    typedef char one;
0060    typedef char (&two)[2];
0061    static A a;
0062    static one test(T1);
0063    static two test(T2);
0064 
0065    enum { value = sizeof(test(a)) };
0066 };
0067 
0068 template <int>
0069 struct init_one;
0070 
0071 template <>
0072 struct init_one<1>
0073 {
0074    template <class A, class T1, class T2>
0075    static void init(const A& a, T1* p1, T2*)
0076    {
0077       *p1 = a;
0078    }
0079 };
0080 
0081 template <>
0082 struct init_one<2>
0083 {
0084    template <class A, class T1, class T2>
0085    static void init(const A& a, T1*, T2* p2)
0086    {
0087       *p2 = a;
0088    }
0089 };
0090 
0091 
0092 // T1 != T2, both non-empty
0093 template <class T1, class T2>
0094 class compressed_pair_0
0095 {
0096 private:
0097    T1 _first;
0098    T2 _second;
0099 public:
0100    typedef T1                                                 first_type;
0101    typedef T2                                                 second_type;
0102    typedef typename call_traits<first_type>::param_type       first_param_type;
0103    typedef typename call_traits<second_type>::param_type      second_param_type;
0104    typedef typename call_traits<first_type>::reference        first_reference;
0105    typedef typename call_traits<second_type>::reference       second_reference;
0106    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0107    typedef typename call_traits<second_type>::const_reference second_const_reference;
0108 
0109             compressed_pair_0() : _first(), _second() {}
0110             compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
0111    template <class A>
0112    explicit compressed_pair_0(const A& val)
0113    {
0114       init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
0115    }
0116    compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
0117       : _first(x.first()), _second(x.second()) {}
0118 
0119 #if 0
0120   compressed_pair_0& operator=(const compressed_pair_0& x) {
0121     cout << "assigning compressed pair 0" << endl;
0122     _first = x._first;
0123     _second = x._second;
0124     cout << "finished assigning compressed pair 0" << endl;
0125     return *this;
0126   }
0127 #endif
0128 
0129    first_reference       first()       { return _first; }
0130    first_const_reference first() const { return _first; }
0131 
0132    second_reference       second()       { return _second; }
0133    second_const_reference second() const { return _second; }
0134 
0135    void swap(compressed_pair_0& y)
0136    {
0137       using std::swap;
0138       swap(_first, y._first);
0139       swap(_second, y._second);
0140    }
0141 };
0142 
0143 // T1 != T2, T2 empty
0144 template <class T1, class T2>
0145 class compressed_pair_1 : T2
0146 {
0147 private:
0148    T1 _first;
0149 public:
0150    typedef T1                                                 first_type;
0151    typedef T2                                                 second_type;
0152    typedef typename call_traits<first_type>::param_type       first_param_type;
0153    typedef typename call_traits<second_type>::param_type      second_param_type;
0154    typedef typename call_traits<first_type>::reference        first_reference;
0155    typedef typename call_traits<second_type>::reference       second_reference;
0156    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0157    typedef typename call_traits<second_type>::const_reference second_const_reference;
0158 
0159             compressed_pair_1() : T2(), _first() {}
0160             compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
0161 
0162    template <class A>
0163    explicit compressed_pair_1(const A& val)
0164    {
0165       init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
0166    }
0167 
0168    compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
0169       : T2(x.second()), _first(x.first()) {}
0170 
0171    first_reference       first()       { return _first; }
0172    first_const_reference first() const { return _first; }
0173 
0174    second_reference       second()       { return *this; }
0175    second_const_reference second() const { return *this; }
0176 
0177    void swap(compressed_pair_1& y)
0178    {
0179       // no need to swap empty base class:
0180       using std::swap;
0181       swap(_first, y._first);
0182    }
0183 };
0184 
0185 // T1 != T2, T1 empty
0186 template <class T1, class T2>
0187 class compressed_pair_2 : T1
0188 {
0189 private:
0190    T2 _second;
0191 public:
0192    typedef T1                                                 first_type;
0193    typedef T2                                                 second_type;
0194    typedef typename call_traits<first_type>::param_type       first_param_type;
0195    typedef typename call_traits<second_type>::param_type      second_param_type;
0196    typedef typename call_traits<first_type>::reference        first_reference;
0197    typedef typename call_traits<second_type>::reference       second_reference;
0198    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0199    typedef typename call_traits<second_type>::const_reference second_const_reference;
0200 
0201             compressed_pair_2() : T1(), _second() {}
0202             compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
0203    template <class A>
0204    explicit compressed_pair_2(const A& val)
0205    {
0206       init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
0207    }
0208    compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
0209       : T1(x.first()), _second(x.second()) {}
0210 
0211 #if 0
0212   compressed_pair_2& operator=(const compressed_pair_2& x) {
0213     cout << "assigning compressed pair 2" << endl;
0214     T1::operator=(x);
0215     _second = x._second;
0216     cout << "finished assigning compressed pair 2" << endl;
0217     return *this;
0218   }
0219 #endif
0220    first_reference       first()       { return *this; }
0221    first_const_reference first() const { return *this; }
0222 
0223    second_reference       second()       { return _second; }
0224    second_const_reference second() const { return _second; }
0225 
0226    void swap(compressed_pair_2& y)
0227    {
0228       // no need to swap empty base class:
0229       using std::swap;
0230       swap(_second, y._second);
0231    }
0232 };
0233 
0234 // T1 != T2, both empty
0235 template <class T1, class T2>
0236 class compressed_pair_3 : T1, T2
0237 {
0238 public:
0239    typedef T1                                                 first_type;
0240    typedef T2                                                 second_type;
0241    typedef typename call_traits<first_type>::param_type       first_param_type;
0242    typedef typename call_traits<second_type>::param_type      second_param_type;
0243    typedef typename call_traits<first_type>::reference        first_reference;
0244    typedef typename call_traits<second_type>::reference       second_reference;
0245    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0246    typedef typename call_traits<second_type>::const_reference second_const_reference;
0247 
0248             compressed_pair_3() : T1(), T2() {}
0249             compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
0250    template <class A>
0251    explicit compressed_pair_3(const A& val)
0252    {
0253       init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
0254    }
0255    compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
0256       : T1(x.first()), T2(x.second()) {}
0257 
0258    first_reference       first()       { return *this; }
0259    first_const_reference first() const { return *this; }
0260 
0261    second_reference       second()       { return *this; }
0262    second_const_reference second() const { return *this; }
0263 
0264    void swap(compressed_pair_3& y)
0265    {
0266       // no need to swap empty base classes:
0267    }
0268 };
0269 
0270 // T1 == T2, and empty
0271 template <class T1, class T2>
0272 class compressed_pair_4 : T1
0273 {
0274 public:
0275    typedef T1                                                 first_type;
0276    typedef T2                                                 second_type;
0277    typedef typename call_traits<first_type>::param_type       first_param_type;
0278    typedef typename call_traits<second_type>::param_type      second_param_type;
0279    typedef typename call_traits<first_type>::reference        first_reference;
0280    typedef typename call_traits<second_type>::reference       second_reference;
0281    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0282    typedef typename call_traits<second_type>::const_reference second_const_reference;
0283 
0284             compressed_pair_4() : T1() {}
0285             compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
0286    // only one single argument constructor since T1 == T2
0287    explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
0288    compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
0289       : T1(x.first()), m_second(x.second()) {}
0290 
0291    first_reference       first()       { return *this; }
0292    first_const_reference first() const { return *this; }
0293 
0294    second_reference       second()       { return m_second; }
0295    second_const_reference second() const { return m_second; }
0296 
0297    void swap(compressed_pair_4& y)
0298    {
0299       // no need to swap empty base classes:
0300    }
0301 private:
0302    T2 m_second;
0303 };
0304 
0305 // T1 == T2, not empty
0306 template <class T1, class T2>
0307 class compressed_pair_5
0308 {
0309 private:
0310    T1 _first;
0311    T2 _second;
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_5() : _first(), _second() {}
0323             compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
0324    // only one single argument constructor since T1 == T2
0325    explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
0326    compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c) 
0327       : _first(c.first()), _second(c.second()) {}
0328 
0329    first_reference       first()       { return _first; }
0330    first_const_reference first() const { return _first; }
0331 
0332    second_reference       second()       { return _second; }
0333    second_const_reference second() const { return _second; }
0334 
0335    void swap(compressed_pair_5& y)
0336    {
0337       using std::swap;
0338       swap(_first, y._first);
0339       swap(_second, y._second);
0340    }
0341 };
0342 
0343 template <bool e1, bool e2, bool same>
0344 struct compressed_pair_chooser
0345 {
0346    template <class T1, class T2>
0347    struct rebind
0348    {
0349       typedef compressed_pair_0<T1, T2> type;
0350    };
0351 };
0352 
0353 template <>
0354 struct compressed_pair_chooser<false, true, false>
0355 {
0356    template <class T1, class T2>
0357    struct rebind
0358    {
0359       typedef compressed_pair_1<T1, T2> type;
0360    };
0361 };
0362 
0363 template <>
0364 struct compressed_pair_chooser<true, false, false>
0365 {
0366    template <class T1, class T2>
0367    struct rebind
0368    {
0369       typedef compressed_pair_2<T1, T2> type;
0370    };
0371 };
0372 
0373 template <>
0374 struct compressed_pair_chooser<true, true, false>
0375 {
0376    template <class T1, class T2>
0377    struct rebind
0378    {
0379       typedef compressed_pair_3<T1, T2> type;
0380    };
0381 };
0382 
0383 template <>
0384 struct compressed_pair_chooser<true, true, true>
0385 {
0386    template <class T1, class T2>
0387    struct rebind
0388    {
0389       typedef compressed_pair_4<T1, T2> type;
0390    };
0391 };
0392 
0393 template <>
0394 struct compressed_pair_chooser<false, false, true>
0395 {
0396    template <class T1, class T2>
0397    struct rebind
0398    {
0399       typedef compressed_pair_5<T1, T2> type;
0400    };
0401 };
0402 
0403 template <class T1, class T2>
0404 struct compressed_pair_traits
0405 {
0406 private:
0407    typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
0408    typedef typename chooser::template rebind<T1, T2> bound_type;
0409 public:
0410    typedef typename bound_type::type type;
0411 };
0412 
0413 } // namespace detail
0414 
0415 template <class T1, class T2>
0416 class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
0417 {
0418 private:
0419    typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
0420 public:
0421    typedef T1                                                 first_type;
0422    typedef T2                                                 second_type;
0423    typedef typename call_traits<first_type>::param_type       first_param_type;
0424    typedef typename call_traits<second_type>::param_type      second_param_type;
0425    typedef typename call_traits<first_type>::reference        first_reference;
0426    typedef typename call_traits<second_type>::reference       second_reference;
0427    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0428    typedef typename call_traits<second_type>::const_reference second_const_reference;
0429 
0430             compressed_pair() : base_type() {}
0431             compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
0432    template <class A>
0433    explicit compressed_pair(const A& x) : base_type(x){}
0434 
0435    first_reference       first()       { return base_type::first(); }
0436    first_const_reference first() const { return base_type::first(); }
0437 
0438    second_reference       second()       { return base_type::second(); }
0439    second_const_reference second() const { return base_type::second(); }
0440 };
0441 
0442 template <class T1, class T2>
0443 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
0444 {
0445    x.swap(y);
0446 }
0447 
0448 #else
0449 // no partial specialisation, no member templates:
0450 
0451 template <class T1, class T2>
0452 class compressed_pair
0453 {
0454 private:
0455    T1 _first;
0456    T2 _second;
0457 public:
0458    typedef T1                                                 first_type;
0459    typedef T2                                                 second_type;
0460    typedef typename call_traits<first_type>::param_type       first_param_type;
0461    typedef typename call_traits<second_type>::param_type      second_param_type;
0462    typedef typename call_traits<first_type>::reference        first_reference;
0463    typedef typename call_traits<second_type>::reference       second_reference;
0464    typedef typename call_traits<first_type>::const_reference  first_const_reference;
0465    typedef typename call_traits<second_type>::const_reference second_const_reference;
0466 
0467             compressed_pair() : _first(), _second() {}
0468             compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
0469    explicit compressed_pair(first_param_type x) : _first(x), _second() {}
0470    // can't define this in case T1 == T2:
0471    // explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
0472 
0473    first_reference       first()       { return _first; }
0474    first_const_reference first() const { return _first; }
0475 
0476    second_reference       second()       { return _second; }
0477    second_const_reference second() const { return _second; }
0478 
0479    void swap(compressed_pair& y)
0480    {
0481       using std::swap;
0482       swap(_first, y._first);
0483       swap(_second, y._second);
0484    }
0485 };
0486 
0487 template <class T1, class T2>
0488 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
0489 {
0490    x.swap(y);
0491 }
0492 
0493 #endif
0494 
0495 } // boost
0496 
0497 #endif // BOOST_OB_COMPRESSED_PAIR_HPP
0498 #endif // BOOST_UTILITY_DOCS