Some workarounds; more to do.

[SVN r1237]
This commit is contained in:
Dave Abrahams
2003-04-28 05:22:04 +00:00
parent 62c2eb051a
commit 357f2c5c23
4 changed files with 199 additions and 85 deletions

View File

@@ -179,17 +179,33 @@ namespace boost
struct iterator_adaptor_base struct iterator_adaptor_base
{ {
private: private:
typedef typename detail::ia_dflt_help<Category , mpl::true_ , BOOST_ITERATOR_CATEGORY<Base> >::type category; typedef typename detail::ia_dflt_help<
typedef typename detail::ia_dflt_help<Reference , is_same<Value, use_default> , iterator_reference<Base> >::type reference; Category, mpl::true_, BOOST_ITERATOR_CATEGORY<Base>
>::type category;
typedef typename detail::ia_dflt_help<
Reference, is_same<Value, use_default>, iterator_reference<Base>
>::type reference;
public: public:
typedef iterator_facade< typedef iterator_facade<
Derived Derived
, typename detail::ia_dflt_help<Value , mpl::true_ , iterator_value<Base> >::type
, typename detail::ia_dflt_help<
Value, mpl::true_, iterator_value<Base>
>::type
, typename access_category_tag<category, reference>::type , typename access_category_tag<category, reference>::type
, typename traversal_category_tag<category>::type , typename traversal_category_tag<category>::type
, typename detail::ia_dflt_help<Reference , is_same<Value, use_default> , iterator_reference<Base> >::type
, typename detail::ia_dflt_help<Difference , mpl::true_ , iterator_difference<Base> >::type , typename detail::ia_dflt_help<
Reference, is_same<Value, use_default>, iterator_reference<Base>
>::type
, typename detail::ia_dflt_help<
Difference, mpl::true_, iterator_difference<Base>
>::type
> >
type; type;
}; };

View File

@@ -16,6 +16,8 @@
#include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_cv.hpp> #include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/aux_/msvc_eti_base.hpp>
#include <cstddef> #include <cstddef>
namespace boost namespace boost
@@ -74,52 +76,82 @@ namespace boost
{ {
}; };
template <class Derived, class Value, class TraversalCategory> template <class TraversalCategory>
struct traversal_archetype_; struct traversal_archetype_impl
{
template <class Derived,class Value> struct archetype;
};
template <class Derived, class Value, class TraversalCategory>
struct traversal_archetype_
: mpl::aux::msvc_eti_base<
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
>::type
{};
template <>
struct traversal_archetype_impl<incrementable_iterator_tag>
{
template<class Derived, class Value> template<class Derived, class Value>
struct traversal_archetype_<Derived, Value, incrementable_iterator_tag> struct archetype
{ {
typedef void difference_type; typedef void difference_type;
Derived& operator++(); Derived& operator++();
Derived operator++(int) const; Derived operator++(int) const;
}; };
};
template <>
struct traversal_archetype_impl<single_pass_iterator_tag>
{
template<class Derived, class Value> template<class Derived, class Value>
struct traversal_archetype_<Derived, Value, single_pass_iterator_tag> struct archetype
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_iterator_tag> >, : public equality_comparable< traversal_archetype_<Derived, Value, single_pass_iterator_tag> >,
public traversal_archetype_<Derived, Value, incrementable_iterator_tag> public traversal_archetype_<Derived, Value, incrementable_iterator_tag>
{ {
}; };
};
template <class Derived, class Value> template <class Derived, class Value>
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&);
template <>
struct traversal_archetype_impl<forward_traversal_tag>
{
template<class Derived, class Value> template<class Derived, class Value>
struct traversal_archetype_<Derived, Value, forward_traversal_tag> struct archetype
: public traversal_archetype_<Derived, Value, single_pass_iterator_tag> : public traversal_archetype_<Derived, Value, single_pass_iterator_tag>
{ {
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
}; };
};
template <>
struct traversal_archetype_impl<bidirectional_traversal_tag>
{
template<class Derived, class Value> template<class Derived, class Value>
struct traversal_archetype_<Derived, Value, bidirectional_traversal_tag> struct archetype
: public traversal_archetype_<Derived, Value, forward_traversal_tag> : public traversal_archetype_<Derived, Value, forward_traversal_tag>
{ {
Derived& operator--(); Derived& operator--();
Derived operator--(int) const; Derived operator--(int) const;
}; };
};
template <>
struct traversal_archetype_impl<random_access_traversal_tag>
{
template<class Derived, class Value> template<class Derived, class Value>
struct traversal_archetype_<Derived, Value, random_access_traversal_tag> struct archetype
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >, : public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag> public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{ {
Derived& operator+=(std::ptrdiff_t); Derived& operator+=(std::ptrdiff_t);
Derived& operator-=(std::ptrdiff_t); Derived& operator-=(std::ptrdiff_t);
}; };
};
template <class Derived, class Value> template <class Derived, class Value>
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&, Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
@@ -153,11 +185,27 @@ namespace boost
} // namespace detail } // namespace detail
template <class Value, class AccessCategory> template <class> struct undefined;
struct access_archetype;
template <class AccessCategory>
struct access_archetype_impl
{
template <class Value> struct archetype;
};
template <class Value, class AccessCategory>
struct access_archetype
: mpl::aux::msvc_eti_base<
typename access_archetype_impl<AccessCategory>::template archetype<Value>
>::type
{
};
template <>
struct access_archetype_impl<readable_iterator_tag>
{
template <class Value> template <class Value>
struct access_archetype<Value, readable_iterator_tag> struct archetype
{ {
typedef typename remove_cv<Value>::type value_type; typedef typename remove_cv<Value>::type value_type;
typedef Value reference; typedef Value reference;
@@ -167,43 +215,63 @@ namespace boost
detail::arrow_proxy<Value> operator->() const; detail::arrow_proxy<Value> operator->() const;
}; };
};
template <class Value> template <>
struct access_archetype<Value, writable_iterator_tag> struct access_archetype_impl<writable_iterator_tag>
{ {
BOOST_STATIC_ASSERT((!is_const<Value>::value)); template <class Value>
struct archetype
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT(!is_const<Value>::value);
# endif
typedef void value_type; typedef void value_type;
typedef void reference; typedef void reference;
typedef void pointer; typedef void pointer;
detail::assign_proxy<Value> operator*() const; detail::assign_proxy<Value> operator*() const;
}; };
};
template <>
struct access_archetype_impl<readable_writable_iterator_tag>
{
template <class Value> template <class Value>
struct access_archetype<Value, readable_writable_iterator_tag> : struct archetype
public virtual access_archetype<Value, readable_iterator_tag> : public virtual access_archetype<Value, readable_iterator_tag>
{ {
typedef detail::read_write_proxy<Value> reference; typedef detail::read_write_proxy<Value> reference;
detail::read_write_proxy<Value> operator*() const; detail::read_write_proxy<Value> operator*() const;
}; };
};
template <>
struct access_archetype_impl<readable_lvalue_iterator_tag>
{
template <class Value> template <class Value>
struct access_archetype<Value, readable_lvalue_iterator_tag> : struct archetype
public virtual access_archetype<Value, readable_iterator_tag> : public virtual access_archetype<Value, readable_iterator_tag>
{ {
typedef Value& reference; typedef Value& reference;
Value& operator*() const; Value& operator*() const;
Value* operator->() const; Value* operator->() const;
}; };
};
template <>
struct access_archetype_impl<writable_lvalue_iterator_tag>
{
template <class Value> template <class Value>
struct access_archetype<Value, writable_lvalue_iterator_tag> struct archetype
: public virtual access_archetype<Value, readable_lvalue_iterator_tag> : public virtual access_archetype<Value, readable_lvalue_iterator_tag>
{ {
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT((!is_const<Value>::value)); BOOST_STATIC_ASSERT((!is_const<Value>::value));
# endif
};
}; };
template <class Derived, class Value, class AccessCategory, class TraversalCategory> template <class Derived, class Value, class AccessCategory, class TraversalCategory>
@@ -217,9 +285,31 @@ namespace boost
template <class Value, class AccessCategory, class TraversalCategory> template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype struct iterator_archetype
: public traversal_archetype<iterator_archetype<Value, AccessCategory, TraversalCategory>, Value, AccessCategory, TraversalCategory>, : public traversal_archetype<
public access_archetype<Value, AccessCategory> iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value, AccessCategory, TraversalCategory
>
, public access_archetype<Value, AccessCategory>
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310)
, 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
>::difference_type
>
# endif
{ {
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310)
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
typedef typename traversal_archetype<
iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value, AccessCategory, TraversalCategory
>::difference_type difference_type;
# endif
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category; typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
iterator_archetype(); iterator_archetype();

View File

@@ -28,6 +28,7 @@
#include <boost/mpl/not.hpp> #include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp> #include <boost/mpl/or.hpp>
#include <boost/mpl/apply.hpp> #include <boost/mpl/apply.hpp>
#include <boost/mpl/aux_/msvc_eti_base.hpp>
#include <iterator> #include <iterator>
@@ -257,8 +258,8 @@ namespace boost {
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
// Deal with ETI // Deal with ETI
template <> struct access_category_tag<int, int> {}; template <> struct access_category_tag<int, int> { typedef void type; };
template <> struct traversal_category_tag<int> {}; template <> struct traversal_category_tag<int> { typedef void type; };
# endif # endif
} // namespace detail } // namespace detail
@@ -299,10 +300,12 @@ namespace boost {
template <class ReturnTag, class TraversalTag> template <class ReturnTag, class TraversalTag>
struct iterator_tag struct iterator_tag
: detail::minimum_category< : mpl::aux::msvc_eti_base<
typename detail::minimum_category<
typename ReturnTag::max_category typename ReturnTag::max_category
, typename TraversalTag::max_category , typename TraversalTag::max_category
>::type >::type
>::type
{ {
typedef ReturnTag returns; typedef ReturnTag returns;
typedef TraversalTag traversal; typedef TraversalTag traversal;

View File

@@ -184,14 +184,19 @@ main()
BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, int&>::value)); BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, int&>::value));
BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, int*>::value)); BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, int*>::value));
BOOST_STATIC_ASSERT((boost::is_same<Iter1::difference_type, std::ptrdiff_t>::value)); BOOST_STATIC_ASSERT((boost::is_same<Iter1::difference_type, std::ptrdiff_t>::value));
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
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
} }
{ {
// 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;
BOOST_STATIC_ASSERT((boost::is_same<Iter1::value_type, int>::value)); BOOST_STATIC_ASSERT((boost::is_same<Iter1::value_type, int>::value));
BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, const int&>::value)); BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, const int&>::value));
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
// Borland has known problems with const
BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, const int*>::value)); BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, const int*>::value));
#endif
} }
// Test the iterator_adaptor // Test the iterator_adaptor