Skip to content

Commit 9c66509

Browse files
committed
Use def_visitor to simplify class def(...) handling.
Workarounds for intel6 and vc6. [SVN r19533]
1 parent d482d57 commit 9c66509

File tree

11 files changed

+254
-130
lines changed

11 files changed

+254
-130
lines changed

include/boost/python/class.hpp

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
# include <boost/python/object/add_to_namespace.hpp>
3939
# include <boost/python/object/class_converters.hpp>
4040

41-
# include <boost/python/detail/string_literal.hpp>
4241
# include <boost/python/detail/overloads_fwd.hpp>
4342
# include <boost/python/detail/operator_id.hpp>
4443
# include <boost/python/detail/member_function_cast.hpp>
@@ -59,11 +58,9 @@
5958

6059
namespace boost { namespace python {
6160

62-
enum no_init_t { no_init };
61+
template <class DerivedVisitor> struct def_visitor;
6362

64-
struct def_arg_base {};
65-
template <class Derived>
66-
struct def_arg : def_arg_base {}; // Generic visitor
63+
enum no_init_t { no_init };
6764

6865
namespace detail
6966
{
@@ -90,9 +87,6 @@ namespace detail
9087
template <class T1, class T2, class T3>
9188
struct has_noncopyable;
9289

93-
template <detail::operator_id, class L, class R>
94-
struct operator_;
95-
9690
// Register to_python converters for a class T. The first argument
9791
// will be mpl::true_ unless noncopyable was specified as a
9892
// class_<...> template parameter. The 2nd argument is a pointer to
@@ -249,7 +243,7 @@ class class_ : public objects::class_base
249243
: base(name, id_vector::size, id_vector().ids)
250244
{
251245
this->register_();
252-
define_init(*this, i.derived());
246+
this->def(i);
253247
this->set_instance_size(holder_selector::additional_size());
254248
}
255249

@@ -259,26 +253,18 @@ class class_ : public objects::class_base
259253
: base(name, id_vector::size, id_vector().ids, doc)
260254
{
261255
this->register_();
262-
define_init(*this, i.derived());
256+
this->def(i);
263257
this->set_instance_size(holder_selector::additional_size());
264258
}
265259

266260
public: // member functions
267261

268-
// Define additional constructors
269-
template <class DerivedT>
270-
self& def(init_base<DerivedT> const& i)
271-
{
272-
define_init(*this, i.derived());
273-
return *this;
274-
}
275-
276262
// Generic visitation
277263
template <class Derived>
278-
self& def(def_arg<Derived> const& visitor)
264+
self& def(def_visitor<Derived> const& visitor)
279265
{
280-
static_cast<Derived const&>(visitor).visit(*this);
281-
return *this;
266+
visitor.visit(*this);
267+
return *this;
282268
}
283269

284270
// Wrap a member function or a non-member function which can take
@@ -324,13 +310,6 @@ class class_ : public objects::class_base
324310
return *this;
325311
}
326312

327-
template <detail::operator_id id, class L, class R>
328-
self& def(detail::operator_<id,L,R> const& op)
329-
{
330-
typedef detail::operator_<id,L,R> op_t;
331-
return this->def(op.name(), &op_t::template apply<T>::execute);
332-
}
333-
334313
//
335314
// Data member access
336315
//
@@ -476,42 +455,27 @@ class class_ : public objects::class_base
476455
inline void register_() const;
477456

478457
//
479-
// These three overloads discriminate between def() as applied to
480-
// things which are already wrapped into callable python::object
481-
// instances, a generic visitor, and everything else.
458+
// These two overloads discriminate between def() as applied to a
459+
// generic visitor and everything else.
482460
//
483-
template <class F, class A1>
461+
template <class Helper, class LeafVisitor, class Visitor>
484462
inline void def_impl(
485463
char const* name
486-
, F f
487-
, detail::def_helper<A1> const& helper
488-
, object const*)
464+
, LeafVisitor
465+
, Helper const& helper
466+
, def_visitor<Visitor> const* v
467+
)
489468
{
490-
// It's too late to specify anything other than docstrings, if
491-
// the callable object is already wrapped.
492-
BOOST_STATIC_ASSERT(
493-
(is_same<char const*,A1>::value
494-
|| detail::is_string_literal<A1>::value));
495-
496-
objects::add_to_namespace(*this, name, f, helper.doc());
469+
v->visit(*this, name, helper);
497470
}
498471

499-
template <class Derived, class A1>
500-
inline void def_impl(
501-
char const* name
502-
, def_arg<Derived> const& visitor
503-
, detail::def_helper<A1> const& helper
504-
, def_arg_base const*)
505-
{
506-
static_cast<Derived const&>(visitor).visit(*this, name);
507-
}
508-
509472
template <class Fn, class Helper>
510473
inline void def_impl(
511474
char const* name
512-
, Fn fn
513-
, Helper const& helper
514-
, ...)
475+
, Fn fn
476+
, Helper const& helper
477+
, ...
478+
)
515479
{
516480
objects::add_to_namespace(
517481
*this, name,
@@ -578,9 +542,11 @@ class class_ : public objects::class_base
578542
, ...)
579543
{
580544
this->def_impl(
581-
name, fn
582-
, detail::def_helper<A1>(a1)
583-
, &fn);
545+
name
546+
, fn
547+
, detail::def_helper<A1>(a1)
548+
, &fn
549+
);
584550

585551
}
586552
};
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright David Abrahams 2003. Permission to copy, use,
2+
// modify, sell and distribute this software is granted provided this
3+
// copyright notice appears in all copies. This software is provided
4+
// "as is" without express or implied warranty, and with no claim as
5+
// to its suitability for any purpose.
6+
#ifndef DEF_VISITOR_DWA2003810_HPP
7+
# define DEF_VISITOR_DWA2003810_HPP
8+
9+
# include <boost/python/detail/prefix.hpp>
10+
# include <boost/detail/workaround.hpp>
11+
12+
namespace boost { namespace python {
13+
14+
template <class DerivedVisitor> class def_visitor;
15+
template <class T, class X1, class X2, class X3> class class_;
16+
17+
class def_visitor_access
18+
{
19+
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
20+
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
21+
// Tasteless as this may seem, making all members public allows member templates
22+
// to work in the absence of member template friends.
23+
public:
24+
# else
25+
template <class Derived> friend class def_visitor;
26+
# endif
27+
28+
// unnamed visit, c.f. init<...>, container suites
29+
template <class V, class classT>
30+
static void visit(V const& v, classT& c)
31+
{
32+
v.derived_visitor().visit(c);
33+
}
34+
35+
// named visit, c.f. object, pure_virtual
36+
template <class V, class classT, class OptionalArgs>
37+
static void visit(
38+
V const& v
39+
, classT& c
40+
, char const* name
41+
, OptionalArgs const& options
42+
)
43+
{
44+
v.derived_visitor().visit(c, name, options);
45+
}
46+
47+
};
48+
49+
50+
template <class DerivedVisitor>
51+
class def_visitor
52+
{
53+
friend class def_visitor_access;
54+
55+
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
56+
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
57+
// Tasteless as this may seem, making all members public allows member templates
58+
// to work in the absence of member template friends.
59+
public:
60+
# else
61+
template <class T, class X1, class X2, class X3> friend class class_;
62+
# endif
63+
64+
// unnamed visit, c.f. init<...>, container suites
65+
template <class classT>
66+
void visit(classT& c) const
67+
{
68+
def_visitor_access::visit(*this, c);
69+
}
70+
71+
// named visit, c.f. object, pure_virtual
72+
template <class classT, class OptionalArgs>
73+
void visit(classT& c, char const* name, OptionalArgs const& options) const
74+
{
75+
def_visitor_access::visit(*this, c, name, options);
76+
}
77+
78+
protected:
79+
DerivedVisitor const& derived_visitor() const
80+
{
81+
return static_cast<DerivedVisitor const&>(*this);
82+
}
83+
};
84+
85+
}} // namespace boost::python
86+
87+
#endif // DEF_VISITOR_DWA2003810_HPP

include/boost/python/detail/def_helper.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# include <boost/mpl/apply.hpp>
1919
# include <boost/tuple/tuple.hpp>
2020
# include <boost/python/detail/not_specified.hpp>
21+
# include <boost/python/detail/def_helper_fwd.hpp>
2122

2223
namespace boost { namespace python {
2324

@@ -143,7 +144,7 @@ namespace detail
143144
// are expected to be the types of the actual (optional) arguments
144145
// passed to def().
145146
//
146-
template <class T1, class T2 = not_specified, class T3 = not_specified, class T4 = not_specified>
147+
template <class T1, class T2, class T3, class T4>
147148
struct def_helper
148149
{
149150
// A tuple type which begins with references to the supplied
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright David Abrahams 2003. Permission to copy, use,
2+
// modify, sell and distribute this software is granted provided this
3+
// copyright notice appears in all copies. This software is provided
4+
// "as is" without express or implied warranty, and with no claim as
5+
// to its suitability for any purpose.
6+
#ifndef DEF_HELPER_FWD_DWA2003810_HPP
7+
# define DEF_HELPER_FWD_DWA2003810_HPP
8+
9+
# include <boost/python/detail/not_specified.hpp>
10+
11+
namespace boost { namespace python { namespace detail {
12+
13+
template <class T1, class T2 = not_specified, class T3 = not_specified, class T4 = not_specified>
14+
struct def_helper;
15+
16+
}}} // namespace boost::python::detail
17+
18+
#endif // DEF_HELPER_FWD_DWA2003810_HPP

include/boost/python/indexing/indexing_suite.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#ifndef INDEXING_SUITE_JDG20036_HPP
88
# define INDEXING_SUITE_JDG20036_HPP
99

10-
# include <boost/python/class.hpp>
10+
# include <boost/python/def_visitor.hpp>
1111
# include <boost/python/register_ptr_to_python.hpp>
1212
# include <boost/python/indexing/detail/indexing_suite_detail.hpp>
1313
# include <boost/python/indexing/py_container_utils.hpp>
@@ -105,7 +105,7 @@ namespace boost { namespace python {
105105
, class Index = typename Container::size_type
106106
>
107107
class indexing_suite
108-
: public def_arg<
108+
: public def_visitor<
109109
indexing_suite<
110110
Container
111111
, DerivedPolicies
@@ -162,7 +162,7 @@ namespace boost { namespace python {
162162
, Index> >::type
163163
slice_handler;
164164

165-
public:
165+
private: // def visitation
166166

167167
template <class Class>
168168
void visit(Class& cl) const
@@ -183,7 +183,9 @@ namespace boost { namespace python {
183183
;
184184
}
185185

186-
private:
186+
friend class python::def_visitor_access;
187+
188+
private:
187189

188190
static object
189191
base_get_item(back_reference<Container&> container, PyObject* i)

0 commit comments

Comments
 (0)