mirror of
https://github.com/boostorg/utility.git
synced 2025-10-05 13:30:55 +02:00
Compare commits
110 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
3de4fe6d47 | ||
|
a5adbbfd5f | ||
|
a19d13f123 | ||
|
78886ab383 | ||
|
168012b465 | ||
|
d9d58ea66e | ||
|
56f5f6e8d5 | ||
|
3cb6420eda | ||
|
60be2c1186 | ||
|
ed210f6b2c | ||
|
029bc59d74 | ||
|
961c08a82f | ||
|
7ee484c614 | ||
|
05c6fbbf99 | ||
|
91078b7f7a | ||
|
20d804afc4 | ||
|
c21f6d1cbf | ||
|
393e79c1fd | ||
|
8b92c8a085 | ||
|
ff73dd94c9 | ||
|
af43904f38 | ||
|
485074f265 | ||
|
2e0ee55b5e | ||
|
e9105d32cb | ||
|
964d23f68c | ||
|
be5aaaae7b | ||
|
bf13bd7b3f | ||
|
352e392fcb | ||
|
083b1b02df | ||
|
648c6240a2 | ||
|
60cab840cb | ||
|
83a4380dab | ||
|
de84fe8d98 | ||
|
ed3cbfdb8e | ||
|
fda44ca17d | ||
|
272025bb07 | ||
|
8e92bcf1b2 | ||
|
84f1ffdefe | ||
|
7e25450054 | ||
|
4a563fa266 | ||
|
aa4c0ec000 | ||
|
e1ecfbdc43 | ||
|
a4e122a82e | ||
|
93216e8fb7 | ||
|
16272c210d | ||
|
e104b00da1 | ||
|
ce5c6bcc08 | ||
|
8694ce31fe | ||
|
d960e5eadd | ||
|
2dc71e87a3 | ||
|
6bf17edde2 | ||
|
88573d515d | ||
|
89b9f77823 | ||
|
765d9be17d | ||
|
7135373008 | ||
|
ee269884fc | ||
|
387540d5f1 | ||
|
2eba7b42a8 | ||
|
07115d26c7 | ||
|
c43ed815a0 | ||
|
ff01e36d12 | ||
|
ac4798b16c | ||
|
d4e14fed0e | ||
|
5f91259344 | ||
|
20a9d9645d | ||
|
c86f6b4abd | ||
|
d66489b5b2 | ||
|
b743ee9f0c | ||
|
95ba69c00a | ||
|
2ac273739c | ||
|
5b4d28708c | ||
|
4cc4383488 | ||
|
8935232248 | ||
|
5c6dd2f172 | ||
|
eeeb7ef5b9 | ||
|
2efc9c1178 | ||
|
a84c46f6e3 | ||
|
a5c3dcdd02 | ||
|
46f7a75eb7 | ||
|
94b6710c5b | ||
|
d8dd3da9ab | ||
|
803ced004a | ||
|
0ea7d36ad0 | ||
|
87aafab759 | ||
|
994d310abd | ||
|
228cdcf05e | ||
|
42598e352c | ||
|
36a9e4d1da | ||
|
456dfd0dea | ||
|
155457e2b5 | ||
|
b5c91485bf | ||
|
c959cf7870 | ||
|
5878c88636 | ||
|
ddcef2fb19 | ||
|
493d124c07 | ||
|
f42060c616 | ||
|
834facc932 | ||
|
f82d0b76ee | ||
|
c25d225275 | ||
|
c503a274b5 | ||
|
087069d215 | ||
|
826a6dd114 | ||
|
f31483838d | ||
|
d8a9b633d9 | ||
|
c060e4466a | ||
|
a9951376f4 | ||
|
bda0c8f5e3 | ||
|
71902f23a2 | ||
|
dfd6c85569 | ||
|
0e41b2cc1a |
@@ -1,53 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2000. 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.
|
||||
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <boost/counting_iterator.hpp>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
// Example of using counting_iterator_generator
|
||||
std::cout << "counting from 0 to 4:" << std::endl;
|
||||
boost::counting_iterator_generator<int>::type first(0), last(4);
|
||||
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using make_counting_iterator()
|
||||
std::cout << "counting from -5 to 4:" << std::endl;
|
||||
std::copy(boost::make_counting_iterator(-5),
|
||||
boost::make_counting_iterator(5),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using counting iterator to create an array of pointers.
|
||||
const int N = 7;
|
||||
std::vector<int> numbers;
|
||||
// Fill "numbers" array with [0,N)
|
||||
std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N),
|
||||
std::back_inserter(numbers));
|
||||
|
||||
std::vector<std::vector<int>::iterator> pointers;
|
||||
|
||||
// Use counting iterator to fill in the array of pointers.
|
||||
std::copy(boost::make_counting_iterator(numbers.begin()),
|
||||
boost::make_counting_iterator(numbers.end()),
|
||||
std::back_inserter(pointers));
|
||||
|
||||
// Use indirect iterator to print out numbers by accessing
|
||||
// them through the array of pointers.
|
||||
std::cout << "indirectly printing out the numbers from 0 to "
|
||||
<< N << std::endl;
|
||||
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
||||
boost::make_indirect_iterator(pointers.end()),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,428 +0,0 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// 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.
|
||||
|
||||
// compressed_pair: pair that "compresses" empty members
|
||||
// (see libs/utility/compressed_pair.htm)
|
||||
//
|
||||
// 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>
|
||||
#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
|
||||
{
|
||||
|
||||
// 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) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_(x) {}
|
||||
|
||||
explicit 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(compressed_pair_imp& 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 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_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: first_type(x), second_(y) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_type(x) {}
|
||||
|
||||
explicit 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(compressed_pair_imp& 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 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_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: second_type(y), first_(x) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_(x) {}
|
||||
|
||||
explicit 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(compressed_pair_imp& 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 T1,
|
||||
private 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_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: first_type(x), second_type(y) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_type(x) {}
|
||||
|
||||
explicit 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(compressed_pair_imp&) {}
|
||||
};
|
||||
|
||||
// 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 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_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type)
|
||||
: first_type(x) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_type(x) {}
|
||||
|
||||
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_imp&) {}
|
||||
private:
|
||||
};
|
||||
|
||||
// 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) {}
|
||||
|
||||
explicit 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(compressed_pair_imp<T1, T2, 5>& 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) {}
|
||||
explicit 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(compressed_pair& 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,128 +0,0 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// 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.
|
||||
//
|
||||
// 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{
|
||||
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_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 simple, bool reference>
|
||||
struct call_traits_chooser
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
typedef standard_call_traits<T> type;
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct call_traits_chooser<true, false>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
typedef simple_call_traits<T> type;
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct call_traits_chooser<false, true>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
typedef reference_call_traits<T> type;
|
||||
};
|
||||
};
|
||||
} // namespace detail
|
||||
template <typename T>
|
||||
struct call_traits
|
||||
{
|
||||
private:
|
||||
typedef detail::call_traits_chooser<(is_pointer<T>::value || is_arithmetic<T>::value) && sizeof(T) <= sizeof(void*), 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
|
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;
|
||||
}
|
@@ -1,210 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2001. 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
|
||||
// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
|
||||
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
|
||||
// on MSVC. Reordered some #ifdefs for coherency.
|
||||
// (David Abrahams)
|
||||
// 13 Feb 2001 Test new VC6 workarounds (David Abrahams)
|
||||
// 11 Feb 2001 Final fixes for Borland (David Abrahams)
|
||||
// 11 Feb 2001 Some fixes for Borland get it closer on that compiler
|
||||
// (David Abrahams)
|
||||
// 07 Feb 2001 More comprehensive testing; factored out static tests for
|
||||
// better reuse (David Abrahams)
|
||||
// 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a
|
||||
// reference type from operator* (David Abrahams)
|
||||
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
// An iterator for which we can get traits.
|
||||
struct my_iterator1
|
||||
: boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
|
||||
{
|
||||
my_iterator1(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator1& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
my_iterator1& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
// Used to prove that we don't require std::iterator<> in the hierarchy under
|
||||
// MSVC6, and that we can compute all the traits for a standard-conforming UDT
|
||||
// iterator.
|
||||
struct my_iterator2
|
||||
: boost::equality_comparable<my_iterator2
|
||||
, boost::incrementable<my_iterator2
|
||||
, boost::dereferenceable<my_iterator2,const char*> > >
|
||||
{
|
||||
typedef char value_type;
|
||||
typedef long difference_type;
|
||||
typedef const char* pointer;
|
||||
typedef const char& reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
my_iterator2(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator2& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
my_iterator2& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
// Used to prove that we're not overly confused by the existence of
|
||||
// std::iterator<> in the hierarchy under MSVC6 - we should find that
|
||||
// boost::detail::iterator_traits<my_iterator3>::difference_type is int.
|
||||
struct my_iterator3 : my_iterator1
|
||||
{
|
||||
typedef int difference_type;
|
||||
my_iterator3(const char* p) : my_iterator1(p) {}
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_portable_tests
|
||||
{
|
||||
// Unfortunately, the VC6 standard library doesn't supply these :(
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::pointer,
|
||||
pointer
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::reference,
|
||||
reference
|
||||
>::value));
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct portable_tests
|
||||
{
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::difference_type,
|
||||
difference_type
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::iterator_category,
|
||||
category
|
||||
>::value));
|
||||
};
|
||||
|
||||
// Test iterator_traits
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct input_iterator_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
typename boost::detail::iterator_traits<Iterator>::value_type,
|
||||
value_type
|
||||
>::value));
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_pointer_test
|
||||
: input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct maybe_pointer_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
#endif
|
||||
{
|
||||
};
|
||||
|
||||
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
|
||||
istream_iterator_test;
|
||||
|
||||
//
|
||||
#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT)
|
||||
typedef ::std::char_traits<char>::off_type distance;
|
||||
non_pointer_test<std::ostream_iterator<int>,int,
|
||||
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
||||
#elif defined(BOOST_MSVC_STD_ITERATOR)
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
int, void, void, void, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#else
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
void, void, void, void, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __KCC
|
||||
typedef long std_list_diff_type;
|
||||
#else
|
||||
typedef std::ptrdiff_t std_list_diff_type;
|
||||
#endif
|
||||
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
|
||||
list_iterator_test;
|
||||
|
||||
maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
vector_iterator_test;
|
||||
|
||||
maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
int_pointer_test;
|
||||
|
||||
non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator1_test;
|
||||
|
||||
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator2_test;
|
||||
|
||||
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator3_test;
|
||||
|
||||
int main()
|
||||
{
|
||||
char chars[100];
|
||||
int ints[100];
|
||||
|
||||
for (std::ptrdiff_t length = 3; length < 100; length += length / 3)
|
||||
{
|
||||
std::list<int> l(length);
|
||||
assert(boost::detail::distance(l.begin(), l.end()) == length);
|
||||
|
||||
std::vector<int> v(length);
|
||||
assert(boost::detail::distance(v.begin(), v.end()) == length);
|
||||
|
||||
assert(boost::detail::distance(&ints[0], ints + length) == length);
|
||||
assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length);
|
||||
}
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user