Skip to content

Commit 61ba4cd

Browse files
author
David Hawkes
committed
Sub-module / sub-class and API changes
[SVN r14488]
1 parent 244e0fa commit 61ba4cd

File tree

15 files changed

+3203
-19
lines changed

15 files changed

+3203
-19
lines changed

Jamfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dll bpl
2323
src/object/function.cpp
2424
src/object/inheritance.cpp
2525
src/object/life_support.cpp
26+
src/py_interface.cpp
2627
src/errors.cpp
2728
src/module.cpp
2829
src/objects2.cpp

include/boost/python/class.hpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# include <boost/python/type_id.hpp>
1515
# include <boost/python/detail/wrap_function.hpp>
1616
# include <boost/python/detail/member_function_cast.hpp>
17+
# include <boost/python/detail/module_base.hpp>
1718
# include <boost/python/object/class_converters.hpp>
1819
# include <boost/type_traits/ice.hpp>
1920
# include <boost/type_traits/same_traits.hpp>
@@ -86,12 +87,12 @@ class class_ : public objects::class_base
8687
public:
8788
// Automatically derive the class name - only works on some
8889
// compilers because type_info::name is sometimes mangled (gcc)
89-
class_();
90+
class_(base const& parent_class = empty_class_base());
9091

9192
// Construct with the class name. [ Would have used a default
9293
// argument but gcc-2.95.2 choked on typeid(T).name() as a default
9394
// parameter value]
94-
class_(char const* name);
95+
class_(char const* name, base const& parent_class = empty_class_base());
9596

9697

9798
// Wrap a member function or a non-member function which can take
@@ -195,6 +196,22 @@ class class_ : public objects::class_base
195196

196197
self& setattr(char const* name, handle<> const&);
197198

199+
// add to module
200+
self& add(module &m)
201+
{
202+
// redundant
203+
// m.add(*this);
204+
return *this;
205+
}
206+
207+
// add to current module
208+
self& add()
209+
{
210+
// redundant
211+
// boost::python::add(*this);
212+
return *this;
213+
}
214+
198215
private: // types
199216
typedef objects::class_id class_id;
200217

@@ -231,7 +248,7 @@ class class_ : public objects::class_base
231248
// implementations
232249
//
233250
template <class T, class X1, class X2, class X3>
234-
inline class_<T,X1,X2,X3>::class_()
251+
inline class_<T,X1,X2,X3>::class_(base const& parent_class)
235252
: base(typeid(T).name(), id_vector::size, id_vector().ids)
236253
{
237254
// register converters
@@ -241,10 +258,16 @@ inline class_<T,X1,X2,X3>::class_()
241258
mpl::bool_t<is_copyable>()
242259
, objects::select_holder<T,held_type>((held_type*)0).get()
243260
, this->object());
261+
262+
// get the context to add the class to
263+
handle<> parent(parent_class.object() ? handle<>(parent_class.object()) :
264+
base::get_class_context_object(typeid(T).name(), object()));
265+
// add the class to the current module
266+
boost::python::detail::module_base::add(object(), parent);
244267
}
245268

246269
template <class T, class X1, class X2, class X3>
247-
inline class_<T,X1,X2,X3>::class_(char const* name)
270+
inline class_<T,X1,X2,X3>::class_(char const* name, base const& parent_class)
248271
: base(name, id_vector::size, id_vector().ids)
249272
{
250273
// register converters
@@ -254,8 +277,13 @@ inline class_<T,X1,X2,X3>::class_(char const* name)
254277
mpl::bool_t<is_copyable>()
255278
, objects::select_holder<T,held_type>((held_type*)0).get()
256279
, this->object());
257-
}
258280

281+
// get the context to add the class to
282+
handle<> parent(parent_class.object() ? handle<>(parent_class.object()) :
283+
base::get_class_context_object(name, object()));
284+
// add the class to the current module
285+
boost::python::detail::module_base::add(object(), parent);
286+
}
259287

260288
template <class T, class X1, class X2, class X3>
261289
inline class_<T,X1,X2,X3>& class_<T,X1,X2,X3>::add_property(char const* name, handle<> const& fget)

include/boost/python/detail/module_base.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
namespace boost { namespace python { namespace detail {
1212

13+
class module_info;
14+
1315
class BOOST_PYTHON_DECL module_base
1416
{
1517
public:
@@ -21,14 +23,22 @@ class BOOST_PYTHON_DECL module_base
2123
void setattr(const char* name, PyObject*);
2224
void setattr(const char* name, handle<> const&);
2325
void add(type_handle const&); // just use the type's name
26+
static module_info* get_module_info();
27+
static void set_module_info(module_info& mi);
28+
static handle<> get_prior_module();
29+
static void set_prior_module(handle<> const& m);
30+
static void add(type_handle const& class_obj, handle<> const& context);
2431

2532
// Return a reference to the Python module object being built
2633
inline handle<> object() const;
2734

2835
protected:
36+
module_base(handle<> const &m) : m_module(m) {}
2937
void add_class(type_handle const& class_obj);
38+
void add_class(type_handle const& class_obj, handle<> const& context);
3039

3140
private:
41+
static module_info*& get_module_info_ref();
3242
handle<> m_module;
3343
static PyMethodDef initial_methods[1];
3444
};
@@ -41,6 +51,12 @@ inline handle<> module_base::object() const
4151
return m_module;
4252
}
4353

54+
inline void module_base::add(type_handle const& class_obj, handle<> const& context)
55+
{
56+
module_base mb(get_prior_module());
57+
mb.add_class(class_obj, context);
58+
}
59+
4460
}}} // namespace boost::python::detail
4561

4662
#endif // MODULE_BASE_DWA2002227_HPP
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright David Hawkes 2002.
2+
// Permission is hereby granted to copy, use and modify this software
3+
// for any purpose, including commercial distribution, provided this
4+
// copyright notice is not removed. No warranty WHATSOEVER is provided with this
5+
// software. Any user(s) accepts this software "as is" and as such they will not
6+
// bind the author(s) to any claim of suitabilty for any purpose.
7+
8+
#ifndef MODULE_INFO
9+
# define MODULE_INFO
10+
11+
#include <boost/python/object.hpp>
12+
13+
namespace boost { namespace python { namespace detail {
14+
15+
class module_info
16+
{
17+
public:
18+
module_info(const char *name)
19+
{
20+
m_module_name = name;
21+
}
22+
void set_module(object const& m)
23+
{
24+
if(!m_primary_module)
25+
m_primary_module = m;
26+
}
27+
object const& get_module() const
28+
{
29+
return m_primary_module;
30+
}
31+
void set_prior_module(object const& m)
32+
{
33+
m_prior_module = m;
34+
}
35+
object const& get_prior_module() const
36+
{
37+
return m_prior_module;
38+
}
39+
const char* get_module_name() const
40+
{
41+
return m_module_name;
42+
}
43+
private:
44+
object m_primary_module;
45+
object m_prior_module;
46+
const char* m_module_name;
47+
};
48+
49+
}}}
50+
51+
#endif // MODULE_INFO

include/boost/python/detail/module_init.hpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,50 @@
88

99
# ifndef BOOST_PYTHON_MODULE_INIT
1010

11+
# define PRE_INIT_FUNC(name) \
12+
void init_module_base_##name() \
13+
{ \
14+
boost::python::detail::module_info mi(#name); \
15+
boost::python::detail::module_base::set_module_info(mi); \
16+
boost::python::module(); \
17+
init_module_##name(); \
18+
}
19+
1120
# if defined(_WIN32) || defined(__CYGWIN__)
1221

1322
# define BOOST_PYTHON_MODULE_INIT(name) \
1423
void init_module_##name(); \
24+
PRE_INIT_FUNC(name) \
1525
extern "C" __declspec(dllexport) void init##name() \
1626
{ \
17-
boost::python::handle_exception(&init_module_##name); \
27+
boost::python::handle_exception(&init_module_base_##name); \
1828
} \
1929
void init_module_##name()
2030

2131
# elif defined(_AIX)
2232

2333
# include <boost/python/detail/aix_init_module.hpp>
2434
# define BOOST_PYTHON_MODULE_INIT(name) \
35+
PRE_INIT_FUNC(name) \
2536
void init_module_##name(); \
2637
extern "C" \
2738
{ \
2839
extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \
2940
void init##name() \
3041
{ \
31-
boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \
42+
boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_base_##name); \
3243
} \
3344
} \
3445
void init_module_##name()
3546

3647
# else
3748

3849
# define BOOST_PYTHON_MODULE_INIT(name) \
50+
PRE_INIT_FUNC(name) \
3951
void init_module_##name(); \
4052
extern "C" void init##name() \
4153
{ \
42-
boost::python::handle_exception(&init_module_##name); \
54+
boost::python::handle_exception(&init_module_base_##name); \
4355
} \
4456
void init_module_##name()
4557

include/boost/python/module.hpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# include <boost/python/class_fwd.hpp>
1414
# include <boost/python/detail/module_base.hpp>
1515
# include <boost/python/detail/module_init.hpp>
16+
# include <boost/python/detail/module_info.hpp>
1617

1718
namespace boost { namespace python {
1819

@@ -21,7 +22,7 @@ class module : public detail::module_base
2122
public:
2223
typedef detail::module_base base;
2324

24-
module(const char* name)
25+
module(const char* name = "")
2526
: base(name) {}
2627

2728
// Add elements to the module
@@ -33,7 +34,8 @@ class module : public detail::module_base
3334
template <class T1, class T2 , class T3, class T4>
3435
module& add(class_<T1,T2,T3,T4> const& c)
3536
{
36-
this->add_class(c.object());
37+
// redundant
38+
// this->add_class(c.object());
3739
return *this;
3840
}
3941

@@ -51,6 +53,14 @@ class module : public detail::module_base
5153
this->setattr(name, boost::python::make_function(fn, handler));
5254
return *this;
5355
}
56+
57+
static module get_prior_module()
58+
{
59+
return module(module_base::get_prior_module());
60+
}
61+
62+
private:
63+
module(handle<> const& m) : base(m) {}
5464
};
5565

5666
//
@@ -80,6 +90,19 @@ inline module& module::add(PyTypeObject* x)
8090
return *this;
8191
}
8292

93+
template <class Fn>
94+
inline void def(char const* name, Fn fn)
95+
{
96+
module::get_prior_module().def(name, fn);
97+
}
98+
99+
100+
template <class Fn, class ResultHandler>
101+
inline void def(char const* name, Fn fn, ResultHandler handler)
102+
{
103+
module::get_prior_module().def(name, fn, handler);
104+
}
105+
83106
}} // namespace boost::python
84107

85108
#endif // MODULE_DWA20011221_HPP

include/boost/python/object/class.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable
3939
void add_property(char const* name, handle<> const& fget);
4040
void add_property(char const* name, handle<> const& fget, handle<> const& fset);
4141
void setattr(char const* name, handle<> const&);
42+
static handle<> get_class_context_object(const char* name, type_handle const& class_obj);
43+
protected:
44+
static class_base const& empty_class_base();
4245
private:
46+
// construct an empty base class
47+
class_base();
4348
type_handle m_object;
4449
};
4550

include/boost/python/object_core.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ inline object::object(detail::borrowed_reference p)
325325
: object_base(python::incref((PyObject*)p))
326326
{}
327327

328-
329328
inline object::object(detail::new_reference p)
330329
: object_base(expect_non_null((PyObject*)p))
331330
{}

0 commit comments

Comments
 (0)