forked from boostorg/iterator
Compare commits
427 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
1ef8189af4 | |||
f3671a6422 | |||
ae45f7abf7 | |||
6363297754 | |||
55fd9078a1 | |||
e22bb495db | |||
54ae365c98 | |||
a9483b5633 | |||
65fe75e558 | |||
7a43350655 | |||
df49ae74e0 | |||
3fe9b7517e | |||
ab372a0a74 | |||
f9c4915b55 | |||
741da59c0d | |||
a0b28e4c8b | |||
ef895f0cc7 | |||
1d018cc602 | |||
88697aad65 | |||
7344357e32 | |||
80501e1eb2 | |||
7707262a07 | |||
ba3e7a459e | |||
295ae05e40 | |||
68268f81eb | |||
3b60f75bc6 | |||
a8f528130a | |||
c0788f2cd8 | |||
c6bc3b2547 | |||
27adbbb6ed | |||
1f999864a1 | |||
65af4c96a9 | |||
aa9e49b727 | |||
3318c82f83 | |||
68791c337a | |||
a396085bc0 | |||
6196a6e591 | |||
4e07575b78 | |||
557ef60557 | |||
4b583d3aa0 | |||
3eca5e8f60 | |||
5947d569b9 | |||
e469abbf57 | |||
c141f6cc59 | |||
55f8a6380a | |||
9c955e8af2 | |||
82108581b9 | |||
c4834d363e | |||
7194aff64c | |||
ca41a4f902 | |||
47a3392c80 | |||
bd765a21fb | |||
cad110e0f3 | |||
3599398eca | |||
dd72d599c8 | |||
1a9677d9dc | |||
a6d200f262 | |||
0c28649d0b | |||
d6405ddd54 | |||
700db48ac7 | |||
2241bb1ae3 | |||
539add7de6 | |||
edb7528136 | |||
254186d6bd | |||
aa62f4f9c7 | |||
f0bc339d55 | |||
2721c3c97e | |||
f49f68c8fe | |||
02f606816d | |||
1ffc31cc37 | |||
0acc6c38ef | |||
da1e5aa3e8 | |||
db0bc36f58 | |||
99bafe363c | |||
b310ccda97 | |||
2a9c00f5b2 | |||
020d0b8f99 | |||
d21781d8d1 | |||
bed1d7fa7a | |||
0c3a68530e | |||
d3daa47561 | |||
62c993978a | |||
74f41dcb5b | |||
c8d1461340 | |||
13dcd5590f | |||
7f125cacb9 | |||
8cf04e1c7b | |||
0122a0c8ec | |||
09549783cc | |||
273c1d784c | |||
a99ab81803 | |||
0cb4ce54ef | |||
0670e05297 | |||
b353d45f2d | |||
19d339c916 | |||
506517191c | |||
b502873f00 | |||
b838d27aa3 | |||
17c373ded3 | |||
09e1cb9a38 | |||
58288cfb48 | |||
cd730895ca | |||
2d2a84f8c4 | |||
4871736269 | |||
fec82e2de8 | |||
a5b14e1a4f | |||
8480d452a9 | |||
5f870d780d | |||
010f715950 | |||
020f2ab867 | |||
2071230859 | |||
413d0b01cf | |||
4abd97910d | |||
564ed3ed88 | |||
c90814e515 | |||
576395a469 | |||
f75a60e074 | |||
3e5f366f4f | |||
a456f8d969 | |||
cfe17e7fe5 | |||
99891db75c | |||
287c7ed0e7 | |||
8bd881070c | |||
9cce6e8052 | |||
b6068667c9 | |||
309f741588 | |||
858e0e0c0b | |||
01fd0c92e3 | |||
23dcc53fed | |||
08cd7bf6e7 | |||
35c14adc12 | |||
3b992521af | |||
646e78dc14 | |||
4a7f6afd6a | |||
8294e14664 | |||
1102c88de7 | |||
c98620a552 | |||
24fcaed649 | |||
2c1eadfea3 | |||
ffe87e904f | |||
fbd5da7237 | |||
ecccc89a70 | |||
2bacc663b1 | |||
c5dc0fbf0e | |||
f358cf3bf4 | |||
6b00e8e0ca | |||
5abf4d7556 | |||
8ca421c140 | |||
1e3da4b77f | |||
7c784ad112 | |||
f72d264b6b | |||
c6526fc609 | |||
3741fa77d2 | |||
ca70d5dee8 | |||
85ad1f59da | |||
73e6736566 | |||
c08cc33394 | |||
8c3ed628dc | |||
792acdb408 | |||
c3fd7076c1 | |||
33f630beca | |||
f1f6262be7 | |||
42147b9e86 | |||
2854c5c761 | |||
731576fbfe | |||
36329b053d | |||
3b93bb25ff | |||
2496402a8c | |||
8a0e9a4fe5 | |||
5049bcdce5 | |||
1c77a5a4ab | |||
9c42ccb0bd | |||
dd50d3f2ab | |||
5f3b97ceff | |||
2d1e40bd20 | |||
a0bb423311 | |||
0f8c236e9d | |||
736044938d | |||
983ba32def | |||
d2dae62215 | |||
9540444061 | |||
482c0cf52b | |||
849f01a0d1 | |||
11770763df | |||
df66940f0f | |||
80f6a13e79 | |||
0f8aa07e5c | |||
6b77e7f8bd | |||
838decca95 | |||
e6c5b80afd | |||
e7b5604ec5 | |||
ea3baba376 | |||
c6a5b7c292 | |||
45e90e0134 | |||
18b1414d6c | |||
7facdd8590 | |||
6cf1230c13 | |||
d70b0d3f05 | |||
527b5e3caa | |||
4e1b53ed36 | |||
eb69638be1 | |||
a5c4497c01 | |||
1033aeb186 | |||
e5d502d2f8 | |||
55e4fe2ab7 | |||
8e2d210d42 | |||
ec8d069057 | |||
2edb688882 | |||
3403cbbae6 | |||
b52b9325ba | |||
1e3b131a84 | |||
250a374e07 | |||
f618d71c0e | |||
3d37ba5120 | |||
e785cc70d1 | |||
3bf52ec2f2 | |||
19dbb5304c | |||
4d13c285ea | |||
08ce6903ce | |||
75e76eb637 | |||
954d12a04d | |||
bcc0e80439 | |||
436f7411f8 | |||
21381f3fa7 | |||
db9d88ad7b | |||
6085e03da0 | |||
b2407b0191 | |||
8181625365 | |||
24052c3dff | |||
c15707fd70 | |||
b4f1b069be | |||
129815f3dd | |||
a7eaa017b1 | |||
6e326921f9 | |||
4a3fd9984d | |||
0074f50573 | |||
ba8dc44eac | |||
b0d3d34fcd | |||
7f0ed4f5be | |||
7fc54ec2d8 | |||
f0add8a043 | |||
5b608e114b | |||
06e1fa88b9 | |||
a6b2a098c1 | |||
4f0684ffac | |||
fbfcf97e18 | |||
45b6a92f61 | |||
c6814925ac | |||
6c114a539d | |||
b6c82968b8 | |||
2271aceab8 | |||
0db07e9455 | |||
f158591054 | |||
1b210355bf | |||
075c341a37 | |||
bab25c04db | |||
2a60dfa087 | |||
ef69c73e89 | |||
bf9534e1ee | |||
0e11bd6a0c | |||
ff10cfd5dc | |||
400f35cbb0 | |||
59340bca4c | |||
6c62f31f0a | |||
dd5fb425fa | |||
c903cf4801 | |||
1c26f7dd43 | |||
c546a3e875 | |||
2183de96a1 | |||
fb1fc6f909 | |||
20b31d1cca | |||
f716d705c5 | |||
1fca93be10 | |||
f96a2b3d81 | |||
a7edd713d8 | |||
bca1c2dea5 | |||
dfad37d0f9 | |||
3376955b80 | |||
e98b130d77 | |||
a450053b0a | |||
0b5b315a7f | |||
5cc31f6539 | |||
f0248daa1e | |||
798562e75b | |||
68e7d3f0d5 | |||
e9bb297ed2 | |||
d5e525dd19 | |||
c326818764 | |||
57ec457f32 | |||
c04b13641f | |||
0bf570c98d | |||
28dfcbd6b0 | |||
9338b11799 | |||
ad5defc9af | |||
81242ad5ae | |||
8997a587e9 | |||
83de27a445 | |||
44d7dfeb9b | |||
84f22cde8d | |||
9387c05d12 | |||
66feb45676 | |||
bdbfcd308e | |||
44757cfcc1 | |||
c1be620888 | |||
36d9a73a60 | |||
f14701232a | |||
296ce3aa89 | |||
1f7c08615f | |||
1b29ec1741 | |||
593311f43e | |||
fe52e0d665 | |||
52e34b2e26 | |||
8cfa950f10 | |||
cc282d81c0 | |||
8c01469b3c | |||
a6ffdb8ebf | |||
2ad29da3b5 | |||
459387273b | |||
09ea8d27e2 | |||
ca1ee306b7 | |||
b63814d3f2 | |||
dfc09c4b26 | |||
f6715137cf | |||
f18906ac6b | |||
522195fd64 | |||
bdc1304326 | |||
633bb0762e | |||
b0b5699a01 | |||
943d2c872b | |||
4ec68b7a0e | |||
e295f71a85 | |||
a8a68dbb7b | |||
8d5717081e | |||
76880f6ce2 | |||
50e645261c | |||
f25ff7a1a4 | |||
104faa5ab3 | |||
4cc5f9a4d6 | |||
7946d32cef | |||
69d8856572 | |||
c055f1afae | |||
cb34b65f3f | |||
f8cd96cb2e | |||
fed5967d9d | |||
81870ac8b6 | |||
6ef3e5d1c7 | |||
dfa751077a | |||
14134e4610 | |||
c7bec1cf56 | |||
e888f18b5a | |||
15abd4c56e | |||
17026cc30d | |||
1c39976ccd | |||
361f62d022 | |||
ebb09db44e | |||
50fe1b062b | |||
30ca43dd08 | |||
ac0c6461fb | |||
d85b8db0aa | |||
a3856b5c60 | |||
20e2818844 | |||
d68ac3db4c | |||
5efcabf3bd | |||
9ac583096c | |||
1710c484b3 | |||
f6cbffeda0 | |||
50ab635593 | |||
d958a5bc82 | |||
5339d7a9d4 | |||
fd29e538ed | |||
1c41a7d0ec | |||
85873e924a | |||
d9b4e41d5a | |||
4968b50fc2 | |||
cbeb7f0632 | |||
abf8390020 | |||
2c89e2b15a | |||
3f49409843 | |||
abafc5d1be | |||
2b7ed5f7a8 | |||
f801c39a59 | |||
bb7ac6bd84 | |||
f325582c40 | |||
36feca8a52 | |||
a5179f6dfc | |||
f98f3497b8 | |||
76af84c0e7 | |||
0f42b93c3b | |||
19977c757f | |||
508696a169 | |||
3ab9da6a99 | |||
bd3312cdf2 | |||
87f93ec521 | |||
afa92675a2 | |||
ed8c60c20b | |||
3fe0d4b532 | |||
8a51271e3b | |||
52c0d22cff | |||
e4447b8e83 | |||
42e873e10c | |||
57a40c8cd2 | |||
a982c42303 | |||
9db269bb5b | |||
e5eaaf6a55 | |||
2225787093 | |||
f19c1c4059 | |||
b0aef5a66d | |||
dfc43d81cf | |||
eda969d7b5 | |||
4c8415a99f | |||
1d6f36e35d | |||
04301ac6e9 | |||
a1ec9da737 | |||
e2a47bdbe5 | |||
2b1fc22b61 | |||
273ec4b975 | |||
4716891117 | |||
80d9e8e4c1 | |||
53eb5346de | |||
e28ca345ea | |||
92d461cda1 | |||
8dace06f04 | |||
ef0bff57d3 | |||
5bacd289b6 | |||
77c1698c6e | |||
2c302ee549 | |||
a586f20d19 |
@ -1,159 +0,0 @@
|
||||
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
|
||||
#define BOOST_ITERATOR_CATEGORIES_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/pending/ct_if.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Return Type Categories
|
||||
struct readable_iterator_tag { };
|
||||
struct writable_iterator_tag { };
|
||||
struct swappable_iterator_tag { };
|
||||
struct mutable_lvalue_iterator_tag :
|
||||
virtual public writable_iterator_tag,
|
||||
virtual public readable_iterator_tag { };
|
||||
struct constant_lvalue_iterator_tag :
|
||||
virtual public readable_iterator_tag { };
|
||||
|
||||
// Traversal Categories
|
||||
struct forward_traversal_tag { };
|
||||
struct bidirectional_traversal_tag : public forward_traversal_tag { };
|
||||
struct random_access_traversal_tag : public bidirectional_traversal_tag { };
|
||||
|
||||
struct error_iterator_tag { };
|
||||
|
||||
// Inherit from iterator_base if your iterator defines its own
|
||||
// return_category and traversal_category. Otherwise, the "old style"
|
||||
// iterator category will be mapped to the return_category and
|
||||
// traversal_category.
|
||||
struct new_iterator_base { };
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct return_category_from_nested_type {
|
||||
template <typename Iterator> struct bind {
|
||||
typedef typename Iterator::return_category type;
|
||||
};
|
||||
};
|
||||
|
||||
struct traversal_category_from_nested_type {
|
||||
template <typename Iterator> struct bind {
|
||||
typedef typename Iterator::traversal_category type;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct choose_lvalue_return {
|
||||
typedef typename ct_if<is_const<ValueType>::value,
|
||||
boost::constant_lvalue_iterator_tag,
|
||||
boost::mutable_lvalue_iterator_tag>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Category, typename ValueType>
|
||||
struct iter_category_to_return {
|
||||
typedef typename ct_if<
|
||||
is_convertible<Category*, std::forward_iterator_tag*>::value,
|
||||
typename choose_lvalue_return<ValueType>::type,
|
||||
typename ct_if<
|
||||
is_convertible<Category*, std::input_iterator_tag*>::value,
|
||||
boost::readable_iterator_tag,
|
||||
typename ct_if<
|
||||
is_convertible<Category*, std::output_iterator_tag*>::value,
|
||||
boost::writable_iterator_tag,
|
||||
boost::error_iterator_tag
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename Category>
|
||||
struct iter_category_to_traversal {
|
||||
typedef typename ct_if<
|
||||
is_convertible<Category*, std::random_access_iterator_tag*>::value,
|
||||
random_access_traversal_tag,
|
||||
typename ct_if<
|
||||
is_convertible<Category*, std::bidirectional_iterator_tag*>::value,
|
||||
bidirectional_traversal_tag,
|
||||
forward_traversal_tag
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
struct return_category_from_old_traits {
|
||||
template <typename Iterator> class bind {
|
||||
typedef boost::detail::iterator_traits<Iterator> OldTraits;
|
||||
typedef typename OldTraits::iterator_category Cat;
|
||||
typedef typename OldTraits::value_type value_type;
|
||||
public:
|
||||
typedef iter_category_to_return<Cat, value_type>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
struct traversal_category_from_old_traits {
|
||||
template <typename Iterator> class bind {
|
||||
typedef boost::detail::iterator_traits<Iterator> OldTraits;
|
||||
typedef typename OldTraits::iterator_category Cat;
|
||||
public:
|
||||
typedef iter_category_to_traversal<Cat>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class choose_return_category {
|
||||
typedef typename ct_if<is_convertible<Iterator*,
|
||||
new_iterator_base*>::value,
|
||||
return_category_from_nested_type,
|
||||
return_category_from_old_traits>::type Choice;
|
||||
public:
|
||||
typedef typename Choice:: template bind<Iterator>::type type;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class choose_traversal_category {
|
||||
typedef typename ct_if<is_convertible<Iterator*,
|
||||
new_iterator_base*>::value,
|
||||
traversal_category_from_nested_type,
|
||||
traversal_category_from_old_traits>::type Choice;
|
||||
public:
|
||||
typedef typename Choice:: template bind<Iterator>::type type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Iterator>
|
||||
struct return_category {
|
||||
typedef typename detail::choose_return_category<Iterator>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <class Iterator>
|
||||
struct traversal_category {
|
||||
typedef typename detail::choose_traversal_category<Iterator>::type type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct return_category<T*>
|
||||
{
|
||||
typedef typename ct_if<is_const<T>::value,
|
||||
constant_lvalue_iterator_tag,
|
||||
mutable_lvalue_iterator_tag>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct traversal_category<T*>
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_CATEGORIES_HPP
|
@ -1,172 +0,0 @@
|
||||
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
|
||||
#define BOOST_ITERATOR_CONCEPTS_HPP
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/iterator_categories.hpp>
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost_concepts {
|
||||
// Used a different namespace here (instead of "boost") so that the
|
||||
// concept descriptions do not take for granted the names in
|
||||
// namespace boost.
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Access Concepts
|
||||
|
||||
template <typename Iterator>
|
||||
class ReadableIteratorConcept {
|
||||
public:
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
||||
boost::readable_iterator_tag*>::value));
|
||||
|
||||
reference r = *i; // or perhaps read(x)
|
||||
value_type v(r);
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename ValueType>
|
||||
class WritableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
||||
boost::writable_iterator_tag*>::value));
|
||||
|
||||
*i = v; // a good alternative could be something like write(x, v)
|
||||
}
|
||||
ValueType v;
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class ConstantLvalueIteratorConcept {
|
||||
public:
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
||||
boost::constant_lvalue_iterator_tag*>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference,
|
||||
const value_type&>::value));
|
||||
|
||||
reference v = *i;
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class MutableLvalueIteratorConcept {
|
||||
public:
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::return_category<Iterator>::type return_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
WritableIteratorConcept<Iterator, value_type> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
||||
boost::mutable_lvalue_iterator_tag*>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
|
||||
|
||||
reference v = *i;
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Traversal Concepts
|
||||
|
||||
template <typename Iterator>
|
||||
class ForwardIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
|
||||
boost::forward_traversal_tag*>::value));
|
||||
++i;
|
||||
(void)i++;
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class BidirectionalIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ForwardIteratorConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
|
||||
boost::bidirectional_traversal_tag*>::value));
|
||||
|
||||
--i;
|
||||
(void)i--;
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class RandomAccessIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename std::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< BidirectionalIteratorConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
|
||||
boost::random_access_traversal_tag*>::value));
|
||||
|
||||
i += n;
|
||||
i = i + n;
|
||||
i = n + i;
|
||||
i -= n;
|
||||
i = i - n;
|
||||
n = i - j;
|
||||
}
|
||||
difference_type n;
|
||||
Iterator i, j;
|
||||
};
|
||||
|
||||
} // namespace boost_concepts
|
||||
|
||||
|
||||
#endif // BOOST_ITERATOR_CONCEPTS_HPP
|
@ -1,73 +0,0 @@
|
||||
#include <boost/iterator_concepts.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
struct new_iterator
|
||||
: public boost::iterator<std::random_access_iterator_tag, int>,
|
||||
public boost::new_iterator_base
|
||||
{
|
||||
typedef boost::random_access_traversal_tag traversal_category;
|
||||
typedef boost::mutable_lvalue_iterator_tag return_category;
|
||||
|
||||
int& operator*() const { return *m_x; }
|
||||
new_iterator& operator++() { return *this; }
|
||||
new_iterator operator++(int) { return *this; }
|
||||
new_iterator& operator--() { return *this; }
|
||||
new_iterator operator--(int) { return *this; }
|
||||
new_iterator& operator+=(std::ptrdiff_t) { return *this; }
|
||||
new_iterator operator+(std::ptrdiff_t) { return *this; }
|
||||
new_iterator& operator-=(std::ptrdiff_t) { return *this; }
|
||||
std::ptrdiff_t operator-(const new_iterator&) const { return 0; }
|
||||
new_iterator operator-(std::ptrdiff_t) const { return *this; }
|
||||
bool operator==(const new_iterator&) const { return false; }
|
||||
bool operator!=(const new_iterator&) const { return false; }
|
||||
bool operator<(const new_iterator&) const { return false; }
|
||||
int* m_x;
|
||||
};
|
||||
new_iterator operator+(std::ptrdiff_t, new_iterator x) { return x; }
|
||||
|
||||
struct old_iterator
|
||||
: public boost::iterator<std::random_access_iterator_tag, int>
|
||||
{
|
||||
int& operator*() const { return *m_x; }
|
||||
old_iterator& operator++() { return *this; }
|
||||
old_iterator operator++(int) { return *this; }
|
||||
old_iterator& operator--() { return *this; }
|
||||
old_iterator operator--(int) { return *this; }
|
||||
old_iterator& operator+=(std::ptrdiff_t) { return *this; }
|
||||
old_iterator operator+(std::ptrdiff_t) { return *this; }
|
||||
old_iterator& operator-=(std::ptrdiff_t) { return *this; }
|
||||
old_iterator operator-(std::ptrdiff_t) const { return *this; }
|
||||
std::ptrdiff_t operator-(const old_iterator&) const { return 0; }
|
||||
bool operator==(const old_iterator&) const { return false; }
|
||||
bool operator!=(const old_iterator&) const { return false; }
|
||||
bool operator<(const old_iterator&) const { return false; }
|
||||
int* m_x;
|
||||
};
|
||||
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
boost::function_requires<
|
||||
boost_concepts::MutableLvalueIteratorConcept<int*> >();
|
||||
boost::function_requires<
|
||||
boost_concepts::RandomAccessIteratorConcept<int*> >();
|
||||
|
||||
boost::function_requires<
|
||||
boost_concepts::ConstantLvalueIteratorConcept<const int*> >();
|
||||
boost::function_requires<
|
||||
boost_concepts::RandomAccessIteratorConcept<const int*> >();
|
||||
#endif
|
||||
|
||||
boost::function_requires<
|
||||
boost_concepts::MutableLvalueIteratorConcept<new_iterator> >();
|
||||
boost::function_requires<
|
||||
boost_concepts::RandomAccessIteratorConcept<new_iterator> >();
|
||||
|
||||
boost::function_requires<
|
||||
boost_concepts::MutableLvalueIteratorConcept<old_iterator> >();
|
||||
boost::function_requires<
|
||||
boost_concepts::RandomAccessIteratorConcept<old_iterator> >();
|
||||
return 0;
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
<html>
|
||||
<!--
|
||||
-- Copyright (c) Jeremy Siek 2000,2001
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. I make no representations about the
|
||||
-- suitability of this software for any purpose. It is provided "as is"
|
||||
-- without express or implied warranty.
|
||||
-->
|
||||
<head>
|
||||
<title>Boost Iterator Traits</title>
|
||||
</head>
|
||||
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
<BR Clear>
|
||||
|
||||
<h1>Boost Iterator Category Traits</h1>
|
||||
Header <tt><a href="../../boost/iterator_categories.hpp">boost/iterator_categories.hpp</a></tt>
|
||||
|
||||
<p>
|
||||
The <tt>boost::traversal_category</tt> and
|
||||
<tt>boost::return_category</tt> traits classes provides access to the
|
||||
category tags for iterators that model the Boost <a
|
||||
href="./iterator_concepts.htm">Iterator Concepts</a>, which are a
|
||||
replacement for the iterator requirements in the C++ standard. The
|
||||
other associated types of the Boost iterator concepts are accessed
|
||||
through the <tt>std::iterator_traits</tt> class.
|
||||
|
||||
<ul>
|
||||
<li><tt>traversal_category<Iter>::type</tt> Can the iterator go forward, backward, etc.?
|
||||
<li><tt>return_category<Iter>::type</tt> Is the iterator read or write only?
|
||||
Is the dereferenced type an lvalue?
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
An important feature of the <tt>boost::traversal_category</tt> and
|
||||
<tt>boost::return_category</tt> classes is that they are <b>backwards
|
||||
compatible</b>, i.e., they automatically work for iterators for which
|
||||
there are valid definitions of <tt>std::iterator_traits</tt>. The old
|
||||
<tt>iterator_category</tt> is mapped to the appropriate traversal and
|
||||
return categories.
|
||||
|
||||
<p>
|
||||
When creating a new iterator type that is meant to work with
|
||||
<tt>boost::traversal_category</tt> and
|
||||
<tt>boost::return_category</tt>, you can either create a
|
||||
specialization of these classes for your iterator type, or you can
|
||||
provide all the necessary associated types as nested typedefs. In
|
||||
this case, your iterator class will need to inherit from
|
||||
<tt>new_iterator_base</tt> to let the category traits know
|
||||
that it will be able to find typedefs for <tt>traversal_category</tt>
|
||||
and <tt>return_category</tt> in you iterator class.
|
||||
|
||||
|
||||
Each of the new iterator requirements will need a category tag.
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
|
||||
// Return Type Categories
|
||||
struct readable_iterator_tag { };
|
||||
struct writable_iterator_tag { };
|
||||
struct swappable_iterator_tag { };
|
||||
struct mutable_lvalue_iterator_tag : virtual public writable_iterator_tag,
|
||||
virtual public readable_iterator_tag { };
|
||||
struct constant_lvalue_iterator_tag : public readable_iterator_tag { };
|
||||
|
||||
// Traversal Categories
|
||||
struct forward_traversal_tag { };
|
||||
struct bidirectional_traversal_tag : public forward_traversal_tag { };
|
||||
struct random_access_traversal_tag : public bidirectional_traversal_tag { };
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The following is pseudo-code for the iterator category traits classes.
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
|
||||
<i>// Inherit from iterator_base if your iterator defines its own
|
||||
// return_category and traversal_category. Otherwise, the "old style"
|
||||
// iterator category will be mapped to the return_category and
|
||||
// traversal_category.</i>
|
||||
struct new_iterator_base { };
|
||||
|
||||
template <typename Iterator>
|
||||
struct return_category
|
||||
{
|
||||
<b><i>// Pseudo-code</i></b>
|
||||
if (Iterator inherits from new_iterator_base) {
|
||||
typedef typename Iterator::return_category type;
|
||||
} else {
|
||||
typedef std::iterator_traits<Iterator> OldTraits;
|
||||
typedef typename OldTraits::iterator_category Cat;
|
||||
if (Cat inherits from std::forward_iterator_tag)
|
||||
if (is-const(T))
|
||||
typedef boost::constant_lvalue_iterator_tag type;
|
||||
else
|
||||
typedef boost::mutable_lvalue_iterator_tag type;
|
||||
else if (Cat inherits from std::input_iterator_tag)
|
||||
typedef boost::readable_iterator_tag type;
|
||||
else if (Cat inherits from std::output_iterator_tag)
|
||||
typedef boost::writable_iterator_tag type;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct return_category<T*>
|
||||
{
|
||||
<b><i>// Pseudo-code</i></b>
|
||||
if (is-const(T))
|
||||
typedef boost::constant_lvalue_iterator_tag type;
|
||||
else
|
||||
typedef boost::mutable_lvalue_iterator_tag type;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct traversal_category
|
||||
{
|
||||
<b><i>// Pseudo-code</i></b>
|
||||
if (Iterator inherits from new_iterator_base) {
|
||||
typedef typename Iterator::traversal_category type;
|
||||
} else {
|
||||
typedef std::iterator_traits<Iterator> OldTraits;
|
||||
typedef typename OldTraits::iterator_category Cat;
|
||||
|
||||
if (Cat inherits from std::random_access_iterator_tag)
|
||||
typedef boost::random_access_traversal_tag type;
|
||||
else if (Cat inherits from std::bidirectional_iterator_tag)
|
||||
typedef boost::bidirectional_traversal_tag type;
|
||||
else if (Cat inherits from std::forward_iterator_tag)
|
||||
typedef boost::forward_traversal_tag type;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct traversal_category<T*>
|
||||
{
|
||||
typedef boost::random_access_traversal_tag type;
|
||||
};
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
<address><a href="mailto:jsiek@lsc.nd.edu">jeremy siek</a></address>
|
||||
<!-- Created: Sun Mar 18 14:06:57 EST 2001 -->
|
||||
<!-- hhmts start -->
|
||||
Last modified: Mon Mar 19 12:59:30 EST 2001
|
||||
<!-- hhmts end -->
|
||||
</body>
|
||||
</html>
|
@ -1,37 +0,0 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 150 2325 4275 4350
|
||||
2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1725 4050 1725 3450
|
||||
2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1725 3150 1725 2550
|
||||
4 0 0 100 0 19 18 0.0000 4 210 3180 375 2550 ForwardTraversalIterator\001
|
||||
4 0 0 100 0 19 18 0.0000 4 210 3765 225 3450 BidirectionalTraversalIterator\001
|
||||
4 0 0 100 0 19 18 0.0000 4 210 4125 150 4350 RandomAccessTraversalIterator\001
|
||||
-6
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4800 3600 4800 2400
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6900 3000 5400 2400
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6900 3000 7500 2400
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6900 3000 9075 2475
|
||||
4 0 0 100 0 19 18 0.0000 4 210 2040 6600 2400 WritableIterator\001
|
||||
4 0 0 100 0 19 18 0.0000 4 210 2145 3900 2400 ReadableIterator\001
|
||||
4 0 0 50 0 19 18 0.0000 4 210 2835 5700 3300 MutableLvalueIterator\001
|
||||
4 0 0 50 0 19 18 0.0000 4 270 2355 9075 2400 SwappableIterator\001
|
||||
4 0 0 50 0 19 18 0.0000 4 210 2970 3825 3900 ConstantLvalueIterator\001
|
Binary file not shown.
Before Width: | Height: | Size: 3.2 KiB |
@ -1,663 +0,0 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) Jeremy Siek 2000
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. I make no representations about the
|
||||
-- suitability of this software for any purpose. It is provided "as is"
|
||||
-- without express or implied warranty.
|
||||
-->
|
||||
<!--
|
||||
-- Copyright (c) 1996-1999
|
||||
-- Silicon Graphics Computer Systems, Inc.
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. Silicon Graphics makes no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
--
|
||||
-- Copyright (c) 1994
|
||||
-- Hewlett-Packard Company
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. Hewlett-Packard Company makes no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
--
|
||||
-->
|
||||
<Head>
|
||||
<Title>Iterator Concepts</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
|
||||
<h1>Iterator Concepts</h1>
|
||||
|
||||
<p>The standard iterator categories and requirements are flawed because
|
||||
they use a single hierarchy of requirements to address two orthogonal
|
||||
issues: <b><i>iterator traversal</i></b> and <b><i>dereference return
|
||||
type</i></b>. The current iterator requirement hierarchy is mainly
|
||||
geared towards iterator traversal (hence the category names), while
|
||||
requirements that address dereference return type sneak in at various
|
||||
places.
|
||||
|
||||
<p>
|
||||
The iterator requirements should be separated into two hierarchies.
|
||||
One set of concepts handles the return type semantics:
|
||||
<ul>
|
||||
<li><a href="#concept:ReadableIterator">Readable Iterator</a></li>
|
||||
<li><a href="#concept:WritableIterator">Writable Iterator</a></li>
|
||||
<li><a href="#concept:SwappableIterator">Swappable Iterator</a></li>
|
||||
<li><a href="#concept:ConstantLvalueIterator">Constant Lvalue Iterator</a></li>
|
||||
<li><a href="#concept:MutableLvalueIterator">Mutable Lvalue Iterator</a></li>
|
||||
</ul>
|
||||
|
||||
The other set of concepts handles iterator traversal:
|
||||
|
||||
<ul>
|
||||
<li><a href="#concept:ForwardTraversalIterator">Forward Traversal Iterator</a></li>
|
||||
<li><a href="#concept:BidirectionalTraversalIterator">Bidirectional Traversal Iterator</a></li>
|
||||
<li><a href="#concept:RandomAccessTraversalIterator">Random Access Traversal Iterator</a></li>
|
||||
</ul>
|
||||
|
||||
The current Input Iterator and Output Iterator requirements will
|
||||
continue to be used as is. Note that Input Iterator implies Readable
|
||||
Iterator and Output Iterator implies Writable Iterator.
|
||||
|
||||
<p>
|
||||
Note: we considered defining a Single-Pass Iterator, which could be
|
||||
combined with Readable or Writable Iterator to replace the Input and
|
||||
Output Iterator requirements. We rejected this idea because there are
|
||||
some differences between Input and Output Iterators that make it hard
|
||||
to merge them: for example Input Iterator requires Equality Comparable
|
||||
while Output Iterator does not.
|
||||
|
||||
|
||||
<p></p>
|
||||
<DIV ALIGN="CENTER"><A NAME="fig:graph-concepts"></A></A>
|
||||
<TABLE>
|
||||
<CAPTION ALIGN="TOP"><STRONG>Figure 1:</STRONG>
|
||||
The iterator concepts and refinement relationships.
|
||||
</CAPTION>
|
||||
<TR><TD><IMG SRC="./iterator_concepts.gif" ></TD></TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
<p></p>
|
||||
|
||||
|
||||
<h2>Relationship with the standard iterator concepts</h2>
|
||||
|
||||
<p>
|
||||
std::Input Iterator implies boost::ReadableIterator.
|
||||
|
||||
<p>
|
||||
std::Output Iterator implies boost::Writable Iterator.
|
||||
|
||||
<p>
|
||||
std::Forward Iterator refines boost::Forward Iterator and
|
||||
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
|
||||
|
||||
<p>
|
||||
std::Bidirectional Iterator refines boost::Bidirectional Iterator and
|
||||
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
|
||||
|
||||
<p>
|
||||
std::Random Access Iterator refines boost::Random Access Iterator and
|
||||
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
|
||||
|
||||
|
||||
<h3>Notation</h3>
|
||||
<Table>
|
||||
<tr>
|
||||
<td><tt>X</tt></td>
|
||||
<td>The iterator type.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>T</tt></td>
|
||||
<td>The value type of <tt>X</tt>, i.e., <tt>std::iterator_traits<X>::value_type</tt>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>x</tt>, <tt>y</tt></td>
|
||||
<td>An object of type <tt>X</tt>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>t</tt></td>
|
||||
<td>An object of type <tt>T</tt>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:ReadableIterator"></A>
|
||||
Readable Iterator
|
||||
</H3>
|
||||
|
||||
A Readable Iterator is an iterator that dereferences to produce an
|
||||
rvalue that is convertible to the <tt>value_type</tt> of the
|
||||
iterator.
|
||||
|
||||
<h3>Associated Types</h3>
|
||||
|
||||
<Table border>
|
||||
|
||||
<tr>
|
||||
<td>Value type</td>
|
||||
<td><tt>std::iterator_traits<X>::value_type</tt></td>
|
||||
<td>The type of the objects pointed to by the iterator.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Reference type</td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
<td>
|
||||
The return type of dereferencing the iterator. This
|
||||
type must be convertible to <tt>T</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Return Category</td>
|
||||
<td><tt>std::return_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::readable_iterator_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<A href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy Constructible</A>
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
|
||||
<tr>
|
||||
<td>Dereference</td>
|
||||
<td><tt>*x</tt></td>
|
||||
<td> </td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Member access</td>
|
||||
<td><tt>x->m</tt></td>
|
||||
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
|
||||
<td>
|
||||
If <tt>m</tt> is a data member, the type of <tt>m</tt>.
|
||||
If <tt>m</tt> is a member function, the return type of <tt>m</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:WritableIterator"></A>
|
||||
Writable Iterator
|
||||
</H3>
|
||||
|
||||
A Writable Iterator is an iterator that can be used to store a value
|
||||
using the dereference-assignment expression.
|
||||
|
||||
<h3>Definitions</h3>
|
||||
|
||||
If <tt>x</tt> is an Writable Iterator of type <tt>X</tt>, then the
|
||||
expression <tt>*x = a;</tt> stores the value <tt>a</tt> into
|
||||
<tt>x</tt>. Note that <tt>operator=</tt>, like other C++ functions,
|
||||
may be overloaded; it may, in fact, even be a template function. In
|
||||
general, then, <tt>a</tt> may be any of several different types. A
|
||||
type <tt>A</tt> belongs to the <i>set of value types</i> of <tt>X</tt>
|
||||
if, for an object <tt>a</tt> of type <tt>A</tt>, <tt>*x = a;</tt> is
|
||||
well-defined and does not require performing any non-trivial
|
||||
conversions on <tt>a</tt>.
|
||||
|
||||
<h3>Associated Types</h3>
|
||||
|
||||
<Table border>
|
||||
|
||||
<tr>
|
||||
<td>Return Category</td>
|
||||
<td><tt>std::return_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::writable_iterator_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</Table>
|
||||
|
||||
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<A href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy Constructible</A>
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<tr>
|
||||
<TH>Name</TH><TH>Expression</TH><TH>Return type</TH>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Dereference assignment</td>
|
||||
<td><tt>*x = a</tt></td>
|
||||
<td>unspecified</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
||||
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:SwappableIterator"></A>
|
||||
Swappable Iterator
|
||||
</H3>
|
||||
|
||||
A Swappable Iterator is an iterator whose dereferenced values can be
|
||||
swapped.
|
||||
|
||||
<p>
|
||||
Note: the requirements for Swappable Iterator are dependent on the
|
||||
issues surrounding <tt>std::swap()</tt> being resolved. Here we assume
|
||||
that the issue will be resolved by allowing the overload of
|
||||
<tt>std::swap()</tt> for user-defined types.
|
||||
|
||||
<p>
|
||||
Note: Readable Iterator and Writable Iterator combined implies
|
||||
Swappable Iterator because of the fully templated
|
||||
<tt>std::swap()</tt>. However, Swappable Iterator does not imply
|
||||
Readable Iterator nor Writable Iterator.
|
||||
|
||||
<h3>Associated Types</h3>
|
||||
|
||||
<Table border>
|
||||
|
||||
<tr>
|
||||
<td>Return Category</td>
|
||||
<td><tt>std::return_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::swappable_iterator_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</Table>
|
||||
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
Of the two valid expressions listed below, only one <b>OR</b> the
|
||||
other is required. If <tt>std::iter_swap()</tt> is overloaded for
|
||||
<tt>X</tt> then <tt>std::swap()</tt> is not required. If
|
||||
<tt>std::iter_swap()</tt> is not overloaded for <tt>X</tt> then the
|
||||
default (fully templated) version is used, which will call
|
||||
<tt>std::swap()</tt> (this means changing the current requirements for
|
||||
<tt>std::iter_swap()</tt>).
|
||||
|
||||
<p>
|
||||
<Table border>
|
||||
<tr>
|
||||
<TH>Name</TH><TH>Expression</TH><TH>Return type</TH>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Iterator Swap</td>
|
||||
<td><tt>std::iter_swap(x, y)</tt></td>
|
||||
<td>void</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Dereference and Swap</td>
|
||||
<td><tt>std::swap(*x, *y)</tt></td>
|
||||
<td>void</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
||||
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:ConstantLvalueIterator"></A>
|
||||
Constant Lvalue Iterator
|
||||
</H3>
|
||||
|
||||
A Constant Lvalue Iterator is an iterator that dereferences to produce a
|
||||
const reference to the pointed-to object, i.e., the associated
|
||||
<tt>reference</tt> type is <tt>const T&</tt>. Changing the value
|
||||
of or destroying an iterator that models Constant Lvalue Iterator does
|
||||
not invalidate pointers and references previously obtained from that
|
||||
iterator.
|
||||
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<a href="#concept:ReadableIterator">Readable Iterator</a>
|
||||
|
||||
<h3>Associated Types</h3>
|
||||
|
||||
<Table border>
|
||||
|
||||
<tr>
|
||||
<td>Reference type</td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
<td>
|
||||
The return type of dereferencing the iterator, which must be
|
||||
<tt>const T&</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- I don't think this is needed
|
||||
<tr>
|
||||
<td>Pointer type</td>
|
||||
<td><tt>std::iterator_traits<X>::pointer</tt></td>
|
||||
<td>
|
||||
The pointer to the value type, which must be <tt>const T*</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
|
||||
<tr>
|
||||
<td>Return Category</td>
|
||||
<td><tt>std::return_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::constant_lvalue_iterator_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<!-- these are not necessary now that we use reference as operator* return type
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
|
||||
<tr>
|
||||
<td>Dereference</td>
|
||||
<td><tt>*x</tt></td>
|
||||
<td> </td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Member access</td>
|
||||
<td><tt>x->m</tt></td>
|
||||
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
-->
|
||||
|
||||
<p>
|
||||
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:MutableLvalueIterator"></A>
|
||||
Mutable Lvalue Iterator
|
||||
</H3>
|
||||
|
||||
A Mutable Lvalue Iterator is an iterator that dereferences to produce a
|
||||
reference to the pointed-to object. The associated <tt>reference</tt>
|
||||
type is <tt>T&</tt>. Changing the value of or destroying an
|
||||
iterator that models Mutable Lvalue Iterator does not invalidate
|
||||
pointers and references previously obtained from that iterator.
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<a href="#concept:ReadableIterator">Readable Iterator</a>,
|
||||
<a href="#concept:WritableIterator">Writable Iterator</a>,
|
||||
and <a href="#concept:SwappableIterator">Swappable Iterator</a>.
|
||||
|
||||
|
||||
|
||||
<h3>Associated Types</h3>
|
||||
|
||||
<Table border>
|
||||
|
||||
<tr>
|
||||
<td>Reference type</td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
<td>The return type of dereferencing the iterator, which must be
|
||||
<tt>T&</tt>.</td>
|
||||
</tr>
|
||||
|
||||
<!-- I don't think this is necessary
|
||||
<tr>
|
||||
<td>Pointer type</td>
|
||||
<td><tt>std::iterator_traits<X>::pointer</tt></td>
|
||||
<td>
|
||||
The pointer to the value type, which is <tt>T*</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
|
||||
<tr>
|
||||
<td>Return Category</td>
|
||||
<td><tt>std::return_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::mutable_lvalue_iterator_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<!-- no longer needed since the return type is specified as reference in the readable iterator
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
|
||||
<tr>
|
||||
<td>Dereference</td>
|
||||
<td><tt>*x</tt></td>
|
||||
<td> </td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Member access</td>
|
||||
<td><tt>x->m</tt></td>
|
||||
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
-->
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:ForwardTraversalIterator"></A>
|
||||
Forward Traversal Iterator
|
||||
</H3>
|
||||
|
||||
The Forward Iterator is an iterator that can be incremented. Also, it
|
||||
is permissible to make multiple passes through the iterator's range.
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<A href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy Constructible</A>,
|
||||
<A href="http://www.boost.org/libs/utility/Assignable.html">Assignable</A>,
|
||||
<A href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default Constructible</A>, and
|
||||
<A href="http://www.sgi.com/tech/stl/EqualityComparable.html">Equality Comparable</A>
|
||||
|
||||
|
||||
<h3>Associated types</h3>
|
||||
|
||||
<Table border>
|
||||
|
||||
<tr>
|
||||
<td>Difference Type</td>
|
||||
<td><tt>std::iterator_traits<X>::difference_type</tt></td>
|
||||
<td>
|
||||
A signed integral type used for representing distances
|
||||
between iterators that point into the same range.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Traversal Category</td>
|
||||
<td><tt>std::traversal_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::forward_traversal_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
</Table>
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<tr>
|
||||
<TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
|
||||
<TH>Return type</TH>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Preincrement</td>
|
||||
<td><tt>++i</tt></td><td> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Postincrement</td>
|
||||
<td><tt>i++</tt></td><td> </td><td>convertible to <tt>const X&</tt></td>
|
||||
</tr>
|
||||
</Table>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:BidirectionalTraversalIterator"></A>
|
||||
Bidirectional Traversal Iterator
|
||||
</H3>
|
||||
|
||||
An iterator that can be incremented and decremented.
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<a href="#concept:ForwardTraversalIterator">Forward Traversal Iterator</a>
|
||||
|
||||
<h3>Associated types</h3>
|
||||
|
||||
<Table border>
|
||||
<tr>
|
||||
<td>Traversal Category</td>
|
||||
<td><tt>std::traversal_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::bidirectional_traversal_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
</Table>
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<tr>
|
||||
<TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
|
||||
<TH>Return type</TH>
|
||||
</tr>
|
||||
<tr><td>Predecrement</td>
|
||||
<td><tt>--i</tt></td><td> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr><td>Postdecrement</td>
|
||||
<td><tt>i--</tt></td><td> </td><td>convertible to <tt>const X&</tt></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<!--------------------------------------------------------------------------->
|
||||
|
||||
<H3><A NAME="concept:RandomAccessTraversalIterator"></A>
|
||||
Random Access Traversal Iterator
|
||||
</H3>
|
||||
|
||||
An iterator that provides constant-time methods for moving forward and
|
||||
backward in arbitrary-sized steps.
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
|
||||
<a href="#concept:BidirectionalTraversalIterator">Bidirectional Traversal Iterator</a> and
|
||||
<A href="http://www.sgi.com/tech/stl/LessThanComparable.html">Less Than Comparable</A> where <tt><</tt> is a total ordering
|
||||
|
||||
<h3>Associated types</h3>
|
||||
|
||||
<Table border>
|
||||
<tr>
|
||||
<td>Traversal Category</td>
|
||||
<td><tt>std::traversal_category<X>::type</tt></td>
|
||||
<td>
|
||||
A type convertible to <tt>std::random_access_traversal_tag</tt>
|
||||
</td>
|
||||
</tr>
|
||||
</Table>
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
|
||||
<TH>Return type</TH>
|
||||
</tr>
|
||||
<tr><td>Iterator addition</td>
|
||||
<td><tt>i += n</tt></td><td> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr><td>Iterator addition</td>
|
||||
<td><tt>i + n</tt> or <tt>n + i</tt></td><td> </td><td><tt>X</tt></td>
|
||||
</tr>
|
||||
<tr><td>Iterator subtraction</td>
|
||||
<td><tt>i -= n</tt></td><td> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr><td>Iterator subtraction</td>
|
||||
<td><tt>i - n</tt></td><td> </td><td><tt>X</tt></td>
|
||||
</tr>
|
||||
<tr><td>Difference</td>
|
||||
<td><tt>i - j</tt></td><td> </td><td><tt>std::iterator_traits<X>::difference_type</tt></td>
|
||||
</tr>
|
||||
<tr><td>Element operator</td>
|
||||
<td><tt>i[n]</tt></td>
|
||||
<td><tt>X</tt> must also be a model of
|
||||
<a href="#concept:ReadableIterator">Readable Iterator</a>. </td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
</tr>
|
||||
<tr><td>Element assignment</td>
|
||||
<td><tt>i[n] = t</tt></td>
|
||||
<td><tt>X</tt> must also be a model of
|
||||
<a href="#concept:WritableIterator">Writable Iterator</a>.</td>
|
||||
<td>unspecified</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2000</TD><TD>
|
||||
<A HREF="../../../../people/jeremy_siek.htm">Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,229 +0,0 @@
|
||||
// (C) Copyright David Abrahams and Jeremy Siek 2000-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.
|
||||
//
|
||||
// Supplies:
|
||||
//
|
||||
// template <class Incrementable> class counting_iterator_traits;
|
||||
// template <class Incrementable> class counting_iterator_policies;
|
||||
//
|
||||
// Iterator traits and policies for adapted iterators whose dereferenced
|
||||
// value progresses through consecutive values of Incrementable when the
|
||||
// iterator is derferenced.
|
||||
//
|
||||
// template <class Incrementable> struct counting_iterator_generator;
|
||||
//
|
||||
// A "type generator" whose nested type "type" is a counting iterator as
|
||||
// described above.
|
||||
//
|
||||
// template <class Incrementable>
|
||||
// typename counting_iterator_generator<Incrementable>::type
|
||||
// make_counting_iterator(Incrementable);
|
||||
//
|
||||
// A function which produces an adapted counting iterator over values of
|
||||
// Incrementable.
|
||||
//
|
||||
// Revision History
|
||||
// 14 Feb 2001 Removed unnecessary typedefs from counting_iterator_traits
|
||||
// (Jeremy Siek)
|
||||
// 11 Feb 2001 Use BOOST_STATIC_CONSTANT (Dave Abrahams)
|
||||
// 11 Feb 2001 Clean up after John Maddocks's (finally effective!) Borland
|
||||
// fixes (David Abrahams).
|
||||
// 10 Feb 2001 Use new iterator_adaptor<> interface (David Abrahams)
|
||||
// 10 Feb 2001 Rolled in supposed Borland fixes from John Maddock, but not
|
||||
// seeing any improvement yet (David Abrahams)
|
||||
// 09 Feb 2001 Factored out is_numeric computation. Borland still
|
||||
// unhappy :( (David Abrahams)
|
||||
// 08 Feb 2001 Beginning of a failed attempt to appease Borland
|
||||
// (David Abrahams)
|
||||
// 07 Feb 2001 rename counting_iterator() -> make_counting_iterator()
|
||||
// (David Abrahams)
|
||||
// 04 Feb 2001 Added counting_iterator_generator; updated comments
|
||||
// (David Abrahams)
|
||||
// 24 Jan 2001 initial revision, based on Jeremy Siek's
|
||||
// boost/pending/integer_range.hpp (David Abrahams)
|
||||
|
||||
#ifndef BOOST_COUNTING_ITERATOR_HPP_DWA20000119
|
||||
# define BOOST_COUNTING_ITERATOR_HPP_DWA20000119
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/iterator_adaptors.hpp>
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/detail/numeric_traits.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/limits.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Template class counting_iterator_traits_select -- choose an
|
||||
// iterator_category and difference_type for a counting_iterator at
|
||||
// compile-time based on whether or not it wraps an integer or an iterator,
|
||||
// using "poor man's partial specialization".
|
||||
template <bool is_integer> struct counting_iterator_traits_select;
|
||||
|
||||
// Incrementable is an iterator type
|
||||
template <>
|
||||
struct counting_iterator_traits_select<false>
|
||||
{
|
||||
template <class Incrementable>
|
||||
struct traits
|
||||
{
|
||||
private:
|
||||
typedef boost::detail::iterator_traits<Incrementable> x;
|
||||
public:
|
||||
typedef typename x::iterator_category iterator_category;
|
||||
typedef typename x::difference_type difference_type;
|
||||
};
|
||||
};
|
||||
|
||||
// Incrementable is a numeric type
|
||||
template <>
|
||||
struct counting_iterator_traits_select<true>
|
||||
{
|
||||
template <class Incrementable>
|
||||
struct traits
|
||||
{
|
||||
typedef typename
|
||||
boost::detail::numeric_traits<Incrementable>::difference_type
|
||||
difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
};
|
||||
};
|
||||
|
||||
// Template class distance_policy_select -- choose a policy for computing the
|
||||
// distance between counting_iterators at compile-time based on whether or not
|
||||
// the iterator wraps an integer or an iterator, using "poor man's partial
|
||||
// specialization".
|
||||
|
||||
template <bool is_integer> struct distance_policy_select;
|
||||
|
||||
// A policy for wrapped iterators
|
||||
template <>
|
||||
struct distance_policy_select<false>
|
||||
{
|
||||
template <class Distance, class Incrementable>
|
||||
struct policy {
|
||||
static Distance distance(Incrementable x, Incrementable y)
|
||||
{ return boost::detail::distance(x, y); }
|
||||
};
|
||||
};
|
||||
|
||||
// A policy for wrapped numbers
|
||||
template <>
|
||||
struct distance_policy_select<true>
|
||||
{
|
||||
template <class Distance, class Incrementable>
|
||||
struct policy {
|
||||
static Distance distance(Incrementable x, Incrementable y)
|
||||
{ return numeric_distance(x, y); }
|
||||
};
|
||||
};
|
||||
|
||||
// Try to detect numeric types at compile time in ways compatible with the
|
||||
// limitations of the compiler and library.
|
||||
template <class T>
|
||||
struct is_numeric {
|
||||
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
|
||||
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
|
||||
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
# if defined(BOOST_HAS_LONG_LONG)
|
||||
BOOST_STATIC_CONSTANT(bool,
|
||||
value = (
|
||||
std::numeric_limits<T>::is_specialized
|
||||
| boost::is_same<T,long long>::value
|
||||
| boost::is_same<T,unsigned long long>::value));
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
|
||||
# endif
|
||||
# else
|
||||
# if !defined(__BORLANDC__)
|
||||
BOOST_STATIC_CONSTANT(bool, value = (
|
||||
boost::is_convertible<int,T>::value && boost::is_convertible<T,int>::value));
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
|
||||
# endif
|
||||
# endif
|
||||
};
|
||||
|
||||
// Compute the distance over arbitrary numeric and/or iterator types
|
||||
template <class Distance, class Incrementable>
|
||||
Distance any_distance(Incrementable start, Incrementable finish, Distance* = 0)
|
||||
{
|
||||
|
||||
return distance_policy_select<(
|
||||
is_numeric<Incrementable>::value)>::template
|
||||
policy<Distance, Incrementable>::distance(start, finish);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Incrementable>
|
||||
struct counting_iterator_traits {
|
||||
private:
|
||||
typedef ::boost::detail::counting_iterator_traits_select<(
|
||||
::boost::detail::is_numeric<Incrementable>::value
|
||||
)> binder;
|
||||
typedef typename binder::template traits<Incrementable> traits;
|
||||
public:
|
||||
typedef typename traits::difference_type difference_type;
|
||||
typedef typename traits::iterator_category iterator_category;
|
||||
};
|
||||
|
||||
template <class Incrementable>
|
||||
struct counting_iterator_policies : public default_iterator_policies
|
||||
{
|
||||
template <class IteratorAdaptor>
|
||||
typename IteratorAdaptor::reference dereference(const IteratorAdaptor& i) const
|
||||
{ return i.base(); }
|
||||
|
||||
template <class Iterator1, class Iterator2>
|
||||
typename Iterator1::difference_type distance(
|
||||
const Iterator1& x, const Iterator2& y) const
|
||||
{
|
||||
typedef typename Iterator1::difference_type difference_type;
|
||||
return boost::detail::any_distance<difference_type>(
|
||||
x.base(), y.base());
|
||||
}
|
||||
};
|
||||
|
||||
// A type generator for counting iterators
|
||||
template <class Incrementable>
|
||||
struct counting_iterator_generator
|
||||
{
|
||||
typedef typename boost::remove_const<
|
||||
Incrementable
|
||||
>::type value_type;
|
||||
|
||||
typedef counting_iterator_traits<value_type> traits;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
value_type
|
||||
, counting_iterator_policies<value_type>
|
||||
, value_type
|
||||
, value_type const&
|
||||
, value_type const*
|
||||
, typename traits::iterator_category
|
||||
, typename traits::difference_type
|
||||
> type;
|
||||
};
|
||||
|
||||
// Manufacture a counting iterator for an arbitrary incrementable type
|
||||
template <class Incrementable>
|
||||
inline typename counting_iterator_generator<Incrementable>::type
|
||||
make_counting_iterator(Incrementable x)
|
||||
{
|
||||
typedef typename counting_iterator_generator<Incrementable>::type result_t;
|
||||
return result_t(x);
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COUNTING_ITERATOR_HPP_DWA20000119
|
@ -1,55 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 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.
|
||||
|
||||
// Revision History:
|
||||
|
||||
// 27 Feb 2001 Jeremy Siek
|
||||
// Initial checkin.
|
||||
|
||||
#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||
#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator {
|
||||
typedef function_output_iterator self;
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
: m_f(f) {}
|
||||
|
||||
struct output_proxy {
|
||||
output_proxy(UnaryFunction& f) : m_f(f) { }
|
||||
template <class T> output_proxy& operator=(const T& value) {
|
||||
m_f(value);
|
||||
return *this;
|
||||
}
|
||||
UnaryFunction& m_f;
|
||||
};
|
||||
output_proxy operator*() { return output_proxy(m_f); }
|
||||
self& operator++() { return *this; }
|
||||
self& operator++(int) { return *this; }
|
||||
private:
|
||||
UnaryFunction m_f;
|
||||
};
|
||||
|
||||
template <class UnaryFunction>
|
||||
inline function_output_iterator<UnaryFunction>
|
||||
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
|
||||
return function_output_iterator<UnaryFunction>(f);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
@ -1,426 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek and David Abrahams 2000-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.
|
||||
//
|
||||
// Revision History:
|
||||
// 11 Feb 2001 Use new iterator_adaptor interface, Fixes for Borland.
|
||||
// (Dave Abrahams)
|
||||
// 04 Feb 2001 Support for user-defined iterator categories (Dave Abrahams)
|
||||
// 30 Jan 2001 Initial Checkin (Dave Abrahams)
|
||||
|
||||
#ifndef BOOST_HALF_OPEN_RANGE_HPP_
|
||||
# define BOOST_HALF_OPEN_RANGE_HPP_
|
||||
|
||||
# include <boost/counting_iterator.hpp>
|
||||
# include <functional>
|
||||
# include <cassert>
|
||||
# include <boost/operators.hpp>
|
||||
# include <string>
|
||||
# include <stdexcept>
|
||||
# include <iterator>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Template class choose_finish -- allows us to maintain the invariant that
|
||||
// start() <= finish() on half_open_range specializations that support random
|
||||
// access.
|
||||
#ifdef __MWERKS__
|
||||
template <class T>
|
||||
const T& choose_finish(const T&, const T& finish, std::input_iterator_tag)
|
||||
{
|
||||
return finish;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& choose_finish(const T&, const T& finish, std::output_iterator_tag)
|
||||
{
|
||||
return finish;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& choose_finish(const T& start, const T& finish, std::random_access_iterator_tag)
|
||||
{
|
||||
return finish < start ? start : finish;
|
||||
}
|
||||
#else
|
||||
template <bool is_random_access> struct finish_chooser;
|
||||
|
||||
template <>
|
||||
struct finish_chooser<false>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
static T choose(const T&, const T& finish)
|
||||
{ return finish; }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct finish_chooser<true>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
static T choose(const T& start, const T& finish)
|
||||
{ return finish < start ? start : finish; }
|
||||
};
|
||||
};
|
||||
|
||||
template <class Category, class Incrementable>
|
||||
struct choose_finish
|
||||
{
|
||||
static const Incrementable choose(const Incrementable& start, const Incrementable& finish)
|
||||
{
|
||||
return finish_chooser<(
|
||||
::boost::is_convertible<Category*,std::random_access_iterator_tag*>::value
|
||||
)>::template rebind<Incrementable>::choose(start, finish);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
struct half_open_range
|
||||
{
|
||||
typedef typename counting_iterator_generator<Incrementable>::type iterator;
|
||||
|
||||
private: // utility type definitions
|
||||
// Using iter_t prevents compiler confusion with boost::iterator
|
||||
typedef typename counting_iterator_generator<Incrementable>::type iter_t;
|
||||
|
||||
typedef std::less<Incrementable> less_value;
|
||||
typedef typename iter_t::iterator_category category;
|
||||
typedef half_open_range<Incrementable> self;
|
||||
|
||||
public:
|
||||
typedef iter_t const_iterator;
|
||||
typedef typename iterator::value_type value_type;
|
||||
typedef typename iterator::difference_type difference_type;
|
||||
typedef typename iterator::reference reference;
|
||||
typedef typename iterator::reference const_reference;
|
||||
typedef typename iterator::pointer pointer;
|
||||
typedef typename iterator::pointer const_pointer;
|
||||
|
||||
// It would be nice to select an unsigned type, but this is appropriate
|
||||
// since the library makes an attempt to select a difference_type which can
|
||||
// hold the difference between any two iterators.
|
||||
typedef typename iterator::difference_type size_type;
|
||||
|
||||
half_open_range(Incrementable start, Incrementable finish)
|
||||
: m_start(start),
|
||||
m_finish(
|
||||
#ifndef __MWERKS__
|
||||
detail::choose_finish<category,Incrementable>::choose(start, finish)
|
||||
#else
|
||||
detail::choose_finish(start, finish, category())
|
||||
#endif
|
||||
)
|
||||
{}
|
||||
|
||||
// Implicit conversion from std::pair<Incrementable,Incrementable> allows us
|
||||
// to accept the results of std::equal_range(), for example.
|
||||
half_open_range(const std::pair<Incrementable,Incrementable>& x)
|
||||
: m_start(x.first),
|
||||
m_finish(
|
||||
#ifndef __MWERKS__
|
||||
detail::choose_finish<category,Incrementable>::choose(x.first, x.second)
|
||||
#else
|
||||
detail::choose_finish(x.first, x.second, category())
|
||||
#endif
|
||||
)
|
||||
{}
|
||||
|
||||
half_open_range& operator=(const self& x)
|
||||
{
|
||||
m_start = x.m_start;
|
||||
m_finish = x.m_finish;
|
||||
return *this;
|
||||
}
|
||||
|
||||
half_open_range& operator=(const std::pair<Incrementable,Incrementable>& x)
|
||||
{
|
||||
m_start = x.first;
|
||||
m_finish =
|
||||
#ifndef __MWERKS__
|
||||
detail::choose_finish<category,Incrementable>::choose(x.first, x.second);
|
||||
#else
|
||||
detail::choose_finish(x.first, x.second, category();
|
||||
#endif
|
||||
}
|
||||
|
||||
iterator begin() const { return iterator(m_start); }
|
||||
iterator end() const { return iterator(m_finish); }
|
||||
|
||||
Incrementable front() const { assert(!this->empty()); return m_start; }
|
||||
Incrementable back() const { assert(!this->empty()); return boost::prior(m_finish); }
|
||||
|
||||
Incrementable start() const { return m_start; }
|
||||
Incrementable finish() const { return m_finish; }
|
||||
|
||||
size_type size() const { return boost::detail::distance(begin(), end()); }
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return m_finish == m_start;
|
||||
}
|
||||
|
||||
void swap(half_open_range& x) {
|
||||
std::swap(m_start, x.m_start);
|
||||
std::swap(m_finish, x.m_finish);
|
||||
}
|
||||
|
||||
public: // functions requiring random access elements
|
||||
|
||||
// REQUIRES: x is reachable from this->front()
|
||||
bool contains(const value_type& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
return !less_value()(x, m_start) && less_value()(x, m_finish);
|
||||
}
|
||||
|
||||
bool contains(const half_open_range& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
return x.empty() || !less_value()(x.m_start, m_start) && !less_value()(m_finish, x.m_finish);
|
||||
}
|
||||
|
||||
bool intersects(const half_open_range& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
return less_value()(
|
||||
less_value()(this->m_start, x.m_start) ? x.m_start : this->m_start,
|
||||
less_value()(this->m_finish, x.m_finish) ? this->m_finish : x.m_finish);
|
||||
}
|
||||
|
||||
half_open_range& operator&=(const half_open_range& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
|
||||
if (less_value()(this->m_start, x.m_start))
|
||||
this->m_start = x.m_start;
|
||||
|
||||
if (less_value()(x.m_finish, this->m_finish))
|
||||
this->m_finish = x.m_finish;
|
||||
|
||||
if (less_value()(this->m_finish, this->m_start))
|
||||
this->m_start = this->m_finish;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
half_open_range& operator|=(const half_open_range& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
|
||||
if (!x.empty())
|
||||
{
|
||||
if (this->empty())
|
||||
{
|
||||
*this = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (less_value()(x.m_start, this->m_start))
|
||||
this->m_start = x.m_start;
|
||||
|
||||
if (less_value()(this->m_finish, x.m_finish))
|
||||
this->m_finish = x.m_finish;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// REQUIRES: x is reachable from this->front()
|
||||
const_iterator find(const value_type& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
|
||||
return const_iterator(this->contains(x) ? x : m_finish);
|
||||
}
|
||||
|
||||
// REQUIRES: index >= 0 && index < size()
|
||||
value_type operator[](size_type index) const
|
||||
{
|
||||
assert(index >= 0 && index < size());
|
||||
return m_start + index;
|
||||
}
|
||||
|
||||
value_type at(size_type index) const
|
||||
{
|
||||
if (index < 0 || index >= size())
|
||||
throw std::out_of_range(std::string("half_open_range"));
|
||||
return m_start + index;
|
||||
}
|
||||
|
||||
private: // data members
|
||||
Incrementable m_start, m_finish;
|
||||
};
|
||||
|
||||
template <class Incrementable>
|
||||
half_open_range<Incrementable> operator|(
|
||||
half_open_range<Incrementable> x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x |= y;
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
half_open_range<Incrementable> operator&(
|
||||
half_open_range<Incrementable> x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x &= y;
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
inline bool operator==(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
const bool y_empty = y.empty();
|
||||
return x.empty() ? y_empty : !y_empty && x.start() == y.start() && x.finish() == y.finish();
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
inline bool operator!=(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
inline half_open_range<Incrementable>
|
||||
make_half_open_range(Incrementable first, Incrementable last)
|
||||
{
|
||||
return half_open_range<Incrementable>(first, last);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool intersects(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x.intersects(y);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool contains(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x.contains(y);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
namespace std {
|
||||
template <class Incrementable> struct less<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
less<Incrementable> cmp;
|
||||
return !y.empty() && (
|
||||
cmp(x.start(), y.start())
|
||||
|| !cmp(y.start(), x.start())
|
||||
&& cmp(x.finish(), y.finish()));
|
||||
}
|
||||
};
|
||||
|
||||
template <class Incrementable> struct less_equal<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
typedef boost::half_open_range<Incrementable> range;
|
||||
less<range> cmp;
|
||||
return !cmp(y,x);
|
||||
}
|
||||
};
|
||||
template <class Incrementable> struct greater<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
typedef boost::half_open_range<Incrementable> range;
|
||||
less<range> cmp;
|
||||
return cmp(y,x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Incrementable> struct greater_equal<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
typedef boost::half_open_range<Incrementable> range;
|
||||
less<range> cmp;
|
||||
return !cmp(x,y);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#else
|
||||
|
||||
namespace boost {
|
||||
// Can't partially specialize std::less et al, so we must provide the operators
|
||||
template <class Incrementable>
|
||||
bool operator<(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !y.empty() && (
|
||||
x.empty() || std::less<Incrementable>()(x.start(), y.start())
|
||||
|| !std::less<Incrementable>()(y.start(), x.start())
|
||||
&& std::less<Incrementable>()(x.finish(), y.finish()));
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool operator>(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool operator<=(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool operator>=(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !(x < y);
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BOOST_HALF_OPEN_RANGE_HPP_
|
@ -1,60 +0,0 @@
|
||||
// interator.hpp workarounds for non-conforming standard libraries ---------//
|
||||
|
||||
// (C) Copyright Boost.org 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.
|
||||
|
||||
// Revision History
|
||||
// 12 Jan 01 added <cstddef> for std::ptrdiff_t (Jens Maurer)
|
||||
// 28 Jun 00 Workarounds to deal with known MSVC bugs (David Abrahams)
|
||||
// 26 Jun 00 Initial version (Jeremy Siek)
|
||||
|
||||
#ifndef BOOST_ITERATOR_HPP
|
||||
#define BOOST_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <cstddef> // std::ptrdiff_t
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
|
||||
template <class Category, class T,
|
||||
class Distance = std::ptrdiff_t,
|
||||
class Pointer = T*, class Reference = T&>
|
||||
struct iterator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef Distance difference_type;
|
||||
typedef Pointer pointer;
|
||||
typedef Reference reference;
|
||||
typedef Category iterator_category;
|
||||
};
|
||||
# else
|
||||
|
||||
// declare iterator_base in namespace detail to work around MSVC bugs which
|
||||
// prevent derivation from an identically-named class in a different namespace.
|
||||
namespace detail {
|
||||
template <class Category, class T, class Distance, class Pointer, class Reference>
|
||||
# if !defined(BOOST_MSVC_STD_ITERATOR)
|
||||
struct iterator_base : std::iterator<Category, T, Distance, Pointer, Reference> {};
|
||||
# else
|
||||
struct iterator_base : std::iterator<Category, T, Distance>
|
||||
{
|
||||
typedef Reference reference;
|
||||
typedef Pointer pointer;
|
||||
typedef Distance difference_type;
|
||||
};
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Category, class T, class Distance = std::ptrdiff_t,
|
||||
class Pointer = T*, class Reference = T&>
|
||||
struct iterator : detail::iterator_base<Category, T, Distance, Pointer, Reference> {};
|
||||
# endif
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_HPP
|
353
include/boost/iterator/zip_iterator.hpp
Executable file
353
include/boost/iterator/zip_iterator.hpp
Executable file
@ -0,0 +1,353 @@
|
||||
// (C) Copyright David Abrahams and Thomas Becker 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.
|
||||
//
|
||||
// Compilers Tested:
|
||||
// =================
|
||||
// Metrowerks Codewarrior Pro 7.2, 8.3
|
||||
// gcc 2.95.3
|
||||
// gcc 3.2
|
||||
// Microsoft VC 6sp5 (test fails due to some compiler bug)
|
||||
// Microsoft VC 7 (works)
|
||||
// Microsoft VC 7.1
|
||||
// Intel 5
|
||||
// Intel 6
|
||||
// Intel 7.1
|
||||
// Intel 8
|
||||
// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
|
||||
|
||||
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||
# define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/detail/minimum_category.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/lambda.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/transform.hpp>
|
||||
|
||||
#include <boost/spirit/fusion/algorithm/transform.hpp>
|
||||
#include <boost/spirit/fusion/algorithm/for_each.hpp>
|
||||
#include <boost/spirit/fusion/algorithm/fold.hpp>
|
||||
#include <boost/spirit/fusion/sequence/generate.hpp>
|
||||
#include <boost/spirit/fusion/sequence/begin.hpp>
|
||||
#include <boost/spirit/fusion/algorithm/push_front.hpp>
|
||||
#include <boost/spirit/fusion/sequence/equal_to.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Zip iterator forward declaration for zip_iterator_base
|
||||
template<typename IteratorTuple>
|
||||
class zip_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Functors to be used with tuple algorithms
|
||||
//
|
||||
template<typename DiffType>
|
||||
class advance_iterator
|
||||
{
|
||||
public:
|
||||
advance_iterator(DiffType step) : m_step(step) {}
|
||||
|
||||
template<typename Iterator>
|
||||
void operator()(Iterator& it) const
|
||||
{ it += m_step; }
|
||||
|
||||
private:
|
||||
DiffType m_step;
|
||||
};
|
||||
//
|
||||
struct increment_iterator
|
||||
{
|
||||
template<typename Iterator>
|
||||
void operator()(Iterator& it) const
|
||||
{ ++it; }
|
||||
};
|
||||
//
|
||||
struct decrement_iterator
|
||||
{
|
||||
template<typename Iterator>
|
||||
void operator()(Iterator& it) const
|
||||
{ --it; }
|
||||
};
|
||||
//
|
||||
struct dereference_iterator
|
||||
{
|
||||
template<typename Iterator>
|
||||
struct apply : iterator_reference<Iterator>
|
||||
{};
|
||||
|
||||
template<typename Iterator>
|
||||
typename apply<Iterator>::type
|
||||
operator()(Iterator const& it) const
|
||||
{ return *it; }
|
||||
};
|
||||
|
||||
struct dereference
|
||||
{
|
||||
template <class Iterator>
|
||||
struct apply
|
||||
: boost::iterator_reference<Iterator>
|
||||
{};
|
||||
|
||||
template <class Iterator>
|
||||
typename apply<Iterator>::type operator()(Iterator const& x) const
|
||||
{
|
||||
return *x;
|
||||
}
|
||||
};
|
||||
|
||||
// Metafunction to obtain the type of the tuple whose element types
|
||||
// are the reference types of an iterator tuple.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct tuple_of_references
|
||||
: mpl::transform<IteratorTuple, dereference::apply<mpl::_1> >
|
||||
{};
|
||||
|
||||
// Metafunction to obtain the minimal traversal tag in a tuple
|
||||
// of iterators.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct minimum_traversal_category_in_iterator_tuple
|
||||
: mpl::fold<
|
||||
typename mpl::transform<
|
||||
IteratorTuple, iterator_traversal<>
|
||||
>::type
|
||||
, random_access_traversal_tag
|
||||
, minimum_category<>
|
||||
>
|
||||
{};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|
||||
template <>
|
||||
struct minimum_traversal_category_in_iterator_tuple<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
#endif
|
||||
|
||||
// We need to call tuple_meta_accumulate with mpl::and_ as the
|
||||
// accumulating functor. To this end, we need to wrap it into
|
||||
// a struct that has exactly two arguments (that is, template
|
||||
// parameters) and not five, like mpl::and_ does.
|
||||
//
|
||||
template<typename Arg1, typename Arg2>
|
||||
struct and_with_two_args
|
||||
: mpl::and_<Arg1, Arg2>
|
||||
{
|
||||
};
|
||||
|
||||
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. In this case I think it's an MPL bug
|
||||
template<>
|
||||
struct and_with_two_args<mpl::_1,mpl::_2>
|
||||
{
|
||||
template <class A1, class A2>
|
||||
struct apply : mpl::and_<A1,A2>
|
||||
{};
|
||||
};
|
||||
# endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class zip_iterator_base
|
||||
//
|
||||
// Builds and exposes the iterator facade type from which the zip
|
||||
// iterator will be derived.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct zip_iterator_base
|
||||
{
|
||||
private:
|
||||
// Reference type is the type of the tuple obtained from the
|
||||
// iterators' reference types.
|
||||
typedef typename
|
||||
detail::tuple_of_references<IteratorTuple>::type reference;
|
||||
|
||||
// Value type is the same as reference type.
|
||||
typedef reference value_type;
|
||||
|
||||
// Difference type is the first iterator's difference type
|
||||
typedef typename iterator_traits<
|
||||
typename mpl::front<IteratorTuple>::type
|
||||
>::difference_type difference_type;
|
||||
|
||||
// Traversal catetgory is the minimum traversal category in the
|
||||
// iterator tuple.
|
||||
typedef typename
|
||||
detail::minimum_traversal_category_in_iterator_tuple<
|
||||
IteratorTuple
|
||||
>::type traversal_category;
|
||||
public:
|
||||
|
||||
// The iterator facade type from which the zip iterator will
|
||||
// be derived.
|
||||
typedef iterator_facade<
|
||||
zip_iterator<IteratorTuple>,
|
||||
value_type,
|
||||
traversal_category,
|
||||
reference,
|
||||
difference_type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct zip_iterator_base<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// zip_iterator class definition
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
class zip_iterator :
|
||||
public detail::zip_iterator_base<IteratorTuple>::type
|
||||
{
|
||||
|
||||
// Typedef super_t as our base class.
|
||||
typedef typename
|
||||
detail::zip_iterator_base<IteratorTuple>::type super_t;
|
||||
|
||||
// iterator_core_access is the iterator's best friend.
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
|
||||
// Construction
|
||||
// ============
|
||||
|
||||
// Default constructor
|
||||
zip_iterator() { }
|
||||
|
||||
// Constructor from iterator tuple
|
||||
zip_iterator(IteratorTuple iterator_tuple)
|
||||
: m_iterator_tuple(iterator_tuple)
|
||||
{ }
|
||||
|
||||
// Copy constructor
|
||||
template<typename OtherIteratorTuple>
|
||||
zip_iterator(
|
||||
const zip_iterator<OtherIteratorTuple>& other,
|
||||
typename enable_if_convertible<
|
||||
OtherIteratorTuple,
|
||||
IteratorTuple
|
||||
>::type* = 0
|
||||
) : m_iterator_tuple(other.get_iterator_tuple())
|
||||
{}
|
||||
|
||||
// Get method for the iterator tuple.
|
||||
const IteratorTuple& get_iterator_tuple() const
|
||||
{ return m_iterator_tuple; }
|
||||
|
||||
private:
|
||||
|
||||
// Implementation of Iterator Operations
|
||||
// =====================================
|
||||
|
||||
// Dereferencing returns a tuple built from the dereferenced
|
||||
// iterators in the iterator tuple.
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
return fusion::generate(fusion::transform(
|
||||
get_iterator_tuple(),
|
||||
detail::dereference_iterator()
|
||||
));
|
||||
}
|
||||
|
||||
// Two zip iterators are equal if all iterators in the iterator
|
||||
// tuple are equal. NOTE: It should be possible to implement this
|
||||
// as
|
||||
//
|
||||
// return get_iterator_tuple() == other.get_iterator_tuple();
|
||||
//
|
||||
// but equality of tuples currently (7/2003) does not compile
|
||||
// under several compilers. No point in bringing in a bunch
|
||||
// of #ifdefs here.
|
||||
//
|
||||
template<typename OtherIteratorTuple>
|
||||
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
|
||||
{
|
||||
return get_iterator_tuple() == other.get_iterator_tuple();
|
||||
}
|
||||
|
||||
// Advancing a zip iterator means to advance all iterators in the
|
||||
// iterator tuple.
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
fusion::for_each(
|
||||
m_iterator_tuple,
|
||||
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
|
||||
);
|
||||
}
|
||||
// Incrementing a zip iterator means to increment all iterators in
|
||||
// the iterator tuple.
|
||||
void increment()
|
||||
{
|
||||
fusion::for_each(
|
||||
m_iterator_tuple,
|
||||
detail::increment_iterator()
|
||||
);
|
||||
}
|
||||
|
||||
// Decrementing a zip iterator means to decrement all iterators in
|
||||
// the iterator tuple.
|
||||
void decrement()
|
||||
{
|
||||
fusion::for_each(
|
||||
m_iterator_tuple,
|
||||
detail::decrement_iterator()
|
||||
);
|
||||
}
|
||||
|
||||
// Distance is calculated using the first iterator in the tuple.
|
||||
template<typename OtherIteratorTuple>
|
||||
typename super_t::difference_type distance_to(
|
||||
const zip_iterator<OtherIteratorTuple>& other
|
||||
) const
|
||||
{
|
||||
return *fusion::begin(other.get_iterator_tuple()) -
|
||||
*fusion::begin(this->get_iterator_tuple());
|
||||
}
|
||||
|
||||
// Data Members
|
||||
// ============
|
||||
|
||||
// The iterator tuple.
|
||||
IteratorTuple m_iterator_tuple;
|
||||
|
||||
};
|
||||
|
||||
// Make function for zip iterator
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
zip_iterator<IteratorTuple>
|
||||
make_zip_iterator(IteratorTuple t)
|
||||
{ return zip_iterator<IteratorTuple>(t); }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,75 +0,0 @@
|
||||
// (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.
|
||||
|
||||
#ifndef BOOST_INT_ITERATOR_H
|
||||
#define BOOST_INT_ITERATOR_H
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#if !defined BOOST_MSVC
|
||||
#include <boost/operators.hpp>
|
||||
#endif
|
||||
#include <iostream>
|
||||
//using namespace std;
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
namespace boost {
|
||||
#endif
|
||||
|
||||
// this should use random_access_iterator_helper but I've had
|
||||
// VC++ portablility problems with that. -JGS
|
||||
template <class IntT>
|
||||
class int_iterator
|
||||
{
|
||||
typedef int_iterator self;
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef IntT value_type;
|
||||
typedef IntT& reference;
|
||||
typedef IntT* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
inline int_iterator() : _i(0) { }
|
||||
inline int_iterator(IntT i) : _i(i) { }
|
||||
inline int_iterator(const self& x) : _i(x._i) { }
|
||||
inline self& operator=(const self& x) { _i = x._i; return *this; }
|
||||
inline IntT operator*() { return _i; }
|
||||
inline IntT operator[](IntT n) { return _i + n; }
|
||||
inline self& operator++() { ++_i; return *this; }
|
||||
inline self operator++(int) { self t = *this; ++_i; return t; }
|
||||
inline self& operator+=(IntT n) { _i += n; return *this; }
|
||||
inline self operator+(IntT n) { self t = *this; t += n; return t; }
|
||||
inline self& operator--() { --_i; return *this; }
|
||||
inline self operator--(int) { self t = *this; --_i; return t; }
|
||||
inline self& operator-=(IntT n) { _i -= n; return *this; }
|
||||
inline IntT operator-(const self& x) const { return _i - x._i; }
|
||||
inline bool operator==(const self& x) const { return _i == x._i; }
|
||||
// vc++ had a problem finding != in random_access_iterator_helper
|
||||
// need to look into this... for now implementing everything here -JGS
|
||||
inline bool operator!=(const self& x) const { return _i != x._i; }
|
||||
inline bool operator<(const self& x) const { return _i < x._i; }
|
||||
inline bool operator<=(const self& x) const { return _i <= x._i; }
|
||||
inline bool operator>(const self& x) const { return _i > x._i; }
|
||||
inline bool operator>=(const self& x) const { return _i >= x._i; }
|
||||
protected:
|
||||
IntT _i;
|
||||
};
|
||||
|
||||
template <class IntT>
|
||||
inline int_iterator<IntT>
|
||||
operator+(IntT n, int_iterator<IntT> t) { t += n; return t; }
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
} /* namespace boost */
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
namespace boost {
|
||||
using ::int_iterator;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* BOOST_INT_ITERATOR_H */
|
@ -1,59 +0,0 @@
|
||||
// (C) Copyright David Abrahams and Jeremy Siek 2000-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.
|
||||
//
|
||||
// Revision History:
|
||||
// 04 Jan 2001 Factored counting_iterator stuff into
|
||||
// boost/counting_iterator.hpp (David Abrahams)
|
||||
|
||||
#ifndef BOOST_INTEGER_RANGE_HPP_
|
||||
#define BOOST_INTEGER_RANGE_HPP_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/counting_iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//=============================================================================
|
||||
// Counting Iterator and Integer Range Class
|
||||
|
||||
template <class IntegerType>
|
||||
struct integer_range {
|
||||
typedef typename counting_iterator_generator<IntegerType>::type iterator;
|
||||
|
||||
typedef iterator const_iterator;
|
||||
typedef IntegerType value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef IntegerType reference;
|
||||
typedef IntegerType const_reference;
|
||||
typedef const IntegerType* pointer;
|
||||
typedef const IntegerType* const_pointer;
|
||||
typedef IntegerType size_type;
|
||||
|
||||
integer_range(IntegerType start, IntegerType finish)
|
||||
: m_start(start), m_finish(finish) { }
|
||||
|
||||
iterator begin() const { return iterator(m_start); }
|
||||
iterator end() const { return iterator(m_finish); }
|
||||
size_type size() const { return m_finish - m_start; }
|
||||
bool empty() const { return m_finish == m_start; }
|
||||
void swap(integer_range& x) {
|
||||
std::swap(m_start, x.m_start);
|
||||
std::swap(m_finish, x.m_finish);
|
||||
}
|
||||
protected:
|
||||
IntegerType m_start, m_finish;
|
||||
};
|
||||
|
||||
template <class IntegerType>
|
||||
inline integer_range<IntegerType>
|
||||
make_integer_range(IntegerType first, IntegerType last)
|
||||
{
|
||||
return integer_range<IntegerType>(first, last);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_INTEGER_RANGE_HPP_
|
@ -1 +0,0 @@
|
||||
#include <boost/iterator_adaptors.hpp>
|
@ -1,253 +0,0 @@
|
||||
#ifndef BOOST_ITERATOR_TESTS_HPP
|
||||
# define BOOST_ITERATOR_TESTS_HPP
|
||||
|
||||
// This is meant to be the beginnings of a comprehensive, generic
|
||||
// test suite for STL concepts such as iterators and containers.
|
||||
//
|
||||
// Revision History:
|
||||
// 28 Apr 2002 Fixed input iterator requirements.
|
||||
// For a == b a++ == b++ is no longer required.
|
||||
// See 24.1.1/3 for details.
|
||||
// (Thomas Witt)
|
||||
// 08 Feb 2001 Fixed bidirectional iterator test so that
|
||||
// --i is no longer a precondition.
|
||||
// (Jeremy Siek)
|
||||
// 04 Feb 2001 Added lvalue test, corrected preconditions
|
||||
// (David Abrahams)
|
||||
|
||||
# include <iterator>
|
||||
# include <assert.h>
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||
|
||||
namespace boost {
|
||||
|
||||
// use this for the value type
|
||||
struct dummyT {
|
||||
dummyT() { }
|
||||
dummyT(detail::dummy_constructor) { }
|
||||
dummyT(int x) : m_x(x) { }
|
||||
int foo() const { return m_x; }
|
||||
bool operator==(const dummyT& d) const { return m_x == d.m_x; }
|
||||
int m_x;
|
||||
};
|
||||
|
||||
|
||||
// Tests whether type Iterator satisfies the requirements for a
|
||||
// TrivialIterator.
|
||||
// Preconditions: i != j, *i == val
|
||||
template <class Iterator, class T>
|
||||
void trivial_iterator_test(const Iterator i, const Iterator j, T val)
|
||||
{
|
||||
Iterator k;
|
||||
assert(i == i);
|
||||
assert(j == j);
|
||||
assert(i != j);
|
||||
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
T v = *i;
|
||||
#else
|
||||
typename std::iterator_traits<Iterator>::value_type v = *i;
|
||||
#endif
|
||||
assert(v == val);
|
||||
#if 0
|
||||
// hmm, this will give a warning for transform_iterator... perhaps
|
||||
// this should be separated out into a stand-alone test since there
|
||||
// are several situations where it can't be used, like for
|
||||
// integer_range::iterator.
|
||||
assert(v == i->foo());
|
||||
#endif
|
||||
k = i;
|
||||
assert(k == k);
|
||||
assert(k == i);
|
||||
assert(k != j);
|
||||
assert(*k == val);
|
||||
}
|
||||
|
||||
|
||||
// Preconditions: i != j
|
||||
template <class Iterator, class T>
|
||||
void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
|
||||
{
|
||||
*i = val;
|
||||
trivial_iterator_test(i, j, val);
|
||||
}
|
||||
|
||||
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void input_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i1(i);
|
||||
|
||||
assert(i == i1);
|
||||
assert(!(i != i1));
|
||||
|
||||
// I can see no generic way to create an input iterator
|
||||
// that is in the domain of== of i and != i.
|
||||
// The following works for istream_iterator but is not
|
||||
// guaranteed to work for arbitrary input iterators.
|
||||
//
|
||||
// Iterator i2;
|
||||
//
|
||||
// assert(i != i2);
|
||||
// assert(!(i == i2));
|
||||
|
||||
assert(*i1 == v1);
|
||||
assert(*i == v1);
|
||||
|
||||
// we cannot test for equivalence of (void)++i & (void)i++
|
||||
// as i is only guaranteed to be single pass.
|
||||
assert(*i++ == v1);
|
||||
|
||||
i1 = i;
|
||||
|
||||
assert(i == i1);
|
||||
assert(!(i != i1));
|
||||
|
||||
assert(*i1 == v2);
|
||||
assert(*i == v2);
|
||||
|
||||
// i is dereferencable, so it must be incrementable.
|
||||
++i;
|
||||
|
||||
// how to test for operator-> ?
|
||||
}
|
||||
|
||||
// how to test output iterator?
|
||||
|
||||
|
||||
template <bool is_pointer> struct lvalue_test
|
||||
{
|
||||
template <class Iterator> static void check(Iterator)
|
||||
{
|
||||
# ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
# else
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
# endif
|
||||
BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
|
||||
|| boost::is_same<reference,const value_type&>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
# ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
template <> struct lvalue_test<true> {
|
||||
template <class T> static void check(T) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
input_iterator_test(i, v1, v2);
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
assert(i == i1++);
|
||||
assert(i != ++i2);
|
||||
|
||||
trivial_iterator_test(i, i1, v1);
|
||||
trivial_iterator_test(i, i2, v1);
|
||||
|
||||
++i;
|
||||
assert(i == i1);
|
||||
assert(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
trivial_iterator_test(i, i1, v2);
|
||||
trivial_iterator_test(i, i2, v2);
|
||||
|
||||
// borland doesn't allow non-type template parameters
|
||||
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
|
||||
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void bidirectional_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
forward_iterator_test(i, v1, v2);
|
||||
++i;
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
assert(i == i1--);
|
||||
assert(i != --i2);
|
||||
|
||||
trivial_iterator_test(i, i1, v2);
|
||||
trivial_iterator_test(i, i2, v2);
|
||||
|
||||
--i;
|
||||
assert(i == i1);
|
||||
assert(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
trivial_iterator_test(i, i1, v1);
|
||||
trivial_iterator_test(i, i2, v1);
|
||||
}
|
||||
|
||||
// mutable_bidirectional_iterator_test
|
||||
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
void random_access_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
{
|
||||
bidirectional_iterator_test(i, vals[0], vals[1]);
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
assert(i == j + c);
|
||||
assert(*i == vals[c]);
|
||||
assert(*i == j[c]);
|
||||
assert(*i == *(j + c));
|
||||
assert(*i == *(c + j));
|
||||
++i;
|
||||
assert(i > j);
|
||||
assert(i >= j);
|
||||
assert(j <= i);
|
||||
assert(j < i);
|
||||
}
|
||||
|
||||
Iterator k = j + N - 1;
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
assert(i == k - c);
|
||||
assert(*i == vals[N - 1 - c]);
|
||||
assert(*i == j[N - 1 - c]);
|
||||
Iterator q = k - c;
|
||||
assert(*i == *q);
|
||||
assert(i > j);
|
||||
assert(i >= j);
|
||||
assert(j <= i);
|
||||
assert(j < i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
// Precondition: i != j
|
||||
template <class Iterator, class ConstIterator>
|
||||
void const_nonconst_iterator_test(Iterator i, ConstIterator j)
|
||||
{
|
||||
assert(i != j);
|
||||
assert(j != i);
|
||||
|
||||
ConstIterator k(i);
|
||||
assert(k == i);
|
||||
assert(i == k);
|
||||
|
||||
k = i;
|
||||
assert(k == i);
|
||||
assert(i == k);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_TESTS_HPP
|
@ -1,72 +0,0 @@
|
||||
// (C) Copyright Toon Knapen 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.
|
||||
//
|
||||
|
||||
#ifndef boost_permutation_iterator_hpp
|
||||
#define boost_permutation_iterator_hpp
|
||||
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template < typename IndexIterator >
|
||||
struct permutation_iterator_policies : public default_iterator_policies
|
||||
{
|
||||
permutation_iterator_policies() {}
|
||||
|
||||
permutation_iterator_policies(IndexIterator order_it)
|
||||
: order_it_( order_it )
|
||||
{}
|
||||
|
||||
template <class IteratorAdaptor>
|
||||
typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const
|
||||
{ return *(x.base() + *order_it_); }
|
||||
|
||||
template <class IteratorAdaptor>
|
||||
void increment(IteratorAdaptor&)
|
||||
{ ++order_it_; }
|
||||
|
||||
template <class IteratorAdaptor>
|
||||
void decrement(IteratorAdaptor&)
|
||||
{ --order_it_; }
|
||||
|
||||
template <class IteratorAdaptor, class DifferenceType>
|
||||
void advance(IteratorAdaptor& x, DifferenceType n)
|
||||
{ std::advance( order_it_, n ); }
|
||||
|
||||
template <class IteratorAdaptor1, class IteratorAdaptor2>
|
||||
typename IteratorAdaptor1::difference_type
|
||||
distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
|
||||
{ return std::distance( x.policies().order_it_, y.policies().order_it_ ); }
|
||||
|
||||
template <class IteratorAdaptor1, class IteratorAdaptor2>
|
||||
bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
|
||||
{ return x.policies().order_it_ == y.policies().order_it_; }
|
||||
|
||||
IndexIterator order_it_;
|
||||
};
|
||||
|
||||
template < typename ElementIterator, typename IndexIterator >
|
||||
struct permutation_iterator_generator
|
||||
{
|
||||
typedef boost::iterator_adaptor
|
||||
< ElementIterator,
|
||||
permutation_iterator_policies< IndexIterator >
|
||||
> type;
|
||||
};
|
||||
|
||||
template < class IndexIterator, class ElementIterator >
|
||||
inline typename permutation_iterator_generator< ElementIterator, IndexIterator >::type
|
||||
make_permutation_iterator(ElementIterator base, IndexIterator order)
|
||||
{
|
||||
typedef typename permutation_iterator_generator< ElementIterator, IndexIterator >::type result_t;
|
||||
return result_t( base, order );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // boost_permutation_iterator_hpp
|
||||
|
836
test/zip_iterator_test.cpp
Executable file
836
test/zip_iterator_test.cpp
Executable file
@ -0,0 +1,836 @@
|
||||
// (C) Copyright Dave Abrahams and Thomas Becker 2003. 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.
|
||||
//
|
||||
|
||||
// File:
|
||||
// =====
|
||||
// zip_iterator_test_main.cpp
|
||||
|
||||
// Author:
|
||||
// =======
|
||||
// Thomas Becker
|
||||
|
||||
// Created:
|
||||
// ========
|
||||
// Jul 15, 2003
|
||||
|
||||
// Purpose:
|
||||
// ========
|
||||
// Test driver for zip_iterator.hpp
|
||||
|
||||
// Compilers Tested:
|
||||
// =================
|
||||
// Metrowerks Codewarrior Pro 7.2, 8.3
|
||||
// gcc 2.95.3
|
||||
// gcc 3.2
|
||||
// Microsoft VC 6sp5 (test fails due to some compiler bug)
|
||||
// Microsoft VC 7 (works)
|
||||
// Microsoft VC 7.1
|
||||
// Intel 5
|
||||
// Intel 6
|
||||
// Intel 7.1
|
||||
// Intel 8
|
||||
// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Includes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define FUSION_MAX_TUPLE_SIZE 13
|
||||
|
||||
#include <boost/iterator/zip_iterator.hpp> // 2nd #include tests #include guard.
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
#include <boost/spirit/fusion/sequence/tuple.hpp>
|
||||
#include <boost/spirit/fusion/sequence/tuple20.hpp>
|
||||
#include <boost/spirit/fusion/sequence/make_tuple.hpp>
|
||||
#include <boost/spirit/fusion/algorithm/push_front.hpp>
|
||||
#include <boost/spirit/fusion/sequence/get.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/iterator/is_readable_iterator.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <stddef.h>
|
||||
|
||||
template <class It>
|
||||
struct pure_traversal
|
||||
: boost::detail::pure_traversal_tag<
|
||||
typename boost::iterator_traversal<It>::type
|
||||
>
|
||||
{};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Das Main Funktion
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int main( void )
|
||||
{
|
||||
|
||||
std::cout << "\n"
|
||||
<< "***********************************************\n"
|
||||
<< "* *\n"
|
||||
<< "* Test driver for boost::zip_iterator *\n"
|
||||
<< "* Copyright Thomas Becker 2003 *\n"
|
||||
<< "* *\n"
|
||||
<< "***********************************************\n\n"
|
||||
<< std::flush;
|
||||
|
||||
size_t num_successful_tests = 0;
|
||||
size_t num_failed_tests = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator construction and dereferencing
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator construction and dereferencing: "
|
||||
<< std::flush;
|
||||
|
||||
std::vector<double> vect1(3);
|
||||
vect1[0] = 42.;
|
||||
vect1[1] = 43.;
|
||||
vect1[2] = 44.;
|
||||
|
||||
std::set<int> intset;
|
||||
intset.insert(52);
|
||||
intset.insert(53);
|
||||
intset.insert(54);
|
||||
//
|
||||
|
||||
typedef
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::set<int>::iterator
|
||||
, std::vector<double>::iterator
|
||||
>
|
||||
> zit_mixed;
|
||||
|
||||
zit_mixed zip_it_mixed = zit_mixed(
|
||||
boost::fusion::make_tuple(
|
||||
intset.begin()
|
||||
, vect1.begin()
|
||||
)
|
||||
);
|
||||
|
||||
boost::fusion::tuple<int, double> val_tuple(
|
||||
*zip_it_mixed);
|
||||
|
||||
boost::fusion::tuple<const int&, double&> ref_tuple(
|
||||
*zip_it_mixed);
|
||||
|
||||
double dblOldVal = boost::fusion::get<1>(ref_tuple);
|
||||
boost::fusion::get<1>(ref_tuple) -= 41.;
|
||||
|
||||
if( 52 == boost::fusion::get<0>(val_tuple) &&
|
||||
42. == boost::fusion::get<1>(val_tuple) &&
|
||||
52 == boost::fusion::get<0>(ref_tuple) &&
|
||||
1. == boost::fusion::get<1>(ref_tuple) &&
|
||||
1. == *vect1.begin()
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
// Undo change to vect1
|
||||
boost::fusion::get<1>(ref_tuple) = dblOldVal;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator with 12 components
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterators with 12 components: "
|
||||
<< std::flush;
|
||||
|
||||
// Declare 12 containers
|
||||
//
|
||||
std::list<int> li1;
|
||||
li1.push_back(1);
|
||||
std::set<int> se1;
|
||||
se1.insert(2);
|
||||
std::vector<int> ve1;
|
||||
ve1.push_back(3);
|
||||
//
|
||||
std::list<int> li2;
|
||||
li2.push_back(4);
|
||||
std::set<int> se2;
|
||||
se2.insert(5);
|
||||
std::vector<int> ve2;
|
||||
ve2.push_back(6);
|
||||
//
|
||||
std::list<int> li3;
|
||||
li3.push_back(7);
|
||||
std::set<int> se3;
|
||||
se3.insert(8);
|
||||
std::vector<int> ve3;
|
||||
ve3.push_back(9);
|
||||
//
|
||||
std::list<int> li4;
|
||||
li4.push_back(10);
|
||||
std::set<int> se4;
|
||||
se4.insert(11);
|
||||
std::vector<int> ve4;
|
||||
ve4.push_back(12);
|
||||
|
||||
// typedefs for cons lists of iterators.
|
||||
typedef boost::fusion::tuple11<
|
||||
std::set<int>::iterator,
|
||||
std::vector<int>::iterator,
|
||||
std::list<int>::iterator,
|
||||
std::set<int>::iterator,
|
||||
std::vector<int>::iterator,
|
||||
std::list<int>::iterator,
|
||||
std::set<int>::iterator,
|
||||
std::vector<int>::iterator,
|
||||
std::list<int>::iterator,
|
||||
std::set<int>::iterator,
|
||||
std::vector<int>::const_iterator
|
||||
> cons_11_its_type;
|
||||
|
||||
//
|
||||
typedef boost::fusion::meta::generate<
|
||||
boost::fusion::meta::push_front<
|
||||
cons_11_its_type,
|
||||
std::list<int>::const_iterator
|
||||
>::type
|
||||
>::type cons_12_its_type;
|
||||
|
||||
// typedefs for cons lists for dereferencing the zip iterator
|
||||
// made from the cons list above.
|
||||
typedef boost::fusion::tuple11<
|
||||
const int&,
|
||||
int&,
|
||||
int&,
|
||||
const int&,
|
||||
int&,
|
||||
int&,
|
||||
const int&,
|
||||
int&,
|
||||
int&,
|
||||
const int&,
|
||||
const int&
|
||||
> cons_11_refs_type;
|
||||
//
|
||||
typedef boost::fusion::meta::generate<
|
||||
boost::fusion::meta::push_front<
|
||||
cons_11_refs_type,
|
||||
const int&
|
||||
>::type
|
||||
>::type cons_12_refs_type;
|
||||
|
||||
// typedef for zip iterator with 12 elements
|
||||
typedef boost::zip_iterator<cons_12_its_type> zip_it_12_type;
|
||||
|
||||
// Declare a 12-element zip iterator.
|
||||
zip_it_12_type zip_it_12(
|
||||
cons_12_its_type(
|
||||
li1.begin(),
|
||||
se1.begin(),
|
||||
ve1.begin(),
|
||||
li2.begin(),
|
||||
se2.begin(),
|
||||
ve2.begin(),
|
||||
li3.begin(),
|
||||
se3.begin(),
|
||||
ve3.begin(),
|
||||
li4.begin(),
|
||||
se4.begin(),
|
||||
ve4.begin()
|
||||
)
|
||||
);
|
||||
|
||||
// Dereference, mess with the result a little.
|
||||
cons_12_refs_type zip_it_12_dereferenced(*zip_it_12);
|
||||
boost::fusion::get<9>(zip_it_12_dereferenced) = 42;
|
||||
|
||||
// Make a copy and move it a little to force some instantiations.
|
||||
zip_it_12_type zip_it_12_copy(zip_it_12);
|
||||
++zip_it_12_copy;
|
||||
|
||||
if( boost::fusion::get<11>(zip_it_12.get_iterator_tuple()) == ve4.begin() &&
|
||||
boost::fusion::get<11>(zip_it_12_copy.get_iterator_tuple()) == ve4.end() &&
|
||||
1 == boost::fusion::get<0>(zip_it_12_dereferenced) &&
|
||||
12 == boost::fusion::get<11>(zip_it_12_dereferenced) &&
|
||||
42 == *(li4.begin())
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator incrementing and dereferencing
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator ++ and *: "
|
||||
<< std::flush;
|
||||
|
||||
std::vector<double> vect2(3);
|
||||
vect2[0] = 2.2;
|
||||
vect2[1] = 3.3;
|
||||
vect2[2] = 4.4;
|
||||
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_begin(
|
||||
boost::fusion::make_tuple(
|
||||
vect1.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_run(
|
||||
boost::fusion::make_tuple(
|
||||
vect1.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_end(
|
||||
boost::fusion::make_tuple(
|
||||
vect1.end(),
|
||||
vect2.end()
|
||||
)
|
||||
);
|
||||
|
||||
if( zip_it_run == zip_it_begin &&
|
||||
42. == boost::fusion::get<0>(*zip_it_run) &&
|
||||
2.2 == boost::fusion::get<1>(*zip_it_run) &&
|
||||
43. == boost::fusion::get<0>(*(++zip_it_run)) &&
|
||||
3.3 == boost::fusion::get<1>(*zip_it_run) &&
|
||||
44. == boost::fusion::get<0>(*(++zip_it_run)) &&
|
||||
4.4 == boost::fusion::get<1>(*zip_it_run) &&
|
||||
zip_it_end == ++zip_it_run
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator decrementing and dereferencing
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator -- and *: "
|
||||
<< std::flush;
|
||||
|
||||
if( zip_it_run == zip_it_end &&
|
||||
zip_it_end == zip_it_run-- &&
|
||||
44. == boost::fusion::get<0>(*zip_it_run) &&
|
||||
4.4 == boost::fusion::get<1>(*zip_it_run) &&
|
||||
43. == boost::fusion::get<0>(*(--zip_it_run)) &&
|
||||
3.3 == boost::fusion::get<1>(*zip_it_run) &&
|
||||
42. == boost::fusion::get<0>(*(--zip_it_run)) &&
|
||||
2.2 == boost::fusion::get<1>(*zip_it_run) &&
|
||||
zip_it_begin == zip_it_run
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator copy construction and equality
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator copy construction and equality: "
|
||||
<< std::flush;
|
||||
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
> zip_it_run_copy(zip_it_run);
|
||||
|
||||
if(zip_it_run == zip_it_run && zip_it_run == zip_it_run_copy)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator inequality
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator inequality: "
|
||||
<< std::flush;
|
||||
|
||||
if(!(zip_it_run != zip_it_run_copy) && zip_it_run != ++zip_it_run_copy)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator less than
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator less than: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run_copy == zip_it_run + 1
|
||||
//
|
||||
if( zip_it_run < zip_it_run_copy &&
|
||||
!( zip_it_run < --zip_it_run_copy) &&
|
||||
zip_it_run == zip_it_run_copy
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator less than or equal
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "zip iterator less than or equal: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run_copy == zip_it_run
|
||||
//
|
||||
++zip_it_run;
|
||||
zip_it_run_copy += 2;
|
||||
|
||||
if( zip_it_run <= zip_it_run_copy &&
|
||||
zip_it_run <= --zip_it_run_copy &&
|
||||
!( zip_it_run <= --zip_it_run_copy) &&
|
||||
zip_it_run <= zip_it_run
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator greater than
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator greater than: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run_copy == zip_it_run - 1
|
||||
//
|
||||
if( zip_it_run > zip_it_run_copy &&
|
||||
!( zip_it_run > ++zip_it_run_copy) &&
|
||||
zip_it_run == zip_it_run_copy
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator greater than or equal
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator greater than or equal: "
|
||||
<< std::flush;
|
||||
|
||||
++zip_it_run;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy + 1
|
||||
//
|
||||
if( zip_it_run >= zip_it_run_copy &&
|
||||
--zip_it_run >= zip_it_run_copy &&
|
||||
! (zip_it_run >= ++zip_it_run_copy)
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator + int
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator + int: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy - 1
|
||||
//
|
||||
zip_it_run = zip_it_run + 2;
|
||||
++zip_it_run_copy;
|
||||
|
||||
if( zip_it_run == zip_it_run_copy && zip_it_run == zip_it_begin + 3 )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator - int
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator - int: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy, and both are at end position
|
||||
//
|
||||
zip_it_run = zip_it_run - 2;
|
||||
--zip_it_run_copy;
|
||||
--zip_it_run_copy;
|
||||
|
||||
if( zip_it_run == zip_it_run_copy && (zip_it_run - 1) == zip_it_begin )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator +=
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator +=: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy, and both are at begin + 1
|
||||
//
|
||||
zip_it_run += 2;
|
||||
if( zip_it_run == zip_it_begin + 3 )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator -=
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator -=: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run is at end position, zip_it_run_copy is at
|
||||
// begin plus one.
|
||||
//
|
||||
zip_it_run -= 2;
|
||||
if( zip_it_run == zip_it_run_copy )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator getting member iterators
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator member iterators: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run and zip_it_run_copy are both at
|
||||
// begin plus one.
|
||||
//
|
||||
if( boost::fusion::get<0>(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 &&
|
||||
boost::fusion::get<1>(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Making zip iterators
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Making zip iterators: "
|
||||
<< std::flush;
|
||||
|
||||
std::vector<boost::fusion::tuple<double, double> >
|
||||
vect_of_tuples(3);
|
||||
|
||||
std::copy(
|
||||
boost::make_zip_iterator(
|
||||
boost::fusion::make_tuple(
|
||||
vect1.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
),
|
||||
boost::make_zip_iterator(
|
||||
boost::fusion::make_tuple(
|
||||
vect1.end(),
|
||||
vect2.end()
|
||||
)
|
||||
),
|
||||
vect_of_tuples.begin()
|
||||
);
|
||||
|
||||
if( 42. == boost::fusion::get<0>(*vect_of_tuples.begin()) &&
|
||||
2.2 == boost::fusion::get<1>(*vect_of_tuples.begin()) &&
|
||||
43. == boost::fusion::get<0>(*(vect_of_tuples.begin() + 1)) &&
|
||||
3.3 == boost::fusion::get<1>(*(vect_of_tuples.begin() + 1)) &&
|
||||
44. == boost::fusion::get<0>(*(vect_of_tuples.begin() + 2)) &&
|
||||
4.4 == boost::fusion::get<1>(*(vect_of_tuples.begin() + 2))
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator non-const --> const conversion
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator non-const to const conversion: "
|
||||
<< std::flush;
|
||||
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::set<int>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_const(
|
||||
boost::fusion::make_tuple(
|
||||
intset.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
//
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::set<int>::iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_half_const(
|
||||
boost::fusion::make_tuple(
|
||||
intset.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
//
|
||||
boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::set<int>::iterator,
|
||||
std::vector<double>::iterator
|
||||
>
|
||||
>
|
||||
zip_it_non_const(
|
||||
boost::fusion::make_tuple(
|
||||
intset.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
|
||||
zip_it_half_const = ++zip_it_non_const;
|
||||
zip_it_const = zip_it_half_const;
|
||||
++zip_it_const;
|
||||
// zip_it_non_const = ++zip_it_const; // Error: can't convert from const to non-const
|
||||
|
||||
if( 54 == boost::fusion::get<0>(*zip_it_const) &&
|
||||
4.4 == boost::fusion::get<1>(*zip_it_const) &&
|
||||
53 == boost::fusion::get<0>(*zip_it_half_const) &&
|
||||
3.3 == boost::fusion::get<1>(*zip_it_half_const)
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator categories
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator categories: "
|
||||
<< std::flush;
|
||||
|
||||
// The big iterator of the previous test has vector, list, and set iterators.
|
||||
// Therefore, it must be bidirectional, but not random access.
|
||||
bool bBigItIsBidirectionalIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<zip_it_12_type>::type
|
||||
, boost::bidirectional_traversal_tag
|
||||
>::value;
|
||||
|
||||
bool bBigItIsRandomAccessIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<zip_it_12_type>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value;
|
||||
|
||||
// A combining iterator with all vector iterators must have random access
|
||||
// traversal.
|
||||
//
|
||||
typedef boost::zip_iterator<
|
||||
boost::fusion::tuple<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
> all_vects_type;
|
||||
|
||||
bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<all_vects_type>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value;
|
||||
|
||||
// The big test.
|
||||
if( bBigItIsBidirectionalIterator &&
|
||||
! bBigItIsRandomAccessIterator &&
|
||||
bAllVectsIsRandomAccessIterator
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests = 0;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
// Done
|
||||
//
|
||||
std::cout << "\nTest Result:"
|
||||
<< "\n============"
|
||||
<< "\nNumber of successful tests: " << static_cast<unsigned int>(num_successful_tests)
|
||||
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
|
||||
<< std::endl;
|
||||
|
||||
return num_failed_tests;
|
||||
}
|
||||
|
Reference in New Issue
Block a user