forked from boostorg/iterator
All workarounds complete! Also some cleanups
[SVN r1249]
This commit is contained in:
@@ -100,7 +100,7 @@ In short, there are many useful iterators that do not fit into the
|
|||||||
current standard iterator categories. As a result, the following bad
|
current standard iterator categories. As a result, the following bad
|
||||||
things happen:
|
things happen:
|
||||||
|
|
||||||
- Iterators are often miss-categorized.
|
- Iterators are often mis-categorized.
|
||||||
|
|
||||||
- Algorithm requirements are more strict than necessary, because they
|
- Algorithm requirements are more strict than necessary, because they
|
||||||
cannot separate the need for random access or bidirectional
|
cannot separate the need for random access or bidirectional
|
||||||
@@ -402,8 +402,8 @@ Iterator Traversal Concepts [lib.iterator.traversal]
|
|||||||
|
|
||||||
In the tables below, ``X`` is an iterator type, ``a`` and ``b`` are
|
In the tables below, ``X`` is an iterator type, ``a`` and ``b`` are
|
||||||
constant objects of type ``X``, ``r`` and ``s`` are mutable objects of
|
constant objects of type ``X``, ``r`` and ``s`` are mutable objects of
|
||||||
type ``X``, ``T`` is ``std::iterator_traits<X>::value_type``,
|
type ``X``, ``T`` is ``std::iterator_traits<X>::value_type``, and
|
||||||
``v`` is a constant object of type ``T``, and ``u`` is an identifier.
|
``v`` is a constant object of type ``T``.
|
||||||
|
|
||||||
|
|
||||||
Incrementable Iterators [lib.incrementable.iterators]
|
Incrementable Iterators [lib.incrementable.iterators]
|
||||||
|
@@ -117,6 +117,12 @@ namespace boost
|
|||||||
bool operator==(traversal_archetype_<Derived, Value, single_pass_iterator_tag> const&,
|
bool operator==(traversal_archetype_<Derived, Value, single_pass_iterator_tag> const&,
|
||||||
traversal_archetype_<Derived, Value, single_pass_iterator_tag> const&);
|
traversal_archetype_<Derived, Value, single_pass_iterator_tag> const&);
|
||||||
|
|
||||||
|
#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_iterator_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, single_pass_iterator_tag> const&);
|
||||||
|
#endif
|
||||||
template <>
|
template <>
|
||||||
struct traversal_archetype_impl<forward_traversal_tag>
|
struct traversal_archetype_impl<forward_traversal_tag>
|
||||||
{
|
{
|
||||||
@@ -274,39 +280,56 @@ namespace boost
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
|
||||||
struct traversal_archetype
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
: detail::operator_brackets< typename remove_cv<Value>::type,
|
struct iterator_archetype;
|
||||||
AccessCategory,
|
|
||||||
TraversalCategory >,
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
detail::traversal_archetype_<Derived, Value, 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
|
||||||
|
>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Value, class AccessCategory, class TraversalCategory>
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
struct iterator_archetype
|
struct iterator_archetype
|
||||||
: public traversal_archetype<
|
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
|
||||||
, Value, AccessCategory, TraversalCategory
|
|
||||||
>
|
|
||||||
, public access_archetype<Value, AccessCategory>
|
, public access_archetype<Value, AccessCategory>
|
||||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310)
|
|
||||||
|
// 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 std::iterator<
|
, public std::iterator<
|
||||||
iterator_tag<AccessCategory,TraversalCategory>
|
iterator_tag<AccessCategory,TraversalCategory>
|
||||||
, typename access_archetype<Value, AccessCategory>::value_type
|
, typename access_archetype<Value, AccessCategory>::value_type
|
||||||
, typename traversal_archetype<
|
, typename traversal_archetype_base<
|
||||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
Value, AccessCategory, TraversalCategory
|
||||||
, Value, AccessCategory, TraversalCategory
|
|
||||||
>::difference_type
|
>::difference_type
|
||||||
>
|
>
|
||||||
# endif
|
# endif
|
||||||
{
|
{
|
||||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310)
|
// Derivation from std::iterator above caused ambiguity, so now
|
||||||
|
// we have to declare all the types here.
|
||||||
|
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||||
|
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||||
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
|
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
|
||||||
|
|
||||||
typedef typename traversal_archetype<
|
typedef typename access_archetype<Value, AccessCategory>::pointer pointer;
|
||||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
|
||||||
, Value, AccessCategory, TraversalCategory
|
typedef typename access_archetype<Value, AccessCategory>::reference reference;
|
||||||
|
|
||||||
|
typedef typename traversal_archetype_base<
|
||||||
|
Value, AccessCategory, TraversalCategory
|
||||||
>::difference_type difference_type;
|
>::difference_type difference_type;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@@ -110,7 +110,7 @@ namespace boost
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct operator_arrow_proxy
|
struct operator_arrow_proxy
|
||||||
{
|
{
|
||||||
operator_arrow_proxy(const T& x) : m_value(x) {}
|
operator_arrow_proxy(T const* px) : m_value(*px) {}
|
||||||
const T* operator->() const { return &m_value; }
|
const T* operator->() const { return &m_value; }
|
||||||
// This function is needed for MWCW and BCC, which won't call operator->
|
// This function is needed for MWCW and BCC, which won't call operator->
|
||||||
// again automatically per 13.3.1.2 para 8
|
// again automatically per 13.3.1.2 para 8
|
||||||
@@ -118,25 +118,28 @@ namespace boost
|
|||||||
T m_value;
|
T m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Reference, class Pointer>
|
// A metafunction that gets the result type for operator->. Also
|
||||||
struct operator_arrow_pointer
|
// has a static function make() which builds the result from a
|
||||||
{
|
// Reference
|
||||||
operator_arrow_pointer(Reference x) : m_p(&x) {}
|
|
||||||
operator Pointer() const { return m_p; }
|
|
||||||
Pointer m_p;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Value, class Category, class Reference, class Pointer>
|
template <class Value, class Category, class Reference, class Pointer>
|
||||||
struct operator_arrow_result
|
struct operator_arrow_result
|
||||||
: mpl::if_<
|
{
|
||||||
|
// 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_tag<
|
is_tag<
|
||||||
readable_lvalue_iterator_tag
|
readable_lvalue_iterator_tag
|
||||||
, typename access_category_tag<Category,Reference>::type
|
, typename access_category_tag<Category,Reference>::type
|
||||||
>
|
>
|
||||||
, Pointer
|
, Pointer
|
||||||
, operator_arrow_proxy<Value>
|
, operator_arrow_proxy<Value>
|
||||||
>
|
>::type type;
|
||||||
|
|
||||||
|
static type make(Reference x)
|
||||||
{
|
{
|
||||||
|
return type(&x);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||||
@@ -370,7 +373,6 @@ namespace boost
|
|||||||
return iterator_core_access::dereference(this->derived());
|
return iterator_core_access::dereference(this->derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needs eventual help for input iterators
|
|
||||||
typename detail::operator_arrow_result<
|
typename detail::operator_arrow_result<
|
||||||
value_type
|
value_type
|
||||||
, iterator_category
|
, iterator_category
|
||||||
@@ -379,14 +381,12 @@ namespace boost
|
|||||||
>::type
|
>::type
|
||||||
operator->() const
|
operator->() const
|
||||||
{
|
{
|
||||||
typedef typename detail::operator_arrow_result<
|
return detail::operator_arrow_result<
|
||||||
value_type
|
value_type
|
||||||
, iterator_category
|
, iterator_category
|
||||||
, reference
|
, reference
|
||||||
, detail::operator_arrow_pointer<reference,pointer>
|
, pointer
|
||||||
>::type result_t;
|
>::make(*this->derived());
|
||||||
|
|
||||||
return result_t(*this->derived());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typename detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::type
|
typename detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::type
|
||||||
|
@@ -188,6 +188,7 @@ main()
|
|||||||
BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
|
BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Test computation of default when the Value is const
|
// Test computation of default when the Value is const
|
||||||
typedef ptr_iterator<int const> Iter1;
|
typedef ptr_iterator<int const> Iter1;
|
||||||
|
@@ -20,6 +20,6 @@ int main()
|
|||||||
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
|
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
|
||||||
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
|
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
|
||||||
}
|
}
|
||||||
|
return 0; // keep msvc happy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user