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_Extensions__h
39 #define __CXX_Extensions__h
40 
41 
42 #ifdef _MSC_VER
43 // disable warning C4786: symbol greater than 255 character,
44 // okay to ignore
45 #pragma warning( disable: 4786 )
46 #endif
47 
48 #include "CXX/WrapPython.h"
49 #include "CXX/Version.hxx"
50 #include "CXX/Python3/Config.hxx"
51 #include "CXX/Python3/CxxDebug.hxx"
52 #include "CXX/Python3/Objects.hxx"
53 
54 extern "C" { extern PyObject py_object_initializer; }
55 
56 #include <vector>
57 #include <map>
58 
59 // ----------------------------------------------------------------------
60 
61 namespace Py
62 {
63     class ExtensionModuleBase;
64 
65     // Make an Exception Type for use in raising custom exceptions
66     class ExtensionExceptionType : public Object
67     {
68     public:
69         ExtensionExceptionType();
70         virtual ~ExtensionExceptionType();
71 
72         // call init to create the type
73         void init( ExtensionModuleBase &module, const std::string &name, ExtensionExceptionType &parent );
74         void init( ExtensionModuleBase &module, const std::string &name );
75     };
76 
77     class MethodTable
78     {
79     public:
80         MethodTable();
81         virtual ~MethodTable();
82 
83         void add( const char *method_name, PyCFunction f, const char *doc="", int flag=1 );
84         PyMethodDef *table();
85 
86     protected:
87         std::vector<PyMethodDef> t;    // accumulator of PyMethodDef's
88         PyMethodDef *mt;        // Actual method table produced when full
89 
90         static PyMethodDef method( const char* method_name, PyCFunction f, int flags=1, const char* doc="" );
91 
92     private:
93         //
94         // prevent the compiler generating these unwanted functions
95         //
96         MethodTable( const MethodTable &m );    //unimplemented
97         void operator=( const MethodTable &m );    //unimplemented
98 
99     }; // end class MethodTable
100 
101     // Note: Python calls noargs as varargs buts args==NULL
102     extern "C" typedef PyObject *(*method_noargs_call_handler_t)( PyObject *_self, PyObject * );
103     extern "C" typedef PyObject *(*method_varargs_call_handler_t)( PyObject *_self, PyObject *_args );
104     extern "C" typedef PyObject *(*method_keyword_call_handler_t)( PyObject *_self, PyObject *_args, PyObject *_dict );
105 
106     template<class T>
107     class MethodDefExt
108     {
109     public:
110         typedef Object (T::*method_noargs_function_t)();
111         typedef Object (T::*method_varargs_function_t)( const Tuple &args );
112         typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
113 
114         // NOARGS
MethodDefExt(const char * _name,method_noargs_function_t _function,method_noargs_call_handler_t _handler,const char * _doc)115         MethodDefExt
116         (
117             const char *_name,
118             method_noargs_function_t _function,
119             method_noargs_call_handler_t _handler,
120             const char *_doc
121         )
122         {
123             ext_meth_def.ml_name = const_cast<char *>( _name );
124             ext_meth_def.ml_meth = reinterpret_cast<method_varargs_call_handler_t>( _handler );
125             ext_meth_def.ml_flags = METH_NOARGS;
126             ext_meth_def.ml_doc = const_cast<char *>( _doc );
127 
128             ext_noargs_function = _function;
129             ext_varargs_function = NULL;
130             ext_keyword_function = NULL;
131         }
132 
133         // VARARGS
MethodDefExt(const char * _name,method_varargs_function_t _function,method_varargs_call_handler_t _handler,const char * _doc)134         MethodDefExt
135         (
136             const char *_name,
137             method_varargs_function_t _function,
138             method_varargs_call_handler_t _handler,
139             const char *_doc
140         )
141         {
142             ext_meth_def.ml_name = const_cast<char *>( _name );
143             ext_meth_def.ml_meth = reinterpret_cast<method_varargs_call_handler_t>( _handler );
144             ext_meth_def.ml_flags = METH_VARARGS;
145             ext_meth_def.ml_doc = const_cast<char *>( _doc );
146 
147             ext_noargs_function = NULL;
148             ext_varargs_function = _function;
149             ext_keyword_function = NULL;
150         }
151 
152         // VARARGS + KEYWORD
MethodDefExt(const char * _name,method_keyword_function_t _function,method_keyword_call_handler_t _handler,const char * _doc)153         MethodDefExt
154         (
155             const char *_name,
156             method_keyword_function_t _function,
157             method_keyword_call_handler_t _handler,
158             const char *_doc
159         )
160         {
161             ext_meth_def.ml_name = const_cast<char *>( _name );
162             ext_meth_def.ml_meth = reinterpret_cast<method_varargs_call_handler_t>( _handler );
163             ext_meth_def.ml_flags = METH_VARARGS|METH_KEYWORDS;
164             ext_meth_def.ml_doc = const_cast<char *>( _doc );
165 
166             ext_noargs_function = NULL;
167             ext_varargs_function = NULL;
168             ext_keyword_function = _function;
169         }
170 
~MethodDefExt()171         ~MethodDefExt()
172         {}
173 
174         PyMethodDef ext_meth_def;
175         method_noargs_function_t ext_noargs_function;
176         method_varargs_function_t ext_varargs_function;
177         method_keyword_function_t ext_keyword_function;
178         Object py_method;
179     };
180 } // Namespace Py
181 
182 #include "CXX/Python3/ExtensionModule.hxx"
183 #include "CXX/Python3/PythonType.hxx"
184 #include "CXX/Python3/ExtensionTypeBase.hxx"
185 #include "CXX/Python3/ExtensionOldType.hxx"
186 #include "CXX/Python3/ExtensionType.hxx"
187 
188 // End of CXX_Extensions.h
189 #endif
190