Only use proxy for *r++ if *r is also a proxy.

[SVN r23516]
This commit is contained in:
Dave Abrahams
2004-07-14 00:40:04 +00:00
parent 254186d6bd
commit edb7528136
2 changed files with 45 additions and 9 deletions

View File

@ -22,6 +22,7 @@
#include <boost/type_traits/add_const.hpp> #include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp> #include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_pod.hpp> #include <boost/type_traits/is_pod.hpp>
@ -195,6 +196,43 @@ namespace boost
Iterator stored_iterator; Iterator stored_iterator;
}; };
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class Reference, class Value>
struct is_non_proxy_reference_impl
{
static Reference r;
template <class R>
static typename mpl::if_<
is_convertible<
R const volatile*
, Value const volatile*
>
, char[1]
, char[2]
>::type& helper(R const&);
BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
};
template <class Reference, class Value>
struct is_non_proxy_reference
: mpl::bool_<
is_non_proxy_reference_impl<Reference, Value>::value
>
{};
# else
template <class Reference, class Value>
struct is_non_proxy_reference
: is_convertible<
typename remove_reference<Reference>::type
const volatile*
, Value const volatile*
>
{};
# endif
// A metafunction to choose the result type of postfix ++ // A metafunction to choose the result type of postfix ++
// //
// Because the C++98 input iterator requirements say that *r++ has // Because the C++98 input iterator requirements say that *r++ has
@ -209,7 +247,7 @@ namespace boost
// supports the operator<. Since there are any number of such // supports the operator<. Since there are any number of such
// operations, we're not going to try to support them. Therefore, // operations, we're not going to try to support them. Therefore,
// even if r++ returns a proxy, *r++ will only return a proxy if // even if r++ returns a proxy, *r++ will only return a proxy if
// CategoryOrTraversal is convertible to std::output_iterator_tag. // *r also returns a proxy.
template <class Iterator, class Value, class Reference, class CategoryOrTraversal> template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
struct postfix_increment_result struct postfix_increment_result
: mpl::apply_if< : mpl::apply_if<
@ -227,9 +265,9 @@ namespace boost
> >
> >
, mpl::if_< , mpl::if_<
is_convertible<CategoryOrTraversal,std::output_iterator_tag> is_non_proxy_reference<Reference,Value>
, writable_postfix_increment_proxy<Iterator>
, postfix_increment_proxy<Iterator> , postfix_increment_proxy<Iterator>
, writable_postfix_increment_proxy<Iterator>
> >
, mpl::identity<Iterator> , mpl::identity<Iterator>
> >

View File

@ -11,12 +11,12 @@
// This is a really, really limited test so far. All we're doing // This is a really, really limited test so far. All we're doing
// right now is checking that the postfix++ proxy for single-pass // right now is checking that the postfix++ proxy for single-pass
// iterators works properly. // iterators works properly.
template <class Ref, class CategoryOrTraversal = boost::single_pass_traversal_tag> template <class Ref>
class counter_iterator class counter_iterator
: public boost::iterator_facade< : public boost::iterator_facade<
counter_iterator<Ref, CategoryOrTraversal> counter_iterator<Ref>
, int const , int const
, CategoryOrTraversal , boost::single_pass_traversal_tag
, Ref , Ref
> >
{ {
@ -63,9 +63,7 @@ int main()
boost::readable_iterator_test(counter_iterator<int const&>(&state), 0); boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
state = 3; state = 3;
boost::readable_iterator_test(counter_iterator<proxy>(&state), 3); boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
state = 5; boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
boost::readable_iterator_test(counter_iterator<proxy,std::output_iterator_tag>(&state), 5);
boost::writable_iterator_test(counter_iterator<proxy,std::output_iterator_tag>(&state), 9, 7);
BOOST_ASSERT(state == 7); BOOST_ASSERT(state == 7);
return 0; return 0;
} }