All workarounds complete! Also some cleanups

[SVN r1249]
This commit is contained in:
Dave Abrahams
2003-04-28 13:54:59 +00:00
parent 70e2b4f922
commit e2b3a260d5
5 changed files with 70 additions and 46 deletions

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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
} }