Skip to content

Commit 92a77df

Browse files
committed
Implemented injected constructors.
Eliminated _DEBUG redefinition warning for CWPro8. [SVN r20126]
1 parent 4f2dbed commit 92a77df

File tree

11 files changed

+561
-124
lines changed

11 files changed

+561
-124
lines changed
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 CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
7+
# define CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
8+
9+
namespace boost { namespace python { namespace converter {
10+
11+
// A ResultConverter base class used to indicate that this result
12+
// converter should be constructed with the original Python argument
13+
// list.
14+
struct context_result_converter {};
15+
16+
}}} // namespace boost::python::converter
17+
18+
#endif // CONTEXT_RESULT_CONVERTER_DWA2003917_HPP

include/boost/python/default_call_policies.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,21 @@ struct default_call_policies
3131
{
3232
// Ownership of this argument tuple will ultimately be adopted by
3333
// the caller.
34-
static PyObject* precall(PyObject* args_)
34+
template <class ArgumentPackage>
35+
static bool precall(ArgumentPackage const&)
3536
{
36-
Py_INCREF(args_);
37-
return args_;
37+
return true;
3838
}
3939

4040
// Pass the result through
41-
static PyObject* postcall(PyObject* args_, PyObject* result)
41+
template <class ArgumentPackage>
42+
static PyObject* postcall(ArgumentPackage const&, PyObject* result)
4243
{
4344
return result;
4445
}
4546

4647
typedef default_result_converter result_converter;
48+
typedef PyObject* argument_package;
4749
};
4850

4951
struct default_result_converter

include/boost/python/detail/caller.hpp

Lines changed: 75 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@
99
# ifndef CALLER_DWA20021121_HPP
1010
# define CALLER_DWA20021121_HPP
1111

12-
# include <boost/compressed_pair.hpp>
13-
14-
# include <boost/mpl/apply.hpp>
15-
# include <boost/mpl/if.hpp>
16-
# include <boost/mpl/size.hpp>
17-
# include <boost/mpl/at.hpp>
18-
# include <boost/type_traits/is_same.hpp>
19-
2012
# include <boost/python/type_id.hpp>
2113
# include <boost/python/handle.hpp>
2214

@@ -25,6 +17,7 @@
2517
# include <boost/python/detail/preprocessor.hpp>
2618

2719
# include <boost/python/arg_from_python.hpp>
20+
# include <boost/python/converter/context_result_converter.hpp>
2821

2922
# include <boost/preprocessor/iterate.hpp>
3023
# include <boost/preprocessor/cat.hpp>
@@ -34,8 +27,39 @@
3427
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
3528
# include <boost/preprocessor/repetition/repeat.hpp>
3629

30+
# include <boost/compressed_pair.hpp>
31+
32+
# include <boost/type_traits/is_same.hpp>
33+
# include <boost/type_traits/is_convertible.hpp>
34+
35+
# include <boost/mpl/apply.hpp>
36+
# include <boost/mpl/apply_if.hpp>
37+
# include <boost/mpl/identity.hpp>
38+
# include <boost/mpl/size.hpp>
39+
# include <boost/mpl/at.hpp>
40+
# include <boost/mpl/int.hpp>
41+
3742
namespace boost { namespace python { namespace detail {
3843

44+
# if 0 // argpkg
45+
template <class N>
46+
inline PyObject* get(N, PyObject* const& args_)
47+
{
48+
return PyTuple_GET_ITEM(args_,N::value);
49+
}
50+
# else
51+
template <unsigned N>
52+
inline PyObject* get(PyObject* const& args_ BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(unsigned,N))
53+
{
54+
return PyTuple_GET_ITEM(args_,N);
55+
}
56+
# endif
57+
58+
inline unsigned arity(PyObject* const& args_)
59+
{
60+
return PyTuple_GET_SIZE(args_);
61+
}
62+
3963
// This "result converter" is really just used as
4064
// a dispatch tag to invoke(...), selecting the appropriate
4165
// implementation
@@ -46,15 +70,34 @@ typedef int void_result_to_python;
4670
// converting the result to python.
4771
template <class Policies, class Result>
4872
struct select_result_converter
49-
: mpl::if_<
73+
: mpl::apply_if<
5074
is_same<Result,void>
51-
, void_result_to_python
52-
, typename mpl::apply1<typename Policies::result_converter,Result>::type*
75+
, mpl::identity<void_result_to_python>
76+
, mpl::apply1<typename Policies::result_converter,Result>
5377
>
5478
{
5579
};
5680

57-
81+
template <class ArgPackage, class ResultConverter>
82+
inline ResultConverter create_result_converter(
83+
ArgPackage const& args_
84+
, ResultConverter*
85+
, converter::context_result_converter*
86+
)
87+
{
88+
return ResultConverter(args_);
89+
}
90+
91+
template <class ArgPackage, class ResultConverter>
92+
inline ResultConverter create_result_converter(
93+
ArgPackage const& args_
94+
, ResultConverter*
95+
, ...
96+
)
97+
{
98+
return ResultConverter();
99+
}
100+
58101
template <unsigned> struct caller_arity;
59102

60103
template <class F, class CallPolicies, class Sig>
@@ -63,12 +106,21 @@ struct caller;
63106
# define BOOST_PYTHON_NEXT(init,name,n) \
64107
typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n;
65108

109+
# if 0 // argpkg
66110
# define BOOST_PYTHON_ARG_CONVERTER(n) \
67111
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
68112
typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \
69-
c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \
113+
c_t##n c##n(get(mpl::int_<n>(), inner_args)); \
70114
if (!c##n.convertible()) \
71115
return 0;
116+
# else
117+
# define BOOST_PYTHON_ARG_CONVERTER(n) \
118+
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
119+
typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \
120+
c_t##n c##n(get<n>(inner_args)); \
121+
if (!c##n.convertible()) \
122+
return 0;
123+
# endif
72124

73125
# define BOOST_PP_ITERATION_PARAMS_1 \
74126
(3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>))
@@ -142,24 +194,26 @@ struct caller_arity<N>
142194
typedef typename mpl::begin<Sig>::type first;
143195
typedef typename first::type result_t;
144196
typedef typename select_result_converter<Policies, result_t>::type result_converter;
197+
typedef typename Policies::argument_package argument_package;
198+
199+
argument_package inner_args(args_);
200+
145201
# if N
146202
# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
147203
# define BOOST_PP_LOCAL_LIMITS (0, N-1)
148204
# include BOOST_PP_LOCAL_ITERATE()
149205
# endif
150206
// all converters have been checked. Now we can do the
151207
// precall part of the policy
152-
PyObject* inner_args = m_data.second().precall(args_);
153-
if (inner_args == 0)
208+
if (!m_data.second().precall(inner_args))
154209
return 0;
155210

156-
// manage the inner arguments
157-
handle<> keeper(allow_null(inner_args));
158-
159-
typedef typename detail::invoke_tag<F>::type tag;
160-
161211
PyObject* result = detail::invoke(
162-
tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c));
212+
detail::invoke_tag<result_t,F>()
213+
, create_result_converter(args_, (result_converter*)0, (result_converter*)0)
214+
, m_data.first()
215+
BOOST_PP_ENUM_TRAILING_PARAMS(N, c)
216+
);
163217

164218
return m_data.second().postcall(inner_args, result);
165219
}

include/boost/python/detail/invoke.hpp

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,19 @@ namespace boost { namespace python { namespace detail {
4545
// invoke(...), selecting the appropriate implementation
4646
typedef int void_result_to_python;
4747

48-
// Trait forward declaration.
49-
template <class T> struct is_defaulted_virtual_fn;
50-
51-
// Tag types describing invocation methods
52-
struct fn_tag {};
53-
struct mem_fn_tag {};
48+
template <bool void_return, bool member>
49+
struct invoke_tag_ {};
5450

5551
// A metafunction returning the appropriate tag type for invoking an
56-
// object of type T.
57-
template <class T>
52+
// object of type F with return type R.
53+
template <class R, class F>
5854
struct invoke_tag
59-
: mpl::if_<
60-
is_member_function_pointer<T>
61-
, mem_fn_tag
62-
, fn_tag
55+
: invoke_tag_<
56+
is_same<R,void>::value
57+
, is_member_function_pointer<F>::value
6358
>
64-
{};
59+
{
60+
};
6561

6662
# define BOOST_PP_ITERATION_PARAMS_1 \
6763
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/invoke.hpp>))
@@ -75,26 +71,26 @@ struct invoke_tag
7571
# define N BOOST_PP_ITERATION()
7672

7773
template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
78-
inline PyObject* invoke(fn_tag, RC*, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
74+
inline PyObject* invoke(invoke_tag_<false,false>, RC const& rc, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
7975
{
80-
return RC()(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ));
76+
return rc(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ));
8177
}
8278

83-
template <class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
84-
inline PyObject* invoke(fn_tag, void_result_to_python, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
79+
template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
80+
inline PyObject* invoke(invoke_tag_<true,false>, RC const&, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
8581
{
8682
f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) );
8783
return none();
8884
}
8985

9086
template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
91-
inline PyObject* invoke(mem_fn_tag, RC*, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
87+
inline PyObject* invoke(invoke_tag_<false,true>, RC const& rc, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
9288
{
93-
return RC()( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) );
89+
return rc( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) );
9490
}
9591

96-
template <class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
97-
inline PyObject* invoke(mem_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
92+
template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
93+
inline PyObject* invoke(invoke_tag_<true,true>, RC const&, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
9894
{
9995
(tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT));
10096
return none();

include/boost/python/detail/signature.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@
99
# ifndef SIGNATURE_DWA20021121_HPP
1010
# define SIGNATURE_DWA20021121_HPP
1111

12-
# include <boost/mpl/at.hpp>
12+
# include <boost/python/type_id.hpp>
1313

1414
# include <boost/python/detail/preprocessor.hpp>
15+
# include <boost/python/detail/indirect_traits.hpp>
16+
1517
# include <boost/preprocessor/iterate.hpp>
1618
# include <boost/preprocessor/iteration/local.hpp>
1719

18-
# include <boost/python/type_id.hpp>
19-
20-
# include <boost/python/detail/indirect_traits.hpp>
20+
# include <boost/mpl/at.hpp>
21+
# include <boost/mpl/size.hpp>
2122

2223
namespace boost { namespace python { namespace detail {
2324

0 commit comments

Comments
 (0)