imgtools/imglib/boostlibrary/boost/iterator/counting_iterator.hpp
changeset 2 39c28ec933dd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/boostlibrary/boost/iterator/counting_iterator.hpp	Mon May 10 19:54:49 2010 +0100
@@ -0,0 +1,215 @@
+// Copyright David Abrahams 2003.
+// 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 COUNTING_ITERATOR_DWA200348_HPP
+# define COUNTING_ITERATOR_DWA200348_HPP
+
+# include <boost/iterator/iterator_adaptor.hpp>
+# include <boost/detail/numeric_traits.hpp>
+# include <boost/mpl/bool.hpp>
+# include <boost/mpl/if.hpp>
+# include <boost/mpl/identity.hpp>
+# include <boost/mpl/eval_if.hpp>
+
+namespace boost {
+
+template <
+    class Incrementable
+  , class CategoryOrTraversal
+  , class Difference
+>
+class counting_iterator;
+
+namespace detail
+{
+  // Try to detect numeric types at compile time in ways compatible
+  // with the limitations of the compiler and library.
+  template <class T>
+  struct is_numeric_impl
+  {
+      // For a while, this wasn't true, but we rely on it below. This is a regression assert.
+      BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
+      
+# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+      
+      BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
+      
+# else
+      
+#  if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
+      BOOST_STATIC_CONSTANT(
+          bool, value = (
+              boost::is_convertible<int,T>::value
+           && boost::is_convertible<T,int>::value
+      ));
+#  else
+    BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
+#  endif
+      
+# endif
+  };
+
+  template <class T>
+  struct is_numeric
+    : mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
+  {};
+
+#  if defined(BOOST_HAS_LONG_LONG)
+  template <>
+  struct is_numeric< ::boost::long_long_type>
+    : mpl::true_ {};
+  
+  template <>
+  struct is_numeric< ::boost::ulong_long_type>
+    : mpl::true_ {};
+#  endif
+
+  // Some compilers fail to have a numeric_limits specialization
+  template <>
+  struct is_numeric<wchar_t>
+    : mpl::true_ {};
+  
+  template <class T>
+  struct numeric_difference
+  {
+      typedef typename boost::detail::numeric_traits<T>::difference_type type;
+  };
+
+  BOOST_STATIC_ASSERT(is_numeric<int>::value);
+  
+  template <class Incrementable, class CategoryOrTraversal, class Difference>
+  struct counting_iterator_base
+  {
+      typedef typename detail::ia_dflt_help<
+          CategoryOrTraversal
+        , mpl::eval_if<
+              is_numeric<Incrementable>
+            , mpl::identity<random_access_traversal_tag>
+            , iterator_traversal<Incrementable>
+          >
+      >::type traversal;
+      
+      typedef typename detail::ia_dflt_help<
+          Difference
+        , mpl::eval_if<
+              is_numeric<Incrementable>
+            , numeric_difference<Incrementable>
+            , iterator_difference<Incrementable>
+          >
+      >::type difference;
+      
+      typedef iterator_adaptor<
+          counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
+        , Incrementable                                           // Base
+        , Incrementable                                           // Value
+# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
+          const  // MSVC won't strip this.  Instead we enable Thomas'
+                 // criterion (see boost/iterator/detail/facade_iterator_category.hpp)
+# endif 
+        , traversal
+        , Incrementable const&                                    // reference
+        , difference
+      > type;
+  };
+
+  // Template class distance_policy_select -- choose a policy for computing the
+  // distance between counting_iterators at compile-time based on whether or not
+  // the iterator wraps an integer or an iterator, using "poor man's partial
+  // specialization".
+
+  template <bool is_integer> struct distance_policy_select;
+
+  // A policy for wrapped iterators
+  template <class Difference, class Incrementable1, class Incrementable2>
+  struct iterator_distance
+  {
+      static Difference distance(Incrementable1 x, Incrementable2 y)
+      {
+          return y - x;
+      }
+  };
+
+  // A policy for wrapped numbers
+  template <class Difference, class Incrementable1, class Incrementable2>
+  struct number_distance
+  {
+      static Difference distance(Incrementable1 x, Incrementable2 y)
+      {
+          return numeric_distance(x, y);
+      }
+  };
+}
+
+template <
+    class Incrementable
+  , class CategoryOrTraversal = use_default
+  , class Difference = use_default
+>
+class counting_iterator
+  : public detail::counting_iterator_base<
+        Incrementable, CategoryOrTraversal, Difference
+    >::type
+{
+    typedef typename detail::counting_iterator_base<
+        Incrementable, CategoryOrTraversal, Difference
+    >::type super_t;
+    
+    friend class iterator_core_access;
+
+ public:
+    typedef typename super_t::difference_type difference_type;
+
+    counting_iterator() { }
+    
+    counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
+
+    counting_iterator(Incrementable x)
+      : super_t(x)
+    {
+    }
+
+# if 0
+    template<class OtherIncrementable>
+    counting_iterator(
+        counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& t
+      , typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
+    )
+      : super_t(t.base())
+    {}
+# endif 
+
+ private:
+    
+    typename super_t::reference dereference() const
+    {
+        return this->base_reference();
+    }
+
+    template <class OtherIncrementable>
+    difference_type
+    distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
+    {
+      typedef typename mpl::if_<
+          detail::is_numeric<Incrementable>
+        , detail::number_distance<difference_type, Incrementable, OtherIncrementable>
+        , detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
+      >::type d;
+
+      return d::distance(this->base(), y.base());
+    }
+};
+
+// Manufacture a counting iterator for an arbitrary incrementable type
+template <class Incrementable>
+inline counting_iterator<Incrementable>
+make_counting_iterator(Incrementable x)
+{
+  typedef counting_iterator<Incrementable> result_t;
+  return result_t(x);
+}
+
+
+} // namespace boost::iterator
+
+#endif // COUNTING_ITERATOR_DWA200348_HPP