forked from boostorg/iterator
Compare commits
369 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
d67deb0f0d | |||
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
|
@ -26,7 +26,9 @@ namespace boost {
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
explicit function_output_iterator() {}
|
||||
|
||||
explicit function_output_iterator(const UnaryFunction& f)
|
||||
: m_f(f) {}
|
||||
|
||||
struct output_proxy {
|
||||
|
@ -5,7 +5,7 @@
|
||||
// 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.
|
||||
// See http://www.boost.org/libs/utility for documentation.
|
||||
|
||||
// Revision History
|
||||
// 12 Jan 01 added <cstddef> for std::ptrdiff_t (Jens Maurer)
|
||||
|
216
include/boost/iterator/counting_iterator.hpp
Normal file
216
include/boost/iterator/counting_iterator.hpp
Normal file
@ -0,0 +1,216 @@
|
||||
// Copyright David Abrahams 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.
|
||||
#ifndef COUNTING_ITERATOR_DWA200348_HPP
|
||||
# define COUNTING_ITERATOR_DWA200348_HPP
|
||||
|
||||
# include <boost/iterator/iterator_adaptor.hpp>
|
||||
# include <boost/detail/numeric_traits.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal
|
||||
, class Difference
|
||||
>
|
||||
class counting_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// 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_impl
|
||||
{
|
||||
// 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
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
|
||||
|
||||
# else
|
||||
|
||||
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
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
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_numeric
|
||||
: mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
|
||||
{};
|
||||
|
||||
# if defined(BOOST_HAS_LONG_LONG)
|
||||
template <>
|
||||
struct is_numeric<long long>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct is_numeric<unsigned long long>
|
||||
: mpl::true_ {};
|
||||
# endif
|
||||
|
||||
// Some compilers fail to have a numeric_limits specialization
|
||||
template <>
|
||||
struct is_numeric<wchar_t>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <class T>
|
||||
struct numeric_difference
|
||||
{
|
||||
typedef typename boost::detail::numeric_traits<T>::difference_type type;
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT(is_numeric<int>::value);
|
||||
|
||||
template <class Incrementable, class CategoryOrTraversal, class Difference>
|
||||
struct counting_iterator_base
|
||||
{
|
||||
typedef typename detail::ia_dflt_help<
|
||||
CategoryOrTraversal
|
||||
, mpl::apply_if<
|
||||
is_numeric<Incrementable>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, iterator_traversal<Incrementable>
|
||||
>
|
||||
>::type traversal;
|
||||
|
||||
typedef typename detail::ia_dflt_help<
|
||||
Difference
|
||||
, mpl::apply_if<
|
||||
is_numeric<Incrementable>
|
||||
, numeric_difference<Incrementable>
|
||||
, iterator_difference<Incrementable>
|
||||
>
|
||||
>::type difference;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
|
||||
, Incrementable // Base
|
||||
, Incrementable // Value
|
||||
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
const // MSVC won't strip this. Instead we enable Thomas'
|
||||
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
|
||||
# endif
|
||||
, traversal
|
||||
, Incrementable const& // reference
|
||||
, difference
|
||||
> type;
|
||||
};
|
||||
|
||||
// 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 <class Difference, class Incrementable1, class Incrementable2>
|
||||
struct iterator_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return y - x;
|
||||
}
|
||||
};
|
||||
|
||||
// A policy for wrapped numbers
|
||||
template <class Difference, class Incrementable1, class Incrementable2>
|
||||
struct number_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return numeric_distance(x, y);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class counting_iterator
|
||||
: public detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type
|
||||
{
|
||||
typedef typename detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
typedef typename super_t::difference_type difference_type;
|
||||
|
||||
counting_iterator() { }
|
||||
|
||||
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
|
||||
|
||||
counting_iterator(Incrementable x)
|
||||
: super_t(x)
|
||||
{
|
||||
}
|
||||
|
||||
# if 0
|
||||
template<class OtherIncrementable>
|
||||
counting_iterator(
|
||||
counting_iterator<OtherIncrementable> const& t
|
||||
, typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
|
||||
)
|
||||
: super_t(t.base())
|
||||
{}
|
||||
# endif
|
||||
|
||||
private:
|
||||
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
return this->base_reference();
|
||||
}
|
||||
|
||||
template <class OtherIncrementable>
|
||||
difference_type
|
||||
distance_to(counting_iterator<OtherIncrementable> const& y) const
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
detail::is_numeric<Incrementable>
|
||||
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
|
||||
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
|
||||
>::type d;
|
||||
|
||||
return d::distance(this->base(), y.base());
|
||||
}
|
||||
};
|
||||
|
||||
// Manufacture a counting iterator for an arbitrary incrementable type
|
||||
template <class Incrementable>
|
||||
inline counting_iterator<Incrementable>
|
||||
make_counting_iterator(Incrementable x)
|
||||
{
|
||||
typedef counting_iterator<Incrementable> result_t;
|
||||
return result_t(x);
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost::iterator
|
||||
|
||||
#endif // COUNTING_ITERATOR_DWA200348_HPP
|
19
include/boost/iterator/detail/any_conversion_eater.hpp
Executable file
19
include/boost/iterator/detail/any_conversion_eater.hpp
Executable file
@ -0,0 +1,19 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||
# define ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
// This type can be used in traits to "eat" up the one user-defined
|
||||
// implicit conversion allowed.
|
||||
struct any_conversion_eater
|
||||
{
|
||||
template <class T>
|
||||
any_conversion_eater(T const&);
|
||||
};
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP
|
1
include/boost/iterator/detail/categories.hpp
Normal file
1
include/boost/iterator/detail/categories.hpp
Normal file
@ -0,0 +1 @@
|
||||
#error obsolete
|
137
include/boost/iterator/detail/config_def.hpp
Normal file
137
include/boost/iterator/detail/config_def.hpp
Normal file
@ -0,0 +1,137 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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.
|
||||
|
||||
// no include guard multiple inclusion intended
|
||||
|
||||
//
|
||||
// This is a temporary workaround until the bulk of this is
|
||||
// available in boost config.
|
||||
// 23/02/03 thw
|
||||
//
|
||||
|
||||
#include <boost/config.hpp> // for prior
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# error you have nested config_def #inclusion.
|
||||
#else
|
||||
# define BOOST_ITERATOR_CONFIG_DEF
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
|
||||
|
||||
// Recall that in general, compilers without partial specialization
|
||||
// can't strip constness. Consider counting_iterator, which normally
|
||||
// passes a const Value to iterator_facade. As a result, any code
|
||||
// which makes a std::vector of the iterator's value_type will fail
|
||||
// when its allocator declares functions overloaded on reference and
|
||||
// const_reference (the same type).
|
||||
//
|
||||
// Furthermore, Borland 5.5.1 drops constness in enough ways that we
|
||||
// end up using a proxy for operator[] when we otherwise shouldn't.
|
||||
// Using reference constness gives it an extra hint that it can
|
||||
// return the value_type from operator[] directly, but is not
|
||||
// strictly neccessary. Not sure how best to resolve this one.
|
||||
|
||||
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \
|
||||
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER))
|
||||
# define BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
|
||||
# if 0 // test code
|
||||
struct v {};
|
||||
|
||||
typedef char (&no)[3];
|
||||
|
||||
template <class T>
|
||||
no foo(T const&, ...);
|
||||
|
||||
template <class T>
|
||||
char foo(T&, int);
|
||||
|
||||
|
||||
struct value_iterator
|
||||
{
|
||||
v operator*() const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lvalue_deref_helper
|
||||
{
|
||||
static T& x;
|
||||
enum { value = (sizeof(foo(*x,0)) == 1) };
|
||||
};
|
||||
|
||||
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
|
||||
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||
# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types"
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2) \
|
||||
|| BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
|
||||
|
||||
# if 0 // test code
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
template <class T>
|
||||
struct foo
|
||||
{
|
||||
foo(T);
|
||||
|
||||
template <class U>
|
||||
foo(foo<U> const& other) : p(other.p) { }
|
||||
|
||||
T p;
|
||||
};
|
||||
|
||||
bool x = boost::is_convertible<foo<int const*>, foo<int*> >::value;
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \
|
||||
|| BOOST_WORKAROUND(__MWERKS__, <= 0x2407) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
# define BOOST_ITERATOR_NO_MPL_AUX_HAS_XXX // "MPL's has_xxx facility doesn't work"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE)
|
||||
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||
#endif
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
# define BOOST_ARG_DEPENDENT_TYPENAME typename
|
||||
# else
|
||||
# define BOOST_ARG_DEPENDENT_TYPENAME
|
||||
# endif
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2) && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(95)) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
|
||||
// GCC-2.95 eagerly instantiates templated constructors and conversion
|
||||
// operators in convertibility checks, causing premature errors.
|
||||
//
|
||||
// Borland's problems are harder to diagnose due to lack of an
|
||||
// instantiation stack backtrace. They may be due in part to the fact
|
||||
// that it drops cv-qualification willy-nilly in templates.
|
||||
# define BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
||||
# endif
|
||||
|
||||
// no include guard; multiple inclusion intended
|
27
include/boost/iterator/detail/config_undef.hpp
Normal file
27
include/boost/iterator/detail/config_undef.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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.
|
||||
|
||||
// no include guard multiple inclusion intended
|
||||
|
||||
//
|
||||
// This is a temporary workaround until the bulk of this is
|
||||
// available in boost config.
|
||||
// 23/02/03 thw
|
||||
//
|
||||
|
||||
#undef BOOST_NO_IS_CONVERTIBLE
|
||||
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
|
||||
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||
#undef BOOST_ARG_DEPENDENT_TYPENAME
|
||||
#undef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
||||
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# undef BOOST_ITERATOR_CONFIG_DEF
|
||||
#else
|
||||
# error missing or nested #include config_def
|
||||
#endif
|
88
include/boost/iterator/detail/enable_if.hpp
Normal file
88
include/boost/iterator/detail/enable_if.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_ENABLE_IF_23022003THW_HPP
|
||||
#define BOOST_ENABLE_IF_23022003THW_HPP
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
//
|
||||
// Boost iterators uses its own enable_if cause we need
|
||||
// special semantics for deficient compilers.
|
||||
// 23/02/03 thw
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace iterators
|
||||
{
|
||||
//
|
||||
// Base machinery for all kinds of enable if
|
||||
//
|
||||
template<bool>
|
||||
struct enabled
|
||||
{
|
||||
template<typename T>
|
||||
struct base
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// For compilers that don't support "Substitution Failure Is Not An Error"
|
||||
// enable_if falls back to always enabled. See comments
|
||||
// on operator implementation for consequences.
|
||||
//
|
||||
template<>
|
||||
struct enabled<false>
|
||||
{
|
||||
template<typename T>
|
||||
struct base
|
||||
{
|
||||
#ifdef BOOST_NO_SFINAE
|
||||
|
||||
typedef T type;
|
||||
|
||||
// This way to do it would give a nice error message containing
|
||||
// invalid overload, but has the big disadvantage that
|
||||
// there is no reference to user code in the error message.
|
||||
//
|
||||
// struct invalid_overload;
|
||||
// typedef invalid_overload type;
|
||||
//
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class Cond,
|
||||
class Return>
|
||||
struct enable_if
|
||||
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
|
||||
: enabled<(Cond::value)>::template base<Return>
|
||||
# else
|
||||
: mpl::identity<Return>
|
||||
# endif
|
||||
{
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
typedef Return type;
|
||||
# endif
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_ENABLE_IF_23022003THW_HPP
|
209
include/boost/iterator/detail/facade_iterator_category.hpp
Executable file
209
include/boost/iterator/detail/facade_iterator_category.hpp
Executable file
@ -0,0 +1,209 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||
|
||||
# include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
|
||||
# include <boost/mpl/and.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# include <boost/type_traits/is_const.hpp>
|
||||
# include <boost/type_traits/is_reference.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
|
||||
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# endif
|
||||
|
||||
//
|
||||
// iterator_category deduction for iterator_facade
|
||||
//
|
||||
|
||||
// forward declaration
|
||||
namespace boost { struct use_default; }
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
struct input_output_iterator_tag
|
||||
: std::input_iterator_tag
|
||||
{
|
||||
// Using inheritance for only input_iterator_tag helps to avoid
|
||||
// ambiguities when a stdlib implementation dispatches on a
|
||||
// function which is overloaded on both input_iterator_tag and
|
||||
// output_iterator_tag, as STLPort does, in its __valid_range
|
||||
// function. I claim it's better to avoid the ambiguity in these
|
||||
// cases.
|
||||
operator std::output_iterator_tag() const
|
||||
{
|
||||
return std::output_iterator_tag();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// True iff the user has explicitly disabled writability of this
|
||||
// iterator. Pass the iterator_facade's Value parameter and its
|
||||
// nested ::reference type.
|
||||
//
|
||||
template <class ValueParam, class Reference>
|
||||
struct iterator_writability_disabled
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
|
||||
: mpl::or_<
|
||||
is_const<Reference>
|
||||
, python::detail::is_reference_to_const<Reference>
|
||||
, is_const<ValueParam>
|
||||
>
|
||||
# else
|
||||
: is_const<ValueParam>
|
||||
# endif
|
||||
{};
|
||||
|
||||
|
||||
//
|
||||
// Convert an iterator_facade's traversal category, Value parameter,
|
||||
// and ::reference type to an appropriate old-style category.
|
||||
//
|
||||
// If writability has been disabled per the above metafunction, the
|
||||
// result will not be convertible to output_iterator_tag.
|
||||
//
|
||||
// Otherwise, if Traversal == single_pass_traversal_tag, the following
|
||||
// conditions will result in a tag that is convertible both to
|
||||
// input_iterator_tag and output_iterator_tag:
|
||||
//
|
||||
// 1. Reference is a reference to non-const
|
||||
// 2. Reference is not a reference and is convertible to Value
|
||||
//
|
||||
template <class Traversal, class ValueParam, class Reference>
|
||||
struct iterator_facade_default_category
|
||||
: mpl::apply_if<
|
||||
mpl::and_<
|
||||
is_reference<Reference>
|
||||
, is_convertible<Traversal,forward_traversal_tag>
|
||||
>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,random_access_traversal_tag>
|
||||
, mpl::identity<std::random_access_iterator_tag>
|
||||
, mpl::if_<
|
||||
is_convertible<Traversal,bidirectional_traversal_tag>
|
||||
, std::bidirectional_iterator_tag
|
||||
, std::forward_iterator_tag
|
||||
>
|
||||
>
|
||||
, typename mpl::apply_if<
|
||||
mpl::and_<
|
||||
is_convertible<Traversal, single_pass_traversal_tag>
|
||||
|
||||
// check for readability
|
||||
, is_convertible<Reference, ValueParam>
|
||||
>
|
||||
, mpl::identity<std::input_iterator_tag>
|
||||
, mpl::identity<Traversal>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// True iff T is convertible to an old-style iterator category.
|
||||
template <class T>
|
||||
struct is_iterator_category
|
||||
: mpl::or_<
|
||||
is_convertible<T,std::input_iterator_tag>
|
||||
, is_convertible<T,std::output_iterator_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_iterator_traversal
|
||||
: is_convertible<T,incrementable_traversal_tag>
|
||||
{};
|
||||
|
||||
//
|
||||
// A composite iterator_category tag convertible to Category (a pure
|
||||
// old-style category) and Traversal (a pure traversal tag).
|
||||
// Traversal must be a strict increase of the traversal power given by
|
||||
// Category.
|
||||
//
|
||||
template <class Category, class Traversal>
|
||||
struct iterator_category_with_traversal
|
||||
: Category, Traversal
|
||||
{
|
||||
# if 0
|
||||
// Because of limitations on multiple user-defined conversions,
|
||||
// this should be a good test of whether convertibility is enough
|
||||
// in the spec, or whether we need to specify inheritance.
|
||||
operator Category() const { return Category(); }
|
||||
operator Traversal() const { return Traversal(); }
|
||||
# endif
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
// Make sure this isn't used to build any categories where
|
||||
// convertibility to Traversal is redundant. Should just use the
|
||||
// Category element in that case.
|
||||
BOOST_STATIC_ASSERT(
|
||||
!(is_convertible<
|
||||
typename iterator_category_to_traversal<Category>::type
|
||||
, Traversal
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT(is_iterator_category<Category>::value);
|
||||
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
|
||||
BOOST_STATIC_ASSERT(!is_iterator_traversal<Category>::value);
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
||||
BOOST_STATIC_ASSERT(is_iterator_traversal<Traversal>::value);
|
||||
# endif
|
||||
# endif
|
||||
};
|
||||
|
||||
// Computes an iterator_category tag whose traversal is Traversal and
|
||||
// which is appropriate for an iterator
|
||||
template <class Traversal, class ValueParam, class Reference>
|
||||
struct facade_iterator_category_impl
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
|
||||
# endif
|
||||
|
||||
typedef typename iterator_facade_default_category<
|
||||
Traversal,ValueParam,Reference
|
||||
>::type category;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_same<
|
||||
Traversal
|
||||
, typename iterator_category_to_traversal<category>::type
|
||||
>
|
||||
, category
|
||||
, iterator_category_with_traversal<category,Traversal>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//
|
||||
// Compute an iterator_category for iterator_facade
|
||||
//
|
||||
template <class CategoryOrTraversal, class ValueParam, class Reference>
|
||||
struct facade_iterator_category
|
||||
: mpl::apply_if<
|
||||
is_iterator_category<CategoryOrTraversal>
|
||||
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
|
||||
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
110
include/boost/iterator/detail/minimum_category.hpp
Executable file
110
include/boost/iterator/detail/minimum_category.hpp
Executable file
@ -0,0 +1,110 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
# define MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost { namespace detail {
|
||||
//
|
||||
// Returns the minimum category type or error_type
|
||||
// if T1 and T2 are unrelated.
|
||||
//
|
||||
// For compilers not supporting is_convertible this only
|
||||
// works with the new boost return and traversal category
|
||||
// types. The exact boost _types_ are required. No derived types
|
||||
// will work.
|
||||
//
|
||||
//
|
||||
template <bool GreaterEqual, bool LessEqual>
|
||||
struct minimum_category_impl
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
{
|
||||
typedef void type;
|
||||
}
|
||||
# endif
|
||||
;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct error_not_related_by_convertibility;
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
: error_not_related_by_convertibility<T1,T2>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
||||
struct minimum_category
|
||||
{
|
||||
typedef minimum_category_impl<
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround
|
||||
is_same<T2,int>::value ||
|
||||
# endif
|
||||
::boost::is_convertible<T1,T2>::value
|
||||
, ::boost::is_convertible<T2,T1>::value
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround
|
||||
|| is_same<T1,int>::value
|
||||
# endif
|
||||
> outer;
|
||||
|
||||
typedef typename outer::template apply<T1,T2> inner;
|
||||
typedef typename inner::type type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category<mpl::_1,mpl::_2>
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply : minimum_category<T1,T2>
|
||||
{};
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround
|
||||
template <>
|
||||
struct minimum_category<int,int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // MINIMUM_CATEGORY_DWA20031119_HPP
|
137
include/boost/iterator/filter_iterator.hpp
Normal file
137
include/boost/iterator/filter_iterator.hpp
Normal file
@ -0,0 +1,137 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_FILTER_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Predicate, class Iterator>
|
||||
struct filter_iterator_base
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>
|
||||
, Iterator
|
||||
, use_default
|
||||
, typename mpl::if_<
|
||||
is_convertible<
|
||||
typename iterator_traversal<Iterator>::type
|
||||
, bidirectional_traversal_tag
|
||||
>
|
||||
, forward_traversal_tag
|
||||
, use_default
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator
|
||||
: public detail::filter_iterator_base<Predicate, Iterator>::type
|
||||
{
|
||||
typedef typename detail::filter_iterator_base<
|
||||
Predicate, Iterator
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
filter_iterator() { }
|
||||
|
||||
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
||||
: super_t(x), m_predicate(f), m_end(end)
|
||||
{
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
filter_iterator(Iterator x, Iterator end = Iterator())
|
||||
: super_t(x), m_predicate(), m_end(end)
|
||||
{
|
||||
// Pro8 is a little too aggressive about instantiating the
|
||||
// body of this function.
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
// Don't allow use of this constructor if Predicate is a
|
||||
// function pointer type, since it will be 0.
|
||||
BOOST_STATIC_ASSERT(is_class<Predicate>::value);
|
||||
#endif
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
template<class OtherIterator>
|
||||
filter_iterator(
|
||||
filter_iterator<Predicate, OtherIterator> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||
)
|
||||
: super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {}
|
||||
|
||||
Predicate predicate() const { return m_predicate; }
|
||||
|
||||
Iterator end() const { return m_end; }
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
++(this->base_reference());
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
while(!this->m_predicate(*--(this->base_reference()))){};
|
||||
}
|
||||
|
||||
void satisfy_predicate()
|
||||
{
|
||||
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
|
||||
++(this->base_reference());
|
||||
}
|
||||
|
||||
// Probably should be the initial base class so it can be
|
||||
// optimized away via EBO if it is an empty class.
|
||||
Predicate m_predicate;
|
||||
Iterator m_end;
|
||||
};
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
filter_iterator<Predicate,Iterator>
|
||||
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
||||
{
|
||||
return filter_iterator<Predicate,Iterator>(f,x,end);
|
||||
}
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
filter_iterator<Predicate,Iterator>
|
||||
make_filter_iterator(
|
||||
typename iterators::enable_if<
|
||||
is_class<Predicate>
|
||||
, Iterator
|
||||
>::type x
|
||||
, Iterator end = Iterator()
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
, Predicate* = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return filter_iterator<Predicate,Iterator>(x,end);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP
|
141
include/boost/iterator/indirect_iterator.hpp
Normal file
141
include/boost/iterator/indirect_iterator.hpp
Normal file
@ -0,0 +1,141 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_INDIRECT_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
#include <boost/pointee.hpp>
|
||||
#include <boost/indirect_reference.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/python/detail/indirect_traits.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||
|
||||
#ifdef BOOST_MPL_NO_AUX_HAS_XXX
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/scoped_ptr.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <memory>
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||
class indirect_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||
struct indirect_base
|
||||
{
|
||||
typedef typename iterator_traits<Iter>::value_type dereferenceable;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
indirect_iterator<Iter, Value, Category, Reference, Difference>
|
||||
, Iter
|
||||
, typename ia_dflt_help<
|
||||
Value, pointee<dereferenceable>
|
||||
>::type
|
||||
, Category
|
||||
, typename ia_dflt_help<
|
||||
Reference
|
||||
, mpl::apply_if<
|
||||
is_same<Value,use_default>
|
||||
, indirect_reference<dereferenceable>
|
||||
, add_reference<Value>
|
||||
>
|
||||
>::type
|
||||
, Difference
|
||||
> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct indirect_base<int, int, int, int, int> {};
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <
|
||||
class Iterator
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class indirect_iterator
|
||||
: public detail::indirect_base<
|
||||
Iterator, Value, Category, Reference, Difference
|
||||
>::type
|
||||
{
|
||||
typedef typename detail::indirect_base<
|
||||
Iterator, Value, Category, Reference, Difference
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
indirect_iterator() {}
|
||||
|
||||
indirect_iterator(Iterator iter)
|
||||
: super_t(iter) {}
|
||||
|
||||
template <
|
||||
class Iterator2, class Value2, class Category2
|
||||
, class Reference2, class Difference2
|
||||
>
|
||||
indirect_iterator(
|
||||
indirect_iterator<
|
||||
Iterator2, Value2, Category2, Reference2, Difference2
|
||||
> const& y
|
||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0
|
||||
)
|
||||
: super_t(y.base())
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
return const_cast<super_t::reference>(**this->base());
|
||||
# else
|
||||
return **this->base();
|
||||
# endif
|
||||
}
|
||||
};
|
||||
|
||||
template <class Iter>
|
||||
inline
|
||||
indirect_iterator<Iter> make_indirect_iterator(Iter x)
|
||||
{
|
||||
return indirect_iterator<Iter>(x);
|
||||
}
|
||||
|
||||
template <class Traits, class Iter>
|
||||
inline
|
||||
indirect_iterator<Iter,Traits> make_indirect_iterator(Iter x, Traits* = 0)
|
||||
{
|
||||
return indirect_iterator<Iter, Traits>(x);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
52
include/boost/iterator/interoperable.hpp
Normal file
52
include/boost/iterator/interoperable.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_INTEROPERABLE_23022003THW_HPP
|
||||
# define BOOST_INTEROPERABLE_23022003THW_HPP
|
||||
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
# include <boost/iterator/detail/config_def.hpp> // must appear last
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
// Meta function that determines whether two
|
||||
// iterator types are considered interoperable.
|
||||
//
|
||||
// Two iterator types A,B are considered interoperable if either
|
||||
// A is convertible to B or vice versa.
|
||||
// This interoperability definition is in sync with the
|
||||
// standards requirements on constant/mutable container
|
||||
// iterators (23.1 [lib.container.requirements]).
|
||||
//
|
||||
// For compilers that don't support is_convertible
|
||||
// is_interoperable gives false positives. See comments
|
||||
// on operator implementation for consequences.
|
||||
//
|
||||
template <typename A, typename B>
|
||||
struct is_interoperable
|
||||
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||
: mpl::true_
|
||||
# else
|
||||
: mpl::or_<
|
||||
is_convertible< A, B >
|
||||
, is_convertible< B, A > >
|
||||
# endif
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_INTEROPERABLE_23022003THW_HPP
|
150
include/boost/iterator/is_lvalue_iterator.hpp
Executable file
150
include/boost/iterator/is_lvalue_iterator.hpp
Executable file
@ -0,0 +1,150 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
# define IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||
|
||||
// should be the last #includes
|
||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
// Calling lvalue_preserver( <expression>, 0 ) returns a reference
|
||||
// to the expression's result if <expression> is an lvalue, or
|
||||
// not_an_lvalue() otherwise.
|
||||
struct not_an_lvalue {};
|
||||
|
||||
template <class T>
|
||||
T& lvalue_preserver(T&, int);
|
||||
|
||||
template <class U>
|
||||
not_an_lvalue lvalue_preserver(U const&, ...);
|
||||
|
||||
# define BOOST_LVALUE_PRESERVER(expr) lvalue_preserver(expr,0)
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_LVALUE_PRESERVER(expr) expr
|
||||
|
||||
#endif
|
||||
|
||||
// Guts of is_lvalue_iterator. Value is the iterator's value_type
|
||||
// and the result is computed in the nested rebind template.
|
||||
template <class Value>
|
||||
struct is_lvalue_iterator_impl
|
||||
{
|
||||
// Eat implicit conversions so we don't report true for things
|
||||
// convertible to Value const&
|
||||
struct conversion_eater
|
||||
{
|
||||
conversion_eater(Value&);
|
||||
};
|
||||
|
||||
static char tester(conversion_eater, int);
|
||||
static char (& tester(any_conversion_eater, ...) )[2];
|
||||
|
||||
template <class It>
|
||||
struct rebind
|
||||
{
|
||||
static It& x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = (
|
||||
sizeof(
|
||||
is_lvalue_iterator_impl<Value>::tester(
|
||||
BOOST_LVALUE_PRESERVER(*x), 0
|
||||
)
|
||||
) == 1
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
#undef BOOST_LVALUE_PRESERVER
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<const void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<const volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// This level of dispatching is required for Borland. We might save
|
||||
// an instantiation by removing it for others.
|
||||
//
|
||||
template <class It>
|
||||
struct is_readable_lvalue_iterator_impl
|
||||
: is_lvalue_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
|
||||
>::template rebind<It>
|
||||
{};
|
||||
|
||||
template <class It>
|
||||
struct is_non_const_lvalue_iterator_impl
|
||||
: is_lvalue_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type
|
||||
>::template rebind<It>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
// Define the trait with full mpl lambda capability and various broken
|
||||
// compiler workarounds
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
|
||||
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
#include <boost/type_traits/detail/bool_trait_undef.hpp>
|
||||
|
||||
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
|
108
include/boost/iterator/is_readable_iterator.hpp
Executable file
108
include/boost/iterator/is_readable_iterator.hpp
Executable file
@ -0,0 +1,108 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
# define IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||
|
||||
// should be the last #include
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Guts of is_readable_iterator. Value is the iterator's value_type
|
||||
// and the result is computed in the nested rebind template.
|
||||
template <class Value>
|
||||
struct is_readable_iterator_impl
|
||||
{
|
||||
static char tester(Value&, int);
|
||||
static char (& tester(any_conversion_eater, ...) )[2];
|
||||
|
||||
template <class It>
|
||||
struct rebind
|
||||
{
|
||||
static It& x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = (
|
||||
sizeof(
|
||||
is_readable_iterator_impl<Value>::tester(*x, 1)
|
||||
) == 1
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
#undef BOOST_READABLE_PRESERVER
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template <>
|
||||
struct is_readable_iterator_impl<void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_readable_iterator_impl<const void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator_impl<volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator_impl<const volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// This level of dispatching is required for Borland. We might save
|
||||
// an instantiation by removing it for others.
|
||||
//
|
||||
template <class It>
|
||||
struct is_readable_iterator_impl2
|
||||
: is_readable_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
|
||||
>::template rebind<It>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
// Define the trait with full mpl lambda capability and various broken
|
||||
// compiler workarounds
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_readable_iterator,T,::boost::detail::is_readable_iterator_impl2<T>::value)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // IS_READABLE_ITERATOR_DWA2003112_HPP
|
346
include/boost/iterator/iterator_adaptor.hpp
Normal file
346
include/boost/iterator/iterator_adaptor.hpp
Normal file
@ -0,0 +1,346 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_ITERATOR_ADAPTOR_23022003THW_HPP
|
||||
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
#else
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// Used as a default template argument internally, merely to
|
||||
// indicate "use the default", this can also be passed by users
|
||||
// explicitly in order to specify that the default should be used.
|
||||
struct use_default;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// the incompleteness of use_default causes massive problems for
|
||||
// is_convertible (naturally). This workaround is fortunately not
|
||||
// needed for vc6/vc7.
|
||||
template<class To>
|
||||
struct is_convertible<use_default,To>
|
||||
: mpl::false_ {};
|
||||
# endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
//
|
||||
// Result type used in enable_if_convertible meta function.
|
||||
// This can be an incomplete type, as only pointers to
|
||||
// enable_if_convertible< ... >::type are used.
|
||||
// We could have used void for this, but conversion to
|
||||
// void* is just to easy.
|
||||
//
|
||||
struct enable_type;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// enable_if for use in adapted iterators constructors.
|
||||
//
|
||||
// In order to provide interoperability between adapted constant and
|
||||
// mutable iterators, adapted iterators will usually provide templated
|
||||
// conversion constructors of the following form
|
||||
//
|
||||
// template <class BaseIterator>
|
||||
// class adapted_iterator :
|
||||
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
|
||||
// {
|
||||
// public:
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// template <class OtherIterator>
|
||||
// adapted_iterator(
|
||||
// OtherIterator const& it
|
||||
// , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
|
||||
//
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
// enable_if_convertible is used to remove those overloads from the overload
|
||||
// set that cannot be instantiated. For all practical purposes only overloads
|
||||
// for constant/mutable interaction will remain. This has the advantage that
|
||||
// meta functions like boost::is_convertible do not return false positives,
|
||||
// as they can only look at the signature of the conversion constructor
|
||||
// and not at the actual instantiation.
|
||||
//
|
||||
// enable_if_interoperable can be safely used in user code. It falls back to
|
||||
// always enabled for compilers that don't support enable_if or is_convertible.
|
||||
// There is no need for compiler specific workarounds in user code.
|
||||
//
|
||||
// The operators implementation relies on boost::is_convertible not returning
|
||||
// false positives for user/library defined iterator types. See comments
|
||||
// on operator implementation for consequences.
|
||||
//
|
||||
# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
|
||||
|
||||
template <class From, class To>
|
||||
struct enable_if_convertible
|
||||
{
|
||||
typedef detail::enable_type type;
|
||||
};
|
||||
|
||||
# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
|
||||
|
||||
// For some reason vc7.1 needs us to "cut off" instantiation
|
||||
// of is_convertible in a few cases.
|
||||
template<typename From, typename To>
|
||||
struct enable_if_convertible
|
||||
: iterators::enable_if<
|
||||
mpl::or_<
|
||||
is_same<From,To>
|
||||
, is_convertible<From, To>
|
||||
>
|
||||
, detail::enable_type
|
||||
>
|
||||
{};
|
||||
|
||||
# else
|
||||
|
||||
template<typename From, typename To>
|
||||
struct enable_if_convertible
|
||||
: iterators::enable_if<
|
||||
is_convertible<From, To>
|
||||
, detail::enable_type
|
||||
>
|
||||
{};
|
||||
|
||||
# endif
|
||||
|
||||
//
|
||||
// Default template argument handling for iterator_adaptor
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
// If T is use_default, return the result of invoking
|
||||
// DefaultNullaryFn, otherwise return T.
|
||||
template <class T, class DefaultNullaryFn>
|
||||
struct ia_dflt_help
|
||||
: mpl::apply_if<
|
||||
is_same<T, use_default>
|
||||
, DefaultNullaryFn
|
||||
, mpl::identity<T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// A metafunction which computes an iterator_adaptor's base class,
|
||||
// a specialization of iterator_facade.
|
||||
template <
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value
|
||||
, class Traversal
|
||||
, class Reference
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_adaptor_base
|
||||
{
|
||||
typedef iterator_facade<
|
||||
Derived
|
||||
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
, typename detail::ia_dflt_help<
|
||||
Value
|
||||
, mpl::apply_if<
|
||||
is_same<Reference,use_default>
|
||||
, iterator_value<Base>
|
||||
, remove_reference<Reference>
|
||||
>
|
||||
>::type
|
||||
# else
|
||||
, typename detail::ia_dflt_help<
|
||||
Value, iterator_value<Base>
|
||||
>::type
|
||||
# endif
|
||||
|
||||
, typename detail::ia_dflt_help<
|
||||
Traversal
|
||||
, iterator_traversal<Base>
|
||||
>::type
|
||||
|
||||
, typename detail::ia_dflt_help<
|
||||
Reference
|
||||
, mpl::apply_if<
|
||||
is_same<Value,use_default>
|
||||
, iterator_reference<Base>
|
||||
, add_reference<Value>
|
||||
>
|
||||
>::type
|
||||
|
||||
, typename detail::ia_dflt_help<
|
||||
Difference, iterator_difference<Base>
|
||||
>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
template <class T> int static_assert_convertible_to(T);
|
||||
}
|
||||
|
||||
//
|
||||
// Iterator Adaptor
|
||||
//
|
||||
// The parameter ordering changed slightly with respect to former
|
||||
// versions of iterator_adaptor The idea is that when the user needs
|
||||
// to fiddle with the reference type it is highly likely that the
|
||||
// iterator category has to be adjusted as well. Any of the
|
||||
// following four template arguments may be ommitted or explicitly
|
||||
// replaced by use_default.
|
||||
//
|
||||
// Value - if supplied, the value_type of the resulting iterator, unless
|
||||
// const. If const, a conforming compiler strips constness for the
|
||||
// value_type. If not supplied, iterator_traits<Base>::value_type is used
|
||||
//
|
||||
// Category - the traversal category of the resulting iterator. If not
|
||||
// supplied, iterator_traversal<Base>::type is used.
|
||||
//
|
||||
// Reference - the reference type of the resulting iterator, and in
|
||||
// particular, the result type of operator*(). If not supplied but
|
||||
// Value is supplied, Value& is used. Otherwise
|
||||
// iterator_traits<Base>::reference is used.
|
||||
//
|
||||
// Difference - the difference_type of the resulting iterator. If not
|
||||
// supplied, iterator_traits<Base>::difference_type is used.
|
||||
//
|
||||
template <
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value = use_default
|
||||
, class Traversal = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class iterator_adaptor
|
||||
: public detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>::type
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
protected:
|
||||
typedef typename detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>::type super_t;
|
||||
public:
|
||||
iterator_adaptor() {}
|
||||
|
||||
explicit iterator_adaptor(Base const &iter)
|
||||
: m_iterator(iter)
|
||||
{
|
||||
}
|
||||
|
||||
Base const& base() const
|
||||
{ return m_iterator; }
|
||||
|
||||
protected:
|
||||
// for convenience in derived classes
|
||||
typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
|
||||
|
||||
//
|
||||
// lvalue access to the Base object for Derived
|
||||
//
|
||||
Base const& base_reference() const
|
||||
{ return m_iterator; }
|
||||
|
||||
Base& base_reference()
|
||||
{ return m_iterator; }
|
||||
|
||||
private:
|
||||
//
|
||||
// Core iterator interface for iterator_facade. This is private
|
||||
// to prevent temptation for Derived classes to use it, which
|
||||
// will often result in an error. Derived classes should use
|
||||
// base_reference(), above, to get direct access to m_iterator.
|
||||
//
|
||||
typename super_t::reference dereference() const
|
||||
{ return *m_iterator; }
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
|
||||
{
|
||||
// Maybe readd with same_distance
|
||||
// BOOST_STATIC_ASSERT(
|
||||
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||
// );
|
||||
return m_iterator == x.base();
|
||||
}
|
||||
|
||||
typedef typename iterator_category_to_traversal<
|
||||
typename super_t::iterator_category
|
||||
>::type my_traversal;
|
||||
|
||||
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
|
||||
typedef int assertion[sizeof(detail::static_assert_convertible_to<cat>(my_traversal()))];
|
||||
// BOOST_STATIC_ASSERT((is_convertible<my_traversal,cat>::value));
|
||||
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
|
||||
m_iterator += n;
|
||||
}
|
||||
|
||||
void increment() { ++m_iterator; }
|
||||
|
||||
void decrement()
|
||||
{
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
|
||||
--m_iterator;
|
||||
}
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
typename super_t::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
|
||||
{
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
|
||||
// Maybe readd with same_distance
|
||||
// BOOST_STATIC_ASSERT(
|
||||
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||
// );
|
||||
return y.base() - m_iterator;
|
||||
}
|
||||
|
||||
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
|
||||
|
||||
private: // data members
|
||||
Base m_iterator;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
501
include/boost/iterator/iterator_archetypes.hpp
Normal file
501
include/boost/iterator/iterator_archetypes.hpp
Normal file
@ -0,0 +1,501 @@
|
||||
// (C) Copyright Jeremy Siek 2002. 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_ITERATOR_ARCHETYPES_HPP
|
||||
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
#include <boost/concept_archetype.hpp>
|
||||
|
||||
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||
#include <boost/mpl/bitand.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype;
|
||||
|
||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype;
|
||||
|
||||
namespace iterator_archetypes
|
||||
{
|
||||
enum {
|
||||
readable_iterator_bit = 1
|
||||
, writable_iterator_bit = 2
|
||||
, swappable_iterator_bit = 4
|
||||
, lvalue_iterator_bit = 8
|
||||
};
|
||||
|
||||
// Not quite tags, since dispatching wouldn't work.
|
||||
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
|
||||
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|writable_iterator_bit)
|
||||
>::type readable_writable_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|lvalue_iterator_bit)
|
||||
>::type readable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(lvalue_iterator_bit|writable_iterator_bit)
|
||||
>::type writable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
|
||||
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
|
||||
|
||||
template <class Derived, class Base>
|
||||
struct has_access
|
||||
: mpl::equal_to<
|
||||
mpl::bitand_<Derived,Base>
|
||||
, Base
|
||||
>
|
||||
{};
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct assign_proxy
|
||||
{
|
||||
assign_proxy& operator=(T) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_proxy
|
||||
{
|
||||
operator T() { return static_object<T>::get(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_write_proxy
|
||||
: read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
|
||||
{
|
||||
read_write_proxy& operator=(T) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct arrow_proxy
|
||||
{
|
||||
T const* operator->() const { return 0; }
|
||||
};
|
||||
|
||||
struct no_operator_brackets {};
|
||||
|
||||
template <class ValueType>
|
||||
struct readable_operator_brackets
|
||||
{
|
||||
read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct writable_operator_brackets
|
||||
{
|
||||
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct operator_brackets
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename mpl::apply_if<
|
||||
is_convertible<TraversalCategory, random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory
|
||||
, iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
, mpl::identity<writable_operator_brackets<Value> >
|
||||
, mpl::if_<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory
|
||||
, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
, readable_operator_brackets<Value>
|
||||
, no_operator_brackets
|
||||
>
|
||||
>
|
||||
, mpl::identity<no_operator_brackets>
|
||||
>::type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class TraversalCategory>
|
||||
struct traversal_archetype_impl
|
||||
{
|
||||
template <class Derived,class Value> struct archetype;
|
||||
};
|
||||
|
||||
// Constructor argument for those iterators that
|
||||
// are not default constructible
|
||||
struct ctor_arg {};
|
||||
|
||||
template <class Derived, class Value, class TraversalCategory>
|
||||
struct traversal_archetype_
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||
>::type
|
||||
{
|
||||
typedef typename
|
||||
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||
base;
|
||||
|
||||
traversal_archetype_() {}
|
||||
|
||||
traversal_archetype_(ctor_arg arg)
|
||||
: base(arg)
|
||||
{}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<incrementable_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
{
|
||||
explicit archetype(ctor_arg) {}
|
||||
|
||||
struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
|
||||
typedef bogus difference_type;
|
||||
|
||||
Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
|
||||
Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<single_pass_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
||||
{
|
||||
explicit archetype(ctor_arg arg)
|
||||
: traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
|
||||
{}
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
// doesn't seem to pick up != from equality_comparable
|
||||
template <class Derived, class Value>
|
||||
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
|
||||
#endif
|
||||
template <>
|
||||
struct traversal_archetype_impl<forward_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
||||
{
|
||||
archetype()
|
||||
: traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
|
||||
{}
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
||||
{
|
||||
Derived& operator--() { return static_object<Derived>::get(); }
|
||||
Derived operator--(int) const { return static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<random_access_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
||||
{
|
||||
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(std::ptrdiff_t,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t)
|
||||
{ return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return 0; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
struct bogus_type;
|
||||
|
||||
template <class Value>
|
||||
struct convertible_type
|
||||
: mpl::if_< is_const<Value>,
|
||||
typename remove_const<Value>::type,
|
||||
bogus_type >
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <class> struct undefined;
|
||||
|
||||
template <class AccessCategory>
|
||||
struct iterator_access_archetype_impl
|
||||
{
|
||||
template <class Value> struct archetype;
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct iterator_access_archetype
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename iterator_access_archetype_impl<
|
||||
AccessCategory
|
||||
>::template archetype<Value>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
typedef typename remove_cv<Value>::type value_type;
|
||||
typedef Value reference;
|
||||
typedef Value* pointer;
|
||||
|
||||
value_type operator*() const { return static_object<value_type>::get(); }
|
||||
|
||||
detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
||||
# endif
|
||||
typedef void value_type;
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
|
||||
detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::readable_writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
typedef detail::read_write_proxy<Value> reference;
|
||||
|
||||
detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
typedef Value& reference;
|
||||
|
||||
Value& operator*() const { return static_object<Value>::get(); }
|
||||
Value* operator->() const { return 0; }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_lvalue_iterator_t
|
||||
>
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
||||
# endif
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype;
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype_base
|
||||
: detail::operator_brackets<
|
||||
typename remove_cv<Value>::type
|
||||
, AccessCategory
|
||||
, TraversalCategory
|
||||
>
|
||||
, detail::traversal_archetype_<
|
||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
||||
, Value
|
||||
, TraversalCategory
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype_base
|
||||
: iterator_access_archetype<Value, AccessCategory>
|
||||
, traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
{
|
||||
typedef iterator_access_archetype<Value, AccessCategory> access;
|
||||
|
||||
typedef typename detail::facade_iterator_category<
|
||||
TraversalCategory
|
||||
, typename mpl::apply_if<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory, iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
, remove_const<Value>
|
||||
, add_const<Value>
|
||||
>::type
|
||||
, typename access::reference
|
||||
>::type iterator_category;
|
||||
|
||||
// Needed for some broken libraries (see below)
|
||||
typedef boost::iterator<
|
||||
iterator_category
|
||||
, Value
|
||||
, typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type
|
||||
, typename access::pointer
|
||||
, typename access::reference
|
||||
> workaround_iterator_base;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype
|
||||
: public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
|
||||
// These broken libraries require derivation from std::iterator
|
||||
// (or related magic) in order to handle iter_swap and other
|
||||
// iterator operations
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
, public detail::iterator_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::workaround_iterator_base
|
||||
# endif
|
||||
{
|
||||
// Derivation from std::iterator above caused references to nested
|
||||
// types to be ambiguous, so now we have to redeclare them all
|
||||
// here.
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
|
||||
typedef detail::iterator_archetype_base<
|
||||
Value,AccessCategory,TraversalCategory
|
||||
> base;
|
||||
|
||||
typedef typename base::value_type value_type;
|
||||
typedef typename base::reference reference;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::iterator_category iterator_category;
|
||||
# endif
|
||||
|
||||
iterator_archetype() { }
|
||||
iterator_archetype(iterator_archetype const& x)
|
||||
: detail::iterator_archetype_base<
|
||||
Value
|
||||
, AccessCategory
|
||||
, TraversalCategory
|
||||
>(x)
|
||||
{}
|
||||
|
||||
iterator_archetype& operator=(iterator_archetype const&)
|
||||
{ return *this; }
|
||||
|
||||
# if 0
|
||||
// Optional conversion from mutable
|
||||
iterator_archetype(
|
||||
iterator_archetype<
|
||||
typename detail::convertible_type<Value>::type
|
||||
, AccessCategory
|
||||
, TraversalCategory> const&
|
||||
);
|
||||
# endif
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_ITERATOR_ARCHETYPES_HPP
|
189
include/boost/iterator/iterator_categories.hpp
Normal file
189
include/boost/iterator/iterator_categories.hpp
Normal file
@ -0,0 +1,189 @@
|
||||
// (C) Copyright Jeremy Siek 2002. 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_ITERATOR_CATEGORIES_HPP
|
||||
# define BOOST_ITERATOR_CATEGORIES_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//
|
||||
// Traversal Categories
|
||||
//
|
||||
|
||||
struct no_traversal_tag {};
|
||||
|
||||
struct incrementable_traversal_tag
|
||||
: no_traversal_tag
|
||||
{
|
||||
// incrementable_traversal_tag() {}
|
||||
// incrementable_traversal_tag(std::output_iterator_tag const&) {};
|
||||
};
|
||||
|
||||
struct single_pass_traversal_tag
|
||||
: incrementable_traversal_tag
|
||||
{
|
||||
// single_pass_traversal_tag() {}
|
||||
// single_pass_traversal_tag(std::input_iterator_tag const&) {};
|
||||
};
|
||||
|
||||
struct forward_traversal_tag
|
||||
: single_pass_traversal_tag
|
||||
{
|
||||
// forward_traversal_tag() {}
|
||||
// forward_traversal_tag(std::forward_iterator_tag const&) {};
|
||||
};
|
||||
|
||||
struct bidirectional_traversal_tag
|
||||
: forward_traversal_tag
|
||||
{
|
||||
// bidirectional_traversal_tag() {};
|
||||
// bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {};
|
||||
};
|
||||
|
||||
struct random_access_traversal_tag
|
||||
: bidirectional_traversal_tag
|
||||
{
|
||||
// random_access_traversal_tag() {};
|
||||
// random_access_traversal_tag(std::random_access_iterator_tag const&) {};
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
// Convert a "strictly old-style" iterator category to a traversal
|
||||
// tag. This is broken out into a separate metafunction to reduce
|
||||
// the cost of instantiating iterator_category_to_traversal, below,
|
||||
// for new-style types.
|
||||
//
|
||||
template <class Cat>
|
||||
struct old_category_to_traversal
|
||||
: mpl::apply_if<
|
||||
is_convertible<Cat,std::random_access_iterator_tag>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::bidirectional_iterator_tag>
|
||||
, mpl::identity<bidirectional_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::forward_iterator_tag>
|
||||
, mpl::identity<forward_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::input_iterator_tag>
|
||||
, mpl::identity<single_pass_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::output_iterator_tag>
|
||||
, mpl::identity<incrementable_traversal_tag>
|
||||
, void
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct old_category_to_traversal<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
template <class Traversal>
|
||||
struct pure_traversal_tag
|
||||
: mpl::apply_if<
|
||||
is_convertible<Traversal,random_access_traversal_tag>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,bidirectional_traversal_tag>
|
||||
, mpl::identity<bidirectional_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,forward_traversal_tag>
|
||||
, mpl::identity<forward_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,single_pass_traversal_tag>
|
||||
, mpl::identity<single_pass_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,incrementable_traversal_tag>
|
||||
, mpl::identity<incrementable_traversal_tag>
|
||||
, void
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct pure_traversal_tag<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
//
|
||||
// Convert an iterator category into a traversal tag
|
||||
//
|
||||
template <class Cat>
|
||||
struct iterator_category_to_traversal
|
||||
: mpl::apply_if< // if already convertible to a traversal tag, we're done.
|
||||
is_convertible<Cat,incrementable_traversal_tag>
|
||||
, mpl::identity<Cat>
|
||||
, detail::old_category_to_traversal<Cat>
|
||||
>
|
||||
{};
|
||||
|
||||
// Trait to get an iterator's traversal category
|
||||
template <class Iterator = mpl::_1>
|
||||
struct iterator_traversal
|
||||
: iterator_category_to_traversal<
|
||||
typename boost::detail::iterator_traits<Iterator>::iterator_category
|
||||
>
|
||||
{};
|
||||
|
||||
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
template <>
|
||||
struct iterator_traversal<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : iterator_traversal<T>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct iterator_traversal<mpl::_>
|
||||
: iterator_traversal<mpl::_1>
|
||||
{};
|
||||
# endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_CATEGORIES_HPP
|
308
include/boost/iterator/iterator_concepts.hpp
Normal file
308
include/boost/iterator/iterator_concepts.hpp
Normal file
@ -0,0 +1,308 @@
|
||||
// (C) Copyright Jeremy Siek 2002. 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_ITERATOR_CONCEPTS_HPP
|
||||
#define BOOST_ITERATOR_CONCEPTS_HPP
|
||||
|
||||
// Revision History
|
||||
// 26 Apr 2003 thw
|
||||
// Adapted to new iterator concepts
|
||||
// 22 Nov 2002 Thomas Witt
|
||||
// Added interoperable concept.
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
// Use boost/limits to work around missing limits headers on some compilers
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
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.
|
||||
|
||||
// We use this in place of STATIC_ASSERT((is_convertible<...>))
|
||||
// because some compilers (CWPro7.x) can't detect convertibility.
|
||||
//
|
||||
// Of course, that just gets us a different error at the moment with
|
||||
// some tests, since new iterator category deduction still depends
|
||||
// on convertibility detection. We might need some specializations
|
||||
// to support this compiler.
|
||||
template <class Target, class Source>
|
||||
struct static_assert_base_and_derived
|
||||
{
|
||||
static_assert_base_and_derived(Target* = (Source*)0) {}
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Access Concepts
|
||||
|
||||
template <typename Iterator>
|
||||
class ReadableIteratorConcept {
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::AssignableConcept<Iterator> >();
|
||||
boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
|
||||
|
||||
value_type v = *i;
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Iterator
|
||||
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
|
||||
>
|
||||
class WritableIteratorConcept {
|
||||
public:
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
|
||||
*i = v;
|
||||
}
|
||||
ValueType v;
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class SwappableIteratorConcept {
|
||||
public:
|
||||
|
||||
void constraints() {
|
||||
std::iter_swap(i1, i2);
|
||||
}
|
||||
Iterator i1;
|
||||
Iterator i2;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class LvalueIteratorConcept
|
||||
{
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
void constraints()
|
||||
{
|
||||
value_type& r = const_cast<value_type&>(*i);
|
||||
boost::ignore_unused_variable_warning(r);
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Traversal Concepts
|
||||
|
||||
template <typename Iterator>
|
||||
class IncrementableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::AssignableConcept<Iterator> >();
|
||||
boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::incrementable_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
++i;
|
||||
(void)i++;
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class SinglePassIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< IncrementableIteratorConcept<Iterator> >();
|
||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::single_pass_traversal_tag
|
||||
>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class ForwardTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< SinglePassIteratorConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
typedef boost::mpl::and_<
|
||||
boost::is_integral<difference_type>,
|
||||
boost::mpl::bool_< std::numeric_limits<difference_type>::is_signed >
|
||||
> difference_type_is_signed_integral;
|
||||
|
||||
BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value);
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::forward_traversal_tag
|
||||
>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class BidirectionalTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ForwardTraversalConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::bidirectional_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
--i;
|
||||
(void)i--;
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class RandomAccessTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< BidirectionalTraversalConcept<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;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Interoperability Concept
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||
{
|
||||
bool b;
|
||||
b = i1 == i2;
|
||||
b = i1 != i2;
|
||||
|
||||
b = i2 == i1;
|
||||
b = i2 != i1;
|
||||
}
|
||||
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2,
|
||||
boost::random_access_traversal_tag, boost::random_access_traversal_tag)
|
||||
{
|
||||
bool b;
|
||||
typename boost::detail::iterator_traits<Iterator2>::difference_type n;
|
||||
b = i1 < i2;
|
||||
b = i1 <= i2;
|
||||
b = i1 > i2;
|
||||
b = i1 >= i2;
|
||||
n = i1 - i2;
|
||||
|
||||
b = i2 < i1;
|
||||
b = i2 <= i1;
|
||||
b = i2 > i1;
|
||||
b = i2 >= i1;
|
||||
n = i2 - i1;
|
||||
}
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2,
|
||||
boost::single_pass_traversal_tag, boost::single_pass_traversal_tag)
|
||||
{ }
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Iterator, typename ConstIterator>
|
||||
class InteroperableIteratorConcept
|
||||
{
|
||||
public:
|
||||
typedef typename boost::detail::pure_traversal_tag<
|
||||
typename boost::iterator_traversal<
|
||||
Iterator
|
||||
>::type
|
||||
>::type traversal_category;
|
||||
|
||||
typedef typename boost::detail::pure_traversal_tag<
|
||||
typename boost::iterator_traversal<
|
||||
ConstIterator
|
||||
>::type
|
||||
>::type const_traversal_category;
|
||||
|
||||
void constraints()
|
||||
{
|
||||
boost::function_requires< SinglePassIteratorConcept<Iterator> >();
|
||||
boost::function_requires< SinglePassIteratorConcept<ConstIterator> >();
|
||||
|
||||
detail::interop_single_pass_constraints(i, ci);
|
||||
detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category());
|
||||
|
||||
ci = i;
|
||||
}
|
||||
Iterator i;
|
||||
ConstIterator ci;
|
||||
};
|
||||
|
||||
} // namespace boost_concepts
|
||||
|
||||
|
||||
#endif // BOOST_ITERATOR_CONCEPTS_HPP
|
861
include/boost/iterator/iterator_facade.hpp
Normal file
861
include/boost/iterator/iterator_facade.hpp
Normal file
@ -0,0 +1,861 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_ITERATOR_FACADE_23022003THW_HPP
|
||||
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/interoperable.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_pod.hpp>
|
||||
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/always.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp> // this goes last
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// This forward declaration is required for the friend declaration
|
||||
// in iterator_core_access
|
||||
template <class I, class V, class TC, class R, class D> class iterator_facade;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// A binary metafunction class that always returns bool. VC6
|
||||
// ICEs on mpl::always<bool>, probably because of the default
|
||||
// parameters.
|
||||
struct always_bool2
|
||||
{
|
||||
template <class T, class U>
|
||||
struct apply
|
||||
{
|
||||
typedef bool type;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// enable if for use in operator implementation.
|
||||
//
|
||||
template <
|
||||
class Facade1
|
||||
, class Facade2
|
||||
, class Return
|
||||
>
|
||||
struct enable_if_interoperable
|
||||
: ::boost::iterators::enable_if<
|
||||
mpl::or_<
|
||||
is_convertible<Facade1, Facade2>
|
||||
, is_convertible<Facade2, Facade1>
|
||||
>
|
||||
, Return
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// Generates associated types for an iterator_facade with the
|
||||
// given parameters.
|
||||
//
|
||||
template <
|
||||
class ValueParam
|
||||
, class CategoryOrTraversal
|
||||
, class Reference
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_facade_types
|
||||
{
|
||||
typedef typename facade_iterator_category<
|
||||
CategoryOrTraversal, ValueParam, Reference
|
||||
>::type iterator_category;
|
||||
|
||||
typedef typename remove_const<ValueParam>::type value_type;
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
detail::iterator_writability_disabled<ValueParam,Reference>
|
||||
, add_pointer<typename add_const<value_type>::type>
|
||||
, add_pointer<value_type>
|
||||
>::type pointer;
|
||||
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|
||||
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
|
||||
|| BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
|
||||
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
|
||||
|
||||
// To interoperate with some broken library/compiler
|
||||
// combinations, user-defined iterators must be derived from
|
||||
// std::iterator. It is possible to implement a standard
|
||||
// library for broken compilers without this limitation.
|
||||
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
|
||||
|
||||
typedef
|
||||
iterator<iterator_category, value_type, Difference, pointer, Reference>
|
||||
base;
|
||||
# endif
|
||||
};
|
||||
|
||||
// iterators whose dereference operators reference the same value
|
||||
// for all iterators into the same sequence (like many input
|
||||
// iterators) need help with their postfix ++: the referenced
|
||||
// value must be read and stored away before the increment occurs
|
||||
// so that *a++ yields the originally referenced element and not
|
||||
// the next one.
|
||||
template <class Iterator>
|
||||
class postfix_increment_proxy
|
||||
{
|
||||
typedef typename iterator_value<Iterator>::type value_type;
|
||||
public:
|
||||
explicit postfix_increment_proxy(Iterator const& x)
|
||||
: stored_value(*x)
|
||||
{}
|
||||
|
||||
// Returning a mutable reference allows nonsense like
|
||||
// (*r++).mutate(), but it imposes fewer assumptions about the
|
||||
// behavior of the value_type. In particular, recall taht
|
||||
// (*r).mutate() is legal if operator* returns by value.
|
||||
value_type&
|
||||
operator*() const
|
||||
{
|
||||
return this->stored_value;
|
||||
}
|
||||
private:
|
||||
mutable value_type stored_value;
|
||||
};
|
||||
|
||||
//
|
||||
// In general, we can't determine that such an iterator isn't
|
||||
// writable -- we also need to store a copy of the old iterator so
|
||||
// that it can be written into.
|
||||
template <class Iterator>
|
||||
class writable_postfix_increment_proxy
|
||||
{
|
||||
typedef typename iterator_value<Iterator>::type value_type;
|
||||
public:
|
||||
explicit writable_postfix_increment_proxy(Iterator const& x)
|
||||
: stored_value(*x)
|
||||
, stored_iterator(x)
|
||||
{}
|
||||
|
||||
// Dereferencing must return a proxy so that both *r++ = o and
|
||||
// value_type(*r++) can work. In this case, *r is the same as
|
||||
// *r++, and the conversion operator below is used to ensure
|
||||
// readability.
|
||||
writable_postfix_increment_proxy const&
|
||||
operator*() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Provides readability of *r++
|
||||
operator value_type&() const
|
||||
{
|
||||
return stored_value;
|
||||
}
|
||||
|
||||
// Provides writability of *r++
|
||||
template <class T>
|
||||
T const& operator=(T const& x) const
|
||||
{
|
||||
*this->stored_iterator = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
// This overload just in case only non-const objects are writable
|
||||
template <class T>
|
||||
T& operator=(T& x) const
|
||||
{
|
||||
*this->stored_iterator = x;
|
||||
return x;
|
||||
}
|
||||
private:
|
||||
mutable value_type stored_value;
|
||||
Iterator stored_iterator;
|
||||
};
|
||||
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class Reference, class Value>
|
||||
struct is_non_proxy_reference_impl
|
||||
{
|
||||
static Reference r;
|
||||
|
||||
template <class R>
|
||||
static typename mpl::if_<
|
||||
is_convertible<
|
||||
R const volatile*
|
||||
, Value const volatile*
|
||||
>
|
||||
, char[1]
|
||||
, char[2]
|
||||
>::type& helper(R const&);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
|
||||
};
|
||||
|
||||
template <class Reference, class Value>
|
||||
struct is_non_proxy_reference
|
||||
: mpl::bool_<
|
||||
is_non_proxy_reference_impl<Reference, Value>::value
|
||||
>
|
||||
{};
|
||||
# else
|
||||
template <class Reference, class Value>
|
||||
struct is_non_proxy_reference
|
||||
: is_convertible<
|
||||
typename remove_reference<Reference>::type
|
||||
const volatile*
|
||||
, Value const volatile*
|
||||
>
|
||||
{};
|
||||
# endif
|
||||
|
||||
// A metafunction to choose the result type of postfix ++
|
||||
//
|
||||
// Because the C++98 input iterator requirements say that *r++ has
|
||||
// type T (value_type), implementations of some standard
|
||||
// algorithms like lexicographical_compare may use constructions
|
||||
// like:
|
||||
//
|
||||
// *r++ < *s++
|
||||
//
|
||||
// If *r++ returns a proxy (as required if r is writable but not
|
||||
// multipass), this sort of expression will fail unless the proxy
|
||||
// supports the operator<. Since there are any number of such
|
||||
// operations, we're not going to try to support them. Therefore,
|
||||
// even if r++ returns a proxy, *r++ will only return a proxy if
|
||||
// *r also returns a proxy.
|
||||
template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
|
||||
struct postfix_increment_result
|
||||
: mpl::apply_if<
|
||||
mpl::and_<
|
||||
// A proxy is only needed for readable iterators
|
||||
is_convertible<Reference,Value>
|
||||
|
||||
// No multipass iterator can have values that disappear
|
||||
// before positions can be re-visited
|
||||
, mpl::not_<
|
||||
is_convertible<
|
||||
typename iterator_category_to_traversal<CategoryOrTraversal>::type
|
||||
, forward_traversal_tag
|
||||
>
|
||||
>
|
||||
>
|
||||
, mpl::if_<
|
||||
is_non_proxy_reference<Reference,Value>
|
||||
, postfix_increment_proxy<Iterator>
|
||||
, writable_postfix_increment_proxy<Iterator>
|
||||
>
|
||||
, mpl::identity<Iterator>
|
||||
>
|
||||
{};
|
||||
|
||||
// operator->() needs special support for input iterators to strictly meet the
|
||||
// standard's requirements. If *i is not a reference type, we must still
|
||||
// produce a (constant) lvalue to which a pointer can be formed. We do that by
|
||||
// returning an instantiation of this special proxy class template.
|
||||
template <class T>
|
||||
struct operator_arrow_proxy
|
||||
{
|
||||
operator_arrow_proxy(T const* px) : m_value(*px) {}
|
||||
const T* operator->() const { return &m_value; }
|
||||
// This function is needed for MWCW and BCC, which won't call operator->
|
||||
// again automatically per 13.3.1.2 para 8
|
||||
operator const T*() const { return &m_value; }
|
||||
T m_value;
|
||||
};
|
||||
|
||||
// A metafunction that gets the result type for operator->. Also
|
||||
// has a static function make() which builds the result from a
|
||||
// Reference
|
||||
template <class ValueType, class Reference, class Pointer>
|
||||
struct operator_arrow_result
|
||||
{
|
||||
// CWPro8.3 won't accept "operator_arrow_result::type", and we
|
||||
// need that type below, so metafunction forwarding would be a
|
||||
// losing proposition here.
|
||||
typedef typename mpl::if_<
|
||||
is_reference<Reference>
|
||||
, Pointer
|
||||
, operator_arrow_proxy<ValueType>
|
||||
>::type type;
|
||||
|
||||
static type make(Reference x)
|
||||
{
|
||||
return type(&x);
|
||||
}
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template<>
|
||||
struct operator_arrow_result<int, int, int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
// A proxy return type for operator[], needed to deal with
|
||||
// iterators that may invalidate referents upon destruction.
|
||||
// Consider the temporary iterator in *(a + n)
|
||||
template <class Iterator>
|
||||
class operator_brackets_proxy
|
||||
{
|
||||
// Iterator is actually an iterator_facade, so we do not have to
|
||||
// go through iterator_traits to access the traits.
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
|
||||
public:
|
||||
operator_brackets_proxy(Iterator const& iter)
|
||||
: m_iter(iter)
|
||||
{}
|
||||
|
||||
operator reference() const
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
operator_brackets_proxy& operator=(value_type const& val)
|
||||
{
|
||||
*m_iter = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator m_iter;
|
||||
};
|
||||
|
||||
// A metafunction that determines whether operator[] must return a
|
||||
// proxy, or whether it can simply return a copy of the value_type.
|
||||
template <class ValueType, class Reference>
|
||||
struct use_operator_brackets_proxy
|
||||
: mpl::not_<
|
||||
mpl::and_<
|
||||
// Really we want an is_copy_constructible trait here,
|
||||
// but is_POD will have to suffice in the meantime.
|
||||
boost::is_POD<ValueType>
|
||||
, iterator_writability_disabled<ValueType,Reference>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Iterator, class Value, class Reference>
|
||||
struct operator_brackets_result
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
use_operator_brackets_proxy<Value,Reference>
|
||||
, operator_brackets_proxy<Iterator>
|
||||
, Value
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
|
||||
{
|
||||
return operator_brackets_proxy<Iterator>(iter);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
|
||||
{
|
||||
return *iter;
|
||||
}
|
||||
|
||||
struct choose_difference_type
|
||||
{
|
||||
template <class I1, class I2>
|
||||
struct apply
|
||||
:
|
||||
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
||||
iterator_difference<I1>
|
||||
# elif BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
mpl::if_<
|
||||
is_convertible<I2,I1>
|
||||
, typename I1::difference_type
|
||||
, typename I2::difference_type
|
||||
>
|
||||
# else
|
||||
mpl::apply_if<
|
||||
is_convertible<I2,I1>
|
||||
, iterator_difference<I1>
|
||||
, iterator_difference<I2>
|
||||
>
|
||||
# endif
|
||||
{};
|
||||
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
|
||||
// Macros which describe the declarations of binary operators
|
||||
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||
template < \
|
||||
class Derived1, class V1, class TC1, class R1, class D1 \
|
||||
, class Derived2, class V2, class TC2, class R2, class D2 \
|
||||
> \
|
||||
prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
|
||||
operator op( \
|
||||
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
|
||||
# else
|
||||
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||
template < \
|
||||
class Derived1, class V1, class TC1, class R1, class D1 \
|
||||
, class Derived2, class V2, class TC2, class R2, class D2 \
|
||||
> \
|
||||
prefix typename detail::enable_if_interoperable< \
|
||||
Derived1, Derived2 \
|
||||
, typename mpl::apply2<result_type,Derived1,Derived2>::type \
|
||||
>::type \
|
||||
operator op( \
|
||||
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
|
||||
# endif
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||
template <class Derived, class V, class TC, class R, class D> \
|
||||
prefix Derived operator+ args
|
||||
|
||||
//
|
||||
// Helper class for granting access to the iterator core interface.
|
||||
//
|
||||
// The simple core interface is used by iterator_facade. The core
|
||||
// interface of a user/library defined iterator type should not be made public
|
||||
// so that it does not clutter the public interface. Instead iterator_core_access
|
||||
// should be made friend so that iterator_facade can access the core
|
||||
// interface through iterator_core_access.
|
||||
//
|
||||
class iterator_core_access
|
||||
{
|
||||
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
// Tasteless as this may seem, making all members public allows member templates
|
||||
// to work in the absence of member template friends.
|
||||
public:
|
||||
# else
|
||||
|
||||
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_RELATION(op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, detail::always_bool2);
|
||||
|
||||
BOOST_ITERATOR_FACADE_RELATION(==)
|
||||
BOOST_ITERATOR_FACADE_RELATION(!=)
|
||||
|
||||
BOOST_ITERATOR_FACADE_RELATION(<)
|
||||
BOOST_ITERATOR_FACADE_RELATION(>)
|
||||
BOOST_ITERATOR_FACADE_RELATION(<=)
|
||||
BOOST_ITERATOR_FACADE_RELATION(>=)
|
||||
# undef BOOST_ITERATOR_FACADE_RELATION
|
||||
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(
|
||||
friend, -, detail::choose_difference_type)
|
||||
;
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend
|
||||
, (iterator_facade<Derived, V, TC, R, D> const&
|
||||
, typename Derived::difference_type)
|
||||
)
|
||||
;
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend
|
||||
, (typename Derived::difference_type
|
||||
, iterator_facade<Derived, V, TC, R, D> const&)
|
||||
)
|
||||
;
|
||||
|
||||
# endif
|
||||
|
||||
template <class Facade>
|
||||
static typename Facade::reference dereference(Facade const& f)
|
||||
{
|
||||
return f.dereference();
|
||||
}
|
||||
|
||||
template <class Facade>
|
||||
static void increment(Facade& f)
|
||||
{
|
||||
f.increment();
|
||||
}
|
||||
|
||||
template <class Facade>
|
||||
static void decrement(Facade& f)
|
||||
{
|
||||
f.decrement();
|
||||
}
|
||||
|
||||
template <class Facade1, class Facade2>
|
||||
static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
|
||||
{
|
||||
return f1.equal(f2);
|
||||
}
|
||||
|
||||
template <class Facade1, class Facade2>
|
||||
static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
|
||||
{
|
||||
return f2.equal(f1);
|
||||
}
|
||||
|
||||
template <class Facade>
|
||||
static void advance(Facade& f, typename Facade::difference_type n)
|
||||
{
|
||||
f.advance(n);
|
||||
}
|
||||
|
||||
template <class Facade1, class Facade2>
|
||||
static typename Facade1::difference_type distance_from(
|
||||
Facade1 const& f1, Facade2 const& f2, mpl::true_)
|
||||
{
|
||||
return -f1.distance_to(f2);
|
||||
}
|
||||
|
||||
template <class Facade1, class Facade2>
|
||||
static typename Facade2::difference_type distance_from(
|
||||
Facade1 const& f1, Facade2 const& f2, mpl::false_)
|
||||
{
|
||||
return f2.distance_to(f1);
|
||||
}
|
||||
|
||||
//
|
||||
// Curiously Recurring Template interface.
|
||||
//
|
||||
template <class I, class V, class TC, class R, class D>
|
||||
static I& derived(iterator_facade<I,V,TC,R,D>& facade)
|
||||
{
|
||||
return *static_cast<I*>(&facade);
|
||||
}
|
||||
|
||||
template <class I, class V, class TC, class R, class D>
|
||||
static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
|
||||
{
|
||||
return *static_cast<I const*>(&facade);
|
||||
}
|
||||
|
||||
private:
|
||||
// objects of this class are useless
|
||||
iterator_core_access(); //undefined
|
||||
};
|
||||
|
||||
//
|
||||
// iterator_facade - use as a public base class for defining new
|
||||
// standard-conforming iterators.
|
||||
//
|
||||
template <
|
||||
class Derived // The derived iterator type being constructed
|
||||
, class Value
|
||||
, class CategoryOrTraversal
|
||||
, class Reference = Value&
|
||||
, class Difference = std::ptrdiff_t
|
||||
>
|
||||
class iterator_facade
|
||||
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||
: public detail::iterator_facade_types<
|
||||
Value, CategoryOrTraversal, Reference, Difference
|
||||
>::base
|
||||
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||
# endif
|
||||
{
|
||||
private:
|
||||
//
|
||||
// Curiously Recurring Template interface.
|
||||
//
|
||||
Derived& derived()
|
||||
{
|
||||
return *static_cast<Derived*>(this);
|
||||
}
|
||||
|
||||
Derived const& derived() const
|
||||
{
|
||||
return *static_cast<Derived const*>(this);
|
||||
}
|
||||
|
||||
typedef detail::iterator_facade_types<
|
||||
Value, CategoryOrTraversal, Reference, Difference
|
||||
> associated_types;
|
||||
|
||||
protected:
|
||||
// For use by derived classes
|
||||
typedef iterator_facade<Derived,Value,Reference,Difference> iterator_facade_;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename associated_types::value_type value_type;
|
||||
typedef Reference reference;
|
||||
typedef Difference difference_type;
|
||||
typedef typename associated_types::pointer pointer;
|
||||
typedef typename associated_types::iterator_category iterator_category;
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
return iterator_core_access::dereference(this->derived());
|
||||
}
|
||||
|
||||
typename detail::operator_arrow_result<
|
||||
value_type
|
||||
, reference
|
||||
, pointer
|
||||
>::type
|
||||
operator->() const
|
||||
{
|
||||
return detail::operator_arrow_result<
|
||||
value_type
|
||||
, reference
|
||||
, pointer
|
||||
>::make(*this->derived());
|
||||
}
|
||||
|
||||
typename detail::operator_brackets_result<Derived,Value,reference>::type
|
||||
operator[](difference_type n) const
|
||||
{
|
||||
typedef detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
|
||||
|
||||
return detail::make_operator_brackets_result<Derived>(
|
||||
this->derived() + n
|
||||
, use_proxy()
|
||||
);
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
{
|
||||
iterator_core_access::increment(this->derived());
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
|
||||
operator++(int)
|
||||
{
|
||||
typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
|
||||
tmp(this->derived());
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
# endif
|
||||
|
||||
Derived& operator--()
|
||||
{
|
||||
iterator_core_access::decrement(this->derived());
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
Derived operator--(int)
|
||||
{
|
||||
Derived tmp(this->derived());
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Derived& operator+=(difference_type n)
|
||||
{
|
||||
iterator_core_access::advance(this->derived(), n);
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
Derived& operator-=(difference_type n)
|
||||
{
|
||||
iterator_core_access::advance(this->derived(), -n);
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
Derived operator-(difference_type x) const
|
||||
{
|
||||
Derived result(this->derived());
|
||||
return result -= x;
|
||||
}
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// There appears to be a bug which trashes the data of classes
|
||||
// derived from iterator_facade when they are assigned unless we
|
||||
// define this assignment operator. This bug is only revealed
|
||||
// (so far) in STLPort debug mode, but it's clearly a codegen
|
||||
// problem so we apply the workaround for all MSVC6.
|
||||
iterator_facade& operator=(iterator_facade const&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
# endif
|
||||
};
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <class I, class V, class TC, class R, class D>
|
||||
typename detail::postfix_increment_result<I,V,R,TC>::type
|
||||
operator++(
|
||||
iterator_facade<I,V,TC,R,D>& i
|
||||
, int
|
||||
)
|
||||
{
|
||||
typename detail::postfix_increment_result<I,V,R,TC>::type
|
||||
tmp(*static_cast<I*>(&i));
|
||||
|
||||
++i;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
//
|
||||
// Comparison operator implementation. The library supplied operators
|
||||
// enables the user to provide fully interoperable constant/mutable
|
||||
// iterator types. I.e. the library provides all operators
|
||||
// for all mutable/constant iterator combinations.
|
||||
//
|
||||
// Note though that this kind of interoperability for constant/mutable
|
||||
// iterators is not required by the standard for container iterators.
|
||||
// All the standard asks for is a conversion mutable -> constant.
|
||||
// Most standard library implementations nowadays provide fully interoperable
|
||||
// iterator implementations, but there are still heavily used implementations
|
||||
// that do not provide them. (Actually it's even worse, they do not provide
|
||||
// them for only a few iterators.)
|
||||
//
|
||||
// ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
|
||||
// enable the user to turn off mixed type operators
|
||||
//
|
||||
// The library takes care to provide only the right operator overloads.
|
||||
// I.e.
|
||||
//
|
||||
// bool operator==(Iterator, Iterator);
|
||||
// bool operator==(ConstIterator, Iterator);
|
||||
// bool operator==(Iterator, ConstIterator);
|
||||
// bool operator==(ConstIterator, ConstIterator);
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// In order to do so it uses c++ idioms that are not yet widely supported
|
||||
// by current compiler releases. The library is designed to degrade gracefully
|
||||
// in the face of compiler deficiencies. In general compiler
|
||||
// deficiencies result in less strict error checking and more obscure
|
||||
// error messages, functionality is not affected.
|
||||
//
|
||||
// For full operation compiler support for "Substitution Failure Is Not An Error"
|
||||
// (aka. enable_if) and boost::is_convertible is required.
|
||||
//
|
||||
// The following problems occur if support is lacking.
|
||||
//
|
||||
// Pseudo code
|
||||
//
|
||||
// ---------------
|
||||
// AdaptorA<Iterator1> a1;
|
||||
// AdaptorA<Iterator2> a2;
|
||||
//
|
||||
// // This will result in a no such overload error in full operation
|
||||
// // If enable_if or is_convertible is not supported
|
||||
// // The instantiation will fail with an error hopefully indicating that
|
||||
// // there is no operator== for Iterator1, Iterator2
|
||||
// // The same will happen if no enable_if is used to remove
|
||||
// // false overloads from the templated conversion constructor
|
||||
// // of AdaptorA.
|
||||
//
|
||||
// a1 == a2;
|
||||
// ----------------
|
||||
//
|
||||
// AdaptorA<Iterator> a;
|
||||
// AdaptorB<Iterator> b;
|
||||
//
|
||||
// // This will result in a no such overload error in full operation
|
||||
// // If enable_if is not supported the static assert used
|
||||
// // in the operator implementation will fail.
|
||||
// // This will accidently work if is_convertible is not supported.
|
||||
//
|
||||
// a == b;
|
||||
// ----------------
|
||||
//
|
||||
|
||||
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
||||
# define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
|
||||
# else
|
||||
# define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
|
||||
# endif
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
|
||||
{ \
|
||||
/* For those compilers that do not support enable_if */ \
|
||||
BOOST_STATIC_ASSERT(( \
|
||||
is_interoperable< Derived1, Derived2 >::value \
|
||||
)); \
|
||||
return_prefix iterator_core_access::base_op( \
|
||||
static_cast<Derived1 const&>(lhs) \
|
||||
, static_cast<Derived2 const&>(rhs) \
|
||||
, BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
|
||||
); \
|
||||
}
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP( \
|
||||
op \
|
||||
, detail::always_bool2 \
|
||||
, return_prefix \
|
||||
, base_op \
|
||||
)
|
||||
|
||||
BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
|
||||
BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
|
||||
|
||||
BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from)
|
||||
BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from)
|
||||
BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from)
|
||||
BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
|
||||
# undef BOOST_ITERATOR_FACADE_RELATION
|
||||
|
||||
// operator- requires an additional part in the static assertion
|
||||
BOOST_ITERATOR_FACADE_INTEROP(
|
||||
-
|
||||
, detail::choose_difference_type
|
||||
, return
|
||||
, distance_from
|
||||
)
|
||||
# undef BOOST_ITERATOR_FACADE_INTEROP
|
||||
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_PLUS(args) \
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
|
||||
{ \
|
||||
Derived tmp(static_cast<Derived const&>(i)); \
|
||||
return tmp += n; \
|
||||
}
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
iterator_facade<Derived, V, TC, R, D> const& i
|
||||
, typename Derived::difference_type n
|
||||
))
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
typename Derived::difference_type n
|
||||
, iterator_facade<Derived, V, TC, R, D> const& i
|
||||
))
|
||||
# undef BOOST_ITERATOR_FACADE_PLUS
|
||||
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
|
93
include/boost/iterator/iterator_traits.hpp
Normal file
93
include/boost/iterator/iterator_traits.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright David Abrahams 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.
|
||||
#ifndef ITERATOR_TRAITS_DWA200347_HPP
|
||||
# define ITERATOR_TRAITS_DWA200347_HPP
|
||||
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Unfortunately, g++ 2.95.x chokes when we define a class template
|
||||
// iterator_category which has the same name as its
|
||||
// std::iterator_category() function, probably due in part to the
|
||||
// "std:: is visible globally" hack it uses. Use
|
||||
// BOOST_ITERATOR_CATEGORY to write code that's portable to older
|
||||
// GCCs.
|
||||
|
||||
# if BOOST_WORKAROUND(__GNUC__, <= 2)
|
||||
# define BOOST_ITERATOR_CATEGORY iterator_category_
|
||||
# else
|
||||
# define BOOST_ITERATOR_CATEGORY iterator_category
|
||||
# endif
|
||||
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_value
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::value_type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_reference
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::reference type;
|
||||
};
|
||||
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_pointer
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::pointer type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_difference
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::difference_type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct BOOST_ITERATOR_CATEGORY
|
||||
{
|
||||
typedef typename detail::iterator_traits<Iterator>::iterator_category type;
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
template <>
|
||||
struct iterator_value<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_reference<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_pointer<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_difference<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BOOST_ITERATOR_CATEGORY<int>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
# endif
|
||||
|
||||
} // namespace boost::iterator
|
||||
|
||||
#endif // ITERATOR_TRAITS_DWA200347_HPP
|
251
include/boost/iterator/new_iterator_tests.hpp
Normal file
251
include/boost/iterator/new_iterator_tests.hpp
Normal file
@ -0,0 +1,251 @@
|
||||
#ifndef BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
# define BOOST_NEW_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 Oct 2002 Started update for new iterator categories
|
||||
// (Jeremy Siek)
|
||||
// 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
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/pending/iterator_tests.hpp>
|
||||
# include <boost/iterator/is_readable_iterator.hpp>
|
||||
# include <boost/iterator/is_lvalue_iterator.hpp>
|
||||
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
# include <boost/detail/is_incrementable.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
||||
// Do separate tests for *i++ so we can treat, e.g., smart pointers,
|
||||
// as readable and/or writable iterators.
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
|
||||
{
|
||||
T v2 = *i1++;
|
||||
assert(v == v2);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
|
||||
{}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
|
||||
{
|
||||
++i1; // we just wrote into that position
|
||||
*i1++ = v;
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
|
||||
{}
|
||||
|
||||
|
||||
// Preconditions: *i == v
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_test(const Iterator i1, T v)
|
||||
{
|
||||
Iterator i2(i1); // Copy Constructible
|
||||
typedef typename detail::iterator_traits<Iterator>::reference ref_t;
|
||||
ref_t r1 = *i1;
|
||||
ref_t r2 = *i2;
|
||||
T v1 = r1;
|
||||
T v2 = r2;
|
||||
assert(v1 == v);
|
||||
assert(v2 == v);
|
||||
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
|
||||
|
||||
// I think we don't really need this as it checks the same things as
|
||||
// the above code.
|
||||
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_test(Iterator i, T v, T v2)
|
||||
{
|
||||
Iterator i2(i); // Copy Constructible
|
||||
*i2 = v;
|
||||
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
writable_iterator_traversal_test(
|
||||
i, v2, mpl::and_<
|
||||
detail::is_incrementable<Iterator>
|
||||
, detail::is_postfix_incrementable<Iterator>
|
||||
>());
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
void swappable_iterator_test(Iterator i, Iterator j)
|
||||
{
|
||||
Iterator i2(i), j2(j);
|
||||
typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
|
||||
iter_swap(i2, j2);
|
||||
typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
|
||||
assert(bi == aj && bj == ai);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void constant_lvalue_iterator_test(Iterator i, T v1)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename detail::iterator_traits<Iterator>::reference reference;
|
||||
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
|
||||
const T& v2 = *i2;
|
||||
assert(v1 == v2);
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename detail::iterator_traits<Iterator>::reference reference;
|
||||
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
|
||||
T& v3 = *i2;
|
||||
assert(v1 == v3);
|
||||
|
||||
// A non-const lvalue iterator is not neccessarily writable, but we
|
||||
// are assuming the value_type is assignable here
|
||||
*i = v2;
|
||||
|
||||
T& v4 = *i2;
|
||||
assert(v2 == v4);
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||
{
|
||||
Iterator i2;
|
||||
Iterator i3(i);
|
||||
i2 = i;
|
||||
assert(i2 == i3);
|
||||
assert(i != j);
|
||||
assert(i2 != j);
|
||||
readable_iterator_test(i, val1);
|
||||
readable_iterator_test(i2, val1);
|
||||
readable_iterator_test(i3, val1);
|
||||
|
||||
assert(i == i2++);
|
||||
assert(i != ++i3);
|
||||
|
||||
readable_iterator_test(i2, val2);
|
||||
readable_iterator_test(i3, val2);
|
||||
|
||||
readable_iterator_test(i, val1);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||
{
|
||||
forward_readable_iterator_test(i, j, val1, val2);
|
||||
Iterator i2 = i;
|
||||
++i2;
|
||||
swappable_iterator_test(i, i2);
|
||||
}
|
||||
|
||||
// bidirectional
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator j(i);
|
||||
++j;
|
||||
forward_readable_iterator_test(i, j, v1, v2);
|
||||
++i;
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
assert(i == i1--);
|
||||
assert(i != --i2);
|
||||
|
||||
readable_iterator_test(i, v2);
|
||||
readable_iterator_test(i1, v1);
|
||||
readable_iterator_test(i2, v1);
|
||||
|
||||
--i;
|
||||
assert(i == i1);
|
||||
assert(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
readable_iterator_test(i, v1);
|
||||
readable_iterator_test(i1, v2);
|
||||
readable_iterator_test(i2, v2);
|
||||
}
|
||||
|
||||
// random access
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
{
|
||||
bidirectional_readable_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]);
|
||||
typename detail::iterator_traits<Iterator>::value_type x = j[c];
|
||||
assert(*i == x);
|
||||
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]);
|
||||
typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
|
||||
assert(*i == x);
|
||||
Iterator q = k - c;
|
||||
assert(*i == *q);
|
||||
assert(i > j);
|
||||
assert(i >= j);
|
||||
assert(j <= i);
|
||||
assert(j < i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_NEW_ITERATOR_TESTS_HPP
|
68
include/boost/iterator/permutation_iterator.hpp
Normal file
68
include/boost/iterator/permutation_iterator.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
// (C) Copyright Toon Knapen 2001.
|
||||
// (C) Copyright David Abrahams 2003.
|
||||
// (C) Copyright Roland Richter 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.
|
||||
|
||||
#ifndef BOOST_PERMUTATION_ITERATOR_HPP
|
||||
#define BOOST_PERMUTATION_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template< class ElementIterator
|
||||
, class IndexIterator>
|
||||
class permutation_iterator
|
||||
: public iterator_adaptor<
|
||||
permutation_iterator<ElementIterator, IndexIterator>
|
||||
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
|
||||
, use_default, typename detail::iterator_traits<ElementIterator>::reference>
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
permutation_iterator<ElementIterator, IndexIterator>
|
||||
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
|
||||
, use_default, typename detail::iterator_traits<ElementIterator>::reference> super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
permutation_iterator() : m_elt_iter() {}
|
||||
|
||||
explicit permutation_iterator(ElementIterator x, IndexIterator y)
|
||||
: super_t(y), m_elt_iter(x) {}
|
||||
|
||||
template<class OtherElementIterator, class OtherIndexIterator>
|
||||
permutation_iterator(
|
||||
permutation_iterator<OtherElementIterator, OtherIndexIterator> const& r
|
||||
, typename enable_if_convertible<OtherElementIterator, ElementIterator>::type* = 0
|
||||
, typename enable_if_convertible<OtherIndexIterator, IndexIterator>::type* = 0
|
||||
)
|
||||
: super_t(r.base()), m_elt_iter(r.m_elt_iter)
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{ return *(m_elt_iter + *this->base()); }
|
||||
|
||||
ElementIterator m_elt_iter;
|
||||
};
|
||||
|
||||
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
permutation_iterator<ElementIterator, IndexIterator>
|
||||
make_permutation_iterator( ElementIterator e, IndexIterator i )
|
||||
{
|
||||
return permutation_iterator<ElementIterator, IndexIterator>( e, i );
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
71
include/boost/iterator/reverse_iterator.hpp
Normal file
71
include/boost/iterator/reverse_iterator.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_REVERSE_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
template <class Iterator>
|
||||
class reverse_iterator
|
||||
: public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
|
||||
{
|
||||
typedef iterator_adaptor< reverse_iterator<Iterator>, Iterator > super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
reverse_iterator() {}
|
||||
|
||||
explicit reverse_iterator(Iterator x)
|
||||
: super_t(x) {}
|
||||
|
||||
template<class OtherIterator>
|
||||
reverse_iterator(
|
||||
reverse_iterator<OtherIterator> const& r
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||
)
|
||||
: super_t(r.base())
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const { return *boost::prior(this->base()); }
|
||||
|
||||
void increment() { --this->base_reference(); }
|
||||
void decrement() { ++this->base_reference(); }
|
||||
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
this->base_reference() += -n;
|
||||
}
|
||||
|
||||
template <class OtherIterator>
|
||||
typename super_t::difference_type
|
||||
distance_to(reverse_iterator<OtherIterator> const& y) const
|
||||
{
|
||||
return this->base_reference() - y.base();
|
||||
}
|
||||
};
|
||||
|
||||
template <class BidirectionalIterator>
|
||||
reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
|
||||
{
|
||||
return reverse_iterator<BidirectionalIterator>(x);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
183
include/boost/iterator/transform_iterator.hpp
Normal file
183
include/boost/iterator/transform_iterator.hpp
Normal file
@ -0,0 +1,183 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// 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_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
||||
# include <boost/type_traits/is_base_and_derived.hpp>
|
||||
|
||||
#endif
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
||||
class transform_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class UnaryFunction>
|
||||
struct function_object_result
|
||||
{
|
||||
typedef typename UnaryFunction::result_type type;
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Return, class Argument>
|
||||
struct function_object_result<Return(*)(Argument)>
|
||||
{
|
||||
typedef Return type;
|
||||
};
|
||||
#endif
|
||||
|
||||
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
||||
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||
struct transform_iterator_base
|
||||
{
|
||||
private:
|
||||
// By default, dereferencing the iterator yields the same as
|
||||
// the function. Do we need to adjust the way
|
||||
// function_object_result is computed for the standard
|
||||
// proposal (e.g. using Doug's result_of)?
|
||||
typedef typename ia_dflt_help<
|
||||
Reference
|
||||
, function_object_result<UnaryFunction>
|
||||
>::type reference;
|
||||
|
||||
// To get the default for Value: remove any reference on the
|
||||
// result type, but retain any constness to signal
|
||||
// non-writability. Note that if we adopt Thomas' suggestion
|
||||
// to key non-writability *only* on the Reference argument,
|
||||
// we'd need to strip constness here as well.
|
||||
typedef typename ia_dflt_help<
|
||||
Value
|
||||
, remove_reference<reference>
|
||||
>::type cv_value_type;
|
||||
|
||||
public:
|
||||
typedef iterator_adaptor<
|
||||
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||
, Iterator
|
||||
, cv_value_type
|
||||
, use_default // Leave the traversal category alone
|
||||
, reference
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||
class transform_iterator
|
||||
: public detail::transform_iterator_base<UnaryFunction, Iterator, Reference, Value>::type
|
||||
{
|
||||
typedef typename
|
||||
detail::transform_iterator_base<UnaryFunction, Iterator, Reference, Value>::type
|
||||
super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
transform_iterator() { }
|
||||
|
||||
transform_iterator(Iterator const& x, UnaryFunction f)
|
||||
: super_t(x), m_f(f) { }
|
||||
|
||||
explicit transform_iterator(Iterator const& x)
|
||||
: super_t(x)
|
||||
{
|
||||
// Pro8 is a little too aggressive about instantiating the
|
||||
// body of this function.
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
// don't provide this constructor if UnaryFunction is a
|
||||
// function pointer type, since it will be 0. Too dangerous.
|
||||
BOOST_STATIC_ASSERT(is_class<UnaryFunction>::value);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<
|
||||
class OtherUnaryFunction
|
||||
, class OtherIterator
|
||||
, class OtherReference
|
||||
, class OtherValue>
|
||||
transform_iterator(
|
||||
transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
|
||||
, typename enable_if_convertible<OtherUnaryFunction, UnaryFunction>::type* = 0
|
||||
#endif
|
||||
)
|
||||
: super_t(t.base()), m_f(t.functor())
|
||||
{}
|
||||
|
||||
UnaryFunction functor() const
|
||||
{ return m_f; }
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{ return m_f(*this->base()); }
|
||||
|
||||
// Probably should be the initial base class so it can be
|
||||
// optimized away via EBO if it is an empty class.
|
||||
UnaryFunction m_f;
|
||||
};
|
||||
|
||||
template <class UnaryFunction, class Iterator>
|
||||
transform_iterator<UnaryFunction, Iterator>
|
||||
make_transform_iterator(Iterator it, UnaryFunction fun)
|
||||
{
|
||||
return transform_iterator<UnaryFunction, Iterator>(it, fun);
|
||||
}
|
||||
|
||||
// Version which allows explicit specification of the UnaryFunction
|
||||
// type.
|
||||
//
|
||||
// This generator is not provided if UnaryFunction is a function
|
||||
// pointer type, because it's too dangerous: the default-constructed
|
||||
// function pointer in the iterator be 0, leading to a runtime
|
||||
// crash.
|
||||
template <class UnaryFunction, class Iterator>
|
||||
typename iterators::enable_if<
|
||||
is_class<UnaryFunction> // We should probably find a cheaper test than is_class<>
|
||||
, transform_iterator<UnaryFunction, Iterator>
|
||||
>::type
|
||||
make_transform_iterator(Iterator it)
|
||||
{
|
||||
return transform_iterator<UnaryFunction, Iterator>(it, UnaryFunction());
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
template <class Return, class Argument, class Iterator>
|
||||
transform_iterator< Return (*)(Argument), Iterator, Return>
|
||||
make_transform_iterator(Iterator it, Return (*fun)(Argument))
|
||||
{
|
||||
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
599
include/boost/iterator/zip_iterator.hpp
Executable file
599
include/boost/iterator/zip_iterator.hpp
Executable file
@ -0,0 +1,599 @@
|
||||
// (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_
|
||||
|
||||
#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/detail/minimum_category.hpp>
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/lambda.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Zip iterator forward declaration for zip_iterator_base
|
||||
template<typename IteratorTuple>
|
||||
class zip_iterator;
|
||||
|
||||
// One important design goal of the zip_iterator is to isolate all
|
||||
// functionality whose implementation relies on the current tuple
|
||||
// implementation. This goal has been achieved as follows: Inside
|
||||
// the namespace detail there is a namespace tuple_impl_specific.
|
||||
// This namespace encapsulates all functionality that is specific
|
||||
// to the current Boost tuple implementation. More precisely, the
|
||||
// namespace tuple_impl_specific provides the following tuple
|
||||
// algorithms and meta-algorithms for the current Boost tuple
|
||||
// implementation:
|
||||
//
|
||||
// tuple_meta_transform
|
||||
// tuple_meta_accumulate
|
||||
// tuple_transform
|
||||
// tuple_for_each
|
||||
//
|
||||
// If the tuple implementation changes, all that needs to be
|
||||
// replaced is the implementation of these four (meta-)algorithms.
|
||||
|
||||
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)
|
||||
{ ++it; }
|
||||
};
|
||||
//
|
||||
struct decrement_iterator
|
||||
{
|
||||
template<typename Iterator>
|
||||
void operator()(Iterator& it)
|
||||
{ --it; }
|
||||
};
|
||||
//
|
||||
struct dereference_iterator
|
||||
{
|
||||
template<typename Iterator>
|
||||
struct apply
|
||||
{
|
||||
typedef typename
|
||||
iterator_traits<Iterator>::reference
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
typename apply<Iterator>::type operator()(Iterator const& it)
|
||||
{ return *it; }
|
||||
};
|
||||
|
||||
|
||||
// The namespace tuple_impl_specific provides two meta-
|
||||
// algorithms and two algorithms for tuples.
|
||||
//
|
||||
namespace tuple_impl_specific
|
||||
{
|
||||
// Meta-transform algorithm for tuples
|
||||
//
|
||||
template<typename Tuple, class UnaryMetaFun>
|
||||
struct tuple_meta_transform;
|
||||
|
||||
template<typename Tuple, class UnaryMetaFun>
|
||||
struct tuple_meta_transform_impl
|
||||
{
|
||||
typedef tuples::cons<
|
||||
typename mpl::apply1<
|
||||
typename mpl::lambda<UnaryMetaFun>::type
|
||||
, typename Tuple::head_type
|
||||
>::type
|
||||
, typename tuple_meta_transform<
|
||||
typename Tuple::tail_type
|
||||
, UnaryMetaFun
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename Tuple, class UnaryMetaFun>
|
||||
struct tuple_meta_transform
|
||||
: mpl::apply_if<
|
||||
boost::is_same<Tuple, tuples::null_type>
|
||||
, mpl::identity<tuples::null_type>
|
||||
, tuple_meta_transform_impl<Tuple, UnaryMetaFun>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// Meta-accumulate algorithm for tuples. Note: The template
|
||||
// parameter StartType corresponds to the initial value in
|
||||
// ordinary accumulation.
|
||||
//
|
||||
template<class Tuple, class BinaryMetaFun, class StartType>
|
||||
struct tuple_meta_accumulate;
|
||||
|
||||
template<
|
||||
typename Tuple
|
||||
, class BinaryMetaFun
|
||||
, typename StartType
|
||||
>
|
||||
struct tuple_meta_accumulate_impl
|
||||
{
|
||||
typedef typename mpl::apply2<
|
||||
typename mpl::lambda<BinaryMetaFun>::type
|
||||
, typename Tuple::head_type
|
||||
, typename tuple_meta_accumulate<
|
||||
typename Tuple::tail_type
|
||||
, BinaryMetaFun
|
||||
, StartType
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename Tuple
|
||||
, class BinaryMetaFun
|
||||
, typename StartType
|
||||
>
|
||||
struct tuple_meta_accumulate
|
||||
: mpl::apply_if<
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
mpl::or_<
|
||||
#endif
|
||||
boost::is_same<Tuple, tuples::null_type>
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
, boost::is_same<Tuple,int>
|
||||
>
|
||||
#endif
|
||||
, mpl::identity<StartType>
|
||||
, tuple_meta_accumulate_impl<
|
||||
Tuple
|
||||
, BinaryMetaFun
|
||||
, StartType
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
||||
|| ( \
|
||||
BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, != 0) && defined(_MSC_VER) \
|
||||
)
|
||||
// Not sure why intel's partial ordering fails in this case, but I'm
|
||||
// assuming int's an MSVC bug-compatibility feature.
|
||||
|
||||
# define BOOST_TUPLE_ALGO_DISPATCH
|
||||
# define BOOST_TUPLE_ALGO(algo) algo##_impl
|
||||
# define BOOST_TUPLE_ALGO_TERMINATOR , int
|
||||
# define BOOST_TUPLE_ALGO_RECURSE , ...
|
||||
#else
|
||||
# define BOOST_TUPLE_ALGO(algo) algo
|
||||
# define BOOST_TUPLE_ALGO_TERMINATOR
|
||||
# define BOOST_TUPLE_ALGO_RECURSE
|
||||
#endif
|
||||
|
||||
// transform algorithm for tuples. The template parameter Fun
|
||||
// must be a unary functor which is also a unary metafunction
|
||||
// class that computes its return type based on its argument
|
||||
// type. For example:
|
||||
//
|
||||
// struct to_ptr
|
||||
// {
|
||||
// template <class Arg>
|
||||
// struct apply
|
||||
// {
|
||||
// typedef Arg* type;
|
||||
// }
|
||||
//
|
||||
// template <class Arg>
|
||||
// Arg* operator()(Arg x);
|
||||
// };
|
||||
template<typename Fun>
|
||||
tuples::null_type BOOST_TUPLE_ALGO(tuple_transform)
|
||||
(tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR)
|
||||
{ return tuples::null_type(); }
|
||||
|
||||
template<typename Tuple, typename Fun>
|
||||
typename tuple_meta_transform<
|
||||
Tuple
|
||||
, Fun
|
||||
>::type
|
||||
|
||||
BOOST_TUPLE_ALGO(tuple_transform)(
|
||||
const Tuple& t,
|
||||
Fun f
|
||||
BOOST_TUPLE_ALGO_RECURSE
|
||||
)
|
||||
{
|
||||
typedef typename tuple_meta_transform<
|
||||
BOOST_DEDUCED_TYPENAME Tuple::tail_type
|
||||
, Fun
|
||||
>::type transformed_tail_type;
|
||||
|
||||
return tuples::cons<
|
||||
BOOST_DEDUCED_TYPENAME mpl::apply1<
|
||||
Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type
|
||||
>::type
|
||||
, transformed_tail_type
|
||||
>(
|
||||
f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef BOOST_TUPLE_ALGO_DISPATCH
|
||||
template<typename Tuple, typename Fun>
|
||||
typename tuple_meta_transform<
|
||||
Tuple
|
||||
, Fun
|
||||
>::type
|
||||
|
||||
tuple_transform(
|
||||
const Tuple& t,
|
||||
Fun f
|
||||
)
|
||||
{
|
||||
return tuple_transform_impl(t, f, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// for_each algorithm for tuples.
|
||||
//
|
||||
template<typename Fun>
|
||||
Fun BOOST_TUPLE_ALGO(tuple_for_each)(
|
||||
tuples::null_type
|
||||
, Fun f BOOST_TUPLE_ALGO_TERMINATOR
|
||||
)
|
||||
{ return f; }
|
||||
|
||||
|
||||
template<typename Tuple, typename Fun>
|
||||
Fun BOOST_TUPLE_ALGO(tuple_for_each)(
|
||||
Tuple& t
|
||||
, Fun f BOOST_TUPLE_ALGO_RECURSE)
|
||||
{
|
||||
f( t.get_head() );
|
||||
return tuple_for_each(t.get_tail(), f);
|
||||
}
|
||||
|
||||
#ifdef BOOST_TUPLE_ALGO_DISPATCH
|
||||
template<typename Tuple, typename Fun>
|
||||
Fun
|
||||
tuple_for_each(
|
||||
Tuple& t,
|
||||
Fun f
|
||||
)
|
||||
{
|
||||
return tuple_for_each_impl(t, f, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Equality of tuples. NOTE: "==" for tuples currently (7/2003)
|
||||
// has problems under some compilers, so I just do my own.
|
||||
// No point in bringing in a bunch of #ifdefs here. This is
|
||||
// going to go away with the next tuple implementation anyway.
|
||||
//
|
||||
bool tuple_equal(tuples::null_type, tuples::null_type)
|
||||
{ return true; }
|
||||
|
||||
template<typename Tuple1, typename Tuple2>
|
||||
bool tuple_equal(
|
||||
Tuple1 const& t1,
|
||||
Tuple2 const& t2
|
||||
)
|
||||
{
|
||||
return t1.get_head() == t2.get_head() &&
|
||||
tuple_equal(t1.get_tail(), t2.get_tail());
|
||||
}
|
||||
}
|
||||
//
|
||||
// end namespace tuple_impl_specific
|
||||
|
||||
template<typename Iterator>
|
||||
struct iterator_reference
|
||||
{
|
||||
typedef typename iterator_traits<Iterator>::reference type;
|
||||
};
|
||||
|
||||
#ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
template<>
|
||||
struct iterator_reference<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : iterator_reference<T> {};
|
||||
};
|
||||
#endif
|
||||
|
||||
// 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
|
||||
: tuple_impl_specific::tuple_meta_transform<
|
||||
IteratorTuple,
|
||||
iterator_reference<mpl::_1>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// Metafunction to obtain the minimal traversal tag in a tuple
|
||||
// of iterators.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct minimum_traversal_category_in_iterator_tuple
|
||||
{
|
||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
||||
IteratorTuple
|
||||
, iterator_traversal<>
|
||||
>::type tuple_of_traversal_tags;
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
||||
tuple_of_traversal_tags
|
||||
, minimum_category<>
|
||||
, random_access_traversal_tag
|
||||
>::type type;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // 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_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 tuples::element<0, 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 detail::tuple_impl_specific::tuple_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 detail::tuple_impl_specific::tuple_equal(
|
||||
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)
|
||||
{
|
||||
detail::tuple_impl_specific::tuple_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()
|
||||
{
|
||||
detail::tuple_impl_specific::tuple_for_each(
|
||||
m_iterator_tuple,
|
||||
detail::increment_iterator()
|
||||
);
|
||||
}
|
||||
|
||||
// Decrementing a zip iterator means to decrement all iterators in
|
||||
// the iterator tuple.
|
||||
void decrement()
|
||||
{
|
||||
detail::tuple_impl_specific::tuple_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 boost::tuples::get<0>(other.get_iterator_tuple()) -
|
||||
boost::tuples::get<0>(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
@ -12,7 +12,8 @@
|
||||
#define BOOST_INTEGER_RANGE_HPP_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/counting_iterator.hpp>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@ -21,7 +22,7 @@ namespace boost {
|
||||
|
||||
template <class IntegerType>
|
||||
struct integer_range {
|
||||
typedef typename counting_iterator_generator<IntegerType>::type iterator;
|
||||
typedef counting_iterator<IntegerType> iterator;
|
||||
|
||||
typedef iterator const_iterator;
|
||||
typedef IntegerType value_type;
|
||||
|
@ -1 +1,7 @@
|
||||
// Copyright David Abrahams 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.
|
||||
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
@ -1,3 +1,8 @@
|
||||
// Copyright David Abrahams and Jeremy Siek 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.
|
||||
#ifndef BOOST_ITERATOR_TESTS_HPP
|
||||
# define BOOST_ITERATOR_TESTS_HPP
|
||||
|
||||
@ -20,6 +25,8 @@
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||
# include <boost/implicit_cast.hpp>
|
||||
# include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@ -33,6 +40,11 @@ struct dummyT {
|
||||
int m_x;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Tests whether type Iterator satisfies the requirements for a
|
||||
// TrivialIterator.
|
||||
@ -196,6 +208,8 @@ void bidirectional_iterator_test(Iterator i, T v1, T v2)
|
||||
|
||||
// mutable_bidirectional_iterator_test
|
||||
|
||||
template <class U> struct undefined;
|
||||
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
void random_access_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
@ -204,10 +218,12 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
assert(i == j + c);
|
||||
assert(*i == vals[c]);
|
||||
assert(*i == j[c]);
|
||||
assert(*i == boost::implicit_cast<value_type>(j[c]));
|
||||
assert(*i == *(j + c));
|
||||
assert(*i == *(c + j));
|
||||
++i;
|
||||
@ -221,7 +237,7 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
assert(i == k - c);
|
||||
assert(*i == vals[N - 1 - c]);
|
||||
assert(*i == j[N - 1 - c]);
|
||||
assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
|
||||
Iterator q = k - c;
|
||||
assert(*i == *q);
|
||||
assert(i > j);
|
||||
|
@ -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
|
||||
|
68
include/boost/pointee.hpp
Executable file
68
include/boost/pointee.hpp
Executable file
@ -0,0 +1,68 @@
|
||||
// Copyright David Abrahams 2004. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef POINTEE_DWA200415_HPP
|
||||
# define POINTEE_DWA200415_HPP
|
||||
|
||||
// dereferenceable_traits provides access to the value_type and
|
||||
// reference of a Dereferenceable type.
|
||||
|
||||
# include <boost/detail/is_incrementable.hpp>
|
||||
# include <boost/iterator/iterator_traits.hpp>
|
||||
# include <boost/type_traits/add_const.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class P>
|
||||
struct smart_ptr_pointee
|
||||
{
|
||||
typedef typename P::element_type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_pointee
|
||||
{
|
||||
typedef typename iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
struct impl
|
||||
{
|
||||
template <class T>
|
||||
static char test(T const&);
|
||||
|
||||
static char (& test(value_type&) )[2];
|
||||
|
||||
static Iterator& x;
|
||||
};
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_constant = sizeof(impl::test(*impl::x)) == 1);
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
::boost::detail::iterator_pointee<Iterator>::is_constant
|
||||
# else
|
||||
is_constant
|
||||
# endif
|
||||
, typename add_const<value_type>::type
|
||||
, value_type
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class P>
|
||||
struct pointee
|
||||
: mpl::apply_if<
|
||||
detail::is_incrementable<P>
|
||||
, detail::iterator_pointee<P>
|
||||
, detail::smart_ptr_pointee<P>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // POINTEE_DWA200415_HPP
|
62
include/boost/shared_container_iterator.hpp
Normal file
62
include/boost/shared_container_iterator.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
// (C) Copyright Ronald Garcia 2002. 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/libs/utility/shared_container_iterator.html for documentation.
|
||||
|
||||
#ifndef SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
||||
#define SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
||||
|
||||
#include "boost/iterator_adaptors.hpp"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename Container>
|
||||
class shared_container_iterator : public iterator_adaptor<
|
||||
shared_container_iterator<Container>,
|
||||
typename Container::iterator> {
|
||||
|
||||
typedef iterator_adaptor<
|
||||
shared_container_iterator<Container>,
|
||||
typename Container::iterator> super_t;
|
||||
|
||||
typedef typename Container::iterator iterator_t;
|
||||
typedef boost::shared_ptr<Container> container_ref_t;
|
||||
|
||||
container_ref_t container_ref;
|
||||
public:
|
||||
shared_container_iterator() { }
|
||||
|
||||
shared_container_iterator(iterator_t const& x,container_ref_t const& c) :
|
||||
super_t(x), container_ref(c) { }
|
||||
|
||||
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
shared_container_iterator<Container>
|
||||
make_shared_container_iterator(typename Container::iterator iter,
|
||||
boost::shared_ptr<Container> const& container) {
|
||||
typedef shared_container_iterator<Container> iterator;
|
||||
return iterator(iter,container);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename Container>
|
||||
std::pair<
|
||||
shared_container_iterator<Container>,
|
||||
shared_container_iterator<Container> >
|
||||
make_shared_container_range(boost::shared_ptr<Container> const& container) {
|
||||
return
|
||||
std::make_pair(
|
||||
make_shared_container_iterator(container->begin(),container),
|
||||
make_shared_container_iterator(container->end(),container));
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
Reference in New Issue
Block a user