diff --git a/doc/v2/slice.html b/doc/v2/slice.html
index cea06553..734e4218 100644
--- a/doc/v2/slice.html
+++ b/doc/v2/slice.html
@@ -105,7 +105,7 @@ constructors
slice();
slice with default stop, start, and
-step values. Equivalent to the slice object created by the Python
+step values. Equivalent to the slice object created as part of the Python
expression base[::].start, stop, and step
-are of type slice_nil or convertible to type object.slice_nil
+ or convertible to type object.
slice(start,stop),
-or the Python expression base[start:stop].base[start:stop].
error_already_set and sets a Python TypeError
exception if no conversion is possible from the arguments to type object.object
template <typename Int1, typename Int2, typename Int3>
slice(Int1 start, Int2 stop, Int3 step);
- Requires: start, stop, and step are integers, slice_nil, or convertible to type object.
+ Requires: start, stop, and step are slice_nil or convertible to type object.
Effects: constructs a new slice with start stop and step
values. Equivalent to the slice object created
by the built-in Python function slice(start,stop,step),
-or the Python expression base[start:stop:step].
+or as part of the Python expression base[start:stop:step].
Throws: error_already_set and sets a Python TypeError
exception if no conversion is possible from the arguments to type
object.
@@ -142,9 +143,9 @@ object.
observer functions
-object slice::start();
-object slice::stop();
-object slice::step();
+object slice::start() const;
+object slice::stop() const;
+object slice::step() const;
- Effects: None.
@@ -153,7 +154,7 @@ object slice::step();
the slice was created with. If the parameter was omitted or
slice_nil was used when the slice was created, than that parameter will
be a reference to PyNone and compare equal to a default-constructed
-object. In principal, any object may be used when creating a
+object. In principal, any object may be used when creating a
slice object, but in practice they are usually integers.
@@ -161,7 +162,8 @@ slice object, but in practice they are usually integers.
template <typename RandomAccessIterator>
slice::range<RandomAccessIterator>
slice::get_indicies(
- RandomAccessIterator const& begin, RandomAccessIterator const& end);
+ RandomAccessIterator const& begin,
+ RandomAccessIterator const& end) const;
- Arguments: A pair of STL-conforming Random Access
@@ -203,7 +205,7 @@ list odd_elements(list l)
return l[slice(_,_,2)];
}
-// Perform a multidimensional rich slice of a Numeric.array
+// Perform a multidimensional extended slice of a Numeric.array
numeric::array even_columns(numeric::array arr)
{
// select every other column, starting with the second, of a 2-D array.
@@ -212,7 +214,7 @@ numeric::array even_columns(numeric::array arr)
}
// Perform a summation over a slice of a std::vector.
-double partial_sum(std::vector<double> const& Foo, slice index)
+double partial_sum(std::vector<double> const& Foo, const slice index)
{
slice::range<std::vector<double>::const_iterator> bounds;
try {
@@ -222,7 +224,7 @@ double partial_sum(std::vector<double> const& Foo, slice index)
return 0.0;
}
double sum = 0.0;
- while (bounds.start != bounds.end) {
+ while (bounds.start != bounds.stop) {
sum += *bounds.start;
std::advance( bounds.start, bounds.step);
}
diff --git a/include/boost/python/slice.hpp b/include/boost/python/slice.hpp
index 9354b485..9f296bc2 100644
--- a/include/boost/python/slice.hpp
+++ b/include/boost/python/slice.hpp
@@ -16,7 +16,7 @@
#include
namespace boost { namespace python {
-
+
class slice : public object
{
private:
@@ -29,7 +29,8 @@ class slice : public object
BOOST_PYTHON_DECL
slice();
- // Each argument must be int, slice_nil, or implicitly convertable to int
+ // Each argument must be slice_nil, or implicitly convertable to object.
+ // They should normally be integers.
template
slice( Integer1 start, Integer2 stop)
: object( new_slice( object(start).ptr(), object(stop).ptr(), NULL))
@@ -48,9 +49,9 @@ class slice : public object
// equal to a default-constructed boost::python::object.
// If a user-defined type wishes to support slicing, then support for the
// special meaning associated with negative indicies is up to the user.
- object start();
- object stop();
- object step();
+ object start() const;
+ object stop() const;
+ object step() const;
// The following algorithm is intended to automate the process of
// determining a slice range when you want to fully support negative
@@ -104,7 +105,7 @@ class slice : public object
template
range
get_indicies( const RandomAccessIterator& begin,
- const RandomAccessIterator& end)
+ const RandomAccessIterator& end) const
{
// This is based loosely on PySlice_GetIndicesEx(), but it has been
// carefully crafted to ensure that these iterators never fall out of
diff --git a/src/slice.cpp b/src/slice.cpp
index 55f8e865..a4dd98f5 100644
--- a/src/slice.cpp
+++ b/src/slice.cpp
@@ -21,21 +21,21 @@ slice::slice()
}
object
-slice::start()
+slice::start() const
{
return object( detail::borrowed_reference(
((PySliceObject*)this->ptr())->start));
}
object
-slice::stop()
+slice::stop() const
{
return object( detail::borrowed_reference(
((PySliceObject*)this->ptr())->stop));
}
object
-slice::step()
+slice::step() const
{
return object( detail::borrowed_reference(
((PySliceObject*)this->ptr())->step));
diff --git a/test/slice.cpp b/test/slice.cpp
index 37d9e83d..d516d008 100644
--- a/test/slice.cpp
+++ b/test/slice.cpp
@@ -1,5 +1,6 @@
#include
#include
+#include
using namespace boost::python;
@@ -75,9 +76,37 @@ bool check_numeric_array_rich_slice()
// Verify functions accepting a slice argument can be called
bool accept_slice( slice) { return true; }
+int check_slice_get_indicies(const slice index)
+{
+ // A vector of integers from [-5, 5].
+ std::vector coll(11);
+ typedef std::vector::iterator coll_iterator;
+
+ for (coll_iterator i = coll.begin(); i != coll.end(); ++i) {
+ *i = i - coll.begin() - 5;
+ }
+
+ slice::range::iterator> bounds;
+ try {
+ bounds = index.get_indicies<>(coll.begin(), coll.end());
+ }
+ catch (std::invalid_argument) {
+ return 0;
+ }
+ int sum = 0;
+ while (bounds.start != bounds.stop) {
+ sum += *bounds.start;
+ std::advance( bounds.start, bounds.step);
+ }
+ sum += *bounds.start;
+ return sum;
+}
+
+
BOOST_PYTHON_MODULE(slice_ext)
{
def( "accept_slice", accept_slice);
def( "check_numeric_array_rich_slice", check_numeric_array_rich_slice);
def( "check_string_rich_slice", check_string_rich_slice);
+ def( "check_slice_get_indicies", check_slice_get_indicies);
}
diff --git a/test/slice.py b/test/slice.py
index fb6a7b03..fafe8a6f 100644
--- a/test/slice.py
+++ b/test/slice.py
@@ -37,6 +37,18 @@ test passed
... print 1
...
1
+>>> check_slice_get_indicies( slice(None))
+0
+>>> check_slice_get_indicies( slice(2,-2))
+0
+>>> check_slice_get_indicies( slice(2, None, 2))
+5
+>>> check_slice_get_indicies( slice(2, None, -1))
+-12
+>>> check_slice_get_indicies( slice( 20, None))
+0
+>>> check_slice_get_indicies( slice( -2, -5, -2))
+6
"""
# Performs an affirmative and negative argument resolution check,