Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/python/test/pickle3.cpp @ 45

Last change on this file since 45 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 3.3 KB
Line 
1// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
2// Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
5/*
6    This example shows how to make an Extension Class "pickleable".
7
8    The world class below contains member data (secret_number) that
9    cannot be restored by any of the constructors. Therefore it is
10    necessary to provide the __getstate__/__setstate__ pair of pickle
11    interface methods.
12
13    The object's __dict__ is included in the result of __getstate__.
14    This requires more code (compare with pickle2.cpp), but is
15    unavoidable if the object's __dict__ is not always empty.
16
17    For more information refer to boost/libs/python/doc/pickle.html.
18 */
19
20#include <boost/python/module.hpp>
21#include <boost/python/def.hpp>
22#include <boost/python/class.hpp>
23#include <boost/python/tuple.hpp>
24#include <boost/python/dict.hpp>
25#include <boost/python/extract.hpp>
26#include <boost/python/back_reference.hpp>
27
28#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
29# define make_tuple boost::python::make_tuple
30#endif
31
32namespace { // Avoid cluttering the global namespace.
33
34  // A friendly class.
35  class world
36  {
37    public:
38      world(const std::string& country) : secret_number(0) {
39        this->country = country;
40      }
41      std::string greet() const { return "Hello from " + country + "!"; }
42      std::string get_country() const { return country; }
43      void set_secret_number(int number) { secret_number = number; }
44      int get_secret_number() const { return secret_number; }
45    private:
46      std::string country;
47      int secret_number;
48  };
49
50  struct world_pickle_suite : boost::python::pickle_suite
51  {
52    static
53    boost::python::tuple
54    getinitargs(const world& w)
55    {
56        using namespace boost::python;
57        return make_tuple(w.get_country());
58    }
59
60    static
61    boost::python::tuple
62    getstate(boost::python::object w_obj)
63    {
64        using namespace boost::python;
65        world const& w = extract<world const&>(w_obj)();
66
67        return make_tuple(w_obj.attr("__dict__"), w.get_secret_number());
68    }
69
70    static
71    void
72    setstate(boost::python::object w_obj, boost::python::tuple state)
73    {
74        using namespace boost::python;
75        world& w = extract<world&>(w_obj)();
76       
77        if (len(state) != 2)
78        {
79          PyErr_SetObject(PyExc_ValueError,
80                          ("expected 2-item tuple in call to __setstate__; got %s"
81                           % state).ptr()
82              );
83          throw_error_already_set();
84        }
85       
86        // restore the object's __dict__
87        dict d = extract<dict>(w_obj.attr("__dict__"))();
88        d.update(state[0]);
89       
90        // restore the internal state of the C++ object
91        long number = extract<long>(state[1]);
92        if (number != 42)
93            w.set_secret_number(number);
94    }
95
96    static bool getstate_manages_dict() { return true; }
97  };
98
99}
100
101BOOST_PYTHON_MODULE(pickle3_ext)
102{
103    boost::python::class_<world>(
104        "world", boost::python::init<const std::string&>())
105        .def("greet", &world::greet)
106        .def("get_secret_number", &world::get_secret_number)
107        .def("set_secret_number", &world::set_secret_number)
108        .def_pickle(world_pickle_suite())
109        ;
110}
Note: See TracBrowser for help on using the repository browser.