Skip to content

Commit 8469d77

Browse files
author
Jonathan Brandmeyer
committed
Add a small set of test cases for slice::get_indicies().
Promote slice::start(), slice::stop(), slice::step, and slice::get_indicies() to const. Fix typos in the documentation. [SVN r23408]
1 parent 44e9ffc commit 8469d77

File tree

5 files changed

+66
-22
lines changed

5 files changed

+66
-22
lines changed

doc/v2/slice.html

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ <h4><a name="slice-spec-ctors"></a>Class <code>slice</code>
105105
<pre>slice();<br></pre>
106106
<dl class="function-semantics">
107107
<dt><b>Effects:</b> constructs a <code>slice</code> with default stop, start, and
108-
step values.&nbsp; Equivalent to the slice object created by the Python
108+
step values.&nbsp; Equivalent to the slice object created as part of the Python
109109
expression <code>base[::].</code></dt>
110110
<dt><b>Throws:</b> nothing.</dt>
111111
</dl>
@@ -115,36 +115,37 @@ <h4><a name="slice-spec-ctors"></a>Class <code>slice</code>
115115
</pre>
116116
<dl class="function-semantics">
117117
<dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code>
118-
are of type <code>slice_nil</code> or convertible to type <code>object</code>.</dt>
118+
are of type <code><a href="object.html#slice_nil-spec">slice_nil</a></code>
119+
or convertible to type <code>object</code>.</dt>
119120
<dt><b>Effects:</b> constructs a new slice with default step value
120121
and the provided start and stop values.&nbsp; Equivalent to the slice
121122
object
122123
created by the built-in Python function <code><a
123124
href="http://www.python.org/doc/current/lib/built-in-funcs.html#12h-62">slice(start,stop)</a></code>,
124-
or the Python expression <code>base[start:stop]</code>.</dt>
125+
or as part of the Python expression <code>base[start:stop]</code>.</dt>
125126
<dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
126127
exception if no conversion is possible from the arguments to type <code>object</code>.</dt>
127128
</dl>
128129
<pre>
129130
template &lt;typename Int1, typename Int2, typename Int3&gt;
130131
slice(Int1 start, Int2 stop, Int3 step);
131132
</pre>
132-
<dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code> are integers, <code>slice_nil</code>, or convertible to type <code>object</code>.</dt>
133+
<dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code> are <code>slice_nil</code> or convertible to type <code>object</code>.</dt>
133134
<dt><b>Effects:</b> constructs a new slice with start stop and step
134135
values.&nbsp; Equivalent to the slice object created
135136
by the built-in Python function <code><a
136137
href="http://www.python.org/doc/current/lib/built-in-functions.html#12h-62">slice(start,stop,step)</a></code>,
137-
or the Python expression <code>base[start:stop:step]</code>.</dt>
138+
or as part of the Python expression <code>base[start:stop:step]</code>.</dt>
138139
<dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
139140
exception if no conversion is possible from the arguments to type
140141
object.</dt>
141142
<h4><a name="slice-spec-observers"></a>Class <code>slice</code>
142143
observer functions<br>
143144
</h4>
144145
<pre>
145-
object slice::start();
146-
object slice::stop();
147-
object slice::step();
146+
object slice::start() const;
147+
object slice::stop() const;
148+
object slice::step() const;
148149
</pre>
149150
<dl class="function-semantics">
150151
<dt><b>Effects:</b> None.</dt>
@@ -153,15 +154,16 @@ <h4><a name="slice-spec-observers"></a>Class <code>slice</code>
153154
the slice was created with.&nbsp;If the parameter was omitted or
154155
slice_nil was used when the slice was created, than that parameter will
155156
be a reference to PyNone and compare equal to a default-constructed
156-
object.&nbsp;In principal, any object may be used when creating a
157+
object.&nbsp; In principal, any object may be used when creating a
157158
slice object, but in practice they are usually integers.</dt>
158159
</dl>
159160
<br>
160161
<pre>
161162
template &lt;typename RandomAccessIterator&gt;
162163
slice::range&lt;RandomAccessIterator&gt;
163164
slice::get_indicies(
164-
RandomAccessIterator const&amp; begin, RandomAccessIterator const&amp; end);
165+
RandomAccessIterator const&amp; begin,
166+
RandomAccessIterator const&amp; end) const;
165167
</pre>
166168
<dl class="function-semantics">
167169
<dt><b>Arguments:</b> A pair of STL-conforming Random Access
@@ -203,7 +205,7 @@ <h2><a name="examples"></a><b>Examples</b></h2>
203205
return l[slice(_,_,2)];
204206
}
205207

206-
// Perform a multidimensional rich slice of a Numeric.array
208+
// Perform a multidimensional extended slice of a Numeric.array
207209
numeric::array even_columns(numeric::array arr)
208210
{
209211
// select every other column, starting with the second, of a 2-D array.
@@ -212,7 +214,7 @@ <h2><a name="examples"></a><b>Examples</b></h2>
212214
}
213215

214216
// Perform a summation over a slice of a std::vector.
215-
double partial_sum(std::vector&lt;double&gt; const&amp; Foo, slice index)
217+
double partial_sum(std::vector&lt;double&gt; const&amp; Foo, const slice index)
216218
{
217219
slice::range&lt;std::vector&lt;double&gt;::const_iterator&gt; bounds;
218220
try {
@@ -222,7 +224,7 @@ <h2><a name="examples"></a><b>Examples</b></h2>
222224
return 0.0;
223225
}
224226
double sum = 0.0;
225-
while (bounds.start != bounds.end) {
227+
while (bounds.start != bounds.stop) {
226228
sum += *bounds.start;
227229
std::advance( bounds.start, bounds.step);
228230
}

include/boost/python/slice.hpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include <algorithm>
1717

1818
namespace boost { namespace python {
19-
19+
2020
class slice : public object
2121
{
2222
private:
@@ -29,7 +29,8 @@ class slice : public object
2929
BOOST_PYTHON_DECL
3030
slice();
3131

32-
// Each argument must be int, slice_nil, or implicitly convertable to int
32+
// Each argument must be slice_nil, or implicitly convertable to object.
33+
// They should normally be integers.
3334
template<typename Integer1, typename Integer2>
3435
slice( Integer1 start, Integer2 stop)
3536
: object( new_slice( object(start).ptr(), object(stop).ptr(), NULL))
@@ -48,9 +49,9 @@ class slice : public object
4849
// equal to a default-constructed boost::python::object.
4950
// If a user-defined type wishes to support slicing, then support for the
5051
// special meaning associated with negative indicies is up to the user.
51-
object start();
52-
object stop();
53-
object step();
52+
object start() const;
53+
object stop() const;
54+
object step() const;
5455

5556
// The following algorithm is intended to automate the process of
5657
// determining a slice range when you want to fully support negative
@@ -104,7 +105,7 @@ class slice : public object
104105
template<typename RandomAccessIterator>
105106
range<RandomAccessIterator>
106107
get_indicies( const RandomAccessIterator& begin,
107-
const RandomAccessIterator& end)
108+
const RandomAccessIterator& end) const
108109
{
109110
// This is based loosely on PySlice_GetIndicesEx(), but it has been
110111
// carefully crafted to ensure that these iterators never fall out of

src/slice.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ slice::slice()
2121
}
2222

2323
object
24-
slice::start()
24+
slice::start() const
2525
{
2626
return object( detail::borrowed_reference(
2727
((PySliceObject*)this->ptr())->start));
2828
}
2929

3030
object
31-
slice::stop()
31+
slice::stop() const
3232
{
3333
return object( detail::borrowed_reference(
3434
((PySliceObject*)this->ptr())->stop));
3535
}
3636

3737
object
38-
slice::step()
38+
slice::step() const
3939
{
4040
return object( detail::borrowed_reference(
4141
((PySliceObject*)this->ptr())->step));

test/slice.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <boost/python.hpp>
22
#include <boost/python/slice.hpp>
3+
#include <vector>
34

45
using namespace boost::python;
56

@@ -75,9 +76,37 @@ bool check_numeric_array_rich_slice()
7576
// Verify functions accepting a slice argument can be called
7677
bool accept_slice( slice) { return true; }
7778

79+
int check_slice_get_indicies(const slice index)
80+
{
81+
// A vector of integers from [-5, 5].
82+
std::vector<int> coll(11);
83+
typedef std::vector<int>::iterator coll_iterator;
84+
85+
for (coll_iterator i = coll.begin(); i != coll.end(); ++i) {
86+
*i = i - coll.begin() - 5;
87+
}
88+
89+
slice::range<std::vector<int>::iterator> bounds;
90+
try {
91+
bounds = index.get_indicies<>(coll.begin(), coll.end());
92+
}
93+
catch (std::invalid_argument) {
94+
return 0;
95+
}
96+
int sum = 0;
97+
while (bounds.start != bounds.stop) {
98+
sum += *bounds.start;
99+
std::advance( bounds.start, bounds.step);
100+
}
101+
sum += *bounds.start;
102+
return sum;
103+
}
104+
105+
78106
BOOST_PYTHON_MODULE(slice_ext)
79107
{
80108
def( "accept_slice", accept_slice);
81109
def( "check_numeric_array_rich_slice", check_numeric_array_rich_slice);
82110
def( "check_string_rich_slice", check_string_rich_slice);
111+
def( "check_slice_get_indicies", check_slice_get_indicies);
83112
}

test/slice.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@
3737
... print 1
3838
...
3939
1
40+
>>> check_slice_get_indicies( slice(None))
41+
0
42+
>>> check_slice_get_indicies( slice(2,-2))
43+
0
44+
>>> check_slice_get_indicies( slice(2, None, 2))
45+
5
46+
>>> check_slice_get_indicies( slice(2, None, -1))
47+
-12
48+
>>> check_slice_get_indicies( slice( 20, None))
49+
0
50+
>>> check_slice_get_indicies( slice( -2, -5, -2))
51+
6
4052
"""
4153

4254
# Performs an affirmative and negative argument resolution check,

0 commit comments

Comments
 (0)