Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61258 - in trunk: boost/range libs/range/test
From: neil_at_[hidden]
Date: 2010-04-13 16:41:12


Author: neilgroves
Date: 2010-04-13 16:41:11 EDT (Tue, 13 Apr 2010)
New Revision: 61258
URL: http://svn.boost.org/trac/boost/changeset/61258

Log:
Boost.Range defect fix for the operator[] of iterator_range. This now reverts to a simpler implementation when the iterator is a pointer.
Added:
   trunk/libs/range/test/pointer_as_iterator.cpp (contents, props changed)
Text files modified:
   trunk/boost/range/iterator_range_core.hpp | 45 ++++++++++++++++++++++++++++++++-------
   trunk/libs/range/test/Jamfile.v2 | 1
   2 files changed, 38 insertions(+), 8 deletions(-)

Modified: trunk/boost/range/iterator_range_core.hpp
==============================================================================
--- trunk/boost/range/iterator_range_core.hpp (original)
+++ trunk/boost/range/iterator_range_core.hpp 2010-04-13 16:41:11 EDT (Tue, 13 Apr 2010)
@@ -298,14 +298,22 @@
                return m_Begin[at];
            }
 #else
- BOOST_DEDUCED_TYPENAME boost::detail::operator_brackets_result<iterator, value_type, reference>::type
- operator[]( difference_type at ) const
- {
- BOOST_ASSERT( at >= 0 && at < size() );
-
- typedef boost::detail::use_operator_brackets_proxy<value_type,reference> use_proxy;
- return boost::detail::make_operator_brackets_result<iterator>(m_Begin + at, use_proxy());
- }
+ // Using the operator_brackets_result mechanism properly supports
+ // the corner cases with proxies for references etc. However
+ // the operator_brackets_result implementation does not support
+ // pointers as iterators. Since a pointer can't have the
+ // issues with proxies this implementation uses a simpler
+ // implementation if the iterator is a pointer.
+ BOOST_DEDUCED_TYPENAME boost::mpl::if_<
+ boost::is_pointer<iterator>,
+ reference,
+ BOOST_DEDUCED_TYPENAME boost::detail::operator_brackets_result<iterator, value_type, reference>::type
+ >::type
+ operator[]( difference_type at ) const
+ {
+ BOOST_ASSERT( at >= 0 && at < size() );
+ return get_at(m_Begin, at);
+ }
 #endif
 
            //
@@ -332,6 +340,27 @@
            }
 
         private:
+ template<class Iterator>
+ static BOOST_DEDUCED_TYPENAME boost::enable_if<
+ boost::is_pointer<Iterator>,
+ reference
+ >::type
+ get_at( Iterator it, difference_type at )
+ {
+ return it[at];
+ }
+
+ template<class Iterator>
+ static BOOST_DEDUCED_TYPENAME boost::disable_if<
+ boost::is_pointer<Iterator>,
+ BOOST_DEDUCED_TYPENAME boost::detail::operator_brackets_result<Iterator, value_type, reference>::type
+ >::type
+ get_at( Iterator it, difference_type at )
+ {
+ typedef boost::detail::use_operator_brackets_proxy<value_type,reference> use_proxy;
+ return boost::detail::make_operator_brackets_result<Iterator>(it + at, use_proxy());
+ }
+
             // begin and end iterators
             IteratorT m_Begin;
             IteratorT m_End;

Modified: trunk/libs/range/test/Jamfile.v2
==============================================================================
--- trunk/libs/range/test/Jamfile.v2 (original)
+++ trunk/libs/range/test/Jamfile.v2 2010-04-13 16:41:11 EDT (Tue, 13 Apr 2010)
@@ -133,6 +133,7 @@
 # [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
     [ range-test join ]
         [ range-test partial_workaround ]
+ [ range-test pointer_as_iterator ]
         [ range-test reversible_range ]
         [ range-test std_container ]
         [ range-test string ]

Added: trunk/libs/range/test/pointer_as_iterator.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/range/test/pointer_as_iterator.cpp 2010-04-13 16:41:11 EDT (Tue, 13 Apr 2010)
@@ -0,0 +1,39 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to 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)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/array.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+#include <vector>
+
+namespace
+{
+ void test_pointer_as_iterator()
+ {
+ boost::array<int,3> arr;
+ boost::iterator_range<const int*> r(arr.begin(), arr.end());
+ r[0];
+ }
+} // anonymous namespace
+
+boost::unit_test::test_suite*
+init_unit_test_suite(int argc, char* argv[])
+{
+ boost::unit_test::test_suite* test
+ = BOOST_TEST_SUITE( "RangeTestSuite.pointer_as_iterator" );
+
+ test->add(BOOST_TEST_CASE( &test_pointer_as_iterator ));
+
+ return test;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk