1
2
3
4
5
6 """
7 This file contains C++ code needed to export one dimensional static arrays.
8 """
9
10
11 namespace = "pyplusplus::containers::static_sized"
12
13 file_name = "__array_1.pypp.hpp"
14
15 code = \
16 """// Copyright 2004-2008 Roman Yakovenko.
17 // Distributed under the Boost Software License, Version 1.0. (See
18 // accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
20
21 #ifndef __array_1_pyplusplus_hpp__
22 #define __array_1_pyplusplus_hpp__
23
24 #include "boost/python.hpp"
25 #include "boost/mpl/if.hpp"
26 #include "boost/type_traits/is_same.hpp"
27 #include "boost/type_traits/is_fundamental.hpp"
28 #include "boost/python/converter/registry.hpp"
29
30 #include <iostream>
31
32 //1 - dimension
33 namespace pyplusplus{ namespace containers{ namespace static_sized{
34
35 inline void
36 raise_on_out_of_range( long unsigned int size, long unsigned int index ){
37 if( size <= index ){
38 throw std::out_of_range("index out of range");
39 }
40 }
41
42 namespace details{
43
44 template<class T>
45 struct is_immutable{
46 BOOST_STATIC_CONSTANT(
47 bool
48 , value = ( boost::is_same< T, std::string >::value )
49 || ( boost::is_same< T, std::wstring >::value )
50 || ( boost::is_fundamental< T >::value )
51 || ( boost::is_enum< T >::value )
52 );
53
54 };
55
56 template<class T>
57 bool is_registered(){
58 namespace bpl = boost::python;
59 bpl::handle<> class_obj( bpl::objects::registered_class_object( bpl::type_id< T >()));
60 return class_obj.get() ? true : false;
61 }
62
63 template< class T >
64 void register_alias( const char* name ){
65 namespace bpl = boost::python;
66 bpl::handle<> class_obj( bpl::objects::registered_class_object( bpl::type_id< T >()));
67 boost::python::scope().attr( name ) = bpl::object( class_obj );
68 }
69
70 }//details
71
72 template< class TItemType, long unsigned int size >
73 struct const_array_1_t{
74
75 typedef BOOST_DEDUCED_TYPENAME boost::call_traits<const TItemType>::param_type param_type;
76
77 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
78 details::is_immutable<TItemType>::value
79 , TItemType
80 , param_type
81 >::type reference_type;
82
83 const_array_1_t( TItemType const * const data )
84 : m_data( data ){
85 if( !data ){
86 throw std::runtime_error( "const_array_1_t: pointer to null has been recieved." );
87 }
88 }
89
90 long unsigned int len() const {
91 return size;
92 }
93
94 reference_type item_ref( long unsigned int index ) const{
95 raise_on_out_of_range( size, index );
96 return m_data[index];
97 }
98
99 private:
100
101 TItemType const * m_data;
102
103 };
104
105 template< class TItemType, long unsigned int size >
106 struct array_1_t{
107
108 typedef BOOST_DEDUCED_TYPENAME boost::call_traits<const TItemType>::param_type param_type;
109
110 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
111 details::is_immutable<TItemType>::value
112 , TItemType
113 , param_type
114 >::type reference_type;
115
116 array_1_t( TItemType * data )
117 : m_data( data ){
118 if( !data ){
119 throw std::runtime_error( "array_1_t: pointer to null has been recieved." );
120 }
121 }
122
123 long unsigned int len() const {
124 return size;
125 }
126
127 reference_type item_ref( long unsigned int index ) const{
128 raise_on_out_of_range( size, index );
129 return m_data[index];
130 }
131
132 void
133 set_item( long unsigned int index, reference_type new_value ){
134 raise_on_out_of_range( size, index );
135 m_data[index] = new_value;
136 }
137
138 private:
139
140 TItemType* m_data;
141
142 };
143
144 template< class TItemType
145 , long unsigned int size
146 , typename CallPolicies=boost::python::default_call_policies >
147 struct register_const_array_1{
148 register_const_array_1(const char* name){
149 namespace bpl = boost::python;
150 typedef const_array_1_t< TItemType, size > wrapper_t;
151
152 if( details::is_registered< wrapper_t >() ){
153 details::register_alias< wrapper_t >( name );
154 }
155 else{
156 bpl::class_< wrapper_t >( name, bpl::no_init )
157 .def( "__getitem__"
158 , &wrapper_t::item_ref
159 , ( bpl::arg("index") )
160 , CallPolicies() )
161 .def( "__len__", &wrapper_t::len );
162 }
163 }
164 };
165
166 template< class TItemType
167 , long unsigned int size
168 , typename CallPolicies=boost::python::default_call_policies >
169 struct register_array_1{
170 register_array_1(const char* name){
171 namespace bpl = boost::python;
172 typedef array_1_t< TItemType, size > wrapper_t;
173 if( details::is_registered< wrapper_t >() ){
174 details::register_alias< wrapper_t >( name );
175 }
176 else{
177 bpl::class_< wrapper_t >( name, bpl::no_init )
178 .def( "__getitem__"
179 , &wrapper_t::item_ref
180 , ( bpl::arg("index") )
181 , CallPolicies() )
182 .def( "__setitem__"
183 , &wrapper_t::set_item
184 , ( bpl::arg("index"), bpl::arg("value") )
185 , CallPolicies() )
186 .def( "__len__", &wrapper_t::len );
187 }
188 }
189 };
190
191 } /*pyplusplus*/ } /*containers*/ } /*static_sized*/
192
193
194 #endif//__array_1_pyplusplus_hpp__
195
196 """
197