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