ob_compressed_pair.hpp

来自「support vector clustering for vc++」· HPP 代码 · 共 511 行 · 第 1/2 页

HPP
511
字号
//  (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.
//  see libs/utility/compressed_pair.hpp
//
/* Release notes:
   20 Jan 2001:
        Fixed obvious bugs (David Abrahams)
   07 Oct 2000:
      Added better single argument constructor support.
   03 Oct 2000:
      Added VC6 support (JM).
   23rd July 2000:
      Additional comments added. (JM)
   Jan 2000:
      Original version: this version crippled for use with crippled compilers
      - John Maddock Jan 2000.
*/


#ifndef BOOST_OB_COMPRESSED_PAIR_HPP
#define BOOST_OB_COMPRESSED_PAIR_HPP

#include <algorithm>
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
#include <boost/type_traits/object_traits.hpp>
#endif
#ifndef BOOST_SAME_TRAITS_HPP
#include <boost/type_traits/same_traits.hpp>
#endif
#ifndef BOOST_CALL_TRAITS_HPP
#include <boost/call_traits.hpp>
#endif

namespace boost
{
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
//
// use member templates to emulate
// partial specialisation.  Note that due to
// problems with overload resolution with VC6
// each of the compressed_pair versions that follow
// have one template single-argument constructor
// in place of two specific constructors:
//

template <class T1, class T2>
class compressed_pair;

namespace detail{

template <class A, class T1, class T2>
struct best_conversion_traits
{
   typedef char one;
   typedef char (&two)[2];
   static A a;
   static one test(T1);
   static two test(T2);

   enum { value = sizeof(test(a)) };
};

template <int>
struct init_one;

template <>
struct init_one<1>
{
   template <class A, class T1, class T2>
   static void init(const A& a, T1* p1, T2*)
   {
      *p1 = a;
   }
};

template <>
struct init_one<2>
{
   template <class A, class T1, class T2>
   static void init(const A& a, T1*, T2* p2)
   {
      *p2 = a;
   }
};


// T1 != T2, both non-empty
template <class T1, class T2>
class compressed_pair_0
{
private:
   T1 _first;
   T2 _second;
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_0() : _first(), _second() {}
            compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
   template <class A>
   explicit compressed_pair_0(const A& val)
   {
      init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
   }
   compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
      : _first(x.first()), _second(x.second()) {}

#if 0
  compressed_pair_0& operator=(const compressed_pair_0& x) {
    cout << "assigning compressed pair 0" << endl;
    _first = x._first;
    _second = x._second;
    cout << "finished assigning compressed pair 0" << endl;
    return *this;
  }
#endif

   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(compressed_pair_0& y)
   {
      using std::swap;
      swap(_first, y._first);
      swap(_second, y._second);
   }
};

// T1 != T2, T2 empty
template <class T1, class T2>
class compressed_pair_1 : T2
{
private:
   T1 _first;
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_1() : T2(), _first() {}
            compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}

   template <class A>
   explicit compressed_pair_1(const A& val)
   {
      init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
   }

   compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
      : T2(x.second()), _first(x.first()) {}

#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
  // Total weirdness. If the assignment to _first is moved after
  // the call to the inherited operator=, then this breaks graph/test/graph.cpp
  // by way of iterator_adaptor.
  compressed_pair_1& operator=(const compressed_pair_1& x) {
    _first = x._first;
    T2::operator=(x);
    return *this;
  }
#endif

   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(compressed_pair_1& y)
   {
      // no need to swap empty base class:
      using std::swap;
      swap(_first, y._first);
   }
};

// T1 != T2, T1 empty
template <class T1, class T2>
class compressed_pair_2 : T1
{
private:
   T2 _second;
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_2() : T1(), _second() {}
            compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
   template <class A>
   explicit compressed_pair_2(const A& val)
   {
      init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
   }
   compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
      : T1(x.first()), _second(x.second()) {}

#if 0
  compressed_pair_2& operator=(const compressed_pair_2& x) {
    cout << "assigning compressed pair 2" << endl;
    T1::operator=(x);
    _second = x._second;
    cout << "finished assigning compressed pair 2" << endl;
    return *this;
  }
#endif
   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(compressed_pair_2& y)
   {
      // no need to swap empty base class:
      using std::swap;
      swap(_second, y._second);
   }
};

// T1 != T2, both empty
template <class T1, class T2>
class compressed_pair_3 : T1, T2
{
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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?