File: range.hxx

package info (click to toggle)
pycxx 5.3.2-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 460 kB
  • ctags: 1,131
  • sloc: cpp: 2,148; makefile: 82; python: 68; sh: 9; ansic: 8
file content (147 lines) | stat: -rw-r--r-- 3,008 bytes parent folder | download
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