summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/python/test/extract.cpp
blob: 40584a0777e3cda7db0c660851edfc101b5c6a52 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python/extract.hpp>
#include <boost/python/list.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/implicit.hpp>
#include <string>
#include <boost/lexical_cast.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include "test_class.hpp"

using namespace boost::python;

typedef test_class<> X;

bool extract_bool(object x) { return extract<bool>(x); }

boost::python::list extract_list(object x)
{
    extract<list> get_list((x));

    // Make sure we always have the right idea about whether it's a list
    bool is_list_1 = get_list.check();
    bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type);
    if (is_list_1 != is_list_2) {
        throw std::runtime_error("is_list_1 == is_list_2 failure.");
    }
    return get_list();
}

char const* extract_cstring(object x)
{
    return extract<char const*>(x);
}

std::string extract_string(object x)
{
    std::string s = extract<std::string>(x);
    return s;
}

std::string const& extract_string_cref(object x)
{
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
# pragma warning(push)
# pragma warning(disable:4172) // msvc lies about returning a reference to temporary
#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 900
# pragma warning(push)
# pragma warning(disable:473) // intel/win32 does too
#endif 
    
    return extract<std::string const&>(x);
    
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 800
# pragma warning(pop)
#endif 
}

X extract_X(object x)
{
    return extract<X>(x);
}

X* extract_X_ptr(object x) { return extract<X*>(x); }

X& extract_X_ref(object x)
{
    extract<X&> get_x(x);
    return get_x;
}

int double_X(object n)
{
    extract<X> x(n);
    return x().value() + x().value();
}

bool check_bool(object x) { return extract<bool>(x).check(); }
bool check_list(object x) { return extract<list>(x).check(); }
bool check_cstring(object x) { return extract<char const*>(x).check(); }
bool check_string(object x) { return extract<std::string>(x).check(); }
bool check_string_cref(object x) { return extract<std::string const&>(x).check(); }
bool check_X(object x) { return extract<X>(x).check(); }
bool check_X_ptr(object x) { return extract<X*>(x).check(); }
bool check_X_ref(object x) { return extract<X&>(x).check(); }

std::string x_rep(X const& x)
{
    return "X("  + boost::lexical_cast<std::string>(x.value()) + ")";
}

BOOST_PYTHON_MODULE(extract_ext)
{
    implicitly_convertible<int, X>();

    def("extract_bool", extract_bool);
    def("extract_list", extract_list);
    def("extract_cstring", extract_cstring);
    def("extract_string", extract_string);
    def("extract_string_cref", extract_string_cref, return_value_policy<reference_existing_object>());
    def("extract_X", extract_X);
    def("extract_X_ptr", extract_X_ptr, return_value_policy<reference_existing_object>());
    def("extract_X_ref", extract_X_ref, return_value_policy<reference_existing_object>());

    def("check_bool", check_bool);
    def("check_list", check_list);
    def("check_cstring", check_cstring);
    def("check_string", check_string);
    def("check_string_cref", check_string_cref);
    def("check_X", check_X);
    def("check_X_ptr", check_X_ptr);
    def("check_X_ref", check_X_ref);

    def("double_X", double_X);

    def("count_Xs", &X::count);
        ;

    object x_class(
        class_<X>("X", init<int>())
            .def( "__repr__", x_rep));
        
    // Instantiate an X object through the Python interface
    object x_obj = x_class(3);

    // Get the C++ object out of the Python object
    X const& x = extract<X&>(x_obj);
    if (x.value() != 3) {
        throw std::runtime_error("x.value() == 3 failure.");
    }
}


#include "module_tail.cpp"