From eb06c122d1ea9d2e63fd9a7ae44b44b6f6f0bfd4 Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Sun, 18 Mar 2001 18:37:49 +0000 Subject: [PATCH] rigged new iterator_traits for backward compatibility [SVN r9577] --- development/boost/iterator_concepts.hpp | 169 +++++--------------- development/boost/iterator_traits.hpp | 123 +++++++++++--- development/libs/iterator/concept_tests.cpp | 66 +++++++- 3 files changed, 205 insertions(+), 153 deletions(-) diff --git a/development/boost/iterator_concepts.hpp b/development/boost/iterator_concepts.hpp index acea6e3..a3ddc8b 100644 --- a/development/boost/iterator_concepts.hpp +++ b/development/boost/iterator_concepts.hpp @@ -3,6 +3,8 @@ #include #include +#include +#include namespace boost_concepts { // Used a different namespace here (instead of "boost") so that the @@ -11,6 +13,7 @@ namespace boost_concepts { //=========================================================================== + // Iterator Access Concepts template class ReadableIteratorConcept { @@ -23,11 +26,12 @@ namespace boost_concepts { void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); - boost::function_requires< boost::DefaultConstructibleConcept >(); - boost::function_requires< - boost::ConvertibleConcept >(); - + boost::DefaultConstructibleConcept >(); + + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + reference r = *i; // or perhaps read(x) value_type v(r); boost::ignore_unused_variable_warning(v); @@ -44,10 +48,11 @@ namespace boost_concepts { void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); - boost::function_requires< boost::DefaultConstructibleConcept >(); - boost::function_requires< - boost::ConvertibleConcept >(); + boost::DefaultConstructibleConcept >(); + + BOOST_STATIC_ASSERT((boost::is_convertible::value)); *i = v; // an alternative could be something like write(x, v) } @@ -65,12 +70,12 @@ namespace boost_concepts { void constraints() { boost::function_requires< ReadableIteratorConcept >(); - - boost::function_requires< - boost::ConvertibleConcept >(); - typedef typename boost::require_same::type req; + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + + BOOST_STATIC_ASSERT((boost::is_same::value)); reference v = *i; boost::ignore_unused_variable_warning(v); @@ -88,13 +93,13 @@ namespace boost_concepts { void constraints() { boost::function_requires< ReadableIteratorConcept >(); - boost::function_requires< WritableIteratorConcept >(); - boost::function_requires< - boost::ConvertibleConcept >(); + WritableIteratorConcept >(); + + BOOST_STATIC_ASSERT((boost::is_convertible::value)); - typedef typename boost::require_same::type req; + BOOST_STATIC_ASSERT((boost::is_same::value)); reference v = *i; boost::ignore_unused_variable_warning(v); @@ -103,24 +108,25 @@ namespace boost_concepts { }; //=========================================================================== + // Iterator Traversal Concepts template class SinglePassIteratorConcept { public: - typedef typename boost::iterator_traits::motion_category - motion_category; + typedef typename boost::iterator_traits::traversal_category + traversal_category; typedef typename boost::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); - boost::function_requires< boost::DefaultConstructibleConcept >(); - boost::function_requires< - boost::ConvertibleConcept >(); - + boost::DefaultConstructibleConcept >(); + + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + // difference_type must be a signed integral type ++i; @@ -133,30 +139,28 @@ namespace boost_concepts { template class ForwardIteratorConcept { public: - typedef typename boost::iterator_traits::motion_category - motion_category; + typedef typename boost::iterator_traits::traversal_category + traversal_category; void constraints() { boost::function_requires< SinglePassIteratorConcept >(); - boost::function_requires< - boost::ConvertibleConcept >(); + BOOST_STATIC_ASSERT((boost::is_convertible::value)); } }; template class BidirectionalIteratorConcept { public: - typedef typename boost::iterator_traits::motion_category - motion_category; + typedef typename boost::iterator_traits::traversal_category + traversal_category; void constraints() { boost::function_requires< ForwardIteratorConcept >(); - boost::function_requires< - boost::ConvertibleConcept >(); + BOOST_STATIC_ASSERT((boost::is_convertible::value)); --i; (void)i--; @@ -167,18 +171,17 @@ namespace boost_concepts { template class RandomAccessIteratorConcept { public: - typedef typename boost::iterator_traits::motion_category - motion_category; + typedef typename boost::iterator_traits::traversal_category + traversal_category; typedef typename boost::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< BidirectionalIteratorConcept >(); - boost::function_requires< - boost::ConvertibleConcept >(); - + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + i += n; i = i + n; i = n + i; @@ -190,92 +193,6 @@ namespace boost_concepts { Iterator i, j; }; - //=========================================================================== - - template - class ReadableRandomAccessIteratorConcept { - public: - typedef typename boost::iterator_traits::value_type value_type; - typedef typename boost::iterator_traits::reference reference; - typedef typename boost::iterator_traits::difference_type - difference_type; - - void constraints() { - boost::function_requires< RandomAccessIteratorConcept >(); - boost::function_requires< ReadableIteratorConcept >(); - - reference r = i[n]; - value_type v(r); - boost::ignore_unused_variable_warning(v); - } - difference_type n; - Iterator i; - }; - - template - class WritableRandomAccessIteratorConcept { - public: - typedef typename boost::iterator_traits::value_type value_type; - typedef typename boost::iterator_traits::difference_type - difference_type; - - void constraints() { - boost::function_requires< RandomAccessIteratorConcept >(); - boost::function_requires< WritableIteratorConcept >(); - - i[n] = v; - boost::ignore_unused_variable_warning(v); - } - difference_type n; - value_type v; - Iterator i; - }; - - template - class ConstantLvalueRandomAccessIteratorConcept { - public: - typedef typename boost::iterator_traits::value_type value_type; - typedef typename boost::iterator_traits::reference reference; - typedef typename boost::iterator_traits::difference_type - difference_type; - - void constraints() { - boost::function_requires< RandomAccessIteratorConcept >(); - boost::function_requires< ReadableIteratorConcept >(); - - typedef typename boost::require_same::type req; - - reference v = i[n]; - boost::ignore_unused_variable_warning(v); - } - difference_type n; - value_type v; - Iterator i; - }; - - template - class MutableLvalueRandomAccessIteratorConcept { - public: - typedef typename boost::iterator_traits::value_type value_type; - typedef typename boost::iterator_traits::reference reference; - typedef typename boost::iterator_traits::difference_type - difference_type; - - void constraints() { - boost::function_requires< RandomAccessIteratorConcept >(); - boost::function_requires< WritableIteratorConcept >(); - boost::function_requires< ReadableIteratorConcept >(); - - typedef typename boost::require_same::type req; - - reference v = i[n]; - boost::ignore_unused_variable_warning(v); - } - difference_type n; - value_type v; - Iterator i; - }; - } // namespace boost_concepts diff --git a/development/boost/iterator_traits.hpp b/development/boost/iterator_traits.hpp index 585f194..6f5d9b2 100644 --- a/development/boost/iterator_traits.hpp +++ b/development/boost/iterator_traits.hpp @@ -2,21 +2,14 @@ #define BOOST_ITERATOR_TRAITS_HPP #include -#include +#include +#include +#include +#include namespace boost { - - template - struct iterator_traits { - typedef typename Iterator::value_type value_type; - typedef typename Iterator::reference reference; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::return_category return_category; - typedef typename Iterator::motion_category motion_category; - }; - // Motion Categories + // Traversal Categories struct single_pass_iterator_tag { }; struct forward_iterator_tag : public single_pass_iterator_tag { }; struct bidirectional_iterator_tag : public forward_iterator_tag { }; @@ -28,29 +21,113 @@ namespace boost { struct mutable_lvalue_iterator_tag : virtual public writable_iterator_tag, virtual public readable_iterator_tag { }; struct constant_lvalue_iterator_tag : public readable_iterator_tag { }; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + 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 { - template - struct pointer_return_category { - typedef constant_lvalue_iterator_tag type; + + struct iter_traits_from_nested_types { + template struct bind { + typedef typename Iterator::value_type value_type; + typedef typename Iterator::reference reference; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::return_category return_category; + typedef typename Iterator::traversal_category traversal_category; + }; }; - template <> - struct pointer_return_category { - typedef mutable_lvalue_iterator_tag type; + + template + struct choose_lvalue_return { + typedef typename ct_if::value, + boost::constant_lvalue_iterator_tag, + boost::mutable_lvalue_iterator_tag>::type type; }; + + + template + struct iter_category_to_return { + typedef typename ct_if< + is_convertible::value, + typename choose_lvalue_return::type, + typename ct_if< + is_convertible::value, + boost::readable_iterator_tag, + typename ct_if< + is_convertible::value, + boost::writable_iterator_tag, + boost::error_iterator_tag + >::type + >::type + >::type type; + }; + + template + struct iter_category_to_traversal { + typedef typename ct_if< + is_convertible::value, + boost::random_access_iterator_tag, + typename ct_if< + is_convertible::value, + boost::bidirectional_iterator_tag, + typename ct_if< + is_convertible::value, + boost::forward_iterator_tag, + boost::single_pass_iterator_tag>::type + >::type + >::type type; + }; + + struct iter_traits_from_old_traits { + template class bind { + typedef boost::detail::iterator_traits OldTraits; + typedef typename OldTraits::iterator_category Cat; + public: + typedef typename OldTraits::value_type value_type; + typedef typename OldTraits::reference reference; + typedef typename OldTraits::pointer pointer; + typedef typename OldTraits::difference_type difference_type; + typedef iter_category_to_return::type return_category; + typedef iter_category_to_traversal::type traversal_category; + }; + }; + + template + class choose_iter_traits { + typedef typename ct_if::value, + iter_traits_from_nested_types, + iter_traits_from_old_traits>::type Choice; + public: + typedef typename Choice:: template bind type; + }; + } // namespace detail + + template + class iterator_traits + : public detail::choose_iter_traits::type { }; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template - struct iterator_traits { + struct iterator_traits + { typedef T value_type; typedef T& reference; typedef T* pointer; typedef std::ptrdiff_t difference_type; - typedef typename detail::pointer_return_category::value>::type + typedef typename ct_if::value, + boost::constant_lvalue_iterator_tag, + boost::mutable_lvalue_iterator_tag>::type return_category; - typedef random_access_iterator_tag motion_category; + typedef boost::random_access_iterator_tag traversal_category; }; #endif diff --git a/development/libs/iterator/concept_tests.cpp b/development/libs/iterator/concept_tests.cpp index 9ef2ed9..032e889 100644 --- a/development/libs/iterator/concept_tests.cpp +++ b/development/libs/iterator/concept_tests.cpp @@ -1,13 +1,71 @@ #include +#include + +struct new_iterator + : public boost::iterator, + public boost::new_iterator_base +{ + typedef boost::random_access_iterator_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 +{ + 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() { - boost::function_requires< - boost_concepts::MutableLvalueRandomAccessIteratorConcept >(); + boost::function_requires< + boost_concepts::MutableLvalueIteratorConcept >(); + boost::function_requires< + boost_concepts::RandomAccessIteratorConcept >(); - boost::function_requires< - boost_concepts::ConstantLvalueRandomAccessIteratorConcept >(); + boost::function_requires< + boost_concepts::ConstantLvalueIteratorConcept >(); + boost::function_requires< + boost_concepts::RandomAccessIteratorConcept >(); + boost::function_requires< + boost_concepts::MutableLvalueIteratorConcept >(); + boost::function_requires< + boost_concepts::RandomAccessIteratorConcept >(); + + boost::function_requires< + boost_concepts::MutableLvalueIteratorConcept >(); + boost::function_requires< + boost_concepts::RandomAccessIteratorConcept >(); return 0; }