2
0
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:
Raoul Gough
2003-09-10 15:37:45 +00:00
parent a8d2e3cc26
commit f587a1b684
2 changed files with 164 additions and 0 deletions

View 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;
}

View 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