mirror of
https://github.com/boostorg/utility.git
synced 2025-06-28 21:41:13 +02:00
Compare commits
1 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
3de4fe6d47 |
@ -1,155 +0,0 @@
|
|||||||
// (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.
|
|
||||||
|
|
||||||
// call_traits: defines typedefs for function usage
|
|
||||||
// (see libs/utility/call_traits.htm)
|
|
||||||
|
|
||||||
/* Release notes:
|
|
||||||
23rd July 2000:
|
|
||||||
Fixed array specialization. (JM)
|
|
||||||
Added Borland specific fixes for reference types
|
|
||||||
(issue raised by Steve Cleary).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_DETAIL_CALL_TRAITS_HPP
|
|
||||||
#define BOOST_DETAIL_CALL_TRAITS_HPP
|
|
||||||
|
|
||||||
#ifndef BOOST_CONFIG_HPP
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#endif
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#include <boost/type_traits/is_arithmetic.hpp>
|
|
||||||
#include <boost/type_traits/is_pointer.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
|
||||||
|
|
||||||
namespace boost{
|
|
||||||
|
|
||||||
namespace detail{
|
|
||||||
|
|
||||||
template <typename T, bool small_>
|
|
||||||
struct ct_imp2
|
|
||||||
{
|
|
||||||
typedef const T& param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct ct_imp2<T, true>
|
|
||||||
{
|
|
||||||
typedef const T param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, bool isp, bool b1>
|
|
||||||
struct ct_imp
|
|
||||||
{
|
|
||||||
typedef const T& param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, bool isp>
|
|
||||||
struct ct_imp<T, isp, true>
|
|
||||||
{
|
|
||||||
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, bool b1>
|
|
||||||
struct ct_imp<T, true, b1>
|
|
||||||
{
|
|
||||||
typedef T const param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct call_traits
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
//
|
|
||||||
// C++ Builder workaround: we should be able to define a compile time
|
|
||||||
// constant and pass that as a single template parameter to ct_imp<T,bool>,
|
|
||||||
// however compiler bugs prevent this - instead pass three bool's to
|
|
||||||
// ct_imp<T,bool,bool,bool> and add an extra partial specialisation
|
|
||||||
// of ct_imp to handle the logic. (JM)
|
|
||||||
typedef typename boost::detail::ct_imp<
|
|
||||||
T,
|
|
||||||
::boost::is_pointer<T>::value,
|
|
||||||
::boost::is_arithmetic<T>::value
|
|
||||||
>::param_type param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct call_traits<T&>
|
|
||||||
{
|
|
||||||
typedef T& value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T& param_type; // hh removed const
|
|
||||||
};
|
|
||||||
|
|
||||||
#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x570 ) )
|
|
||||||
// these are illegal specialisations; cv-qualifies applied to
|
|
||||||
// references have no effect according to [8.3.2p1],
|
|
||||||
// C++ Builder requires them though as it treats cv-qualified
|
|
||||||
// references as distinct types...
|
|
||||||
template <typename T>
|
|
||||||
struct call_traits<T&const>
|
|
||||||
{
|
|
||||||
typedef T& value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T& param_type; // hh removed const
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
struct call_traits<T&volatile>
|
|
||||||
{
|
|
||||||
typedef T& value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T& param_type; // hh removed const
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
struct call_traits<T&const volatile>
|
|
||||||
{
|
|
||||||
typedef T& value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T& param_type; // hh removed const
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
struct call_traits<T [N]>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef T array_type[N];
|
|
||||||
public:
|
|
||||||
// degrades array to pointer:
|
|
||||||
typedef const T* value_type;
|
|
||||||
typedef array_type& reference;
|
|
||||||
typedef const array_type& const_reference;
|
|
||||||
typedef const T* const param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
struct call_traits<const T [N]>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef const T array_type[N];
|
|
||||||
public:
|
|
||||||
// degrades array to pointer:
|
|
||||||
typedef const T* value_type;
|
|
||||||
typedef array_type& reference;
|
|
||||||
typedef const array_type& const_reference;
|
|
||||||
typedef const T* const param_type;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BOOST_DETAIL_CALL_TRAITS_HPP
|
|
@ -1,432 +0,0 @@
|
|||||||
// (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/compressed_pair.htm)
|
|
||||||
//
|
|
||||||
// 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_same.hpp>
|
|
||||||
#include <boost/call_traits.hpp>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
class compressed_pair;
|
|
||||||
|
|
||||||
|
|
||||||
// compressed_pair
|
|
||||||
|
|
||||||
namespace details
|
|
||||||
{
|
|
||||||
// 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>
|
|
||||||
: private ::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>
|
|
||||||
: private ::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>
|
|
||||||
: private ::boost::remove_cv<T1>::type,
|
|
||||||
private ::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
|
|
||||||
// Note does not actually store an instance of T2 at all -
|
|
||||||
// but reuses T1 base class for both first() and second().
|
|
||||||
template <class T1, class T2>
|
|
||||||
class compressed_pair_imp<T1, T2, 4>
|
|
||||||
: private ::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_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // details
|
|
||||||
|
|
||||||
template <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::is_empty<T1>::value,
|
|
||||||
::boost::is_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::is_empty<T1>::value,
|
|
||||||
::boost::is_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::is_empty<T>::value,
|
|
||||||
::boost::is_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::is_empty<T>::value,
|
|
||||||
::boost::is_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>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
|
||||||
{
|
|
||||||
x.swap(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
|||||||
// (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.
|
|
||||||
//
|
|
||||||
// Crippled version for crippled compilers:
|
|
||||||
// see libs/utility/call_traits.htm
|
|
||||||
//
|
|
||||||
|
|
||||||
/* Release notes:
|
|
||||||
01st October 2000:
|
|
||||||
Fixed call_traits on VC6, using "poor man's partial specialisation",
|
|
||||||
using ideas taken from "Generative programming" by Krzysztof Czarnecki
|
|
||||||
& Ulrich Eisenecker.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_OB_CALL_TRAITS_HPP
|
|
||||||
#define BOOST_OB_CALL_TRAITS_HPP
|
|
||||||
|
|
||||||
#ifndef BOOST_CONFIG_HPP
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
|
|
||||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
|
||||||
#endif
|
|
||||||
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
|
|
||||||
#include <boost/type_traits/composite_traits.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost{
|
|
||||||
|
|
||||||
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
|
||||||
//
|
|
||||||
// use member templates to emulate
|
|
||||||
// partial specialisation:
|
|
||||||
//
|
|
||||||
namespace detail{
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct standard_call_traits
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef const T& param_type;
|
|
||||||
};
|
|
||||||
template <class T>
|
|
||||||
struct simple_call_traits
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef const T param_type;
|
|
||||||
};
|
|
||||||
template <class T>
|
|
||||||
struct reference_call_traits
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T reference;
|
|
||||||
typedef T const_reference;
|
|
||||||
typedef T param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool pointer, bool arithmetic, bool reference>
|
|
||||||
struct call_traits_chooser
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef standard_call_traits<T> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct call_traits_chooser<true, false, false>
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef simple_call_traits<T> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct call_traits_chooser<false, false, true>
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef reference_call_traits<T> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool size_is_small>
|
|
||||||
struct call_traits_sizeof_chooser2
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
struct small_rebind
|
|
||||||
{
|
|
||||||
typedef simple_call_traits<T> small_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct call_traits_sizeof_chooser2<false>
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
struct small_rebind
|
|
||||||
{
|
|
||||||
typedef standard_call_traits<T> small_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct call_traits_chooser<false, true, false>
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) };
|
|
||||||
typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser;
|
|
||||||
typedef typename chooser::template small_rebind<T> bound_type;
|
|
||||||
typedef typename bound_type::small_type type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
template <typename T>
|
|
||||||
struct call_traits
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef detail::call_traits_chooser<
|
|
||||||
::boost::is_pointer<T>::value,
|
|
||||||
::boost::is_arithmetic<T>::value,
|
|
||||||
::boost::is_reference<T>::value
|
|
||||||
> chooser;
|
|
||||||
typedef typename chooser::template rebind<T> bound_type;
|
|
||||||
typedef typename bound_type::type call_traits_type;
|
|
||||||
public:
|
|
||||||
typedef typename call_traits_type::value_type value_type;
|
|
||||||
typedef typename call_traits_type::reference reference;
|
|
||||||
typedef typename call_traits_type::const_reference const_reference;
|
|
||||||
typedef typename call_traits_type::param_type param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
//
|
|
||||||
// sorry call_traits is completely non-functional
|
|
||||||
// blame your broken compiler:
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct call_traits
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef const T& param_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // member templates
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BOOST_OB_CALL_TRAITS_HPP
|
|
@ -1,510 +0,0 @@
|
|||||||
// (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;
|
|
||||||
|
|
||||||
compressed_pair_3() : T1(), T2() {}
|
|
||||||
compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
|
|
||||||
template <class A>
|
|
||||||
explicit compressed_pair_3(const A& val)
|
|
||||||
{
|
|
||||||
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
|
|
||||||
}
|
|
||||||
compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
|
|
||||||
: T1(x.first()), T2(x.second()) {}
|
|
||||||
|
|
||||||
first_reference first() { return *this; }
|
|
||||||
first_const_reference first() const { return *this; }
|
|
||||||
|
|
||||||
second_reference second() { return *this; }
|
|
||||||
second_const_reference second() const { return *this; }
|
|
||||||
|
|
||||||
void swap(compressed_pair_3& y)
|
|
||||||
{
|
|
||||||
// no need to swap empty base classes:
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// T1 == T2, and empty
|
|
||||||
template <class T1, class T2>
|
|
||||||
class compressed_pair_4 : T1
|
|
||||||
{
|
|
||||||
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_4() : T1() {}
|
|
||||||
compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
|
|
||||||
// only one single argument constructor since T1 == T2
|
|
||||||
explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
|
|
||||||
compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
|
|
||||||
: T1(x.first()), m_second(x.second()) {}
|
|
||||||
|
|
||||||
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(compressed_pair_4& y)
|
|
||||||
{
|
|
||||||
// no need to swap empty base classes:
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
T2 m_second;
|
|
||||||
};
|
|
||||||
|
|
||||||
// T1 == T2, not empty
|
|
||||||
template <class T1, class T2>
|
|
||||||
class compressed_pair_5
|
|
||||||
{
|
|
||||||
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_5() : _first(), _second() {}
|
|
||||||
compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
|
||||||
// only one single argument constructor since T1 == T2
|
|
||||||
explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
|
|
||||||
compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
|
|
||||||
: _first(c.first()), _second(c.second()) {}
|
|
||||||
|
|
||||||
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_5& y)
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
swap(_first, y._first);
|
|
||||||
swap(_second, y._second);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool e1, bool e2, bool same>
|
|
||||||
struct compressed_pair_chooser
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef compressed_pair_0<T1, T2> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct compressed_pair_chooser<false, true, false>
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef compressed_pair_1<T1, T2> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct compressed_pair_chooser<true, false, false>
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef compressed_pair_2<T1, T2> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct compressed_pair_chooser<true, true, false>
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef compressed_pair_3<T1, T2> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct compressed_pair_chooser<true, true, true>
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef compressed_pair_4<T1, T2> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct compressed_pair_chooser<false, false, true>
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef compressed_pair_5<T1, T2> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct compressed_pair_traits
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
|
|
||||||
typedef typename chooser::template rebind<T1, T2> bound_type;
|
|
||||||
public:
|
|
||||||
typedef typename bound_type::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef typename detail::compressed_pair_traits<T1, T2>::type base_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() : base_type() {}
|
|
||||||
compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
|
|
||||||
template <class A>
|
|
||||||
explicit compressed_pair(const A& x) : base_type(x){}
|
|
||||||
|
|
||||||
first_reference first() { return base_type::first(); }
|
|
||||||
first_const_reference first() const { return base_type::first(); }
|
|
||||||
|
|
||||||
second_reference second() { return base_type::second(); }
|
|
||||||
second_const_reference second() const { return base_type::second(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
|
||||||
{
|
|
||||||
x.swap(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
// no partial specialisation, no member templates:
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
class compressed_pair
|
|
||||||
{
|
|
||||||
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() : _first(), _second() {}
|
|
||||||
compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
|
||||||
explicit compressed_pair(first_param_type x) : _first(x), _second() {}
|
|
||||||
// can't define this in case T1 == T2:
|
|
||||||
// explicit compressed_pair(second_param_type y) : _first(), _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(compressed_pair& y)
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
swap(_first, y._first);
|
|
||||||
swap(_second, y._second);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
|
||||||
{
|
|
||||||
x.swap(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // boost
|
|
||||||
|
|
||||||
#endif // BOOST_OB_COMPRESSED_PAIR_HPP
|
|
||||||
|
|
||||||
|
|
||||||
|
|
458
iterator_adaptor_test.cpp
Normal file
458
iterator_adaptor_test.cpp
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
// Demonstrate and test boost/operators.hpp on std::iterators -------------//
|
||||||
|
|
||||||
|
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
|
// Revision History
|
||||||
|
// 19 Feb 01 Take adavantage of improved iterator_traits to do more tests
|
||||||
|
// on MSVC. Hack around an MSVC-with-STLport internal compiler
|
||||||
|
// error. (David Abrahams)
|
||||||
|
// 11 Feb 01 Added test of operator-> for forward and input iterators.
|
||||||
|
// (Jeremy Siek)
|
||||||
|
// 11 Feb 01 Borland fixes (David Abrahams)
|
||||||
|
// 10 Feb 01 Use new adaptors interface. (David Abrahams)
|
||||||
|
// 10 Feb 01 Use new filter_ interface. (David Abrahams)
|
||||||
|
// 09 Feb 01 Use new reverse_ and indirect_ interfaces. Replace
|
||||||
|
// BOOST_NO_STD_ITERATOR_TRAITS with
|
||||||
|
// BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION to prove we've
|
||||||
|
// normalized to core compiler capabilities (David Abrahams)
|
||||||
|
// 08 Feb 01 Use Jeremy's new make_reverse_iterator form; add more
|
||||||
|
// comprehensive testing. Force-decay array function arguments to
|
||||||
|
// pointers.
|
||||||
|
// 07 Feb 01 Added tests for the make_xxx_iterator() helper functions.
|
||||||
|
// (Jeremy Siek)
|
||||||
|
// 07 Feb 01 Replaced use of xxx_pair_generator with xxx_generator where
|
||||||
|
// possible (which was all but the projection iterator).
|
||||||
|
// (Jeremy Siek)
|
||||||
|
// 06 Feb 01 Removed now-defaulted template arguments where possible
|
||||||
|
// Updated names to correspond to new generator naming convention.
|
||||||
|
// Added a trivial test for make_transform_iterator().
|
||||||
|
// Gave traits for const iterators a mutable value_type, per std.
|
||||||
|
// Resurrected my original tests for indirect iterators.
|
||||||
|
// (David Abrahams)
|
||||||
|
// 04 Feb 01 Fix for compilers without standard iterator_traits
|
||||||
|
// (David Abrahams)
|
||||||
|
// 13 Jun 00 Added const version of the iterator tests (Jeremy Siek)
|
||||||
|
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <boost/iterator_adaptors.hpp>
|
||||||
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
#include <boost/pending/integer_range.hpp>
|
||||||
|
#include <boost/concept_archetype.hpp>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||||
|
|
||||||
|
using boost::dummyT;
|
||||||
|
|
||||||
|
struct my_iter_traits {
|
||||||
|
typedef dummyT value_type;
|
||||||
|
typedef dummyT* pointer;
|
||||||
|
typedef dummyT& reference;
|
||||||
|
typedef my_iterator_tag iterator_category;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct my_const_iter_traits {
|
||||||
|
typedef dummyT value_type;
|
||||||
|
typedef const dummyT* pointer;
|
||||||
|
typedef const dummyT& reference;
|
||||||
|
typedef my_iterator_tag iterator_category;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::iterator_adaptor<dummyT*,
|
||||||
|
boost::default_iterator_policies, dummyT> my_iterator;
|
||||||
|
|
||||||
|
typedef boost::iterator_adaptor<const dummyT*,
|
||||||
|
boost::default_iterator_policies, const dummyT> const_my_iterator;
|
||||||
|
|
||||||
|
|
||||||
|
struct mult_functor {
|
||||||
|
typedef int result_type;
|
||||||
|
typedef int argument_type;
|
||||||
|
// Functors used with transform_iterator must be
|
||||||
|
// DefaultConstructible, as the transform_iterator must be
|
||||||
|
// DefaultConstructible to satisfy the requirements for
|
||||||
|
// TrivialIterator.
|
||||||
|
mult_functor() { }
|
||||||
|
mult_functor(int aa) : a(aa) { }
|
||||||
|
int operator()(int b) const { return a * b; }
|
||||||
|
int a;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Pair>
|
||||||
|
struct select1st_
|
||||||
|
: public std::unary_function<Pair, typename Pair::first_type>
|
||||||
|
{
|
||||||
|
const typename Pair::first_type& operator()(const Pair& x) const {
|
||||||
|
return x.first;
|
||||||
|
}
|
||||||
|
typename Pair::first_type& operator()(Pair& x) const {
|
||||||
|
return x.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct one_or_four {
|
||||||
|
bool operator()(dummyT x) const {
|
||||||
|
return x.foo() == 1 || x.foo() == 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::deque<int> storage;
|
||||||
|
typedef std::deque<int*> pointer_deque;
|
||||||
|
typedef std::set<storage::iterator> iterator_set;
|
||||||
|
|
||||||
|
void more_indirect_iterator_tests()
|
||||||
|
{
|
||||||
|
// For some reason all heck breaks loose in the compiler under these conditions.
|
||||||
|
#if !defined(BOOST_MSVC) || !defined(__STL_DEBUG)
|
||||||
|
storage store(1000);
|
||||||
|
std::generate(store.begin(), store.end(), rand);
|
||||||
|
|
||||||
|
pointer_deque ptr_deque;
|
||||||
|
iterator_set iter_set;
|
||||||
|
|
||||||
|
for (storage::iterator p = store.begin(); p != store.end(); ++p)
|
||||||
|
{
|
||||||
|
ptr_deque.push_back(&*p);
|
||||||
|
iter_set.insert(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_pair_generator<
|
||||||
|
pointer_deque::iterator
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, int
|
||||||
|
#endif
|
||||||
|
> IndirectDeque;
|
||||||
|
|
||||||
|
IndirectDeque::iterator db(ptr_deque.begin());
|
||||||
|
IndirectDeque::iterator de(ptr_deque.end());
|
||||||
|
assert(static_cast<std::size_t>(de - db) == store.size());
|
||||||
|
assert(db + store.size() == de);
|
||||||
|
IndirectDeque::const_iterator dci(db);
|
||||||
|
assert(db == dci);
|
||||||
|
assert(dci == db);
|
||||||
|
assert(dci != de);
|
||||||
|
assert(dci < de);
|
||||||
|
assert(dci <= de);
|
||||||
|
assert(de >= dci);
|
||||||
|
assert(de > dci);
|
||||||
|
dci = de;
|
||||||
|
assert(dci == de);
|
||||||
|
|
||||||
|
boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin()));
|
||||||
|
|
||||||
|
*db = 999;
|
||||||
|
assert(store.front() == 999);
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<
|
||||||
|
iterator_set::iterator
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, int
|
||||||
|
#endif
|
||||||
|
>::type indirect_set_iterator;
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<
|
||||||
|
iterator_set::iterator,
|
||||||
|
const int
|
||||||
|
>::type const_indirect_set_iterator;
|
||||||
|
|
||||||
|
indirect_set_iterator sb(iter_set.begin());
|
||||||
|
indirect_set_iterator se(iter_set.end());
|
||||||
|
const_indirect_set_iterator sci(iter_set.begin());
|
||||||
|
assert(sci == sb);
|
||||||
|
assert(sci != se);
|
||||||
|
sci = se;
|
||||||
|
assert(sci == se);
|
||||||
|
|
||||||
|
*boost::prior(se) = 888;
|
||||||
|
assert(store.back() == 888);
|
||||||
|
assert(std::equal(sb, se, store.begin()));
|
||||||
|
|
||||||
|
boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]);
|
||||||
|
assert(std::equal(db, de, store.begin()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
|
||||||
|
dummyT(3), dummyT(4), dummyT(5) };
|
||||||
|
const int N = sizeof(array)/sizeof(dummyT);
|
||||||
|
|
||||||
|
// sanity check, if this doesn't pass the test is buggy
|
||||||
|
boost::random_access_iterator_test(array,N,array);
|
||||||
|
|
||||||
|
// Check that the policy concept checks and the default policy
|
||||||
|
// implementation match up.
|
||||||
|
boost::function_requires<
|
||||||
|
boost::RandomAccessIteratorPoliciesConcept<
|
||||||
|
boost::default_iterator_policies, int*,
|
||||||
|
boost::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t,
|
||||||
|
int*, int&>
|
||||||
|
> >();
|
||||||
|
|
||||||
|
// Test the iterator_adaptor
|
||||||
|
{
|
||||||
|
my_iterator i(array);
|
||||||
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
|
||||||
|
const_my_iterator j(array);
|
||||||
|
boost::random_access_iterator_test(j, N, array);
|
||||||
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator
|
||||||
|
{
|
||||||
|
int x[N], y[N];
|
||||||
|
for (int k = 0; k < N; ++k)
|
||||||
|
x[k] = k;
|
||||||
|
std::copy(x, x + N, y);
|
||||||
|
|
||||||
|
for (int k2 = 0; k2 < N; ++k2)
|
||||||
|
x[k2] = x[k2] * 2;
|
||||||
|
|
||||||
|
boost::transform_iterator_generator<mult_functor, int*>::type
|
||||||
|
i(y, mult_functor(2));
|
||||||
|
boost::input_iterator_test(i, x[0], x[1]);
|
||||||
|
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_functor(2)), x[0], x[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test indirect_iterator_generator
|
||||||
|
{
|
||||||
|
dummyT* ptr[N];
|
||||||
|
for (int k = 0; k < N; ++k)
|
||||||
|
ptr[k] = array + k;
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<dummyT**
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, dummyT
|
||||||
|
#endif
|
||||||
|
>::type indirect_iterator;
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<dummyT**, const dummyT>::type const_indirect_iterator;
|
||||||
|
|
||||||
|
indirect_iterator i(ptr);
|
||||||
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check operator->
|
||||||
|
assert((*i).m_x == i->foo());
|
||||||
|
|
||||||
|
const_indirect_iterator j(ptr);
|
||||||
|
boost::random_access_iterator_test(j, N, array);
|
||||||
|
|
||||||
|
dummyT*const* const_ptr = ptr;
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
|
||||||
|
#endif
|
||||||
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
|
|
||||||
|
more_indirect_iterator_tests();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test projection_iterator_pair_generator
|
||||||
|
{
|
||||||
|
typedef std::pair<dummyT,dummyT> Pair;
|
||||||
|
Pair pair_array[N];
|
||||||
|
for (int k = 0; k < N; ++k)
|
||||||
|
pair_array[k].first = array[k];
|
||||||
|
|
||||||
|
typedef boost::projection_iterator_pair_generator<select1st_<Pair>,
|
||||||
|
Pair*, const Pair*
|
||||||
|
> Projection;
|
||||||
|
|
||||||
|
Projection::iterator i(pair_array);
|
||||||
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
|
||||||
|
boost::random_access_iterator_test(boost::make_projection_iterator(pair_array, select1st_<Pair>()), N, array);
|
||||||
|
boost::random_access_iterator_test(boost::make_projection_iterator< select1st_<Pair> >(pair_array), N, array);
|
||||||
|
|
||||||
|
Projection::const_iterator j(pair_array);
|
||||||
|
boost::random_access_iterator_test(j, N, array);
|
||||||
|
|
||||||
|
boost::random_access_iterator_test(boost::make_const_projection_iterator(pair_array, select1st_<Pair>()), N, array);
|
||||||
|
boost::random_access_iterator_test(boost::make_const_projection_iterator<select1st_<Pair> >(pair_array), N, array);
|
||||||
|
|
||||||
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test reverse_iterator_generator
|
||||||
|
{
|
||||||
|
dummyT reversed[N];
|
||||||
|
std::copy(array, array + N, reversed);
|
||||||
|
std::reverse(reversed, reversed + N);
|
||||||
|
|
||||||
|
typedef boost::reverse_iterator_generator<dummyT*
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, dummyT
|
||||||
|
#endif
|
||||||
|
>::type reverse_iterator;
|
||||||
|
|
||||||
|
reverse_iterator i(reversed + N);
|
||||||
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef boost::reverse_iterator_generator<const dummyT*
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, const dummyT
|
||||||
|
#endif
|
||||||
|
>::type const_reverse_iterator;
|
||||||
|
|
||||||
|
const_reverse_iterator j(reversed + N);
|
||||||
|
boost::random_access_iterator_test(j, N, array);
|
||||||
|
|
||||||
|
const dummyT* const_reversed = reversed;
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test reverse_iterator_generator again, with traits fully deducible on all platforms
|
||||||
|
{
|
||||||
|
std::deque<dummyT> reversed_container;
|
||||||
|
std::reverse_copy(array, array + N, std::back_inserter(reversed_container));
|
||||||
|
const std::deque<dummyT>::iterator reversed = reversed_container.begin();
|
||||||
|
|
||||||
|
|
||||||
|
typedef boost::reverse_iterator_generator<
|
||||||
|
std::deque<dummyT>::iterator>::type reverse_iterator;
|
||||||
|
typedef boost::reverse_iterator_generator<
|
||||||
|
std::deque<dummyT>::const_iterator, const dummyT>::type const_reverse_iterator;
|
||||||
|
|
||||||
|
// MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation
|
||||||
|
// (e.g. "reversed + N") is used in the constructor below.
|
||||||
|
const std::deque<dummyT>::iterator finish = reversed_container.end();
|
||||||
|
reverse_iterator i(finish);
|
||||||
|
|
||||||
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);
|
||||||
|
|
||||||
|
const_reverse_iterator j = reverse_iterator(finish);
|
||||||
|
boost::random_access_iterator_test(j, N, array);
|
||||||
|
|
||||||
|
const std::deque<dummyT>::const_iterator const_reversed = reversed;
|
||||||
|
boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
|
||||||
|
|
||||||
|
// Many compilers' builtin deque iterators don't interoperate well, though
|
||||||
|
// STLport fixes that problem.
|
||||||
|
#if defined(__SGI_STL_PORT) || !defined(__GNUC__) && !defined(__BORLANDC__) && !defined(BOOST_MSVC)
|
||||||
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test integer_range's iterators
|
||||||
|
{
|
||||||
|
int int_array[] = { 0, 1, 2, 3, 4, 5 };
|
||||||
|
boost::integer_range<int> r(0, 5);
|
||||||
|
boost::random_access_iterator_test(r.begin(), r.size(), int_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test filter iterator
|
||||||
|
{
|
||||||
|
// Using typedefs for filter_gen::type and filter_gen::policies_type
|
||||||
|
// confused Borland terribly.
|
||||||
|
typedef boost::detail::non_bidirectional_category<dummyT*>::type category;
|
||||||
|
|
||||||
|
typedef ::boost::filter_iterator_generator<one_or_four, dummyT*
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, dummyT
|
||||||
|
#endif
|
||||||
|
>::type filter_iter;
|
||||||
|
|
||||||
|
filter_iter i(array, filter_iter::policies_type(one_or_four(), array + N));
|
||||||
|
boost::forward_iterator_test(i, dummyT(1), dummyT(4));
|
||||||
|
|
||||||
|
enum { is_forward = boost::is_same<
|
||||||
|
filter_iter::iterator_category,
|
||||||
|
std::forward_iterator_tag>::value };
|
||||||
|
BOOST_STATIC_ASSERT(is_forward);
|
||||||
|
|
||||||
|
// On compilers not supporting partial specialization, we can do more type
|
||||||
|
// deduction with deque iterators than with pointers... unless the library
|
||||||
|
// is broken ;-(
|
||||||
|
#if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT)
|
||||||
|
std::deque<dummyT> array2;
|
||||||
|
std::copy(array+0, array+N, std::back_inserter(array2));
|
||||||
|
boost::forward_iterator_test(
|
||||||
|
boost::make_filter_iterator(array2.begin(), array2.end(), one_or_four()),
|
||||||
|
dummyT(1), dummyT(4));
|
||||||
|
|
||||||
|
boost::forward_iterator_test(
|
||||||
|
boost::make_filter_iterator<one_or_four>(array2.begin(), array2.end()),
|
||||||
|
dummyT(1), dummyT(4));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_MSVC) // This just freaks MSVC out completely
|
||||||
|
boost::forward_iterator_test(
|
||||||
|
boost::make_filter_iterator<one_or_four>(
|
||||||
|
boost::make_reverse_iterator(array2.end()),
|
||||||
|
boost::make_reverse_iterator(array2.begin())
|
||||||
|
),
|
||||||
|
dummyT(4), dummyT(1));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
boost::forward_iterator_test(
|
||||||
|
boost::make_filter_iterator(array+0, array+N, one_or_four()),
|
||||||
|
dummyT(1), dummyT(4));
|
||||||
|
|
||||||
|
boost::forward_iterator_test(
|
||||||
|
boost::make_filter_iterator<one_or_four>(array, array + N),
|
||||||
|
dummyT(1), dummyT(4));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// check operator-> with a forward iterator
|
||||||
|
{
|
||||||
|
boost::forward_iterator_archetype<dummyT> forward_iter;
|
||||||
|
typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>,
|
||||||
|
boost::default_iterator_policies,
|
||||||
|
dummyT, const dummyT&, const dummyT*,
|
||||||
|
std::forward_iterator_tag, std::ptrdiff_t> adaptor_type;
|
||||||
|
adaptor_type i(forward_iter);
|
||||||
|
if (0) // don't do this, just make sure it compiles
|
||||||
|
assert((*i).m_x == i->foo());
|
||||||
|
}
|
||||||
|
// check operator-> with an input iterator
|
||||||
|
{
|
||||||
|
boost::input_iterator_archetype<dummyT> input_iter;
|
||||||
|
typedef boost::iterator_adaptor<boost::input_iterator_archetype<dummyT>,
|
||||||
|
boost::default_iterator_policies,
|
||||||
|
dummyT, const dummyT&, const dummyT*,
|
||||||
|
std::input_iterator_tag, std::ptrdiff_t> adaptor_type;
|
||||||
|
adaptor_type i(input_iter);
|
||||||
|
if (0) // don't do this, just make sure it compiles
|
||||||
|
assert((*i).m_x == i->foo());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user