Package pyplusplus :: Package code_repository :: Module array_1

Source Code for Module pyplusplus.code_repository.array_1

  1  # Copyright 2004-2008 Roman Yakovenko. 
  2  # Distributed under the Boost Software License, Version 1.0. (See 
  3  # accompanying file LICENSE_1_0.txt or copy at 
  4  # http://www.boost.org/LICENSE_1_0.txt) 
  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