GCC Code Coverage Report
Directory: emc/rs274ngc/ Exec Total Coverage
File: emc/rs274ngc/array1.hh Lines: 12 30 40.0 %
Date: 2016-10-27 Branches: 57 192 29.7 %

Line Exec Source
1
// Copyright 2004 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
#ifndef __array_1_pyplusplus_hpp__
7
#define __array_1_pyplusplus_hpp__
8
9
#include <boost/python/iterator.hpp>
10
#include <boost/python/enum.hpp>
11
#include <boost/python/object.hpp>
12
#include <boost/python/scope.hpp>
13
#include <boost/python/converter/registry.hpp>
14
#include <stdexcept>
15
#include <type_traits>
16
17
#include <iostream>
18
19
//1 - dimension
20
namespace pyplusplus{ namespace containers{ namespace static_sized{
21
22
inline void
23
raise_on_out_of_range( long unsigned int size, long unsigned int index ){
24
    if( size <= index ){
25
        throw std::out_of_range("index out of range");
26
    }
27
}
28
29
namespace details{
30
31
template<class T>
32
struct is_immutable{
33
    enum { value =
34
        ( std::is_same< T, std::string >::value )
35
                  || ( std::is_same< T, std::wstring >::value )
36
                  || ( std::is_fundamental< T >::value )
37
                  || ( std::is_enum< T >::value ) };
38
};
39
40
template<class T>
41
680
bool is_registered(){
42
    namespace bpl = boost::python;
43
680
    bpl::handle<> class_obj( bpl::objects::registered_class_object( bpl::type_id< T >()));
44
680
    return class_obj.get() ? true : false;
45
}
46
47
template< class T >
48
68
void register_alias( const char* name ){
49
    namespace bpl = boost::python;
50
68
    bpl::handle<> class_obj( bpl::objects::registered_class_object( bpl::type_id< T >()));
51
272
    boost::python::scope().attr( name ) = bpl::object( class_obj );
52
68
}
53
54
}//details
55
56
template< class TItemType, long unsigned int size >
57
struct const_array_1_t{
58
59
    typedef BOOST_DEDUCED_TYPENAME boost::call_traits<const TItemType>::param_type param_type;
60
61
    typedef typename std::conditional<
62
            details::is_immutable<TItemType>::value
63
            , TItemType
64
            , param_type
65
        >::type reference_type;
66
67
    const_array_1_t( TItemType const * const data )
68
    : m_data( data ){
69
        if( !data ){
70
            throw std::runtime_error( "const_array_1_t: pointer to null has been recieved." );
71
        }
72
    }
73
74
    long unsigned int len() const {
75
        return size;
76
    }
77
78
    reference_type item_ref( long unsigned int index ) const{
79
        raise_on_out_of_range( size, index );
80
        return m_data[index];
81
    }
82
83
private:
84
85
    TItemType const * m_data;
86
87
};
88
89
template< class TItemType, long unsigned int size >
90
struct array_1_t{
91
92
    typedef BOOST_DEDUCED_TYPENAME boost::call_traits<const TItemType>::param_type param_type;
93
94
    typedef typename std::conditional<
95
            details::is_immutable<TItemType>::value
96
            , TItemType
97
            , param_type
98
        >::type reference_type;
99
100
    array_1_t( TItemType * data )
101
    : m_data( data ){
102
        if( !data ){
103
            throw std::runtime_error( "array_1_t: pointer to null has been recieved." );
104
        }
105
    }
106
107
    long unsigned int len() const {
108
        return size;
109
    }
110
111
    reference_type item_ref( long unsigned int index ) const{
112
        raise_on_out_of_range( size, index );
113
        return m_data[index];
114
    }
115
116
    void
117
    set_item( long unsigned int index, reference_type new_value ){
118
        raise_on_out_of_range( size, index );
119
        m_data[index] = new_value;
120
    }
121
122
private:
123
124
    TItemType* m_data;
125
126
};
127
128
template< class TItemType
129
          , long unsigned int size
130
          , typename CallPolicies=boost::python::default_call_policies >
131
struct register_const_array_1{
132
    register_const_array_1(const char* name){
133
        namespace bpl = boost::python;
134
        typedef const_array_1_t< TItemType, size > wrapper_t;
135
136
        if( details::is_registered< wrapper_t >() ){
137
            details::register_alias< wrapper_t >( name );
138
        }
139
        else{
140
            bpl::class_< wrapper_t >( name, bpl::no_init )
141
                .def( "__getitem__"
142
                      , &wrapper_t::item_ref
143
                      , ( bpl::arg("index") )
144
                      , CallPolicies() )
145
                .def( "__len__", &wrapper_t::len );
146
        }
147
    }
148
};
149
150
template< class TItemType
151
          , long unsigned int size
152
          , typename CallPolicies=boost::python::default_call_policies >
153
struct register_array_1{
154
680
    register_array_1(const char* name){
155
        namespace bpl = boost::python;
156
        typedef array_1_t< TItemType, size > wrapper_t;
157
680
        if( details::is_registered< wrapper_t >() ){
158
68
            details::register_alias< wrapper_t >( name );
159
        }
160
        else{
161
4284
            bpl::class_< wrapper_t >( name, bpl::no_init )
162
                .def( "__getitem__"
163
                      , &wrapper_t::item_ref
164
                      , ( bpl::arg("index") )
165
                      , CallPolicies() )
166
                .def( "__setitem__"
167
                      , &wrapper_t::set_item
168
                      , ( bpl::arg("index"), bpl::arg("value") )
169
                      , CallPolicies()  )
170
                .def( "__len__", &wrapper_t::len );
171
        }
172
680
    }
173
};
174
175
} /*pyplusplus*/ } /*containers*/ } /*static_sized*/
176
177
178
#endif//__array_1_pyplusplus_hpp__