annotate DEPENDENCIES/generic/include/boost/python/make_constructor.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright David Abrahams 2001.
Chris@16 2 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 3 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 4 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5 #ifndef MAKE_CONSTRUCTOR_DWA20011221_HPP
Chris@16 6 # define MAKE_CONSTRUCTOR_DWA20011221_HPP
Chris@16 7
Chris@16 8 # include <boost/python/detail/prefix.hpp>
Chris@16 9
Chris@16 10 # include <boost/python/default_call_policies.hpp>
Chris@16 11 # include <boost/python/args.hpp>
Chris@16 12 # include <boost/python/object_fwd.hpp>
Chris@16 13
Chris@16 14 # include <boost/python/object/function_object.hpp>
Chris@16 15 # include <boost/python/object/make_holder.hpp>
Chris@16 16 # include <boost/python/object/pointer_holder.hpp>
Chris@16 17 # include <boost/python/converter/context_result_converter.hpp>
Chris@16 18
Chris@16 19 # include <boost/python/detail/caller.hpp>
Chris@16 20 # include <boost/python/detail/none.hpp>
Chris@16 21
Chris@16 22 # include <boost/mpl/size.hpp>
Chris@16 23 # include <boost/mpl/int.hpp>
Chris@16 24 # include <boost/mpl/push_front.hpp>
Chris@16 25 # include <boost/mpl/pop_front.hpp>
Chris@16 26 # include <boost/mpl/assert.hpp>
Chris@16 27
Chris@16 28 namespace boost { namespace python {
Chris@16 29
Chris@16 30 namespace detail
Chris@16 31 {
Chris@16 32 template <class T>
Chris@16 33 struct install_holder : converter::context_result_converter
Chris@16 34 {
Chris@16 35 install_holder(PyObject* args_)
Chris@16 36 : m_self(PyTuple_GetItem(args_, 0)) {}
Chris@16 37
Chris@16 38 PyObject* operator()(T x) const
Chris@16 39 {
Chris@16 40 dispatch(x, is_pointer<T>());
Chris@16 41 return none();
Chris@16 42 }
Chris@16 43
Chris@16 44 private:
Chris@16 45 template <class U>
Chris@16 46 void dispatch(U* x, mpl::true_) const
Chris@16 47 {
Chris@16 48 std::auto_ptr<U> owner(x);
Chris@16 49 dispatch(owner, mpl::false_());
Chris@16 50 }
Chris@16 51
Chris@16 52 template <class Ptr>
Chris@16 53 void dispatch(Ptr x, mpl::false_) const
Chris@16 54 {
Chris@16 55 typedef typename pointee<Ptr>::type value_type;
Chris@16 56 typedef objects::pointer_holder<Ptr,value_type> holder;
Chris@16 57 typedef objects::instance<holder> instance_t;
Chris@16 58
Chris@16 59 void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder));
Chris@16 60 try {
Chris@16 61 (new (memory) holder(x))->install(this->m_self);
Chris@16 62 }
Chris@16 63 catch(...) {
Chris@16 64 holder::deallocate(this->m_self, memory);
Chris@16 65 throw;
Chris@16 66 }
Chris@16 67 }
Chris@16 68
Chris@16 69 PyObject* m_self;
Chris@16 70 };
Chris@16 71
Chris@16 72 struct constructor_result_converter
Chris@16 73 {
Chris@16 74 template <class T>
Chris@16 75 struct apply
Chris@16 76 {
Chris@16 77 typedef install_holder<T> type;
Chris@16 78 };
Chris@16 79 };
Chris@16 80
Chris@16 81 template <class BaseArgs, class Offset>
Chris@16 82 struct offset_args
Chris@16 83 {
Chris@16 84 offset_args(BaseArgs base_) : base(base_) {}
Chris@16 85 BaseArgs base;
Chris@16 86 };
Chris@16 87
Chris@16 88 template <int N, class BaseArgs, class Offset>
Chris@16 89 inline PyObject* get(mpl::int_<N>, offset_args<BaseArgs,Offset> const& args_)
Chris@16 90 {
Chris@16 91 return get(mpl::int_<(N+Offset::value)>(), args_.base);
Chris@16 92 }
Chris@16 93
Chris@16 94 template <class BaseArgs, class Offset>
Chris@16 95 inline unsigned arity(offset_args<BaseArgs,Offset> const& args_)
Chris@16 96 {
Chris@16 97 return arity(args_.base) - Offset::value;
Chris@16 98 }
Chris@16 99
Chris@16 100 template <class BasePolicy_ = default_call_policies>
Chris@16 101 struct constructor_policy : BasePolicy_
Chris@16 102 {
Chris@16 103 constructor_policy(BasePolicy_ base) : BasePolicy_(base) {}
Chris@16 104
Chris@16 105 // If the BasePolicy_ supplied a result converter it would be
Chris@16 106 // ignored; issue an error if it's not the default.
Chris@16 107 #if defined _MSC_VER && _MSC_VER < 1300
Chris@16 108 typedef is_same<
Chris@16 109 typename BasePolicy_::result_converter
Chris@16 110 , default_result_converter
Chris@16 111 > same_result_converter;
Chris@16 112 //see above for explanation
Chris@16 113 BOOST_STATIC_ASSERT(same_result_converter::value) ;
Chris@16 114 #else
Chris@16 115 BOOST_MPL_ASSERT_MSG(
Chris@16 116 (is_same<
Chris@16 117 typename BasePolicy_::result_converter
Chris@16 118 , default_result_converter
Chris@16 119 >::value)
Chris@16 120 , MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
Chris@16 121 , (typename BasePolicy_::result_converter)
Chris@16 122 );
Chris@16 123 #endif
Chris@16 124 typedef constructor_result_converter result_converter;
Chris@16 125 typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
Chris@16 126 };
Chris@16 127
Chris@16 128 template <class InnerSignature>
Chris@16 129 struct outer_constructor_signature
Chris@16 130 {
Chris@16 131 typedef typename mpl::pop_front<InnerSignature>::type inner_args;
Chris@16 132 typedef typename mpl::push_front<inner_args,object>::type outer_args;
Chris@16 133 typedef typename mpl::push_front<outer_args,void>::type type;
Chris@16 134 };
Chris@16 135
Chris@16 136 // ETI workaround
Chris@16 137 template <>
Chris@16 138 struct outer_constructor_signature<int>
Chris@16 139 {
Chris@16 140 typedef int type;
Chris@16 141 };
Chris@16 142
Chris@16 143 //
Chris@16 144 // These helper functions for make_constructor (below) do the raw work
Chris@16 145 // of constructing a Python object from some invokable entity. See
Chris@16 146 // <boost/python/detail/caller.hpp> for more information about how
Chris@16 147 // the Sig arguments is used.
Chris@16 148 //
Chris@16 149 // @group make_constructor_aux {
Chris@16 150 template <class F, class CallPolicies, class Sig>
Chris@16 151 object make_constructor_aux(
Chris@16 152 F f // An object that can be invoked by detail::invoke()
Chris@16 153 , CallPolicies const& p // CallPolicies to use in the invocation
Chris@16 154 , Sig const& // An MPL sequence of argument types expected by F
Chris@16 155 )
Chris@16 156 {
Chris@16 157 typedef typename outer_constructor_signature<Sig>::type outer_signature;
Chris@16 158
Chris@16 159 typedef constructor_policy<CallPolicies> inner_policy;
Chris@16 160
Chris@16 161 return objects::function_object(
Chris@16 162 objects::py_function(
Chris@16 163 detail::caller<F,inner_policy,Sig>(f, inner_policy(p))
Chris@16 164 , outer_signature()
Chris@16 165 )
Chris@16 166 );
Chris@16 167 }
Chris@16 168
Chris@16 169 // As above, except that it accepts argument keywords. NumKeywords
Chris@16 170 // is used only for a compile-time assertion to make sure the user
Chris@16 171 // doesn't pass more keywords than the function can accept. To
Chris@16 172 // disable all checking, pass mpl::int_<0> for NumKeywords.
Chris@16 173 template <class F, class CallPolicies, class Sig, class NumKeywords>
Chris@16 174 object make_constructor_aux(
Chris@16 175 F f
Chris@16 176 , CallPolicies const& p
Chris@16 177 , Sig const&
Chris@16 178 , detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names
Chris@16 179 , NumKeywords // An MPL integral type wrapper: the size of kw
Chris@16 180 )
Chris@16 181 {
Chris@16 182 enum { arity = mpl::size<Sig>::value - 1 };
Chris@16 183
Chris@16 184 typedef typename detail::error::more_keywords_than_function_arguments<
Chris@16 185 NumKeywords::value, arity
Chris@16 186 >::too_many_keywords assertion;
Chris@16 187
Chris@16 188 typedef typename outer_constructor_signature<Sig>::type outer_signature;
Chris@16 189
Chris@16 190 typedef constructor_policy<CallPolicies> inner_policy;
Chris@16 191
Chris@16 192 return objects::function_object(
Chris@16 193 objects::py_function(
Chris@16 194 detail::caller<F,inner_policy,Sig>(f, inner_policy(p))
Chris@16 195 , outer_signature()
Chris@16 196 )
Chris@16 197 , kw
Chris@16 198 );
Chris@16 199 }
Chris@16 200 // }
Chris@16 201
Chris@16 202 //
Chris@16 203 // These dispatch functions are used to discriminate between the
Chris@16 204 // cases when the 3rd argument is keywords or when it is a
Chris@16 205 // signature.
Chris@16 206 //
Chris@16 207 // @group Helpers for make_constructor when called with 3 arguments. {
Chris@16 208 //
Chris@16 209 template <class F, class CallPolicies, class Keywords>
Chris@16 210 object make_constructor_dispatch(F f, CallPolicies const& policies, Keywords const& kw, mpl::true_)
Chris@16 211 {
Chris@16 212 return detail::make_constructor_aux(
Chris@16 213 f
Chris@16 214 , policies
Chris@16 215 , detail::get_signature(f)
Chris@16 216 , kw.range()
Chris@16 217 , mpl::int_<Keywords::size>()
Chris@16 218 );
Chris@16 219 }
Chris@16 220
Chris@16 221 template <class F, class CallPolicies, class Signature>
Chris@16 222 object make_constructor_dispatch(F f, CallPolicies const& policies, Signature const& sig, mpl::false_)
Chris@16 223 {
Chris@16 224 return detail::make_constructor_aux(
Chris@16 225 f
Chris@16 226 , policies
Chris@16 227 , sig
Chris@16 228 );
Chris@16 229 }
Chris@16 230 // }
Chris@16 231 }
Chris@16 232
Chris@16 233 // These overloaded functions wrap a function or member function
Chris@16 234 // pointer as a Python object, using optional CallPolicies,
Chris@16 235 // Keywords, and/or Signature. @group {
Chris@16 236 //
Chris@16 237 template <class F>
Chris@16 238 object make_constructor(F f)
Chris@16 239 {
Chris@16 240 return detail::make_constructor_aux(
Chris@16 241 f,default_call_policies(), detail::get_signature(f));
Chris@16 242 }
Chris@16 243
Chris@16 244 template <class F, class CallPolicies>
Chris@16 245 object make_constructor(F f, CallPolicies const& policies)
Chris@16 246 {
Chris@16 247 return detail::make_constructor_aux(
Chris@16 248 f, policies, detail::get_signature(f));
Chris@16 249 }
Chris@16 250
Chris@16 251 template <class F, class CallPolicies, class KeywordsOrSignature>
Chris@16 252 object make_constructor(
Chris@16 253 F f
Chris@16 254 , CallPolicies const& policies
Chris@16 255 , KeywordsOrSignature const& keywords_or_signature)
Chris@16 256 {
Chris@16 257 typedef typename
Chris@16 258 detail::is_reference_to_keywords<KeywordsOrSignature&>::type
Chris@16 259 is_kw;
Chris@16 260
Chris@16 261 return detail::make_constructor_dispatch(
Chris@16 262 f
Chris@16 263 , policies
Chris@16 264 , keywords_or_signature
Chris@16 265 , is_kw()
Chris@16 266 );
Chris@16 267 }
Chris@16 268
Chris@16 269 template <class F, class CallPolicies, class Keywords, class Signature>
Chris@16 270 object make_constructor(
Chris@16 271 F f
Chris@16 272 , CallPolicies const& policies
Chris@16 273 , Keywords const& kw
Chris@16 274 , Signature const& sig
Chris@16 275 )
Chris@16 276 {
Chris@16 277 return detail::make_constructor_aux(
Chris@16 278 f
Chris@16 279 , policies
Chris@16 280 , sig
Chris@16 281 , kw.range()
Chris@16 282 , mpl::int_<Keywords::size>()
Chris@16 283 );
Chris@16 284 }
Chris@16 285 // }
Chris@16 286
Chris@16 287 }}
Chris@16 288
Chris@16 289
Chris@16 290 #endif // MAKE_CONSTRUCTOR_DWA20011221_HPP