1 //-----------------------------------------------------------------------------
2 //
3 // Copyright (c) 1998 - 2007, The Regents of the University of California
4 // Produced at the Lawrence Livermore National Laboratory
5 // All rights reserved.
6 //
7 // This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
8 // full copyright notice is contained in the file COPYRIGHT located at the root
9 // of the PyCXX distribution.
10 //
11 // Redistribution  and  use  in  source  and  binary  forms,  with  or  without
12 // modification, are permitted provided that the following conditions are met:
13 //
14 //  - Redistributions of  source code must  retain the above  copyright notice,
15 //    this list of conditions and the disclaimer below.
16 //  - Redistributions in binary form must reproduce the above copyright notice,
17 //    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
18 //    documentation and/or materials provided with the distribution.
19 //  - Neither the name of the UC/LLNL nor  the names of its contributors may be
20 //    used to  endorse or  promote products derived from  this software without
21 //    specific prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
24 // AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
25 // IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
26 // ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
27 // CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
28 // ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
29 // DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
30 // SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
31 // CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
32 // LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
33 // OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
34 // DAMAGE.
35 //
36 //-----------------------------------------------------------------------------
37 
38 #ifndef __CXX_ExtensionTypeBase__h
39 #define __CXX_ExtensionTypeBase__h
40 
41 namespace Py
42 {
43     // Class PythonExtension is what you inherit from to create
44     // a new Python extension type. You give your class itself
45     // as the template paramter.
46 
47     // There are two ways that extension objects can get destroyed.
48     // 1. Their reference count goes to zero
49     // 2. Someone does an explicit delete on a pointer.
50     // In(1) the problem is to get the destructor called
51     //      We register a special deallocator in the Python type object
52     //      (see behaviors()) to do this.
53     // In(2) there is no problem, the dtor gets called.
54 
55     // PythonExtension does not use the usual Python heap allocator,
56     // instead using new/delete. We do the setting of the type object
57     // and reference count, usually done by PyObject_New, in the
58     // base class ctor.
59 
60     // This special deallocator does a delete on the pointer.
61 
62     class PythonExtensionBase : public PyObject
63     {
64     public:
65         PythonExtensionBase();
66         virtual ~PythonExtensionBase();
67 
68     public:
69         // object
70         virtual void reinit( Tuple &args, Dict &kwds );
71 
72         // object basics
73 #if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7
74         virtual int print( FILE *, int );
75 #endif
76         virtual Object getattr( const char * );
77         virtual int setattr( const char *, const Object & );
78         virtual Object getattro( const String & );
79         Object genericGetAttro( const String & );
80         virtual int setattro( const String &, const Object & );
81         int genericSetAttro( const String &, const Object & );
82         virtual int compare( const Object & );
83         virtual Object rich_compare( const Object &, int );
84         virtual Object repr();
85         virtual Object str();
86         virtual long hash();
87         virtual Object call( const Object &, const Object & );
88         virtual Object iter();
89         virtual PyObject *iternext();
90 
91         // Sequence methods
92         virtual PyCxx_ssize_t sequence_length();
93         virtual Object sequence_concat( const Object & );
94         virtual Object sequence_repeat( Py_ssize_t );
95         virtual Object sequence_item( Py_ssize_t );
96 
97         virtual int sequence_ass_item( Py_ssize_t, const Object & );
98 
99         virtual Object sequence_inplace_concat( const Object & );
100         virtual Object sequence_inplace_repeat( Py_ssize_t );
101 
102         virtual int sequence_contains( const Object & );
103 
104         // Mapping
105         virtual PyCxx_ssize_t mapping_length();
106         virtual Object mapping_subscript( const Object & );
107 
108         virtual int mapping_ass_subscript( const Object &, const Object & );
109 
110         // Number
111         virtual Object number_negative();
112         virtual Object number_positive();
113         virtual Object number_absolute();
114         virtual Object number_invert();
115         virtual Object number_int();
116         virtual Object number_float();
117         virtual Object number_add( const Object & );
118         virtual Object number_subtract( const Object & );
119         virtual Object number_multiply( const Object & );
120         virtual Object number_remainder( const Object & );
121         virtual Object number_divmod( const Object & );
122         virtual Object number_lshift( const Object & );
123         virtual Object number_rshift( const Object & );
124         virtual Object number_and( const Object & );
125         virtual Object number_xor( const Object & );
126         virtual Object number_or( const Object & );
127         virtual Object number_power( const Object &, const Object & );
128         virtual Object number_floor_divide( const Object & );
129         virtual Object number_true_divide( const Object & );
130         virtual Object number_index();
131 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
132         virtual Object number_matrix_multiply( const Object & );
133 #endif
134 
135         virtual Object number_inplace_add( const Object & );
136         virtual Object number_inplace_subtract( const Object & );
137         virtual Object number_inplace_multiply( const Object & );
138         virtual Object number_inplace_remainder( const Object & );
139         virtual Object number_inplace_power( const Object &, const Object & );
140         virtual Object number_inplace_lshift( const Object & );
141         virtual Object number_inplace_rshift( const Object & );
142         virtual Object number_inplace_and( const Object & );
143         virtual Object number_inplace_xor( const Object & );
144         virtual Object number_inplace_or( const Object & );
145         virtual Object number_inplace_floor_divide( const Object & );
146         virtual Object number_inplace_true_divide( const Object & );
147 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
148         virtual Object number_inplace_matrix_multiply( const Object & );
149 #endif
150 
151 #if !defined( Py_LIMITED_API )
152         // Buffer
153         virtual int buffer_get( Py_buffer *, int flags );
154         virtual int buffer_release( Py_buffer *buf );
155 #endif
156 
157     public:
158         // helper functions to call function fn_name with 0 to 9 args
159         Object callOnSelf( const std::string &fn_name );
160         Object callOnSelf( const std::string &fn_name,
161                                 const Object &arg1 );
162         Object callOnSelf( const std::string &fn_name,
163                                 const Object &arg1, const Object &arg2 );
164         Object callOnSelf( const std::string &fn_name,
165                                 const Object &arg1, const Object &arg2, const Object &arg3 );
166         Object callOnSelf( const std::string &fn_name,
167                                 const Object &arg1, const Object &arg2, const Object &arg3,
168                                 const Object &arg4 );
169         Object callOnSelf( const std::string &fn_name,
170                                 const Object &arg1, const Object &arg2, const Object &arg3,
171                                 const Object &arg4, const Object &arg5 );
172         Object callOnSelf( const std::string &fn_name,
173                                 const Object &arg1, const Object &arg2, const Object &arg3,
174                                 const Object &arg4, const Object &arg5, const Object &arg6 );
175         Object callOnSelf( const std::string &fn_name,
176                                 const Object &arg1, const Object &arg2, const Object &arg3,
177                                 const Object &arg4, const Object &arg5, const Object &arg6,
178                                 const Object &arg7 );
179         Object callOnSelf( const std::string &fn_name,
180                                 const Object &arg1, const Object &arg2, const Object &arg3,
181                                 const Object &arg4, const Object &arg5, const Object &arg6,
182                                 const Object &arg7, const Object &arg8 );
183         Object callOnSelf( const std::string &fn_name,
184                                 const Object &arg1, const Object &arg2, const Object &arg3,
185                                 const Object &arg4, const Object &arg5, const Object &arg6,
186                                 const Object &arg7, const Object &arg8, const Object &arg9 );
187 
188     public:
189         virtual PyObject *selfPtr() = 0;
190         virtual Object self() = 0;
191 
192     private:
193         void missing_method( void );
194         static PyObject *method_call_handler( PyObject *self, PyObject *args );
195     };
196 
197 } // Namespace Py
198 
199 // End of __CXX_ExtensionTypeBase__h
200 #endif
201