1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#ifndef __r__h
#define __r__h
#include "CXX/Extensions.hxx"
#include STR_STREAM
// Making an extension object
class range: public Py::PythonExtension<range>
{
public:
long start;
long stop;
long step;
range(long start_, long stop_, long step_ = 1L)
{
start = start_;
stop = stop_;
step = step_;
std::cout << "range object created " << this << std::endl;
}
virtual ~range()
{
std::cout << "range object destroyed " << this << std::endl;
}
static void init_type(void);
long length() const
{
return (stop - start + 1)/step;
}
long item(int i) const
{
if( i >= length() )
// this exception stops a Python for loop over range.
throw Py::IndexError("index too large");
return start + i * step;
}
range* slice(int i, int j) const
{
int first = start + i * step;
int last = start + j * step;
return new range(first, last, step);
}
range* extend(int k) const
{
return new range(start, stop + k, step);
}
std::string asString() const
{
std::OSTRSTREAM s;
s << "range(" << start << ", " << stop << ", " << step << ")" << std::ends;
return std::string(s.str());
}
// override functions from PythonExtension
virtual Py::Object repr();
virtual Py::Object getattr( const char *name );
virtual int sequence_length();
virtual Py::Object sequence_item( int i );
virtual Py::Object sequence_concat( const Py::Object &j );
virtual Py::Object sequence_slice( int i, int j );
// define python methods of this object
Py::Object amethod (const Py::Tuple& args);
Py::Object value (const Py::Tuple& args);
Py::Object assign (const Py::Tuple& args);
Py::Object reference_count (const Py::Tuple& args)
{
return Py::Int(this->ob_refcnt);
}
Py::Object c_value(const Py::Tuple&) const
{
Py::List result;
for(int i = start; i <= stop; i += step)
{
result.append(Py::Int(i));
}
return result;
}
void c_assign(const Py::Tuple&, const Py::Object& rhs)
{
Py::Tuple w(rhs);
w.verify_length(3);
start = long(Py::Int(w[0]));
stop = long(Py::Int(w[1]));
step = long(Py::Int(w[2]));
}
};
class RangeSequence: public Py::SeqBase<Py::Int>
{
public:
explicit RangeSequence (PyObject *pyob, bool owned = false): Py::SeqBase<Py::Int>(pyob, owned)
{
validate();
}
explicit RangeSequence(int start, int stop, int step = 1)
{
set (new range(start, stop, step), true);
}
RangeSequence(const RangeSequence& other): Py::SeqBase<Py::Int>(*other)
{
validate();
}
RangeSequence& operator= (const Py::Object& rhs)
{
return (*this = *rhs);
}
RangeSequence& operator= (PyObject* rhsp)
{
if(ptr() == rhsp) return *this;
set(rhsp);
return *this;
}
virtual bool accepts(PyObject *pyob) const
{
return pyob && range::check(pyob);
}
Py::Object value(const Py::Tuple& t) const
{
return static_cast<range *>(ptr())->c_value(t);
}
void assign(const Py::Tuple& t, const Py::Object& rhs)
{
static_cast<range *>(ptr())->c_assign(t, rhs);
}
};
#endif
|