]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/iterator/iterator_facade.hpp
Don't allow newline characters in document settings.
[lyx.git] / boost / boost / iterator / iterator_facade.hpp
index 0e10fc41d06cc1bd81f974458f679fb8ef7bde13..5ee73b5aa4dfcc80af01878fc73f7ae224841493 100644 (file)
@@ -1,16 +1,12 @@
 // (C) Copyright David Abrahams 2002.
 // (C) Copyright Jeremy Siek    2002.
 // (C) Copyright Thomas Witt    2002.
-// Permission to copy, use, modify,
-// sell and distribute this software is granted provided this
-// copyright notice appears in all copies. This software is provided
-// "as is" without express or implied warranty, and with no claim as
-// to its suitability for any purpose.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
 #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
 #define BOOST_ITERATOR_FACADE_23022003THW_HPP
 
-#include <boost/static_assert.hpp>
-
 #include <boost/iterator.hpp>
 #include <boost/iterator/interoperable.hpp>
 #include <boost/iterator/iterator_traits.hpp>
 #include <boost/iterator/detail/facade_iterator_category.hpp>
 #include <boost/iterator/detail/enable_if.hpp>
 
+#include <boost/implicit_cast.hpp>
+#include <boost/static_assert.hpp>
+
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_traits/add_const.hpp>
 #include <boost/type_traits/add_pointer.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_pod.hpp>
 
-#include <boost/mpl/apply_if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/if.hpp>
 #include <boost/mpl/or.hpp>
 #include <boost/mpl/and.hpp>
+#include <boost/mpl/not.hpp>
 #include <boost/mpl/always.hpp>
 #include <boost/mpl/apply.hpp>
-
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
-# include <boost/mpl/if.hpp>
-#endif
+#include <boost/mpl/identity.hpp>
 
 #include <boost/iterator/detail/config_def.hpp> // this goes last
 
@@ -56,7 +55,7 @@ namespace boost
             typedef bool type;
         };
     };
-    
+
     //
     // enable if for use in operator implementation.
     //
@@ -66,6 +65,18 @@ namespace boost
       , class Return
     >
     struct enable_if_interoperable
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+    {
+        typedef typename mpl::if_<
+            mpl::or_<
+                is_convertible<Facade1, Facade2>
+              , is_convertible<Facade2, Facade1>
+            >
+          , Return
+          , int[3]
+        >::type type;
+    };        
+#else
       : ::boost::iterators::enable_if<
            mpl::or_<
                is_convertible<Facade1, Facade2>
@@ -73,8 +84,8 @@ namespace boost
            >
          , Return
         >
-    {
-    };
+    {};
+#endif 
 
     //
     // Generates associated types for an iterator_facade with the
@@ -94,9 +105,10 @@ namespace boost
         
         typedef typename remove_const<ValueParam>::type value_type;
         
-        typedef typename mpl::apply_if<
-            detail::iterator_writability_disabled<ValueParam,Reference>
-          , add_pointer<typename add_const<value_type>::type>
+        // Not the real associated pointer type
+        typedef typename mpl::eval_if<
+            boost::detail::iterator_writability_disabled<ValueParam,Reference>
+          , add_pointer<const value_type>
           , add_pointer<value_type>
         >::type pointer;
       
@@ -118,27 +130,187 @@ namespace boost
 # endif
     };
 
+    // iterators whose dereference operators reference the same value
+    // for all iterators into the same sequence (like many input
+    // iterators) need help with their postfix ++: the referenced
+    // value must be read and stored away before the increment occurs
+    // so that *a++ yields the originally referenced element and not
+    // the next one.
+    template <class Iterator>
+    class postfix_increment_proxy
+    {
+        typedef typename iterator_value<Iterator>::type value_type;
+     public:
+        explicit postfix_increment_proxy(Iterator const& x)
+          : stored_value(*x)
+        {}
+
+        // Returning a mutable reference allows nonsense like
+        // (*r++).mutate(), but it imposes fewer assumptions about the
+        // behavior of the value_type.  In particular, recall taht
+        // (*r).mutate() is legal if operator* returns by value.
+        value_type&
+        operator*() const
+        {
+            return this->stored_value;
+        }
+     private:
+        mutable value_type stored_value;
+    };
+    
+    //
+    // In general, we can't determine that such an iterator isn't
+    // writable -- we also need to store a copy of the old iterator so
+    // that it can be written into.
+    template <class Iterator>
+    class writable_postfix_increment_proxy
+    {
+        typedef typename iterator_value<Iterator>::type value_type;
+     public:
+        explicit writable_postfix_increment_proxy(Iterator const& x)
+          : stored_value(*x)
+          , stored_iterator(x)
+        {}
+
+        // Dereferencing must return a proxy so that both *r++ = o and
+        // value_type(*r++) can work.  In this case, *r is the same as
+        // *r++, and the conversion operator below is used to ensure
+        // readability.
+        writable_postfix_increment_proxy const&
+        operator*() const
+        {
+            return *this;
+        }
+
+        // Provides readability of *r++
+        operator value_type&() const
+        {
+            return stored_value;
+        }
+
+        // Provides writability of *r++
+        template <class T>
+        T const& operator=(T const& x) const
+        {
+            *this->stored_iterator = x;
+            return x;
+        }
+
+        // This overload just in case only non-const objects are writable
+        template <class T>
+        T& operator=(T& x) const
+        {
+            *this->stored_iterator = x;
+            return x;
+        }
+
+        // Provides X(r++)
+        operator Iterator const&() const
+        {
+            return stored_iterator;
+        }
+        
+     private:
+        mutable value_type stored_value;
+        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 ++
+    //
+    // Because the C++98 input iterator requirements say that *r++ has
+    // type T (value_type), implementations of some standard
+    // algorithms like lexicographical_compare may use constructions
+    // like:
+    //
+    //          *r++ < *s++
+    //
+    // If *r++ returns a proxy (as required if r is writable but not
+    // multipass), this sort of expression will fail unless the proxy
+    // supports the operator<.  Since there are any number of such
+    // operations, we're not going to try to support them.  Therefore,
+    // even if r++ returns a proxy, *r++ will only return a proxy if
+    // *r also returns a proxy.
+    template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
+    struct postfix_increment_result
+      : mpl::eval_if<
+            mpl::and_<
+                // A proxy is only needed for readable iterators
+                is_convertible<Reference,Value const&>
+                
+                // No multipass iterator can have values that disappear
+                // before positions can be re-visited
+              , mpl::not_<
+                    is_convertible<
+                        typename iterator_category_to_traversal<CategoryOrTraversal>::type
+                      , forward_traversal_tag
+                    >
+                >
+            >
+          , mpl::if_<
+                is_non_proxy_reference<Reference,Value>
+              , postfix_increment_proxy<Iterator>
+              , writable_postfix_increment_proxy<Iterator>
+            >
+          , mpl::identity<Iterator>
+        >
+    {};
 
     // operator->() needs special support for input iterators to strictly meet the
     // standard's requirements. If *i is not a reference type, we must still
-    // produce a (constant) lvalue to which a pointer can be formed. We do that by
+    // produce a lvalue to which a pointer can be formed. We do that by
     // returning an instantiation of this special proxy class template.
-
     template <class T>
     struct operator_arrow_proxy
     {
         operator_arrow_proxy(T const* px) : m_value(*px) {}
-        const T* operator->() const { return &m_value; }
+        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;
+        operator T*() const { return &m_value; }
+        mutable 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 Reference, class Pointer>
+    template <class ValueType, class Reference, class Pointer>
     struct operator_arrow_result
     {
         // CWPro8.3 won't accept "operator_arrow_result::type", and we
@@ -147,16 +319,16 @@ namespace boost
         typedef typename mpl::if_<
             is_reference<Reference>
           , Pointer
-          , operator_arrow_proxy<Value>
+          , operator_arrow_proxy<ValueType>
         >::type type;
 
         static type make(Reference x)
         {
-            return type(&x);
+            return boost::implicit_cast<type>(&x);
         }
     };
 
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
+# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
     // Deal with ETI
     template<>
     struct operator_arrow_result<int, int, int>
@@ -165,13 +337,14 @@ namespace boost
     };
 # endif
 
-    //
-    // Iterator is actually an iterator_facade, so we do not have to
-    // go through iterator_traits to access the traits.
-    //
+    // A proxy return type for operator[], needed to deal with
+    // iterators that may invalidate referents upon destruction.
+    // Consider the temporary iterator in *(a + n)
     template <class Iterator>
     class operator_brackets_proxy
     {
+        // Iterator is actually an iterator_facade, so we do not have to
+        // go through iterator_traits to access the traits.
         typedef typename Iterator::reference  reference;
         typedef typename Iterator::value_type value_type;
 
@@ -195,13 +368,17 @@ namespace boost
         Iterator m_iter;
     };
 
-    template <class Value, class Reference>
+    // A metafunction that determines whether operator[] must return a
+    // proxy, or whether it can simply return a copy of the value_type.
+    template <class ValueType, class Reference>
     struct use_operator_brackets_proxy
-      : mpl::and_<
-            // Really we want an is_copy_constructible trait here,
-            // but is_POD will have to suffice in the meantime.
-            boost::is_POD<Value>
-          , iterator_writability_disabled<Value,Reference>
+      : mpl::not_<
+            mpl::and_<
+                // Really we want an is_copy_constructible trait here,
+                // but is_POD will have to suffice in the meantime.
+                boost::is_POD<ValueType>
+              , iterator_writability_disabled<ValueType,Reference>
+            >
         >
     {};
         
@@ -210,19 +387,19 @@ namespace boost
     {
         typedef typename mpl::if_<
             use_operator_brackets_proxy<Value,Reference>
-          , Value 
           , operator_brackets_proxy<Iterator>
+          , Value
         >::type type;
     };
 
     template <class Iterator>
-    operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::false_)
+    operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
     {
         return operator_brackets_proxy<Iterator>(iter);
     }
 
     template <class Iterator>
-    typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::true_)
+    typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
     {
       return *iter;
     }
@@ -234,14 +411,14 @@ namespace boost
           :
 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
           iterator_difference<I1>
-# elif BOOST_WORKAROUND(BOOST_MSVC, == 1200)
+# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
           mpl::if_<
               is_convertible<I2,I1>
             , typename I1::difference_type
             , typename I2::difference_type
           >
 # else 
-          mpl::apply_if<
+          mpl::eval_if<
               is_convertible<I2,I1>
             , iterator_difference<I1>
             , iterator_difference<I2>
@@ -255,28 +432,28 @@ namespace boost
 
   // Macros which describe the declarations of binary operators
 # ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
-#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)   \
-    template <                                                          \
-        class Derived1, class V1, class TC1, class R1, class D1         \
-      , class Derived2, class V2, class TC2, class R2, class D2         \
-    >                                                                   \
-    prefix typename mpl::apply2<result_type,Derived1,Derived2>::type    \
-    operator op(                                                        \
-        iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs           \
-      , iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
+#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)       \
+    template <                                                              \
+        class Derived1, class V1, class TC1, class Reference1, class Difference1 \
+      , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
+    >                                                                       \
+    prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
+    operator op(                                                            \
+        iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
+      , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
 # else 
 #  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)   \
     template <                                                          \
-        class Derived1, class V1, class TC1, class R1, class D1         \
-      , class Derived2, class V2, class TC2, class R2, class D2         \
+        class Derived1, class V1, class TC1, class Reference1, class Difference1 \
+      , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
     >                                                                   \
-    prefix typename detail::enable_if_interoperable<                    \
+    prefix typename boost::detail::enable_if_interoperable<             \
         Derived1, Derived2                                              \
       , typename mpl::apply2<result_type,Derived1,Derived2>::type       \
     >::type                                                             \
     operator op(                                                        \
-        iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs           \
-      , iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
+        iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
+      , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
 # endif 
 
 #  define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args)              \
@@ -294,8 +471,7 @@ namespace boost
   //
   class iterator_core_access
   {
-# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)                  \
-    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
+# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)                  
       // Tasteless as this may seem, making all members public allows member templates
       // to work in the absence of member template friends.
    public:
@@ -304,7 +480,7 @@ namespace boost
       template <class I, class V, class TC, class R, class D> friend class iterator_facade;
 
 #  define BOOST_ITERATOR_FACADE_RELATION(op)                                \
-      BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, detail::always_bool2);
+      BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::detail::always_bool2);
 
       BOOST_ITERATOR_FACADE_RELATION(==)
       BOOST_ITERATOR_FACADE_RELATION(!=)
@@ -316,18 +492,18 @@ namespace boost
 #  undef BOOST_ITERATOR_FACADE_RELATION
 
       BOOST_ITERATOR_FACADE_INTEROP_HEAD(
-          friend, -, detail::choose_difference_type)
+          friend, -, boost::detail::choose_difference_type)
       ;
 
       BOOST_ITERATOR_FACADE_PLUS_HEAD(
-          friend                                
+          friend inline
           , (iterator_facade<Derived, V, TC, R, D> const&
            , typename Derived::difference_type)
       )
       ;
 
       BOOST_ITERATOR_FACADE_PLUS_HEAD(
-          friend
+          friend inline
         , (typename Derived::difference_type
            , iterator_facade<Derived, V, TC, R, D> const&)
       )
@@ -385,6 +561,21 @@ namespace boost
           return f2.distance_to(f1);
       }
 
+      //
+      // Curiously Recurring Template interface.
+      //
+      template <class I, class V, class TC, class R, class D>
+      static I& derived(iterator_facade<I,V,TC,R,D>& facade)
+      {
+          return *static_cast<I*>(&facade);
+      }
+
+      template <class I, class V, class TC, class R, class D>
+      static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
+      {
+          return *static_cast<I const*>(&facade);
+      }
+
    private:
       // objects of this class are useless
       iterator_core_access(); //undefined
@@ -403,7 +594,7 @@ namespace boost
   >
   class iterator_facade
 # ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
-    : public detail::iterator_facade_types<
+    : public boost::detail::iterator_facade_types<
          Value, CategoryOrTraversal, Reference, Difference
       >::base
 #  undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
@@ -413,28 +604,38 @@ namespace boost
       //
       // Curiously Recurring Template interface.
       //
-      typedef Derived derived_t;
-
       Derived& derived()
       {
-          return static_cast<Derived&>(*this);
+          return *static_cast<Derived*>(this);
       }
 
       Derived const& derived() const
       {
-          return static_cast<Derived const&>(*this);
+          return *static_cast<Derived const*>(this);
       }
 
-      typedef detail::iterator_facade_types<
+      typedef boost::detail::iterator_facade_types<
          Value, CategoryOrTraversal, Reference, Difference
       > associated_types;
+
+      typedef boost::detail::operator_arrow_result<
+        typename associated_types::value_type
+        , Reference
+        , typename associated_types::pointer
+      > pointer_;
+
+   protected:
+      // For use by derived classes
+      typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
       
    public:
 
       typedef typename associated_types::value_type value_type;
       typedef Reference reference;
       typedef Difference difference_type;
-      typedef typename associated_types::pointer pointer;
+
+      typedef typename pointer_::type pointer;
+
       typedef typename associated_types::iterator_category iterator_category;
 
       reference operator*() const
@@ -442,26 +643,17 @@ namespace boost
           return iterator_core_access::dereference(this->derived());
       }
 
-      typename detail::operator_arrow_result<
-          value_type
-        , reference
-        , pointer
-      >::type
-      operator->() const
+      pointer operator->() const
       {
-          return detail::operator_arrow_result<
-              value_type
-            , reference
-            , pointer
-          >::make(*this->derived());
+          return pointer_::make(*this->derived());
       }
         
-      typename detail::operator_brackets_result<Derived,Value,Reference>::type
+      typename boost::detail::operator_brackets_result<Derived,Value,reference>::type
       operator[](difference_type n) const
       {
-          typedef detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
+          typedef boost::detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
           
-          return detail::make_operator_brackets_result<Derived>(
+          return boost::detail::make_operator_brackets_result<Derived>(
               this->derived() + n
             , use_proxy()
           );
@@ -473,13 +665,17 @@ namespace boost
           return this->derived();
       }
 
-      Derived operator++(int)
+# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+      typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
+      operator++(int)
       {
-          Derived tmp(this->derived());
+          typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
+          tmp(this->derived());
           ++*this;
           return tmp;
       }
-
+# endif
+      
       Derived& operator--()
       {
           iterator_core_access::decrement(this->derived());
@@ -511,7 +707,7 @@ namespace boost
           return result -= x;
       }
 
-# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
+# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
       // There appears to be a bug which trashes the data of classes
       // derived from iterator_facade when they are assigned unless we
       // define this assignment operator.  This bug is only revealed
@@ -524,8 +720,26 @@ namespace boost
 # endif
   };
 
+# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+  template <class I, class V, class TC, class R, class D>
+  inline typename boost::detail::postfix_increment_result<I,V,R,TC>::type
+  operator++(
+      iterator_facade<I,V,TC,R,D>& i
+    , int
+  )
+  {
+      typename boost::detail::postfix_increment_result<I,V,R,TC>::type
+          tmp(*static_cast<I*>(&i));
+      
+      ++i;
+      
+      return tmp;
+  }
+# endif 
+
+  
   //
-  // Operator implementation. The library supplied operators
+  // Comparison operator implementation. The library supplied operators
   // enables the user to provide fully interoperable constant/mutable
   // iterator types. I.e. the library provides all operators
   // for all mutable/constant iterator combinations.
@@ -605,8 +819,8 @@ namespace boost
           is_interoperable< Derived1, Derived2 >::value                         \
       ));                                                                       \
       return_prefix iterator_core_access::base_op(                              \
-          static_cast<Derived1 const&>(lhs)                                     \
-        , static_cast<Derived2 const&>(rhs)                                     \
+          *static_cast<Derived1 const*>(&lhs)                                   \
+        , *static_cast<Derived2 const*>(&rhs)                                   \
         , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
       );                                                                        \
   }
@@ -614,7 +828,7 @@ namespace boost
 # define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
   BOOST_ITERATOR_FACADE_INTEROP(                                    \
       op                                                            \
-    , detail::always_bool2                                          \
+    , boost::detail::always_bool2                                   \
     , return_prefix                                                 \
     , base_op                                                       \
   )
@@ -631,7 +845,7 @@ namespace boost
   // operator- requires an additional part in the static assertion
   BOOST_ITERATOR_FACADE_INTEROP(
       -
-    , detail::choose_difference_type
+    , boost::detail::choose_difference_type
     , return
     , distance_from
   )