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
things happen:
- Iterators are often miss-categorized.
- Iterators are often mis-categorized.
- Algorithm requirements are more strict than necessary, because they
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
constant objects of type ``X``, ``r`` and ``s`` are mutable objects of
type ``X``, ``T`` is ``std::iterator_traits<X>::value_type``,
``v`` is a constant object of type ``T``, and ``u`` is an identifier.
type ``X``, ``T`` is ``std::iterator_traits<X>::value_type``, and
``v`` is a constant object of type ``T``.
Incrementable Iterators [lib.incrementable.iterators]

View File

@@ -117,6 +117,12 @@ namespace boost
bool operator==(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 <>
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
: detail::operator_brackets< typename remove_cv<Value>::type,
AccessCategory,
TraversalCategory >,
detail::traversal_archetype_<Derived, Value, TraversalCategory>
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
>
{
};
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype
: public traversal_archetype<
iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value, AccessCategory, TraversalCategory
>
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
, 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<
iterator_tag<AccessCategory,TraversalCategory>
, typename access_archetype<Value, AccessCategory>::value_type
, typename traversal_archetype<
iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value, AccessCategory, TraversalCategory
, typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type
>
# 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 traversal_archetype<
iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value, AccessCategory, TraversalCategory
typedef typename access_archetype<Value, AccessCategory>::pointer pointer;
typedef typename access_archetype<Value, AccessCategory>::reference reference;
typedef typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type difference_type;
# endif

View File

@@ -110,33 +110,36 @@ namespace boost
template <class T>
struct operator_arrow_proxy
{
operator_arrow_proxy(const T& x) : m_value(x) {}
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;
};
template <class Reference, class Pointer>
struct operator_arrow_pointer
{
operator_arrow_pointer(Reference x) : m_p(&x) {}
operator Pointer() const { return m_p; }
Pointer m_p;
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 Value, class Category, class Reference, class Pointer>
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<
readable_lvalue_iterator_tag
, typename access_category_tag<Category,Reference>::type
>
, Pointer
, operator_arrow_proxy<Value>
>
{
>::type type;
static type make(Reference x)
{
return type(&x);
}
};
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
@@ -370,7 +373,6 @@ namespace boost
return iterator_core_access::dereference(this->derived());
}
// Needs eventual help for input iterators
typename detail::operator_arrow_result<
value_type
, iterator_category
@@ -379,14 +381,12 @@ namespace boost
>::type
operator->() const
{
typedef typename detail::operator_arrow_result<
return detail::operator_arrow_result<
value_type
, iterator_category
, reference
, detail::operator_arrow_pointer<reference,pointer>
>::type result_t;
return result_t(*this->derived());
, pointer
>::make(*this->derived());
}
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));
#endif
}
{
// Test computation of default when the Value is const
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::RandomAccessTraversalConcept<iter> >();
}
return 0; // keep msvc happy
}