mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-10 07:33:53 +00:00
Improved category handling in iterator_adaptor.
[SVN r19231]
This commit is contained in:
parent
3fe0d4b532
commit
ed8c60c20b
@ -329,6 +329,25 @@ namespace boost
|
||||
template <> struct minimum_category<int, int> { typedef minimum_category type; };
|
||||
# endif
|
||||
|
||||
//
|
||||
// Tag classification for use in iterator_adaptor
|
||||
//
|
||||
template <class Tag>
|
||||
struct is_access_tag
|
||||
: mpl::or_<
|
||||
is_tag<readable_iterator_tag, Tag>
|
||||
, mpl::or_<
|
||||
is_tag<writable_iterator_tag, Tag>
|
||||
, is_tag<swappable_iterator_tag, Tag>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Tag>
|
||||
struct is_traversal_tag
|
||||
: is_tag<incrementable_traversal_tag, Tag>
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
@ -15,34 +15,25 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class Iterator>
|
||||
struct filter_iterator_category
|
||||
{
|
||||
typedef iterator_tag<
|
||||
typename access_category<Iterator>::type
|
||||
, typename minimum_category<
|
||||
bidirectional_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator
|
||||
: public iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, typename detail::filter_iterator_category<Iterator>::type
|
||||
, typename detail::minimum_category<
|
||||
bidirectional_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, typename detail::filter_iterator_category<Iterator>::type
|
||||
, typename detail::minimum_category<
|
||||
bidirectional_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
> super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
@ -148,9 +148,18 @@ namespace boost
|
||||
>
|
||||
struct iterator_adaptor_base
|
||||
{
|
||||
private: // intermediate results
|
||||
typedef typename detail::ia_dflt_help<
|
||||
Category, BOOST_ITERATOR_CATEGORY<Base>
|
||||
private: // intermediate results
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
mpl::or_<
|
||||
is_same<Category, use_default>
|
||||
, mpl::or_<
|
||||
is_access_tag<Category>
|
||||
, is_traversal_tag<Category>
|
||||
>
|
||||
>
|
||||
, BOOST_ITERATOR_CATEGORY<Base>
|
||||
, mpl::identity<Category>
|
||||
>::type category;
|
||||
|
||||
typedef typename detail::ia_dflt_help<
|
||||
@ -170,9 +179,17 @@ namespace boost
|
||||
Value, iterator_value<Base>
|
||||
>::type
|
||||
|
||||
, typename access_category_tag<category, reference>::type
|
||||
|
||||
, typename traversal_category_tag<category>::type
|
||||
, typename mpl::apply_if<
|
||||
is_access_tag<Category>
|
||||
, mpl::identity<Category>
|
||||
, access_category_tag<category, reference>
|
||||
>::type
|
||||
|
||||
, typename mpl::apply_if<
|
||||
is_traversal_tag<Category>
|
||||
, mpl::identity<Category>
|
||||
, traversal_category_tag<category>
|
||||
>::type
|
||||
|
||||
, reference
|
||||
|
||||
|
@ -90,10 +90,7 @@ namespace boost
|
||||
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||
, Iterator
|
||||
, cv_value_type
|
||||
, iterator_tag<
|
||||
access_category
|
||||
, typename traversal_category<Iterator>::type
|
||||
>
|
||||
, access_category
|
||||
, result_type
|
||||
> type;
|
||||
};
|
||||
|
@ -112,6 +112,17 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
// Non-functional iterator for category modification checking
|
||||
template <class Iter, class Category>
|
||||
struct modify_category
|
||||
: boost::iterator_adaptor<
|
||||
modify_category<Iter, Category>
|
||||
, Iter
|
||||
, boost::use_default
|
||||
, Category
|
||||
>
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct fwd_iterator
|
||||
: boost::iterator_adaptor<
|
||||
@ -221,6 +232,15 @@ main()
|
||||
|
||||
test = static_assert_same<BaseIter::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
|
||||
test = static_assert_same<Iter::iterator_category::access, boost::readable_lvalue_iterator_tag>::value;
|
||||
|
||||
// Test category modification
|
||||
typedef modify_category<BaseIter, boost::readable_iterator_tag> ReadableIter;
|
||||
test = static_assert_same<ReadableIter::iterator_category::access, boost::readable_iterator_tag>::value;
|
||||
|
||||
typedef modify_category<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
|
||||
test = static_assert_same<BaseIter::iterator_category::traversal, boost::random_access_traversal_tag>::value;
|
||||
test = static_assert_same<IncrementableIter::iterator_category::traversal, boost::incrementable_traversal_tag>::value;
|
||||
|
||||
}
|
||||
|
||||
// Test the iterator_adaptor
|
||||
|
@ -91,6 +91,25 @@ void category_test()
|
||||
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
|
||||
>::value;
|
||||
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< incrementable_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< single_pass_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< forward_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< bidirectional_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< random_access_traversal_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!is_traversal_tag< std::input_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((!is_traversal_tag< readable_iterator_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< writable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< swappable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_writable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_lvalue_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< writable_lvalue_iterator_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!is_access_tag< std::input_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((!is_access_tag< incrementable_traversal_tag >::value));
|
||||
|
||||
(void)test;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user