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