summaryrefslogtreecommitdiff
blob: bf33f38109489d8e48a26fd8293ec1570e7f49f7 (plain)
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
generate code for Boost.NumPy[1] to accelerate c 1D array handling

Upstream: https://sourceforge.net/p/pygccxml/patches/2/

Index: pyplusplus/code_creators/__init__.py
===================================================================
--- pyplusplus/code_creators/__init__.py.orig
+++ pyplusplus/code_creators/__init__.py
@@ -110,6 +110,8 @@ from member_variable import bit_field_t
 from member_variable import bit_field_wrapper_t
 from member_variable import array_mv_t
 from member_variable import array_mv_wrapper_t
+from member_variable import array_numpy_t
+from member_variable import array_numpy_wrapper_t
 from member_variable import mem_var_ref_t
 from member_variable import mem_var_ref_wrapper_t
 from member_variable import member_variable_addressof_t
Index: pyplusplus/code_creators/code_creator.py
===================================================================
--- pyplusplus/code_creators/code_creator.py.orig
+++ pyplusplus/code_creators/code_creator.py
@@ -126,6 +126,7 @@ class code_creator_t(object):
         files = []
         if self.code_generator == self.CODE_GENERATOR_TYPES.BOOST_PYTHON:
             files.append( "boost/python.hpp" )
+            files.append( "boost/numpy.hpp" )
             files.append( code_repository.named_tuple.file_name )
         else:
             files.append( code_repository.ctypes_utils.file_name )
Index: pyplusplus/code_creators/member_variable.py
===================================================================
--- pyplusplus/code_creators/member_variable.py.orig
+++ pyplusplus/code_creators/member_variable.py
@@ -507,7 +507,95 @@ class array_mv_wrapper_t( code_creator.c
     def _get_system_files_impl( self ):
         return [code_repository.array_1.file_name]
 
+class array_numpy_t( member_variable_base_t ):
+    """
+    Creates boost.python code that exposes array member variable via boost.numpy.
+    """
+    def __init__(self, variable, wrapper ):
+        member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper )
+        self.works_on_instance = False
+
+    def _create_body( self ):
+        answer = []
+        doc = ''
+        if self.declaration.type_qualifiers.has_static:
+            answer.append( self.parent.class_var_name + '.add_static_property' )
+        else:
+            if self.documentation:
+                doc = self.documentation
+            answer.append( self.parent.class_var_name + '.add_property' )
+        answer.append('( "%s", &%s );' % (self.declaration.name, self.wrapper.wrapper_creator_full_name ))
+        if doc:
+            answer.append( os.linesep )
+            answer.append( self.PARAM_SEPARATOR )
+            answer.append( doc )
+        return ''.join( answer )
+
+    def _create_impl( self ):
+        answer = []
+        answer.append( '{ //%s, type=%s' % ( self.declaration, self.declaration.type ) )
+        answer.append( os.linesep )
+        answer.append( self.indent( self._create_body() ) )
+        answer.append( os.linesep )
+        answer.append( '}' )
+        return ''.join( answer )
+
+    def _get_system_files_impl( self ):
+        return []
 
+class array_numpy_wrapper_t( code_creator.code_creator_t
+                          , declaration_based.declaration_based_t ):
+    """registers array class"""
+    def __init__(self, variable ):
+        code_creator.code_creator_t.__init__( self )
+        declaration_based.declaration_based_t.__init__( self, declaration=variable)
+        self.py_class_type = declarations.reference_t(declarations.const_t(declarations.dummy_type_t( "bp::object" )))
+
+    @property
+    def wrapped_class_type( self ):
+        wrapped_cls_type = declarations.declarated_t( self.declaration.parent )
+        if declarations.is_const( self.declaration.type ):
+            wrapped_cls_type = declarations.const_t( wrapped_cls_type )
+        return declarations.reference_t( wrapped_cls_type )
+            
+    @property
+    def wrapper_creator_name(self):
+        return '_'.join( ['pyplusplus', self.declaration.name, 'wrapper'] )
+
+    @property
+    def wrapper_creator_full_name(self):
+        return '::'.join( [self.parent.full_name, self.wrapper_creator_name] )
+
+    def _create_impl( self ):        
+        if self.declaration.type_qualifiers.has_static:
+            tmpl = [ "static %(wrapper_type)s %(wrapper_creator_name)s( ){" ]
+            tmpl.append( self.indent( "return bn::from_data( %(parent_class_type)s::%(mem_var_ref)s," ) )
+        else:
+            tmpl = [ "static %(wrapper_type)s %(wrapper_creator_name)s( %(py_class_type)s inst ){" ]
+            tmpl.append( self.indent( "return bn::from_data(bp::extract< %(wrapped_class_type)s >(inst)().%(mem_var_ref)s," ) )
+        owner = "bp::object()"
+
+        tmpl.append( self.indent(self.indent("bn::dtype::get_builtin< %(item_type)s >(), bp::make_tuple(%(array_size)s),")) )
+        tmpl.append( self.indent(self.indent("bp::make_tuple(sizeof(%(item_type)s)), %(owner)s);")) )
+        tmpl.append( "}" )
+        
+        tmpl = os.linesep.join( tmpl )
+        
+        return tmpl % {
+                'wrapper_type' : "bn::ndarray"
+              , 'parent_class_type' : self.parent.declaration.partial_decl_string
+              , 'wrapper_creator_name' : self.wrapper_creator_name
+              , 'wrapped_class_type' : self.wrapped_class_type.decl_string
+              , 'mem_var_ref' : self.declaration.name
+              , 'py_class_type' : self.py_class_type.decl_string
+              , 'item_type' : declarations.array_item_type( self.declaration.type ).decl_string
+              , 'array_size': declarations.array_size( self.declaration.type )
+              , 'owner': owner
+            }
+
+    def _get_system_files_impl( self ):
+        return []
+        
 class mem_var_ref_t( member_variable_base_t ):
     """
     creates get/set accessors for class member variable, that has type reference.
Index: pyplusplus/code_creators/module_body.py
===================================================================
--- pyplusplus/code_creators/module_body.py.orig
+++ pyplusplus/code_creators/module_body.py
@@ -18,6 +18,7 @@ class module_body_t(compound.compound_t)
     def _create_impl(self):
         result = []
         result.append( "BOOST_PYTHON_MODULE(%s){" % self.name )
+        result.append( "bn::initialize();" )
         result.append( compound.compound_t.create_internal_code( self.creators ) )
         result.append( "}" )
         return os.linesep.join( result )
Index: pyplusplus/creators_factory/bpcreator.py
===================================================================
--- pyplusplus/creators_factory/bpcreator.py.orig
+++ pyplusplus/creators_factory/bpcreator.py
@@ -76,10 +76,14 @@ class bpcreator_t( declarations.decl_vis
         global_ns = declarations.get_global_namespace(decls)
 
         self.__extmodule = code_creators.bpmodule_t( global_ns )
-        if boost_python_ns_name:
-            bp_ns_alias = code_creators.namespace_alias_t( alias=boost_python_ns_name
-                                                           , full_namespace_name='::boost::python' )
-            self.__extmodule.adopt_creator( bp_ns_alias )
+
+        # alias of boost::numpy is hard-coded here, as it  will be merged into boost::python.
+        for ns_name, full_ns_name in {boost_python_ns_name: '::boost::python'
+                                    , 'bn': '::boost::numpy'}.iteritems():
+            if ns_name:
+                ns_alias = code_creators.namespace_alias_t( alias=ns_name
+                                                          , full_namespace_name=full_ns_name )
+                self.__extmodule.adopt_creator( ns_alias )
 
         self.__module_body = code_creators.module_body_t( name=module_name )
 
@@ -723,8 +727,12 @@ class bpcreator_t( declarations.decl_vis
                 wrapper = code_creators.bit_field_wrapper_t( variable=self.curr_decl )
                 maker = code_creators.bit_field_t( variable=self.curr_decl, wrapper=wrapper )
             elif declarations.is_array( self.curr_decl.type ):
-                wrapper = code_creators.array_mv_wrapper_t( variable=self.curr_decl )
-                maker = code_creators.array_mv_t( variable=self.curr_decl, wrapper=wrapper )
+                if declarations.is_arithmetic(declarations.array_item_type( self.curr_decl.type )):
+                    wrapper = code_creators.array_numpy_wrapper_t( variable=self.curr_decl )
+                    maker = code_creators.array_numpy_t( variable=self.curr_decl, wrapper=wrapper )
+                else:
+                    wrapper = code_creators.array_mv_wrapper_t( variable=self.curr_decl )
+                    maker = code_creators.array_mv_t( variable=self.curr_decl, wrapper=wrapper )
             elif declarations.is_pointer( self.curr_decl.type ):
                 wrapper = code_creators.member_variable_wrapper_t( variable=self.curr_decl )
                 maker = code_creators.member_variable_t( variable=self.curr_decl, wrapper=wrapper )