2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-24 18:12:43 +00:00

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]
This commit is contained in:
Jonathan Brandmeyer
2004-07-08 17:29:51 +00:00
parent 44e9ffc5ca
commit 8469d7727d
5 changed files with 66 additions and 22 deletions

View File

@@ -105,7 +105,7 @@ constructors<br>
<pre>slice();<br></pre>
<dl class="function-semantics">
<dt><b>Effects:</b> constructs a <code>slice</code> with default stop, start, and
step values.&nbsp; Equivalent to the slice object created by the Python
step values.&nbsp; Equivalent to the slice object created as part of the Python
expression <code>base[::].</code></dt>
<dt><b>Throws:</b> nothing.</dt>
</dl>
@@ -115,13 +115,14 @@ slice(Int1 start, Int2 stop);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code>
are of type <code>slice_nil</code> or convertible to type <code>object</code>.</dt>
are of type <code><a href="object.html#slice_nil-spec">slice_nil</a></code>
or convertible to type <code>object</code>.</dt>
<dt><b>Effects:</b> constructs a new slice with default step value
and the provided start and stop values.&nbsp; Equivalent to the slice
object
created by the built-in Python function <code><a
href="http://www.python.org/doc/current/lib/built-in-funcs.html#12h-62">slice(start,stop)</a></code>,
or the Python expression <code>base[start:stop]</code>.</dt>
or as part of the Python expression <code>base[start:stop]</code>.</dt>
<dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
exception if no conversion is possible from the arguments to type <code>object</code>.</dt>
</dl>
@@ -129,12 +130,12 @@ exception if no conversion is possible from the arguments to type <code>object</
template &lt;typename Int1, typename Int2, typename Int3&gt;
slice(Int1 start, Int2 stop, Int3 step);
</pre>
<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>
<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>
<dt><b>Effects:</b> constructs a new slice with start stop and step
values.&nbsp; Equivalent to the slice object created
by the built-in Python function <code><a
href="http://www.python.org/doc/current/lib/built-in-functions.html#12h-62">slice(start,stop,step)</a></code>,
or the Python expression <code>base[start:stop:step]</code>.</dt>
or as part of the Python expression <code>base[start:stop:step]</code>.</dt>
<dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
exception if no conversion is possible from the arguments to type
object.</dt>
@@ -142,9 +143,9 @@ object.</dt>
observer functions<br>
</h4>
<pre>
object slice::start();
object slice::stop();
object slice::step();
object slice::start() const;
object slice::stop() const;
object slice::step() const;
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> None.</dt>
@@ -153,7 +154,7 @@ object slice::step();
the slice was created with.&nbsp;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.&nbsp;In principal, any object may be used when creating a
object.&nbsp; In principal, any object may be used when creating a
slice object, but in practice they are usually integers.</dt>
</dl>
<br>
@@ -161,7 +162,8 @@ slice object, but in practice they are usually integers.</dt>
template &lt;typename RandomAccessIterator&gt;
slice::range&lt;RandomAccessIterator&gt;
slice::get_indicies(
RandomAccessIterator const&amp; begin, RandomAccessIterator const&amp; end);
RandomAccessIterator const&amp; begin,
RandomAccessIterator const&amp; end) const;
</pre>
<dl class="function-semantics">
<dt><b>Arguments:</b> 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&lt;double&gt; const&amp; Foo, slice index)
double partial_sum(std::vector&lt;double&gt; const&amp; Foo, const slice index)
{
slice::range&lt;std::vector&lt;double&gt;::const_iterator&gt; bounds;
try {
@@ -222,7 +224,7 @@ double partial_sum(std::vector&lt;double&gt; const&amp; 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);
}

View File

@@ -16,7 +16,7 @@
#include <algorithm>
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<typename Integer1, typename Integer2>
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<typename RandomAccessIterator>
range<RandomAccessIterator>
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

View File

@@ -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));

View File

@@ -1,5 +1,6 @@
#include <boost/python.hpp>
#include <boost/python/slice.hpp>
#include <vector>
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<int> coll(11);
typedef std::vector<int>::iterator coll_iterator;
for (coll_iterator i = coll.begin(); i != coll.end(); ++i) {
*i = i - coll.begin() - 5;
}
slice::range<std::vector<int>::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);
}

View File

@@ -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,