1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/iterator/iterator_facade.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,879 @@
1.4 +// (C) Copyright David Abrahams 2002.
1.5 +// (C) Copyright Jeremy Siek 2002.
1.6 +// (C) Copyright Thomas Witt 2002.
1.7 +// Distributed under the Boost Software License, Version 1.0. (See
1.8 +// accompanying file LICENSE_1_0.txt or copy at
1.9 +// http://www.boost.org/LICENSE_1_0.txt)
1.10 +#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
1.11 +#define BOOST_ITERATOR_FACADE_23022003THW_HPP
1.12 +
1.13 +#include <boost/iterator.hpp>
1.14 +#include <boost/iterator/interoperable.hpp>
1.15 +#include <boost/iterator/iterator_traits.hpp>
1.16 +
1.17 +#include <boost/iterator/detail/facade_iterator_category.hpp>
1.18 +#include <boost/iterator/detail/enable_if.hpp>
1.19 +
1.20 +#include <boost/implicit_cast.hpp>
1.21 +#include <boost/static_assert.hpp>
1.22 +
1.23 +#include <boost/type_traits/is_same.hpp>
1.24 +#include <boost/type_traits/add_const.hpp>
1.25 +#include <boost/type_traits/add_pointer.hpp>
1.26 +#include <boost/type_traits/remove_const.hpp>
1.27 +#include <boost/type_traits/remove_reference.hpp>
1.28 +#include <boost/type_traits/is_convertible.hpp>
1.29 +#include <boost/type_traits/is_pod.hpp>
1.30 +
1.31 +#include <boost/mpl/eval_if.hpp>
1.32 +#include <boost/mpl/if.hpp>
1.33 +#include <boost/mpl/or.hpp>
1.34 +#include <boost/mpl/and.hpp>
1.35 +#include <boost/mpl/not.hpp>
1.36 +#include <boost/mpl/always.hpp>
1.37 +#include <boost/mpl/apply.hpp>
1.38 +#include <boost/mpl/identity.hpp>
1.39 +
1.40 +#include <boost/iterator/detail/config_def.hpp> // this goes last
1.41 +
1.42 +namespace boost
1.43 +{
1.44 + // This forward declaration is required for the friend declaration
1.45 + // in iterator_core_access
1.46 + template <class I, class V, class TC, class R, class D> class iterator_facade;
1.47 +
1.48 + namespace detail
1.49 + {
1.50 + // A binary metafunction class that always returns bool. VC6
1.51 + // ICEs on mpl::always<bool>, probably because of the default
1.52 + // parameters.
1.53 + struct always_bool2
1.54 + {
1.55 + template <class T, class U>
1.56 + struct apply
1.57 + {
1.58 + typedef bool type;
1.59 + };
1.60 + };
1.61 +
1.62 + //
1.63 + // enable if for use in operator implementation.
1.64 + //
1.65 + template <
1.66 + class Facade1
1.67 + , class Facade2
1.68 + , class Return
1.69 + >
1.70 + struct enable_if_interoperable
1.71 +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
1.72 + {
1.73 + typedef typename mpl::if_<
1.74 + mpl::or_<
1.75 + is_convertible<Facade1, Facade2>
1.76 + , is_convertible<Facade2, Facade1>
1.77 + >
1.78 + , Return
1.79 + , int[3]
1.80 + >::type type;
1.81 + };
1.82 +#else
1.83 + : ::boost::iterators::enable_if<
1.84 + mpl::or_<
1.85 + is_convertible<Facade1, Facade2>
1.86 + , is_convertible<Facade2, Facade1>
1.87 + >
1.88 + , Return
1.89 + >
1.90 + {};
1.91 +#endif
1.92 +
1.93 + //
1.94 + // Generates associated types for an iterator_facade with the
1.95 + // given parameters.
1.96 + //
1.97 + template <
1.98 + class ValueParam
1.99 + , class CategoryOrTraversal
1.100 + , class Reference
1.101 + , class Difference
1.102 + >
1.103 + struct iterator_facade_types
1.104 + {
1.105 + typedef typename facade_iterator_category<
1.106 + CategoryOrTraversal, ValueParam, Reference
1.107 + >::type iterator_category;
1.108 +
1.109 + typedef typename remove_const<ValueParam>::type value_type;
1.110 +
1.111 + typedef typename mpl::eval_if<
1.112 + detail::iterator_writability_disabled<ValueParam,Reference>
1.113 + , add_pointer<const value_type>
1.114 + , add_pointer<value_type>
1.115 + >::type pointer;
1.116 +
1.117 +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
1.118 + && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
1.119 + || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
1.120 + || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
1.121 + || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
1.122 +
1.123 + // To interoperate with some broken library/compiler
1.124 + // combinations, user-defined iterators must be derived from
1.125 + // std::iterator. It is possible to implement a standard
1.126 + // library for broken compilers without this limitation.
1.127 +# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
1.128 +
1.129 + typedef
1.130 + iterator<iterator_category, value_type, Difference, pointer, Reference>
1.131 + base;
1.132 +# endif
1.133 + };
1.134 +
1.135 + // iterators whose dereference operators reference the same value
1.136 + // for all iterators into the same sequence (like many input
1.137 + // iterators) need help with their postfix ++: the referenced
1.138 + // value must be read and stored away before the increment occurs
1.139 + // so that *a++ yields the originally referenced element and not
1.140 + // the next one.
1.141 + template <class Iterator>
1.142 + class postfix_increment_proxy
1.143 + {
1.144 + typedef typename iterator_value<Iterator>::type value_type;
1.145 + public:
1.146 + explicit postfix_increment_proxy(Iterator const& x)
1.147 + : stored_value(*x)
1.148 + {}
1.149 +
1.150 + // Returning a mutable reference allows nonsense like
1.151 + // (*r++).mutate(), but it imposes fewer assumptions about the
1.152 + // behavior of the value_type. In particular, recall taht
1.153 + // (*r).mutate() is legal if operator* returns by value.
1.154 + value_type&
1.155 + operator*() const
1.156 + {
1.157 + return this->stored_value;
1.158 + }
1.159 + private:
1.160 + mutable value_type stored_value;
1.161 + };
1.162 +
1.163 + //
1.164 + // In general, we can't determine that such an iterator isn't
1.165 + // writable -- we also need to store a copy of the old iterator so
1.166 + // that it can be written into.
1.167 + template <class Iterator>
1.168 + class writable_postfix_increment_proxy
1.169 + {
1.170 + typedef typename iterator_value<Iterator>::type value_type;
1.171 + public:
1.172 + explicit writable_postfix_increment_proxy(Iterator const& x)
1.173 + : stored_value(*x)
1.174 + , stored_iterator(x)
1.175 + {}
1.176 +
1.177 + // Dereferencing must return a proxy so that both *r++ = o and
1.178 + // value_type(*r++) can work. In this case, *r is the same as
1.179 + // *r++, and the conversion operator below is used to ensure
1.180 + // readability.
1.181 + writable_postfix_increment_proxy const&
1.182 + operator*() const
1.183 + {
1.184 + return *this;
1.185 + }
1.186 +
1.187 + // Provides readability of *r++
1.188 + operator value_type&() const
1.189 + {
1.190 + return stored_value;
1.191 + }
1.192 +
1.193 + // Provides writability of *r++
1.194 + template <class T>
1.195 + T const& operator=(T const& x) const
1.196 + {
1.197 + *this->stored_iterator = x;
1.198 + return x;
1.199 + }
1.200 +
1.201 + // This overload just in case only non-const objects are writable
1.202 + template <class T>
1.203 + T& operator=(T& x) const
1.204 + {
1.205 + *this->stored_iterator = x;
1.206 + return x;
1.207 + }
1.208 +
1.209 + // Provides X(r++)
1.210 + operator Iterator const&() const
1.211 + {
1.212 + return stored_iterator;
1.213 + }
1.214 +
1.215 + private:
1.216 + mutable value_type stored_value;
1.217 + Iterator stored_iterator;
1.218 + };
1.219 +
1.220 +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.221 +
1.222 + template <class Reference, class Value>
1.223 + struct is_non_proxy_reference_impl
1.224 + {
1.225 + static Reference r;
1.226 +
1.227 + template <class R>
1.228 + static typename mpl::if_<
1.229 + is_convertible<
1.230 + R const volatile*
1.231 + , Value const volatile*
1.232 + >
1.233 + , char[1]
1.234 + , char[2]
1.235 + >::type& helper(R const&);
1.236 +
1.237 + BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
1.238 + };
1.239 +
1.240 + template <class Reference, class Value>
1.241 + struct is_non_proxy_reference
1.242 + : mpl::bool_<
1.243 + is_non_proxy_reference_impl<Reference, Value>::value
1.244 + >
1.245 + {};
1.246 +# else
1.247 + template <class Reference, class Value>
1.248 + struct is_non_proxy_reference
1.249 + : is_convertible<
1.250 + typename remove_reference<Reference>::type
1.251 + const volatile*
1.252 + , Value const volatile*
1.253 + >
1.254 + {};
1.255 +# endif
1.256 +
1.257 + // A metafunction to choose the result type of postfix ++
1.258 + //
1.259 + // Because the C++98 input iterator requirements say that *r++ has
1.260 + // type T (value_type), implementations of some standard
1.261 + // algorithms like lexicographical_compare may use constructions
1.262 + // like:
1.263 + //
1.264 + // *r++ < *s++
1.265 + //
1.266 + // If *r++ returns a proxy (as required if r is writable but not
1.267 + // multipass), this sort of expression will fail unless the proxy
1.268 + // supports the operator<. Since there are any number of such
1.269 + // operations, we're not going to try to support them. Therefore,
1.270 + // even if r++ returns a proxy, *r++ will only return a proxy if
1.271 + // *r also returns a proxy.
1.272 + template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
1.273 + struct postfix_increment_result
1.274 + : mpl::eval_if<
1.275 + mpl::and_<
1.276 + // A proxy is only needed for readable iterators
1.277 + is_convertible<Reference,Value const&>
1.278 +
1.279 + // No multipass iterator can have values that disappear
1.280 + // before positions can be re-visited
1.281 + , mpl::not_<
1.282 + is_convertible<
1.283 + typename iterator_category_to_traversal<CategoryOrTraversal>::type
1.284 + , forward_traversal_tag
1.285 + >
1.286 + >
1.287 + >
1.288 + , mpl::if_<
1.289 + is_non_proxy_reference<Reference,Value>
1.290 + , postfix_increment_proxy<Iterator>
1.291 + , writable_postfix_increment_proxy<Iterator>
1.292 + >
1.293 + , mpl::identity<Iterator>
1.294 + >
1.295 + {};
1.296 +
1.297 + // operator->() needs special support for input iterators to strictly meet the
1.298 + // standard's requirements. If *i is not a reference type, we must still
1.299 + // produce a lvalue to which a pointer can be formed. We do that by
1.300 + // returning an instantiation of this special proxy class template.
1.301 + template <class T>
1.302 + struct operator_arrow_proxy
1.303 + {
1.304 + operator_arrow_proxy(T const* px) : m_value(*px) {}
1.305 + T* operator->() const { return &m_value; }
1.306 + // This function is needed for MWCW and BCC, which won't call operator->
1.307 + // again automatically per 13.3.1.2 para 8
1.308 + operator T*() const { return &m_value; }
1.309 + mutable T m_value;
1.310 + };
1.311 +
1.312 + // A metafunction that gets the result type for operator->. Also
1.313 + // has a static function make() which builds the result from a
1.314 + // Reference
1.315 + template <class ValueType, class Reference, class Pointer>
1.316 + struct operator_arrow_result
1.317 + {
1.318 + // CWPro8.3 won't accept "operator_arrow_result::type", and we
1.319 + // need that type below, so metafunction forwarding would be a
1.320 + // losing proposition here.
1.321 + typedef typename mpl::if_<
1.322 + is_reference<Reference>
1.323 + , Pointer
1.324 + , operator_arrow_proxy<ValueType>
1.325 + >::type type;
1.326 +
1.327 + static type make(Reference x)
1.328 + {
1.329 + return implicit_cast<type>(&x);
1.330 + }
1.331 + };
1.332 +
1.333 +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.334 + // Deal with ETI
1.335 + template<>
1.336 + struct operator_arrow_result<int, int, int>
1.337 + {
1.338 + typedef int type;
1.339 + };
1.340 +# endif
1.341 +
1.342 + // A proxy return type for operator[], needed to deal with
1.343 + // iterators that may invalidate referents upon destruction.
1.344 + // Consider the temporary iterator in *(a + n)
1.345 + template <class Iterator>
1.346 + class operator_brackets_proxy
1.347 + {
1.348 + // Iterator is actually an iterator_facade, so we do not have to
1.349 + // go through iterator_traits to access the traits.
1.350 + typedef typename Iterator::reference reference;
1.351 + typedef typename Iterator::value_type value_type;
1.352 +
1.353 + public:
1.354 + operator_brackets_proxy(Iterator const& iter)
1.355 + : m_iter(iter)
1.356 + {}
1.357 +
1.358 + operator reference() const
1.359 + {
1.360 + return *m_iter;
1.361 + }
1.362 +
1.363 + operator_brackets_proxy& operator=(value_type const& val)
1.364 + {
1.365 + *m_iter = val;
1.366 + return *this;
1.367 + }
1.368 +
1.369 + private:
1.370 + Iterator m_iter;
1.371 + };
1.372 +
1.373 + // A metafunction that determines whether operator[] must return a
1.374 + // proxy, or whether it can simply return a copy of the value_type.
1.375 + template <class ValueType, class Reference>
1.376 + struct use_operator_brackets_proxy
1.377 + : mpl::not_<
1.378 + mpl::and_<
1.379 + // Really we want an is_copy_constructible trait here,
1.380 + // but is_POD will have to suffice in the meantime.
1.381 + boost::is_POD<ValueType>
1.382 + , iterator_writability_disabled<ValueType,Reference>
1.383 + >
1.384 + >
1.385 + {};
1.386 +
1.387 + template <class Iterator, class Value, class Reference>
1.388 + struct operator_brackets_result
1.389 + {
1.390 + typedef typename mpl::if_<
1.391 + use_operator_brackets_proxy<Value,Reference>
1.392 + , operator_brackets_proxy<Iterator>
1.393 + , Value
1.394 + >::type type;
1.395 + };
1.396 +
1.397 + template <class Iterator>
1.398 + operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
1.399 + {
1.400 + return operator_brackets_proxy<Iterator>(iter);
1.401 + }
1.402 +
1.403 + template <class Iterator>
1.404 + typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
1.405 + {
1.406 + return *iter;
1.407 + }
1.408 +
1.409 + struct choose_difference_type
1.410 + {
1.411 + template <class I1, class I2>
1.412 + struct apply
1.413 + :
1.414 +# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
1.415 + iterator_difference<I1>
1.416 +# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.417 + mpl::if_<
1.418 + is_convertible<I2,I1>
1.419 + , typename I1::difference_type
1.420 + , typename I2::difference_type
1.421 + >
1.422 +# else
1.423 + mpl::eval_if<
1.424 + is_convertible<I2,I1>
1.425 + , iterator_difference<I1>
1.426 + , iterator_difference<I2>
1.427 + >
1.428 +# endif
1.429 + {};
1.430 +
1.431 + };
1.432 + } // namespace detail
1.433 +
1.434 +
1.435 + // Macros which describe the declarations of binary operators
1.436 +# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
1.437 +# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
1.438 + template < \
1.439 + class Derived1, class V1, class TC1, class R1, class D1 \
1.440 + , class Derived2, class V2, class TC2, class R2, class D2 \
1.441 + > \
1.442 + prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
1.443 + operator op( \
1.444 + iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
1.445 + , iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
1.446 +# else
1.447 +# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
1.448 + template < \
1.449 + class Derived1, class V1, class TC1, class R1, class D1 \
1.450 + , class Derived2, class V2, class TC2, class R2, class D2 \
1.451 + > \
1.452 + prefix typename detail::enable_if_interoperable< \
1.453 + Derived1, Derived2 \
1.454 + , typename mpl::apply2<result_type,Derived1,Derived2>::type \
1.455 + >::type \
1.456 + operator op( \
1.457 + iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
1.458 + , iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
1.459 +# endif
1.460 +
1.461 +# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
1.462 + template <class Derived, class V, class TC, class R, class D> \
1.463 + prefix Derived operator+ args
1.464 +
1.465 + //
1.466 + // Helper class for granting access to the iterator core interface.
1.467 + //
1.468 + // The simple core interface is used by iterator_facade. The core
1.469 + // interface of a user/library defined iterator type should not be made public
1.470 + // so that it does not clutter the public interface. Instead iterator_core_access
1.471 + // should be made friend so that iterator_facade can access the core
1.472 + // interface through iterator_core_access.
1.473 + //
1.474 + class iterator_core_access
1.475 + {
1.476 +# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
1.477 + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
1.478 + // Tasteless as this may seem, making all members public allows member templates
1.479 + // to work in the absence of member template friends.
1.480 + public:
1.481 +# else
1.482 +
1.483 + template <class I, class V, class TC, class R, class D> friend class iterator_facade;
1.484 +
1.485 +# define BOOST_ITERATOR_FACADE_RELATION(op) \
1.486 + BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, detail::always_bool2);
1.487 +
1.488 + BOOST_ITERATOR_FACADE_RELATION(==)
1.489 + BOOST_ITERATOR_FACADE_RELATION(!=)
1.490 +
1.491 + BOOST_ITERATOR_FACADE_RELATION(<)
1.492 + BOOST_ITERATOR_FACADE_RELATION(>)
1.493 + BOOST_ITERATOR_FACADE_RELATION(<=)
1.494 + BOOST_ITERATOR_FACADE_RELATION(>=)
1.495 +# undef BOOST_ITERATOR_FACADE_RELATION
1.496 +
1.497 + BOOST_ITERATOR_FACADE_INTEROP_HEAD(
1.498 + friend, -, detail::choose_difference_type)
1.499 + ;
1.500 +
1.501 + BOOST_ITERATOR_FACADE_PLUS_HEAD(
1.502 + friend inline
1.503 + , (iterator_facade<Derived, V, TC, R, D> const&
1.504 + , typename Derived::difference_type)
1.505 + )
1.506 + ;
1.507 +
1.508 + BOOST_ITERATOR_FACADE_PLUS_HEAD(
1.509 + friend inline
1.510 + , (typename Derived::difference_type
1.511 + , iterator_facade<Derived, V, TC, R, D> const&)
1.512 + )
1.513 + ;
1.514 +
1.515 +# endif
1.516 +
1.517 + template <class Facade>
1.518 + static typename Facade::reference dereference(Facade const& f)
1.519 + {
1.520 + return f.dereference();
1.521 + }
1.522 +
1.523 + template <class Facade>
1.524 + static void increment(Facade& f)
1.525 + {
1.526 + f.increment();
1.527 + }
1.528 +
1.529 + template <class Facade>
1.530 + static void decrement(Facade& f)
1.531 + {
1.532 + f.decrement();
1.533 + }
1.534 +
1.535 + template <class Facade1, class Facade2>
1.536 + static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
1.537 + {
1.538 + return f1.equal(f2);
1.539 + }
1.540 +
1.541 + template <class Facade1, class Facade2>
1.542 + static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
1.543 + {
1.544 + return f2.equal(f1);
1.545 + }
1.546 +
1.547 + template <class Facade>
1.548 + static void advance(Facade& f, typename Facade::difference_type n)
1.549 + {
1.550 + f.advance(n);
1.551 + }
1.552 +
1.553 + template <class Facade1, class Facade2>
1.554 + static typename Facade1::difference_type distance_from(
1.555 + Facade1 const& f1, Facade2 const& f2, mpl::true_)
1.556 + {
1.557 + return -f1.distance_to(f2);
1.558 + }
1.559 +
1.560 + template <class Facade1, class Facade2>
1.561 + static typename Facade2::difference_type distance_from(
1.562 + Facade1 const& f1, Facade2 const& f2, mpl::false_)
1.563 + {
1.564 + return f2.distance_to(f1);
1.565 + }
1.566 +
1.567 + //
1.568 + // Curiously Recurring Template interface.
1.569 + //
1.570 + template <class I, class V, class TC, class R, class D>
1.571 + static I& derived(iterator_facade<I,V,TC,R,D>& facade)
1.572 + {
1.573 + return *static_cast<I*>(&facade);
1.574 + }
1.575 +
1.576 + template <class I, class V, class TC, class R, class D>
1.577 + static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
1.578 + {
1.579 + return *static_cast<I const*>(&facade);
1.580 + }
1.581 +
1.582 + private:
1.583 + // objects of this class are useless
1.584 + iterator_core_access(); //undefined
1.585 + };
1.586 +
1.587 + //
1.588 + // iterator_facade - use as a public base class for defining new
1.589 + // standard-conforming iterators.
1.590 + //
1.591 + template <
1.592 + class Derived // The derived iterator type being constructed
1.593 + , class Value
1.594 + , class CategoryOrTraversal
1.595 + , class Reference = Value&
1.596 + , class Difference = std::ptrdiff_t
1.597 + >
1.598 + class iterator_facade
1.599 +# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
1.600 + : public detail::iterator_facade_types<
1.601 + Value, CategoryOrTraversal, Reference, Difference
1.602 + >::base
1.603 +# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
1.604 +# endif
1.605 + {
1.606 + private:
1.607 + //
1.608 + // Curiously Recurring Template interface.
1.609 + //
1.610 + Derived& derived()
1.611 + {
1.612 + return *static_cast<Derived*>(this);
1.613 + }
1.614 +
1.615 + Derived const& derived() const
1.616 + {
1.617 + return *static_cast<Derived const*>(this);
1.618 + }
1.619 +
1.620 + typedef detail::iterator_facade_types<
1.621 + Value, CategoryOrTraversal, Reference, Difference
1.622 + > associated_types;
1.623 +
1.624 + protected:
1.625 + // For use by derived classes
1.626 + typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
1.627 +
1.628 + public:
1.629 +
1.630 + typedef typename associated_types::value_type value_type;
1.631 + typedef Reference reference;
1.632 + typedef Difference difference_type;
1.633 + typedef typename associated_types::pointer pointer;
1.634 + typedef typename associated_types::iterator_category iterator_category;
1.635 +
1.636 + reference operator*() const
1.637 + {
1.638 + return iterator_core_access::dereference(this->derived());
1.639 + }
1.640 +
1.641 + typename detail::operator_arrow_result<
1.642 + value_type
1.643 + , reference
1.644 + , pointer
1.645 + >::type
1.646 + operator->() const
1.647 + {
1.648 + return detail::operator_arrow_result<
1.649 + value_type
1.650 + , reference
1.651 + , pointer
1.652 + >::make(*this->derived());
1.653 + }
1.654 +
1.655 + typename detail::operator_brackets_result<Derived,Value,reference>::type
1.656 + operator[](difference_type n) const
1.657 + {
1.658 + typedef detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
1.659 +
1.660 + return detail::make_operator_brackets_result<Derived>(
1.661 + this->derived() + n
1.662 + , use_proxy()
1.663 + );
1.664 + }
1.665 +
1.666 + Derived& operator++()
1.667 + {
1.668 + iterator_core_access::increment(this->derived());
1.669 + return this->derived();
1.670 + }
1.671 +
1.672 +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.673 + typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
1.674 + operator++(int)
1.675 + {
1.676 + typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
1.677 + tmp(this->derived());
1.678 + ++*this;
1.679 + return tmp;
1.680 + }
1.681 +# endif
1.682 +
1.683 + Derived& operator--()
1.684 + {
1.685 + iterator_core_access::decrement(this->derived());
1.686 + return this->derived();
1.687 + }
1.688 +
1.689 + Derived operator--(int)
1.690 + {
1.691 + Derived tmp(this->derived());
1.692 + --*this;
1.693 + return tmp;
1.694 + }
1.695 +
1.696 + Derived& operator+=(difference_type n)
1.697 + {
1.698 + iterator_core_access::advance(this->derived(), n);
1.699 + return this->derived();
1.700 + }
1.701 +
1.702 + Derived& operator-=(difference_type n)
1.703 + {
1.704 + iterator_core_access::advance(this->derived(), -n);
1.705 + return this->derived();
1.706 + }
1.707 +
1.708 + Derived operator-(difference_type x) const
1.709 + {
1.710 + Derived result(this->derived());
1.711 + return result -= x;
1.712 + }
1.713 +
1.714 +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.715 + // There appears to be a bug which trashes the data of classes
1.716 + // derived from iterator_facade when they are assigned unless we
1.717 + // define this assignment operator. This bug is only revealed
1.718 + // (so far) in STLPort debug mode, but it's clearly a codegen
1.719 + // problem so we apply the workaround for all MSVC6.
1.720 + iterator_facade& operator=(iterator_facade const&)
1.721 + {
1.722 + return *this;
1.723 + }
1.724 +# endif
1.725 + };
1.726 +
1.727 +# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.728 + template <class I, class V, class TC, class R, class D>
1.729 + inline typename detail::postfix_increment_result<I,V,R,TC>::type
1.730 + operator++(
1.731 + iterator_facade<I,V,TC,R,D>& i
1.732 + , int
1.733 + )
1.734 + {
1.735 + typename detail::postfix_increment_result<I,V,R,TC>::type
1.736 + tmp(*static_cast<I*>(&i));
1.737 +
1.738 + ++i;
1.739 +
1.740 + return tmp;
1.741 + }
1.742 +# endif
1.743 +
1.744 +
1.745 + //
1.746 + // Comparison operator implementation. The library supplied operators
1.747 + // enables the user to provide fully interoperable constant/mutable
1.748 + // iterator types. I.e. the library provides all operators
1.749 + // for all mutable/constant iterator combinations.
1.750 + //
1.751 + // Note though that this kind of interoperability for constant/mutable
1.752 + // iterators is not required by the standard for container iterators.
1.753 + // All the standard asks for is a conversion mutable -> constant.
1.754 + // Most standard library implementations nowadays provide fully interoperable
1.755 + // iterator implementations, but there are still heavily used implementations
1.756 + // that do not provide them. (Actually it's even worse, they do not provide
1.757 + // them for only a few iterators.)
1.758 + //
1.759 + // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
1.760 + // enable the user to turn off mixed type operators
1.761 + //
1.762 + // The library takes care to provide only the right operator overloads.
1.763 + // I.e.
1.764 + //
1.765 + // bool operator==(Iterator, Iterator);
1.766 + // bool operator==(ConstIterator, Iterator);
1.767 + // bool operator==(Iterator, ConstIterator);
1.768 + // bool operator==(ConstIterator, ConstIterator);
1.769 + //
1.770 + // ...
1.771 + //
1.772 + // In order to do so it uses c++ idioms that are not yet widely supported
1.773 + // by current compiler releases. The library is designed to degrade gracefully
1.774 + // in the face of compiler deficiencies. In general compiler
1.775 + // deficiencies result in less strict error checking and more obscure
1.776 + // error messages, functionality is not affected.
1.777 + //
1.778 + // For full operation compiler support for "Substitution Failure Is Not An Error"
1.779 + // (aka. enable_if) and boost::is_convertible is required.
1.780 + //
1.781 + // The following problems occur if support is lacking.
1.782 + //
1.783 + // Pseudo code
1.784 + //
1.785 + // ---------------
1.786 + // AdaptorA<Iterator1> a1;
1.787 + // AdaptorA<Iterator2> a2;
1.788 + //
1.789 + // // This will result in a no such overload error in full operation
1.790 + // // If enable_if or is_convertible is not supported
1.791 + // // The instantiation will fail with an error hopefully indicating that
1.792 + // // there is no operator== for Iterator1, Iterator2
1.793 + // // The same will happen if no enable_if is used to remove
1.794 + // // false overloads from the templated conversion constructor
1.795 + // // of AdaptorA.
1.796 + //
1.797 + // a1 == a2;
1.798 + // ----------------
1.799 + //
1.800 + // AdaptorA<Iterator> a;
1.801 + // AdaptorB<Iterator> b;
1.802 + //
1.803 + // // This will result in a no such overload error in full operation
1.804 + // // If enable_if is not supported the static assert used
1.805 + // // in the operator implementation will fail.
1.806 + // // This will accidently work if is_convertible is not supported.
1.807 + //
1.808 + // a == b;
1.809 + // ----------------
1.810 + //
1.811 +
1.812 +# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
1.813 +# define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
1.814 +# else
1.815 +# define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
1.816 +# endif
1.817 +
1.818 +# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
1.819 + BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
1.820 + { \
1.821 + /* For those compilers that do not support enable_if */ \
1.822 + BOOST_STATIC_ASSERT(( \
1.823 + is_interoperable< Derived1, Derived2 >::value \
1.824 + )); \
1.825 + return_prefix iterator_core_access::base_op( \
1.826 + *static_cast<Derived1 const*>(&lhs) \
1.827 + , *static_cast<Derived2 const*>(&rhs) \
1.828 + , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
1.829 + ); \
1.830 + }
1.831 +
1.832 +# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
1.833 + BOOST_ITERATOR_FACADE_INTEROP( \
1.834 + op \
1.835 + , detail::always_bool2 \
1.836 + , return_prefix \
1.837 + , base_op \
1.838 + )
1.839 +
1.840 + BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
1.841 + BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
1.842 +
1.843 + BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from)
1.844 + BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from)
1.845 + BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from)
1.846 + BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
1.847 +# undef BOOST_ITERATOR_FACADE_RELATION
1.848 +
1.849 + // operator- requires an additional part in the static assertion
1.850 + BOOST_ITERATOR_FACADE_INTEROP(
1.851 + -
1.852 + , detail::choose_difference_type
1.853 + , return
1.854 + , distance_from
1.855 + )
1.856 +# undef BOOST_ITERATOR_FACADE_INTEROP
1.857 +# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
1.858 +
1.859 +# define BOOST_ITERATOR_FACADE_PLUS(args) \
1.860 + BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
1.861 + { \
1.862 + Derived tmp(static_cast<Derived const&>(i)); \
1.863 + return tmp += n; \
1.864 + }
1.865 +
1.866 +BOOST_ITERATOR_FACADE_PLUS((
1.867 + iterator_facade<Derived, V, TC, R, D> const& i
1.868 + , typename Derived::difference_type n
1.869 +))
1.870 +
1.871 +BOOST_ITERATOR_FACADE_PLUS((
1.872 + typename Derived::difference_type n
1.873 + , iterator_facade<Derived, V, TC, R, D> const& i
1.874 +))
1.875 +# undef BOOST_ITERATOR_FACADE_PLUS
1.876 +# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
1.877 +
1.878 +} // namespace boost
1.879 +
1.880 +#include <boost/iterator/detail/config_undef.hpp>
1.881 +
1.882 +#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP