src/sysc/packages/boost/detail/compressed_pair.hpp

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

Generated on Wed Apr 25 13:53:28 2007 for SystemC by  doxygen 1.5.1