mirror of
https://github.com/boostorg/python.git
synced 2026-02-01 20:52:13 +00:00
TypeWrapper for Python slice objects
[SVN r1525]
This commit is contained in:
93
include/boost/python/suite/indexing/slice.cpp
Executable file
93
include/boost/python/suite/indexing/slice.cpp
Executable file
@@ -0,0 +1,93 @@
|
||||
// -*- mode:c++ -*-
|
||||
//
|
||||
// Module slice.cpp
|
||||
//
|
||||
// Copyright (c) 2003 Raoul M. Gough
|
||||
//
|
||||
// This material is provided "as is", with absolutely no warranty expressed
|
||||
// or implied. Any use is at your own risk.
|
||||
//
|
||||
// Permission to use or copy this material for any purpose is hereby
|
||||
// granted without fee, provided the above notices are retained on all
|
||||
// copies. Permission to modify the material and to distribute modified
|
||||
// versions is granted, provided the above notices are retained, and a
|
||||
// notice that the material was modified is included with the above
|
||||
// copyright notice.
|
||||
//
|
||||
// History
|
||||
// =======
|
||||
// 2003/ 9/10 rmg File creation
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
#include "slice.hpp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Check that setLength has been called, and throw otherwise
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void indexing::slice::validate () const
|
||||
{
|
||||
if (mDirection == 0)
|
||||
{
|
||||
PyErr_SetString (PyExc_RuntimeError
|
||||
, "slice access attempted before setLength called");
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Slice constructor
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
indexing::slice::slice (boost::python::detail::borrowed_reference ref)
|
||||
: boost::python::object (ref)
|
||||
, mStart (0)
|
||||
, mStep (0)
|
||||
, mStop (0)
|
||||
, mDirection (0)
|
||||
{
|
||||
if (!PySlice_Check (this->ptr()))
|
||||
{
|
||||
PyErr_SetString (PyExc_TypeError
|
||||
, "slice constructor: passed a non-slice object");
|
||||
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
|
||||
// This slice object is useless until setLength is called
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Set up our member variables for a sequence of a given length
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void indexing::slice::setLength (int sequenceLength)
|
||||
{
|
||||
PySlice_GetIndices ((PySliceObject *) this->ptr()
|
||||
, sequenceLength
|
||||
, &mStart
|
||||
, &mStop
|
||||
, &mStep);
|
||||
|
||||
if (mStep == 0)
|
||||
{
|
||||
// Can happen with Python prior to 2.3
|
||||
PyErr_SetString (PyExc_ValueError, "slice step cannot be zero");
|
||||
boost::python::throw_error_already_set ();
|
||||
}
|
||||
|
||||
mStart = std::max (0, std::min (sequenceLength, mStart));
|
||||
mStop = std::max (0, std::min (sequenceLength, mStop));
|
||||
mDirection = (mStep > 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Check if an index is within the range of this slice
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool indexing::slice::inRange (int index)
|
||||
{
|
||||
return ((mStop - index) * mDirection) > 0;
|
||||
}
|
||||
71
include/boost/python/suite/indexing/slice.hpp
Executable file
71
include/boost/python/suite/indexing/slice.hpp
Executable file
@@ -0,0 +1,71 @@
|
||||
// -*- mode:c++ -*-
|
||||
//
|
||||
// Header file slice.hpp
|
||||
//
|
||||
// Copyright (c) 2003 Raoul M. Gough
|
||||
//
|
||||
// This material is provided "as is", with absolutely no warranty expressed
|
||||
// or implied. Any use is at your own risk.
|
||||
//
|
||||
// Permission to use or copy this material for any purpose is hereby
|
||||
// granted without fee, provided the above notices are retained on all
|
||||
// copies. Permission to modify the material and to distribute modified
|
||||
// versions is granted, provided the above notices are retained, and a
|
||||
// notice that the material was modified is included with the above
|
||||
// copyright notice.
|
||||
//
|
||||
// History
|
||||
// =======
|
||||
// 2003/ 9/10 rmg File creation
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
#ifndef slice_rmg_20030910_included
|
||||
#define slice_rmg_20030910_included
|
||||
|
||||
#include <Python.h>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/converter/pytype_object_mgr_traits.hpp>
|
||||
|
||||
namespace indexing
|
||||
{
|
||||
struct slice : public boost::python::object
|
||||
{
|
||||
//
|
||||
// *** WARNING ***
|
||||
//
|
||||
// A newly constructed slice object is useless until setLength is called
|
||||
//
|
||||
|
||||
slice (boost::python::detail::borrowed_reference ref);
|
||||
void setLength (int sequenceLength);
|
||||
|
||||
int start() const { validate(); return mStart; }
|
||||
int step() const { validate(); return mStep; }
|
||||
int stop() const { validate(); return mStop; }
|
||||
|
||||
int size() const { validate(); return (mStop - mStart) / mStep; }
|
||||
|
||||
bool inRange (int index);
|
||||
|
||||
private:
|
||||
void validate () const; // throws unless setLength has been called
|
||||
|
||||
int mStart;
|
||||
int mStep;
|
||||
int mStop;
|
||||
int mDirection;
|
||||
};
|
||||
}
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
// Specialized converter to handle PySlice_Type objects
|
||||
template<>
|
||||
struct object_manager_traits<indexing::slice>
|
||||
: pytype_object_manager_traits<&PySlice_Type, ::indexing::slice>
|
||||
{
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif // slice_rmg_20030910_included
|
||||
Reference in New Issue
Block a user