diff options
Diffstat (limited to 'boost/python/detail')
65 files changed, 4552 insertions, 0 deletions
diff --git a/boost/python/detail/aix_init_module.hpp b/boost/python/detail/aix_init_module.hpp new file mode 100644 index 0000000000..9214dbf09b --- /dev/null +++ b/boost/python/detail/aix_init_module.hpp @@ -0,0 +1,26 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef AIX_INIT_MODULE_DWA2002529_HPP +# define AIX_INIT_MODULE_DWA2002529_HPP +# ifdef _AIX +# include <boost/python/detail/prefix.hpp> +# include <cstdio> +# ifdef __KCC +# include <iostream> // this works around a problem in KCC 4.0f +# endif + +namespace boost { namespace python { namespace detail { + +extern "C" +{ + typedef PyObject* (*so_load_function)(char*,char*,FILE*); +} + +void aix_init_module(so_load_function, char const* name, void (*init_module)()); + +}}} // namespace boost::python::detail +# endif + +#endif // AIX_INIT_MODULE_DWA2002529_HPP diff --git a/boost/python/detail/api_placeholder.hpp b/boost/python/detail/api_placeholder.hpp new file mode 100644 index 0000000000..5975a13bda --- /dev/null +++ b/boost/python/detail/api_placeholder.hpp @@ -0,0 +1,15 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// DEPRECATED HEADER (2006 Jan 12) +// Provided only for backward compatibility. +// The boost::python::len() function is now defined in object.hpp. + +#ifndef BOOST_PYTHON_API_PLACE_HOLDER_HPP +#define BOOST_PYTHON_API_PLACE_HOLDER_HPP + +#include <boost/python/object.hpp> + +#endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP diff --git a/boost/python/detail/borrowed_ptr.hpp b/boost/python/detail/borrowed_ptr.hpp new file mode 100644 index 0000000000..b88457b83a --- /dev/null +++ b/boost/python/detail/borrowed_ptr.hpp @@ -0,0 +1,111 @@ +#ifndef BORROWED_PTR_DWA20020601_HPP +# define BORROWED_PTR_DWA20020601_HPP +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +# include <boost/config.hpp> +# include <boost/type.hpp> +# include <boost/mpl/if.hpp> +# include <boost/type_traits/object_traits.hpp> +# include <boost/type_traits/cv_traits.hpp> +# include <boost/python/tag.hpp> + +namespace boost { namespace python { namespace detail { + +template<class T> class borrowed +{ + typedef T type; +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template<typename T> +struct is_borrowed_ptr +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +# if !defined(__MWERKS__) || __MWERKS__ > 0x3000 +template<typename T> +struct is_borrowed_ptr<borrowed<T>*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template<typename T> +struct is_borrowed_ptr<borrowed<T> const*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template<typename T> +struct is_borrowed_ptr<borrowed<T> volatile*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template<typename T> +struct is_borrowed_ptr<borrowed<T> const volatile*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; +# else +template<typename T> +struct is_borrowed +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; +template<typename T> +struct is_borrowed<borrowed<T> > +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; +template<typename T> +struct is_borrowed_ptr<T*> + : is_borrowed<typename remove_cv<T>::type> +{ +}; +# endif + +# else // no partial specialization + +typedef char (&yes_borrowed_ptr_t)[1]; +typedef char (&no_borrowed_ptr_t)[2]; + +no_borrowed_ptr_t is_borrowed_ptr_test(...); + +template <class T> +typename mpl::if_c< + is_pointer<T>::value + , T + , int + >::type +is_borrowed_ptr_test1(boost::type<T>); + +template<typename T> +yes_borrowed_ptr_t is_borrowed_ptr_test(borrowed<T> const volatile*); + +template<typename T> +class is_borrowed_ptr +{ + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_borrowed_ptr_test(is_borrowed_ptr_test1(boost::type<T>()))) + == sizeof(detail::yes_borrowed_ptr_t))); +}; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +} + +template <class T> +inline T* get_managed_object(detail::borrowed<T> const volatile* p, tag_t) +{ + return (T*)p; +} + +}} // namespace boost::python::detail + +#endif // #ifndef BORROWED_PTR_DWA20020601_HPP diff --git a/boost/python/detail/caller.hpp b/boost/python/detail/caller.hpp new file mode 100644 index 0000000000..e479bf427d --- /dev/null +++ b/boost/python/detail/caller.hpp @@ -0,0 +1,259 @@ +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +# ifndef CALLER_DWA20021121_HPP +# define CALLER_DWA20021121_HPP + +# include <boost/python/type_id.hpp> +# include <boost/python/handle.hpp> + +# include <boost/detail/indirect_traits.hpp> + +# include <boost/python/detail/invoke.hpp> +# include <boost/python/detail/signature.hpp> +# include <boost/python/detail/preprocessor.hpp> + +# include <boost/python/arg_from_python.hpp> +# include <boost/python/converter/context_result_converter.hpp> +# include <boost/python/converter/builtin_converters.hpp> + +# include <boost/preprocessor/iterate.hpp> +# include <boost/preprocessor/cat.hpp> +# include <boost/preprocessor/dec.hpp> +# include <boost/preprocessor/if.hpp> +# include <boost/preprocessor/iteration/local.hpp> +# include <boost/preprocessor/repetition/enum_trailing_params.hpp> +# include <boost/preprocessor/repetition/repeat.hpp> + +# include <boost/compressed_pair.hpp> + +# include <boost/type_traits/is_same.hpp> +# include <boost/type_traits/is_convertible.hpp> + +# include <boost/mpl/apply.hpp> +# include <boost/mpl/eval_if.hpp> +# include <boost/mpl/identity.hpp> +# include <boost/mpl/size.hpp> +# include <boost/mpl/at.hpp> +# include <boost/mpl/int.hpp> +# include <boost/mpl/next.hpp> + +namespace boost { namespace python { namespace detail { + +template <int N> +inline PyObject* get(mpl::int_<N>, PyObject* const& args_) +{ + return PyTuple_GET_ITEM(args_,N); +} + +inline unsigned arity(PyObject* const& args_) +{ + return PyTuple_GET_SIZE(args_); +} + +// This "result converter" is really just used as +// a dispatch tag to invoke(...), selecting the appropriate +// implementation +typedef int void_result_to_python; + +// Given a model of CallPolicies and a C++ result type, this +// metafunction selects the appropriate converter to use for +// converting the result to python. +template <class Policies, class Result> +struct select_result_converter + : mpl::eval_if< + is_same<Result,void> + , mpl::identity<void_result_to_python> + , mpl::apply1<typename Policies::result_converter,Result> + > +{ +}; + +template <class ArgPackage, class ResultConverter> +inline ResultConverter create_result_converter( + ArgPackage const& args_ + , ResultConverter* + , converter::context_result_converter* +) +{ + return ResultConverter(args_); +} + +template <class ArgPackage, class ResultConverter> +inline ResultConverter create_result_converter( + ArgPackage const& + , ResultConverter* + , ... +) +{ + return ResultConverter(); +} + +#ifndef BOOST_PYTHON_NO_PY_SIGNATURES +template <class ResultConverter> +struct converter_target_type +{ + static PyTypeObject const *get_pytype() + { + return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype(); + } +}; + +template < > +struct converter_target_type <void_result_to_python > +{ + static PyTypeObject const *get_pytype() + { + return 0; + } +}; +#endif + + +template <unsigned> struct caller_arity; + +template <class F, class CallPolicies, class Sig> +struct caller; + +# define BOOST_PYTHON_NEXT(init,name,n) \ + typedef BOOST_PP_IF(n,typename mpl::next< BOOST_PP_CAT(name,BOOST_PP_DEC(n)) >::type, init) name##n; + +# define BOOST_PYTHON_ARG_CONVERTER(n) \ + BOOST_PYTHON_NEXT(typename mpl::next<first>::type, arg_iter,n) \ + typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \ + c_t##n c##n(get(mpl::int_<n>(), inner_args)); \ + if (!c##n.convertible()) \ + return 0; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>)) +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_ARG_CONVERTER +# undef BOOST_PYTHON_NEXT + +// A metafunction returning the base class used for caller<class F, +// class ConverterGenerators, class CallPolicies, class Sig>. +template <class F, class CallPolicies, class Sig> +struct caller_base_select +{ + enum { arity = mpl::size<Sig>::value - 1 }; + typedef typename caller_arity<arity>::template impl<F,CallPolicies,Sig> type; +}; + +// A function object type which wraps C++ objects as Python callable +// objects. +// +// Template Arguments: +// +// F - +// the C++ `function object' that will be called. Might +// actually be any data for which an appropriate invoke_tag() can +// be generated. invoke(...) takes care of the actual invocation syntax. +// +// CallPolicies - +// The precall, postcall, and what kind of resultconverter to +// generate for mpl::front<Sig>::type +// +// Sig - +// The `intended signature' of the function. An MPL sequence +// beginning with a result type and continuing with a list of +// argument types. +template <class F, class CallPolicies, class Sig> +struct caller + : caller_base_select<F,CallPolicies,Sig>::type +{ + typedef typename caller_base_select< + F,CallPolicies,Sig + >::type base; + + typedef PyObject* result_type; + + caller(F f, CallPolicies p) : base(f,p) {} + +}; + +}}} // namespace boost::python::detail + +# endif // CALLER_DWA20021121_HPP + +#else + +# define N BOOST_PP_ITERATION() + +template <> +struct caller_arity<N> +{ + template <class F, class Policies, class Sig> + struct impl + { + impl(F f, Policies p) : m_data(f,p) {} + + PyObject* operator()(PyObject* args_, PyObject*) // eliminate + // this + // trailing + // keyword dict + { + typedef typename mpl::begin<Sig>::type first; + typedef typename first::type result_t; + typedef typename select_result_converter<Policies, result_t>::type result_converter; + typedef typename Policies::argument_package argument_package; + + argument_package inner_args(args_); + +# if N +# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i) +# define BOOST_PP_LOCAL_LIMITS (0, N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + // all converters have been checked. Now we can do the + // precall part of the policy + if (!m_data.second().precall(inner_args)) + return 0; + + PyObject* result = detail::invoke( + detail::invoke_tag<result_t,F>() + , create_result_converter(args_, (result_converter*)0, (result_converter*)0) + , m_data.first() + BOOST_PP_ENUM_TRAILING_PARAMS(N, c) + ); + + return m_data.second().postcall(inner_args, result); + } + + static unsigned min_arity() { return N; } + + static py_func_sig_info signature() + { + const signature_element * sig = detail::signature<Sig>::elements(); +#ifndef BOOST_PYTHON_NO_PY_SIGNATURES + + typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype; + typedef typename select_result_converter<Policies, rtype>::type result_converter; + + static const signature_element ret = { + (boost::is_void<rtype>::value ? "void" : type_id<rtype>().name()) + , &detail::converter_target_type<result_converter>::get_pytype + , boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value + }; + py_func_sig_info res = {sig, &ret }; +#else + py_func_sig_info res = {sig, sig }; +#endif + + return res; + } + private: + compressed_pair<F,Policies> m_data; + }; +}; + + + +#endif // BOOST_PP_IS_ITERATING + + diff --git a/boost/python/detail/config.hpp b/boost/python/detail/config.hpp new file mode 100644 index 0000000000..acafc03747 --- /dev/null +++ b/boost/python/detail/config.hpp @@ -0,0 +1,141 @@ +// (C) Copyright David Abrahams 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The author gratefully acknowleges the support of Dragon Systems, Inc., in +// producing this work. + +// Revision History: +// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams) + +#ifndef CONFIG_DWA052200_H_ +# define CONFIG_DWA052200_H_ + +# include <boost/config.hpp> +# include <boost/detail/workaround.hpp> + +# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE + // A gcc bug forces some symbols into the global namespace +# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE +# define BOOST_PYTHON_END_CONVERSION_NAMESPACE +# define BOOST_PYTHON_CONVERSION +# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x +# else +# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python { +# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python +# define BOOST_PYTHON_CONVERSION boost::python +# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';' +# endif + +# if defined(BOOST_MSVC) +# if _MSC_VER < 1300 +# define BOOST_MSVC6_OR_EARLIER 1 +# endif + +# pragma warning (disable : 4786) // disable truncated debug symbols +# pragma warning (disable : 4251) // disable exported dll function +# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or 'false' +# pragma warning (disable : 4275) // non dll-interface class + +# elif defined(__ICL) && __ICL < 600 // Intel C++ 5 + +# pragma warning(disable: 985) // identifier was truncated in debug information + +# endif + +// The STLport puts all of the standard 'C' library names in std (as far as the +// user is concerned), but without it you need a fix if you're using MSVC or +// Intel C++ +# if defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_CSTD_ +# else +# define BOOST_CSTD_ std +# endif + +/***************************************************************************** + * + * Set up dll import/export options: + * + ****************************************************************************/ + +// backwards compatibility: +#ifdef BOOST_PYTHON_STATIC_LIB +# define BOOST_PYTHON_STATIC_LINK +# elif !defined(BOOST_PYTHON_DYNAMIC_LIB) +# define BOOST_PYTHON_DYNAMIC_LIB +#endif + +#if defined(BOOST_PYTHON_DYNAMIC_LIB) + +# if !defined(_WIN32) && !defined(__CYGWIN__) \ + && !defined(BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY) \ + && BOOST_WORKAROUND(__GNUC__, >= 3) && (__GNUC_MINOR__ >=5 || __GNUC__ > 3) +# define BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY 1 +# endif + +# if BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY +# if defined(BOOST_PYTHON_SOURCE) +# define BOOST_PYTHON_DECL __attribute__ ((visibility("default"))) +# define BOOST_PYTHON_BUILD_DLL +# else +# define BOOST_PYTHON_DECL +# endif +# define BOOST_PYTHON_DECL_FORWARD +# define BOOST_PYTHON_DECL_EXCEPTION __attribute__ ((visibility("default"))) +# elif (defined(_WIN32) || defined(__CYGWIN__)) +# if defined(BOOST_PYTHON_SOURCE) +# define BOOST_PYTHON_DECL __declspec(dllexport) +# define BOOST_PYTHON_BUILD_DLL +# else +# define BOOST_PYTHON_DECL __declspec(dllimport) +# endif +# endif + +#endif + +#ifndef BOOST_PYTHON_DECL +# define BOOST_PYTHON_DECL +#endif + +#ifndef BOOST_PYTHON_DECL_FORWARD +# define BOOST_PYTHON_DECL_FORWARD BOOST_PYTHON_DECL +#endif + +#ifndef BOOST_PYTHON_DECL_EXCEPTION +# define BOOST_PYTHON_DECL_EXCEPTION BOOST_PYTHON_DECL +#endif + +#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) +// Replace broken Tru64/cxx offsetof macro +# define BOOST_PYTHON_OFFSETOF(s_name, s_member) \ + ((size_t)__INTADDR__(&(((s_name *)0)->s_member))) +#else +# define BOOST_PYTHON_OFFSETOF offsetof +#endif + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_PYTHON_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_PYTHON_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_python +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#ifdef BOOST_PYTHON_DYNAMIC_LIB +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled + +#ifndef BOOST_PYTHON_NO_PY_SIGNATURES +#define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition +#endif + +#endif // CONFIG_DWA052200_H_ diff --git a/boost/python/detail/construct.hpp b/boost/python/detail/construct.hpp new file mode 100644 index 0000000000..5f15d22c6e --- /dev/null +++ b/boost/python/detail/construct.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef CONSTRUCT_REFERENCE_DWA2002716_HPP +# define CONSTRUCT_REFERENCE_DWA2002716_HPP + +namespace boost { namespace python { namespace detail { + +template <class T, class Arg> +void construct_pointee(void* storage, Arg& x +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + , T const volatile* +# else + , T const* +# endif + ) +{ + new (storage) T(x); +} + +template <class T, class Arg> +void construct_referent_impl(void* storage, Arg& x, T&(*)()) +{ + construct_pointee(storage, x, (T*)0); +} + +template <class T, class Arg> +void construct_referent(void* storage, Arg const& x, T(*tag)() = 0) +{ + construct_referent_impl(storage, x, tag); +} + +template <class T, class Arg> +void construct_referent(void* storage, Arg& x, T(*tag)() = 0) +{ + construct_referent_impl(storage, x, tag); +} + +}}} // namespace boost::python::detail + +#endif // CONSTRUCT_REFERENCE_DWA2002716_HPP diff --git a/boost/python/detail/convertible.hpp b/boost/python/detail/convertible.hpp new file mode 100644 index 0000000000..2ce552f5f7 --- /dev/null +++ b/boost/python/detail/convertible.hpp @@ -0,0 +1,38 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef CONVERTIBLE_DWA2002614_HPP +# define CONVERTIBLE_DWA2002614_HPP + +# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241 +# include <boost/mpl/if.hpp> +# include <boost/type_traits/conversion_traits.hpp> +# endif + +// Supplies a runtime is_convertible check which can be used with tag +// dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible +namespace boost { namespace python { namespace detail { + +typedef char* yes_convertible; +typedef int* no_convertible; + +template <class Target> +struct convertible +{ +# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 || __EDG_VERSION__ == 238 + static inline no_convertible check(...) { return 0; } + static inline yes_convertible check(Target) { return 0; } +# else + template <class X> + static inline typename mpl::if_c< + is_convertible<X,Target>::value + , yes_convertible + , no_convertible + >::type check(X const&) { return 0; } +# endif +}; + +}}} // namespace boost::python::detail + +#endif // CONVERTIBLE_DWA2002614_HPP diff --git a/boost/python/detail/copy_ctor_mutates_rhs.hpp b/boost/python/detail/copy_ctor_mutates_rhs.hpp new file mode 100644 index 0000000000..4ca8d03911 --- /dev/null +++ b/boost/python/detail/copy_ctor_mutates_rhs.hpp @@ -0,0 +1,21 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef COPY_CTOR_MUTATES_RHS_DWA2003219_HPP +# define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP + +#include <boost/python/detail/is_auto_ptr.hpp> +#include <boost/mpl/bool.hpp> + +namespace boost { namespace python { namespace detail { + +template <class T> +struct copy_ctor_mutates_rhs + : is_auto_ptr<T> +{ +}; + +}}} // namespace boost::python::detail + +#endif // COPY_CTOR_MUTATES_RHS_DWA2003219_HPP diff --git a/boost/python/detail/cv_category.hpp b/boost/python/detail/cv_category.hpp new file mode 100644 index 0000000000..1765b36f8c --- /dev/null +++ b/boost/python/detail/cv_category.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef CV_CATEGORY_DWA200222_HPP +# define CV_CATEGORY_DWA200222_HPP +# include <boost/type_traits/cv_traits.hpp> + +namespace boost { namespace python { namespace detail { + +template <bool is_const_, bool is_volatile_> +struct cv_tag +{ + BOOST_STATIC_CONSTANT(bool, is_const = is_const_); + BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_); +}; + +typedef cv_tag<false,false> cv_unqualified; +typedef cv_tag<true,false> const_; +typedef cv_tag<false,true> volatile_; +typedef cv_tag<true,true> const_volatile_; + +template <class T> +struct cv_category +{ +// BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value); +// BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value); + typedef cv_tag< + ::boost::is_const<T>::value + , ::boost::is_volatile<T>::value + > type; +}; + +}}} // namespace boost::python::detail + +#endif // CV_CATEGORY_DWA200222_HPP diff --git a/boost/python/detail/dealloc.hpp b/boost/python/detail/dealloc.hpp new file mode 100644 index 0000000000..f2d914b18c --- /dev/null +++ b/boost/python/detail/dealloc.hpp @@ -0,0 +1,17 @@ +// Copyright Gottfried Ganßauge 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +# ifndef BOOST_PYTHON_DETAIL_DEALLOC_HPP_ +# define BOOST_PYTHON_DETAIL_DEALLOC_HPP_ +namespace boost { namespace python { namespace detail { + extern "C" + { + inline void dealloc(PyObject* self) + { + PyObject_Del(self); + } + } +}}} // namespace boost::python::detail +# endif // BOOST_PYTHON_DETAIL_DEALLOC_HPP_ diff --git a/boost/python/detail/decorated_type_id.hpp b/boost/python/detail/decorated_type_id.hpp new file mode 100644 index 0000000000..535508b43d --- /dev/null +++ b/boost/python/detail/decorated_type_id.hpp @@ -0,0 +1,76 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef DECORATED_TYPE_ID_DWA2002517_HPP +# define DECORATED_TYPE_ID_DWA2002517_HPP + +# include <boost/python/type_id.hpp> +# include <boost/python/detail/indirect_traits.hpp> +# include <boost/type_traits/cv_traits.hpp> + +namespace boost { namespace python { namespace detail { + +struct decorated_type_info : totally_ordered<decorated_type_info> +{ + enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; + + decorated_type_info(type_info, decoration = decoration()); + + inline bool operator<(decorated_type_info const& rhs) const; + inline bool operator==(decorated_type_info const& rhs) const; + + friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); + + operator type_info const&() const; + private: // type + typedef type_info base_id_t; + + private: // data members + decoration m_decoration; + base_id_t m_base_type; +}; + +template <class T> +inline decorated_type_info decorated_type_id(boost::type<T>* = 0) +{ + return decorated_type_info( + type_id<T>() + , decorated_type_info::decoration( + (is_const<T>::value || indirect_traits::is_reference_to_const<T>::value + ? decorated_type_info::const_ : 0) + | (is_volatile<T>::value || indirect_traits::is_reference_to_volatile<T>::value + ? decorated_type_info::volatile_ : 0) + | (is_reference<T>::value ? decorated_type_info::reference : 0) + ) + ); +} + +inline decorated_type_info::decorated_type_info(type_info base_t, decoration decoration) + : m_decoration(decoration) + , m_base_type(base_t) +{ +} + +inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const +{ + return m_decoration < rhs.m_decoration + || (m_decoration == rhs.m_decoration + && m_base_type < rhs.m_base_type); +} + +inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const +{ + return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; +} + +inline decorated_type_info::operator type_info const&() const +{ + return m_base_type; +} + +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); + +}}} // namespace boost::python::detail + +#endif // DECORATED_TYPE_ID_DWA2002517_HPP diff --git a/boost/python/detail/decref_guard.hpp b/boost/python/detail/decref_guard.hpp new file mode 100644 index 0000000000..d713e0a604 --- /dev/null +++ b/boost/python/detail/decref_guard.hpp @@ -0,0 +1,21 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef DECREF_GUARD_DWA20021220_HPP +# define DECREF_GUARD_DWA20021220_HPP + +namespace boost { namespace python { namespace detail { + +struct decref_guard +{ + decref_guard(PyObject* o) : obj(o) {} + ~decref_guard() { Py_XDECREF(obj); } + void cancel() { obj = 0; } + private: + PyObject* obj; +}; + +}}} // namespace boost::python::detail + +#endif // DECREF_GUARD_DWA20021220_HPP diff --git a/boost/python/detail/def_helper.hpp b/boost/python/detail/def_helper.hpp new file mode 100644 index 0000000000..e68ca0cd7b --- /dev/null +++ b/boost/python/detail/def_helper.hpp @@ -0,0 +1,212 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef DEF_HELPER_DWA200287_HPP +# define DEF_HELPER_DWA200287_HPP + +# include <boost/python/args.hpp> +# include <boost/type_traits/ice.hpp> +# include <boost/type_traits/same_traits.hpp> +# include <boost/python/detail/indirect_traits.hpp> +# include <boost/mpl/not.hpp> +# include <boost/mpl/and.hpp> +# include <boost/mpl/or.hpp> +# include <boost/type_traits/add_reference.hpp> +# include <boost/mpl/lambda.hpp> +# include <boost/mpl/apply.hpp> +# include <boost/tuple/tuple.hpp> +# include <boost/python/detail/not_specified.hpp> +# include <boost/python/detail/def_helper_fwd.hpp> + +namespace boost { namespace python { + +struct default_call_policies; + +namespace detail +{ + // tuple_extract<Tuple,Predicate>::extract(t) returns the first + // element of a Tuple whose type E satisfies the given Predicate + // applied to add_reference<E>. The Predicate must be an MPL + // metafunction class. + template <class Tuple, class Predicate> + struct tuple_extract; + + // Implementation class for when the tuple's head type does not + // satisfy the Predicate + template <bool matched> + struct tuple_extract_impl + { + template <class Tuple, class Predicate> + struct apply + { + typedef typename Tuple::head_type result_type; + + static typename Tuple::head_type extract(Tuple const& x) + { + return x.get_head(); + } + }; + }; + + // Implementation specialization for when the tuple's head type + // satisfies the predicate + template <> + struct tuple_extract_impl<false> + { + template <class Tuple, class Predicate> + struct apply + { + // recursive application of tuple_extract on the tail of the tuple + typedef tuple_extract<typename Tuple::tail_type, Predicate> next; + typedef typename next::result_type result_type; + + static result_type extract(Tuple const& x) + { + return next::extract(x.get_tail()); + } + }; + }; + + // A metafunction which selects a version of tuple_extract_impl to + // use for the implementation of tuple_extract + template <class Tuple, class Predicate> + struct tuple_extract_base_select + { + typedef typename Tuple::head_type head_type; + typedef typename mpl::apply1<Predicate, typename add_reference<head_type>::type>::type match_t; + BOOST_STATIC_CONSTANT(bool, match = match_t::value); + typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type; + }; + + template <class Tuple, class Predicate> + struct tuple_extract + : tuple_extract_base_select< + Tuple + , typename mpl::lambda<Predicate>::type + >::type + { + }; + + + // + // Specialized extractors for the docstring, keywords, CallPolicies, + // and default implementation of virtual functions + // + + template <class Tuple> + struct doc_extract + : tuple_extract< + Tuple + , mpl::not_< + mpl::or_< + indirect_traits::is_reference_to_class<mpl::_1> + , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 > + > + > + > + { + }; + + template <class Tuple> + struct keyword_extract + : tuple_extract<Tuple, is_reference_to_keywords<mpl::_1 > > + { + }; + + template <class Tuple> + struct policy_extract + : tuple_extract< + Tuple + , mpl::and_< + mpl::not_<is_same<not_specified const&,mpl::_1> > + , indirect_traits::is_reference_to_class<mpl::_1 > + , mpl::not_<is_reference_to_keywords<mpl::_1 > > + > + > + { + }; + + template <class Tuple> + struct default_implementation_extract + : tuple_extract< + Tuple + , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 > + > + { + }; + + // + // A helper class for decoding the optional arguments to def() + // invocations, which can be supplied in any order and are + // discriminated by their type properties. The template parameters + // are expected to be the types of the actual (optional) arguments + // passed to def(). + // + template <class T1, class T2, class T3, class T4> + struct def_helper + { + // A tuple type which begins with references to the supplied + // arguments and ends with actual representatives of the default + // types. + typedef boost::tuples::tuple< + T1 const& + , T2 const& + , T3 const& + , T4 const& + , default_call_policies + , detail::keywords<0> + , char const* + , void(not_specified::*)() // A function pointer type which is never an + // appropriate default implementation + > all_t; + + // Constructors; these initialize an member of the tuple type + // shown above. + def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {} + def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {} + def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {} + def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {} + + private: // types + typedef typename default_implementation_extract<all_t>::result_type default_implementation_t; + + public: // Constants which can be used for static assertions. + + // Users must not supply a default implementation for non-class + // methods. + BOOST_STATIC_CONSTANT( + bool, has_default_implementation = ( + !is_same<default_implementation_t, void(not_specified::*)()>::value)); + + public: // Extractor functions which pull the appropriate value out + // of the tuple + char const* doc() const + { + return doc_extract<all_t>::extract(m_all); + } + + typename keyword_extract<all_t>::result_type keywords() const + { + return keyword_extract<all_t>::extract(m_all); + } + + typename policy_extract<all_t>::result_type policies() const + { + return policy_extract<all_t>::extract(m_all); + } + + default_implementation_t default_implementation() const + { + return default_implementation_extract<all_t>::extract(m_all); + } + + private: // data members + all_t m_all; + not_specified m_nil; // for filling in not_specified slots + }; +} + +}} // namespace boost::python::detail + +#endif // DEF_HELPER_DWA200287_HPP diff --git a/boost/python/detail/def_helper_fwd.hpp b/boost/python/detail/def_helper_fwd.hpp new file mode 100644 index 0000000000..31c22e97a3 --- /dev/null +++ b/boost/python/detail/def_helper_fwd.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef DEF_HELPER_FWD_DWA2003810_HPP +# define DEF_HELPER_FWD_DWA2003810_HPP + +# include <boost/python/detail/not_specified.hpp> + +namespace boost { namespace python { namespace detail { + +template <class T1, class T2 = not_specified, class T3 = not_specified, class T4 = not_specified> +struct def_helper; + +}}} // namespace boost::python::detail + +#endif // DEF_HELPER_FWD_DWA2003810_HPP diff --git a/boost/python/detail/defaults_def.hpp b/boost/python/detail/defaults_def.hpp new file mode 100644 index 0000000000..68799f83e6 --- /dev/null +++ b/boost/python/detail/defaults_def.hpp @@ -0,0 +1,291 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002, Joel de Guzman, 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_PP_IS_ITERATING) + +#ifndef DEFAULTS_DEF_JDG20020811_HPP +#define DEFAULTS_DEF_JDG20020811_HPP + +#include <boost/python/detail/defaults_gen.hpp> +#include <boost/type_traits.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/size.hpp> +#include <boost/static_assert.hpp> +#include <boost/preprocessor/iterate.hpp> +#include <boost/python/class_fwd.hpp> +#include <boost/python/scope.hpp> +#include <boost/preprocessor/debug/line.hpp> +#include <boost/python/detail/scope.hpp> +#include <boost/python/detail/make_keyword_range_fn.hpp> +#include <boost/python/object/add_to_namespace.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace python { + +struct module; + +namespace objects +{ + struct class_base; +} + +namespace detail +{ + // Called as:: + // + // name_space_def(ns, "func", func, kw, policies, docstring, &ns) + // + // Dispatch to properly add f to namespace ns. + // + // @group define_stub_function helpers { + template <class Func, class CallPolicies, class NameSpaceT> + static void name_space_def( + NameSpaceT& name_space + , char const* name + , Func f + , keyword_range const& kw + , CallPolicies const& policies + , char const* doc + , objects::class_base* + ) + { + typedef typename NameSpaceT::wrapped_type wrapped_type; + + objects::add_to_namespace( + name_space, name, + detail::make_keyword_range_function( + f, policies, kw, get_signature(f, (wrapped_type*)0)) + , doc + ); + } + + template <class Func, class CallPolicies> + static void name_space_def( + object& name_space + , char const* name + , Func f + , keyword_range const& kw + , CallPolicies const& policies + , char const* doc + , ... + ) + { + scope within(name_space); + + detail::scope_setattr_doc( + name + , detail::make_keyword_range_function(f, policies, kw) + , doc); + } + + // For backward compatibility -- is this obsolete? + template <class Func, class CallPolicies, class NameSpaceT> + static void name_space_def( + NameSpaceT& name_space + , char const* name + , Func f + , keyword_range const& kw // ignored + , CallPolicies const& policies + , char const* doc + , module* + ) + { + name_space.def(name, f, policies, doc); + } + // } + + + // Expansions of :: + // + // template <typename OverloadsT, typename NameSpaceT> + // inline void + // define_stub_function( + // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_<N>) + // { + // name_space.def(name, &OverloadsT::func_N); + // } + // + // where N runs from 0 to BOOST_PYTHON_MAX_ARITY. + // + // The set of overloaded functions (define_stub_function) expects: + // + // 1. char const* name: function name that will be visible to python + // 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) + // 3. NameSpaceT& name_space: a python::class_ or python::module instance + // 4. int_t<N>: the Nth overloaded function (OverloadsT::func_N) + // (see defaults_gen.hpp) + // 5. char const* name: doc string + // + // @group define_stub_function<N> { + template <int N> + struct define_stub_function {}; + +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>)) + +#include BOOST_PP_ITERATE() + + // } + + // This helper template struct does the actual recursive + // definition. There's a generic version + // define_with_defaults_helper<N> and a terminal case + // define_with_defaults_helper<0>. The struct and its + // specialization has a sole static member function def that + // expects: + // + // 1. char const* name: function name that will be + // visible to python + // + // 2. OverloadsT: a function overloads struct + // (see defaults_gen.hpp) + // + // 3. NameSpaceT& name_space: a python::class_ or + // python::module instance + // + // 4. char const* name: doc string + // + // The def static member function calls a corresponding + // define_stub_function<N>. The general case recursively calls + // define_with_defaults_helper<N-1>::def until it reaches the + // terminal case case define_with_defaults_helper<0>. + template <int N> + struct define_with_defaults_helper { + + template <class StubsT, class CallPolicies, class NameSpaceT> + static void + def( + char const* name, + StubsT stubs, + keyword_range kw, + CallPolicies const& policies, + NameSpaceT& name_space, + char const* doc) + { + // define the NTH stub function of stubs + define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc); + + if (kw.second > kw.first) + --kw.second; + + // call the next define_with_defaults_helper + define_with_defaults_helper<N-1>::def(name, stubs, kw, policies, name_space, doc); + } + }; + + template <> + struct define_with_defaults_helper<0> { + + template <class StubsT, class CallPolicies, class NameSpaceT> + static void + def( + char const* name, + StubsT stubs, + keyword_range const& kw, + CallPolicies const& policies, + NameSpaceT& name_space, + char const* doc) + { + // define the Oth stub function of stubs + define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc); + // return + } + }; + + // define_with_defaults + // + // 1. char const* name: function name that will be + // visible to python + // + // 2. OverloadsT: a function overloads struct + // (see defaults_gen.hpp) + // + // 3. CallPolicies& policies: Call policies + // 4. NameSpaceT& name_space: a python::class_ or + // python::module instance + // + // 5. SigT sig: Function signature typelist + // (see defaults_gen.hpp) + // + // 6. char const* name: doc string + // + // This is the main entry point. This function recursively + // defines all stub functions of StubT (see defaults_gen.hpp) in + // NameSpaceT name_space which can be either a python::class_ or + // a python::module. The sig argument is a typelist that + // specifies the return type, the class (for member functions, + // and the arguments. Here are some SigT examples: + // + // int foo(int) mpl::vector<int, int> + // void bar(int, int) mpl::vector<void, int, int> + // void C::foo(int) mpl::vector<void, C, int> + // + template <class OverloadsT, class NameSpaceT, class SigT> + inline void + define_with_defaults( + char const* name, + OverloadsT const& overloads, + NameSpaceT& name_space, + SigT const&) + { + typedef typename mpl::front<SigT>::type return_type; + typedef typename OverloadsT::void_return_type void_return_type; + typedef typename OverloadsT::non_void_return_type non_void_return_type; + + typedef typename mpl::if_c< + boost::is_same<void, return_type>::value + , void_return_type + , non_void_return_type + >::type stubs_type; + + BOOST_STATIC_ASSERT( + (stubs_type::max_args) <= mpl::size<SigT>::value); + + typedef typename stubs_type::template gen<SigT> gen_type; + define_with_defaults_helper<stubs_type::n_funcs-1>::def( + name + , gen_type() + , overloads.keywords() + , overloads.call_policies() + , name_space + , overloads.doc_string()); + } + +} // namespace detail + +}} // namespace boost::python + +#endif // DEFAULTS_DEF_JDG20020811_HPP + +#else // defined(BOOST_PP_IS_ITERATING) +// PP vertical iteration code + + +template <> +struct define_stub_function<BOOST_PP_ITERATION()> { + template <class StubsT, class CallPolicies, class NameSpaceT> + static void define( + char const* name + , StubsT const& + , keyword_range const& kw + , CallPolicies const& policies + , NameSpaceT& name_space + , char const* doc) + { + detail::name_space_def( + name_space + , name + , &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()) + , kw + , policies + , doc + , &name_space); + } +}; + +#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/boost/python/detail/defaults_gen.hpp b/boost/python/detail/defaults_gen.hpp new file mode 100644 index 0000000000..0b3e0e2604 --- /dev/null +++ b/boost/python/detail/defaults_gen.hpp @@ -0,0 +1,388 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002, Joel de Guzman, 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef DEFAULTS_GEN_JDG20020807_HPP +#define DEFAULTS_GEN_JDG20020807_HPP + +#include <boost/python/detail/preprocessor.hpp> +#include <boost/preprocessor/repeat.hpp> +#include <boost/preprocessor/repeat_from_to.hpp> +#include <boost/preprocessor/enum.hpp> +#include <boost/preprocessor/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> +#include <boost/preprocessor/tuple.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/arithmetic/sub.hpp> +#include <boost/preprocessor/stringize.hpp> +#include <boost/preprocessor/inc.hpp> +#include <boost/preprocessor/empty.hpp> +#include <boost/preprocessor/comma_if.hpp> +#include <boost/config.hpp> +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/deref.hpp> +#include <cstddef> + +namespace boost { namespace python { + +namespace detail +{ + // overloads_base is used as a base class for all function + // stubs. This class holds the doc_string of the stubs. + struct overloads_base + { + overloads_base(char const* doc_) + : m_doc(doc_) {} + + overloads_base(char const* doc_, detail::keyword_range const& kw) + : m_doc(doc_), m_keywords(kw) {} + + char const* doc_string() const + { + return m_doc; + } + + detail::keyword_range const& keywords() const + { + return m_keywords; + } + + private: + char const* m_doc; + detail::keyword_range m_keywords; + }; + + // overloads_proxy is generated by the overloads_common operator[] (see + // below). This class holds a user defined call policies of the stubs. + template <class CallPoliciesT, class OverloadsT> + struct overloads_proxy + : public overloads_base + { + typedef typename OverloadsT::non_void_return_type non_void_return_type; + typedef typename OverloadsT::void_return_type void_return_type; + + overloads_proxy( + CallPoliciesT const& policies_ + , char const* doc + , keyword_range const& kw + ) + : overloads_base(doc, kw) + , policies(policies_) + {} + + CallPoliciesT + call_policies() const + { + return policies; + } + + CallPoliciesT policies; + }; + + // overloads_common is our default function stubs base class. This + // class returns the default_call_policies in its call_policies() + // member function. It can generate a overloads_proxy however through + // its operator[] + template <class DerivedT> + struct overloads_common + : public overloads_base + { + overloads_common(char const* doc) + : overloads_base(doc) {} + + overloads_common(char const* doc, keyword_range const& kw) + : overloads_base(doc, kw) {} + + default_call_policies + call_policies() const + { + return default_call_policies(); + } + + template <class CallPoliciesT> + overloads_proxy<CallPoliciesT, DerivedT> + operator[](CallPoliciesT const& policies) const + { + return overloads_proxy<CallPoliciesT, DerivedT>( + policies, this->doc_string(), this->keywords()); + } + }; + +}}} // namespace boost::python::detail + + +#define BOOST_PYTHON_TYPEDEF_GEN(z, index, data) \ + typedef typename ::boost::mpl::next<BOOST_PP_CAT(iter, index)>::type \ + BOOST_PP_CAT(iter, BOOST_PP_INC(index)); \ + typedef typename ::boost::mpl::deref<BOOST_PP_CAT(iter, index)>::type \ + BOOST_PP_CAT(T, index); + +#define BOOST_PYTHON_FUNC_WRAPPER_GEN(z, index, data) \ + static RT BOOST_PP_CAT(func_, \ + BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \ + BOOST_PP_ENUM_BINARY_PARAMS_Z( \ + 1, index, T, arg)) \ + { \ + BOOST_PP_TUPLE_ELEM(3, 2, data) \ + BOOST_PP_TUPLE_ELEM(3, 0, data)( \ + BOOST_PP_ENUM_PARAMS( \ + index, \ + arg)); \ + } + +#define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ + struct fstubs_name \ + { \ + BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \ + BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \ + \ + template <typename SigT> \ + struct gen \ + { \ + typedef typename ::boost::mpl::begin<SigT>::type rt_iter; \ + typedef typename ::boost::mpl::deref<rt_iter>::type RT; \ + typedef typename ::boost::mpl::next<rt_iter>::type iter0; \ + \ + BOOST_PP_REPEAT_2ND( \ + n_args, \ + BOOST_PYTHON_TYPEDEF_GEN, \ + 0) \ + \ + BOOST_PP_REPEAT_FROM_TO_2( \ + BOOST_PP_SUB_D(1, n_args, n_dflts), \ + BOOST_PP_INC(n_args), \ + BOOST_PYTHON_FUNC_WRAPPER_GEN, \ + (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \ + }; \ + }; \ + +/////////////////////////////////////////////////////////////////////////////// +#define BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN(z, index, data) \ + static RT BOOST_PP_CAT(func_, \ + BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \ + ClassT obj BOOST_PP_COMMA_IF(index) \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(1, index, T, arg) \ + ) \ + { \ + BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)( \ + BOOST_PP_ENUM_PARAMS(index, arg) \ + ); \ + } + +#define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ + struct fstubs_name \ + { \ + BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \ + BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \ + \ + template <typename SigT> \ + struct gen \ + { \ + typedef typename ::boost::mpl::begin<SigT>::type rt_iter; \ + typedef typename ::boost::mpl::deref<rt_iter>::type RT; \ + \ + typedef typename ::boost::mpl::next<rt_iter>::type class_iter; \ + typedef typename ::boost::mpl::deref<class_iter>::type ClassT; \ + typedef typename ::boost::mpl::next<class_iter>::type iter0; \ + \ + BOOST_PP_REPEAT_2ND( \ + n_args, \ + BOOST_PYTHON_TYPEDEF_GEN, \ + 0) \ + \ + BOOST_PP_REPEAT_FROM_TO_2( \ + BOOST_PP_SUB_D(1, n_args, n_dflts), \ + BOOST_PP_INC(n_args), \ + BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN, \ + (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \ + }; \ + }; + +#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ + fstubs_name(char const* doc = 0) \ + : ::boost::python::detail::overloads_common<fstubs_name>(doc) {} \ + template <std::size_t N> \ + fstubs_name(char const* doc, ::boost::python::detail::keywords<N> const& keywords) \ + : ::boost::python::detail::overloads_common<fstubs_name>( \ + doc, keywords.range()) \ + { \ + typedef typename ::boost::python::detail:: \ + error::more_keywords_than_function_arguments< \ + N,n_args>::too_many_keywords assertion; \ + } \ + template <std::size_t N> \ + fstubs_name(::boost::python::detail::keywords<N> const& keywords, char const* doc = 0) \ + : ::boost::python::detail::overloads_common<fstubs_name>( \ + doc, keywords.range()) \ + { \ + typedef typename ::boost::python::detail:: \ + error::more_keywords_than_function_arguments< \ + N,n_args>::too_many_keywords assertion; \ + } + +# if defined(BOOST_NO_VOID_RETURNS) + +# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + struct fstubs_name \ + : public ::boost::python::detail::overloads_common<fstubs_name> \ + { \ + BOOST_PYTHON_GEN_FUNCTION( \ + fname, non_void_return_type, n_args, n_dflts, return) \ + BOOST_PYTHON_GEN_FUNCTION( \ + fname, void_return_type, n_args, n_dflts, ;) \ + \ + BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ + }; + +# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + struct fstubs_name \ + : public ::boost::python::detail::overloads_common<fstubs_name> \ + { \ + BOOST_PYTHON_GEN_MEM_FUNCTION( \ + fname, non_void_return_type, n_args, n_dflts, return) \ + BOOST_PYTHON_GEN_MEM_FUNCTION( \ + fname, void_return_type, n_args, n_dflts, ;) \ + \ + BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \ + }; + +# else // !defined(BOOST_NO_VOID_RETURNS) + +# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + struct fstubs_name \ + : public ::boost::python::detail::overloads_common<fstubs_name> \ + { \ + BOOST_PYTHON_GEN_FUNCTION( \ + fname, non_void_return_type, n_args, n_dflts, return) \ + \ + typedef non_void_return_type void_return_type; \ + BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ + }; + + +# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + struct fstubs_name \ + : public ::boost::python::detail::overloads_common<fstubs_name> \ + { \ + BOOST_PYTHON_GEN_MEM_FUNCTION( \ + fname, non_void_return_type, n_args, n_dflts, return) \ + \ + typedef non_void_return_type void_return_type; \ + BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \ + }; + +# endif // !defined(BOOST_NO_VOID_RETURNS) + +/////////////////////////////////////////////////////////////////////////////// +// +// MAIN MACROS +// +// Given generator_name, fname, min_args and max_args, These macros +// generate function stubs that forward to a function or member function +// named fname. max_args is the arity of the function or member function +// fname. fname can have default arguments. min_args is the minimum +// arity that fname can accept. +// +// There are two versions: +// +// 1. BOOST_PYTHON_FUNCTION_OVERLOADS for free functions +// 2. BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for member functions. +// +// For instance, given a function: +// +// int +// foo(int a, char b = 1, unsigned c = 2, double d = 3) +// { +// return a + b + c + int(d); +// } +// +// The macro invocation: +// +// BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) +// +// Generates this code: +// +// struct foo_stubsNonVoid +// { +// static const int n_funcs = 4; +// static const int max_args = n_funcs; +// +// template <typename SigT> +// struct gen +// { +// typedef typename ::boost::mpl::begin<SigT>::type rt_iter; +// typedef typename rt_iter::type RT; +// typedef typename rt_iter::next iter0; +// typedef typename iter0::type T0; +// typedef typename iter0::next iter1; +// typedef typename iter1::type T1; +// typedef typename iter1::next iter2; +// typedef typename iter2::type T2; +// typedef typename iter2::next iter3; +// typedef typename iter3::type T3; +// typedef typename iter3::next iter4; +// +// static RT func_0(T0 arg0) +// { return foo(arg0); } +// +// static RT func_1(T0 arg0, T1 arg1) +// { return foo(arg0, arg1); } +// +// static RT func_2(T0 arg0, T1 arg1, T2 arg2) +// { return foo(arg0, arg1, arg2); } +// +// static RT func_3(T0 arg0, T1 arg1, T2 arg2, T3 arg3) +// { return foo(arg0, arg1, arg2, arg3); } +// }; +// }; +// +// struct foo_overloads +// : public boost::python::detail::overloads_common<foo_overloads> +// { +// typedef foo_overloadsNonVoid non_void_return_type; +// typedef foo_overloadsNonVoid void_return_type; +// +// foo_overloads(char const* doc = 0) +// : boost::python::detail::overloads_common<foo_overloads>(doc) {} +// }; +// +// The typedefs non_void_return_type and void_return_type are +// used to handle compilers that do not support void returns. The +// example above typedefs non_void_return_type and +// void_return_type to foo_overloadsNonVoid. On compilers that do +// not support void returns, there are two versions: +// foo_overloadsNonVoid and foo_overloadsVoid. The "Void" +// version is almost identical to the "NonVoid" version except +// for the return type (void) and the lack of the return keyword. +// +// See the overloads_common above for a description of the +// foo_overloads' base class. +// +/////////////////////////////////////////////////////////////////////////////// +#define BOOST_PYTHON_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \ + BOOST_PYTHON_GEN_FUNCTION_STUB( \ + fname, \ + generator_name, \ + max_args, \ + BOOST_PP_SUB_D(1, max_args, min_args)) + +#define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \ + BOOST_PYTHON_GEN_MEM_FUNCTION_STUB( \ + fname, \ + generator_name, \ + max_args, \ + BOOST_PP_SUB_D(1, max_args, min_args)) + +// deprecated macro names (to be removed) +#define BOOST_PYTHON_FUNCTION_GENERATOR BOOST_PYTHON_FUNCTION_OVERLOADS +#define BOOST_PYTHON_MEM_FUN_GENERATOR BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS + +/////////////////////////////////////////////////////////////////////////////// +#endif // DEFAULTS_GEN_JDG20020807_HPP + + diff --git a/boost/python/detail/dependent.hpp b/boost/python/detail/dependent.hpp new file mode 100644 index 0000000000..70392c4d78 --- /dev/null +++ b/boost/python/detail/dependent.hpp @@ -0,0 +1,27 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef DEPENDENT_DWA200286_HPP +# define DEPENDENT_DWA200286_HPP + +namespace boost { namespace python { namespace detail { + +// A way to turn a concrete type T into a type dependent on U. This +// keeps conforming compilers (those implementing proper 2-phase +// name lookup for templates) from complaining about incomplete +// types in situations where it would otherwise be inconvenient or +// impossible to re-order code so that all types are defined in time. + +// One such use is when we must return an incomplete T from a member +// function template (which must be defined in the class body to +// keep MSVC happy). +template <class T, class U> +struct dependent +{ + typedef T type; +}; + +}}} // namespace boost::python::detail + +#endif // DEPENDENT_DWA200286_HPP diff --git a/boost/python/detail/destroy.hpp b/boost/python/detail/destroy.hpp new file mode 100644 index 0000000000..0172dca28f --- /dev/null +++ b/boost/python/detail/destroy.hpp @@ -0,0 +1,106 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef DESTROY_DWA2002221_HPP +# define DESTROY_DWA2002221_HPP + +# include <boost/type_traits/is_array.hpp> +# include <boost/detail/workaround.hpp> +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) +# include <boost/type_traits/is_enum.hpp> +# endif +namespace boost { namespace python { namespace detail { + +template < + bool array +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + , bool enum_ // vc7 has a problem destroying enums +# endif + > struct value_destroyer; + +template <> +struct value_destroyer< + false +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + , false +# endif + > +{ + template <class T> + static void execute(T const volatile* p) + { + p->~T(); + } +}; + +template <> +struct value_destroyer< + true +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + , false +# endif + > +{ + template <class A, class T> + static void execute(A*, T const volatile* const first) + { + for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p) + { + value_destroyer< + boost::is_array<T>::value +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + , boost::is_enum<T>::value +# endif + >::execute(p); + } + } + + template <class T> + static void execute(T const volatile* p) + { + execute(p, *p); + } +}; + +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) +template <> +struct value_destroyer<true,true> +{ + template <class T> + static void execute(T const volatile*) + { + } +}; + +template <> +struct value_destroyer<false,true> +{ + template <class T> + static void execute(T const volatile*) + { + } +}; +# endif +template <class T> +inline void destroy_referent_impl(void* p, T& (*)()) +{ + // note: cv-qualification needed for MSVC6 + // must come *before* T for metrowerks + value_destroyer< + (boost::is_array<T>::value) +# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + , (boost::is_enum<T>::value) +# endif + >::execute((const volatile T*)p); +} + +template <class T> +inline void destroy_referent(void* p, T(*)() = 0) +{ + destroy_referent_impl(p, (T(*)())0); +} + +}}} // namespace boost::python::detail + +#endif // DESTROY_DWA2002221_HPP diff --git a/boost/python/detail/enable_if.hpp b/boost/python/detail/enable_if.hpp new file mode 100644 index 0000000000..46a1d532b3 --- /dev/null +++ b/boost/python/detail/enable_if.hpp @@ -0,0 +1,72 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef ENABLE_IF_DWA2004722_HPP +# define ENABLE_IF_DWA2004722_HPP + +# include <boost/python/detail/sfinae.hpp> +# include <boost/detail/workaround.hpp> + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# include <boost/mpl/if.hpp> + +namespace boost { namespace python { namespace detail { + +template <class T> struct always_void { typedef void type; }; + +template <class C, class T = int> +struct enable_if_arg +{ + typedef typename mpl::if_<C,T,int&>::type type; +}; + +template <class C, class T = int> +struct disable_if_arg +{ + typedef typename mpl::if_<C,int&,T>::type type; +}; + +template <class C, class T = typename always_void<C>::type> +struct enable_if_ret +{ + typedef typename mpl::if_<C,T,int[2]>::type type; +}; + +template <class C, class T = typename always_void<C>::type> +struct disable_if_ret +{ + typedef typename mpl::if_<C,int[2],T>::type type; +}; + +}}} // namespace boost::python::detail + +# elif !defined(BOOST_NO_SFINAE) +# include <boost/utility/enable_if.hpp> + +namespace boost { namespace python { namespace detail { + +template <class C, class T = int> +struct enable_if_arg + : enable_if<C,T> +{}; + +template <class C, class T = int> +struct disable_if_arg + : disable_if<C,T> +{}; + +template <class C, class T = void> +struct enable_if_ret + : enable_if<C,T> +{}; + +template <class C, class T = void> +struct disable_if_ret + : disable_if<C,T> +{}; + +}}} // namespace boost::python::detail + +# endif + +#endif // ENABLE_IF_DWA2004722_HPP diff --git a/boost/python/detail/exception_handler.hpp b/boost/python/detail/exception_handler.hpp new file mode 100644 index 0000000000..7f49868be6 --- /dev/null +++ b/boost/python/detail/exception_handler.hpp @@ -0,0 +1,48 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef EXCEPTION_HANDLER_DWA2002810_HPP +# define EXCEPTION_HANDLER_DWA2002810_HPP + +# include <boost/python/detail/config.hpp> +# include <boost/function/function0.hpp> +# include <boost/function/function2.hpp> + +namespace boost { namespace python { namespace detail { + +struct BOOST_PYTHON_DECL_FORWARD exception_handler; + +typedef function2<bool, exception_handler const&, function0<void> const&> handler_function; + +struct BOOST_PYTHON_DECL exception_handler +{ + private: // types + + public: + explicit exception_handler(handler_function const& impl); + + inline bool handle(function0<void> const& f) const; + + bool operator()(function0<void> const& f) const; + + static exception_handler* chain; + + private: + static exception_handler* tail; + + handler_function m_impl; + exception_handler* m_next; +}; + + +inline bool exception_handler::handle(function0<void> const& f) const +{ + return this->m_impl(*this, f); +} + +BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f); + +}}} // namespace boost::python::detail + +#endif // EXCEPTION_HANDLER_DWA2002810_HPP diff --git a/boost/python/detail/force_instantiate.hpp b/boost/python/detail/force_instantiate.hpp new file mode 100644 index 0000000000..63e2874945 --- /dev/null +++ b/boost/python/detail/force_instantiate.hpp @@ -0,0 +1,32 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef FORCE_INSTANTIATE_DWA200265_HPP +# define FORCE_INSTANTIATE_DWA200265_HPP + +namespace boost { namespace python { namespace detail { + +// Allows us to force the argument to be instantiated without +// incurring unused variable warnings + +# if !defined(BOOST_MSVC) || BOOST_MSVC < 1300 || _MSC_FULL_VER > 13102196 + +template <class T> +inline void force_instantiate(T const&) {} + +# else + +# pragma optimize("g", off) +inline void force_instantiate_impl(...) {} +# pragma optimize("", on) +template <class T> +inline void force_instantiate(T const& x) +{ + detail::force_instantiate_impl(&x); +} +# endif + +}}} // namespace boost::python::detail + +#endif // FORCE_INSTANTIATE_DWA200265_HPP diff --git a/boost/python/detail/if_else.hpp b/boost/python/detail/if_else.hpp new file mode 100644 index 0000000000..244e63a8ae --- /dev/null +++ b/boost/python/detail/if_else.hpp @@ -0,0 +1,116 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef IF_ELSE_DWA2002322_HPP +# define IF_ELSE_DWA2002322_HPP +# include <boost/config.hpp> + +namespace boost { namespace python { namespace detail { + +template <class T> struct elif_selected; + +template <class T> +struct if_selected +{ + template <bool b> + struct elif : elif_selected<T> + { + }; + + template <class U> + struct else_ + { + typedef T type; + }; +}; + +# if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) +namespace msvc70_aux { + +template< bool > struct inherit_from +{ + template< typename T > struct result + { + typedef T type; + }; +}; + +template<> struct inherit_from<true> +{ + template< typename T > struct result + { + struct type {}; + }; +}; + +template< typename T > +struct never_true +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +} // namespace msvc70_aux + +#endif // # if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) + +template <class T> +struct elif_selected +{ +# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) + template <class U> class then; +# elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300) + template <class U> + struct then : msvc70_aux::inherit_from< msvc70_aux::never_true<U>::value > + ::template result< if_selected<T> >::type + { + }; +# else + template <class U> + struct then : if_selected<T> + { + }; +# endif +}; + +# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) +template <class T> +template <class U> +class elif_selected<T>::then : public if_selected<T> +{ +}; +# endif + +template <bool b> struct if_ +{ + template <class T> + struct then : if_selected<T> + { + }; +}; + +struct if_unselected +{ + template <bool b> struct elif : if_<b> + { + }; + + template <class U> + struct else_ + { + typedef U type; + }; +}; + +template <> +struct if_<false> +{ + template <class T> + struct then : if_unselected + { + }; +}; + +}}} // namespace boost::python::detail + +#endif // IF_ELSE_DWA2002322_HPP diff --git a/boost/python/detail/indirect_traits.hpp b/boost/python/detail/indirect_traits.hpp new file mode 100644 index 0000000000..ce8ba310a2 --- /dev/null +++ b/boost/python/detail/indirect_traits.hpp @@ -0,0 +1,13 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef INDIRECT_TRAITS_DWA2004915_HPP +# define INDIRECT_TRAITS_DWA2004915_HPP + +# include <boost/detail/indirect_traits.hpp> + +namespace boost { namespace python { +namespace indirect_traits = boost::detail::indirect_traits; +}} // namespace boost::python::detail + +#endif // INDIRECT_TRAITS_DWA2004915_HPP diff --git a/boost/python/detail/invoke.hpp b/boost/python/detail/invoke.hpp new file mode 100644 index 0000000000..939fa11818 --- /dev/null +++ b/boost/python/detail/invoke.hpp @@ -0,0 +1,100 @@ +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +# ifndef INVOKE_DWA20021122_HPP +# define INVOKE_DWA20021122_HPP + +# include <boost/python/detail/prefix.hpp> +# include <boost/python/detail/preprocessor.hpp> +# include <boost/python/detail/none.hpp> + +# include <boost/type_traits/is_member_function_pointer.hpp> + +# include <boost/preprocessor/iterate.hpp> +# include <boost/preprocessor/facilities/intercept.hpp> +# include <boost/preprocessor/repetition/enum_trailing_params.hpp> +# include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp> +# include <boost/preprocessor/repetition/enum_binary_params.hpp> +# include <boost/python/to_python_value.hpp> + +// This file declares a series of overloaded invoke(...) functions, +// used to invoke wrapped C++ function (object)s from Python. Each one +// accepts: +// +// - a tag which identifies the invocation syntax (e.g. member +// functions must be invoked with a different syntax from regular +// functions) +// +// - a pointer to a result converter type, used solely as a way of +// transmitting the type of the result converter to the function (or +// an int, if the return type is void). +// +// - the "function", which may be a function object, a function or +// member function pointer, or a defaulted_virtual_fn. +// +// - The arg_from_python converters for each of the arguments to be +// passed to the function being invoked. + +namespace boost { namespace python { namespace detail { + +// This "result converter" is really just used as a dispatch tag to +// invoke(...), selecting the appropriate implementation +typedef int void_result_to_python; + +template <bool void_return, bool member> +struct invoke_tag_ {}; + +// A metafunction returning the appropriate tag type for invoking an +// object of type F with return type R. +template <class R, class F> +struct invoke_tag + : invoke_tag_< + is_same<R,void>::value + , is_member_function_pointer<F>::value + > +{ +}; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/invoke.hpp>)) +# include BOOST_PP_ITERATE() + +}}} // namespace boost::python::detail + +# endif // INVOKE_DWA20021122_HPP +#else + +# define N BOOST_PP_ITERATION() + +template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)> +inline PyObject* invoke(invoke_tag_<false,false>, RC const& rc, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + return rc(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) )); +} + +template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)> +inline PyObject* invoke(invoke_tag_<true,false>, RC const&, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ); + return none(); +} + +template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)> +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) ) +{ + return rc( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) ); +} + +template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)> +inline PyObject* invoke(invoke_tag_<true,true>, RC const&, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)); + return none(); +} + +# undef N + +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/python/detail/is_auto_ptr.hpp b/boost/python/detail/is_auto_ptr.hpp new file mode 100644 index 0000000000..3b8198b8dd --- /dev/null +++ b/boost/python/detail/is_auto_ptr.hpp @@ -0,0 +1,30 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_AUTO_PTR_DWA2003224_HPP +# define IS_AUTO_PTR_DWA2003224_HPP + +# ifndef BOOST_NO_AUTO_PTR +# include <boost/python/detail/is_xxx.hpp> +# include <memory> +# endif + +namespace boost { namespace python { namespace detail { + +# if !defined(BOOST_NO_AUTO_PTR) + +BOOST_PYTHON_IS_XXX_DEF(auto_ptr, std::auto_ptr, 1) + +# else + +template <class T> +struct is_auto_ptr : mpl::false_ +{ +}; + +# endif + +}}} // namespace boost::python::detail + +#endif // IS_AUTO_PTR_DWA2003224_HPP diff --git a/boost/python/detail/is_shared_ptr.hpp b/boost/python/detail/is_shared_ptr.hpp new file mode 100644 index 0000000000..547af3f1cb --- /dev/null +++ b/boost/python/detail/is_shared_ptr.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_SHARED_PTR_DWA2003224_HPP +# define IS_SHARED_PTR_DWA2003224_HPP + +# include <boost/python/detail/is_xxx.hpp> +# include <boost/shared_ptr.hpp> + +namespace boost { namespace python { namespace detail { + +BOOST_PYTHON_IS_XXX_DEF(shared_ptr, shared_ptr, 1) + +}}} // namespace boost::python::detail + +#endif // IS_SHARED_PTR_DWA2003224_HPP diff --git a/boost/python/detail/is_wrapper.hpp b/boost/python/detail/is_wrapper.hpp new file mode 100644 index 0000000000..d7bce7b627 --- /dev/null +++ b/boost/python/detail/is_wrapper.hpp @@ -0,0 +1,29 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_WRAPPER_DWA2004723_HPP +# define IS_WRAPPER_DWA2004723_HPP + +# include <boost/python/detail/prefix.hpp> +# include <boost/mpl/bool.hpp> + +namespace boost { namespace python { + +template <class T> class wrapper; + +namespace detail +{ + typedef char (&is_not_wrapper)[2]; + is_not_wrapper is_wrapper_helper(...); + template <class T> + char is_wrapper_helper(wrapper<T> const volatile*); + + // A metafunction returning true iff T is [derived from] wrapper<U> + template <class T> + struct is_wrapper + : mpl::bool_<(sizeof(detail::is_wrapper_helper((T*)0)) == 1)> + {}; + +}}} // namespace boost::python::detail + +#endif // IS_WRAPPER_DWA2004723_HPP diff --git a/boost/python/detail/is_xxx.hpp b/boost/python/detail/is_xxx.hpp new file mode 100644 index 0000000000..9ddfafd3c0 --- /dev/null +++ b/boost/python/detail/is_xxx.hpp @@ -0,0 +1,13 @@ +// Copyright David Abrahams 2005. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_XXX_DWA2003224_HPP +# define IS_XXX_DWA2003224_HPP + +# include <boost/detail/is_xxx.hpp> + +# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \ + BOOST_DETAIL_IS_XXX_DEF(name, qualified_name, nargs) + +#endif // IS_XXX_DWA2003224_HPP diff --git a/boost/python/detail/make_keyword_range_fn.hpp b/boost/python/detail/make_keyword_range_fn.hpp new file mode 100644 index 0000000000..c4795cf887 --- /dev/null +++ b/boost/python/detail/make_keyword_range_fn.hpp @@ -0,0 +1,72 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP +# define MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP + +# include <boost/python/make_function.hpp> +# include <boost/python/args_fwd.hpp> + +# include <boost/python/object/make_holder.hpp> + +# include <boost/mpl/size.hpp> + + +namespace boost { namespace python { namespace detail { + +// Think of this as a version of make_function without a compile-time +// check that the size of kw is no greater than the expected arity of +// F. This version is needed when defining functions with default +// arguments, because compile-time information about the number of +// keywords is missing for all but the initial function definition. +// +// @group make_keyword_range_function { +template <class F, class Policies> +object make_keyword_range_function( + F f + , Policies const& policies + , keyword_range const& kw) +{ + return detail::make_function_aux( + f, policies, detail::get_signature(f), kw, mpl::int_<0>()); +} + +template <class F, class Policies, class Signature> +object make_keyword_range_function( + F f + , Policies const& policies + , keyword_range const& kw + , Signature const& sig) +{ + return detail::make_function_aux( + f, policies, sig, kw, mpl::int_<0>()); +} +// } + +// Builds an '__init__' function which inserts the given Holder type +// in a wrapped C++ class instance. ArgList is an MPL type sequence +// describing the C++ argument types to be passed to Holder's +// constructor. +// +// Holder and ArgList are intended to be explicitly specified. +template <class ArgList, class Arity, class Holder, class CallPolicies> +object make_keyword_range_constructor( + CallPolicies const& policies // The CallPolicies with which to invoke the Holder's constructor + , detail::keyword_range const& kw // The (possibly empty) set of associated argument keywords + , Holder* = 0 + , ArgList* = 0, Arity* = 0) +{ +#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE) + python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_(); +#endif + return detail::make_keyword_range_function( + objects::make_holder<Arity::value> + ::template apply<Holder,ArgList>::execute + , policies + , kw); +} + +}}} // namespace boost::python::detail + +#endif // MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP diff --git a/boost/python/detail/make_tuple.hpp b/boost/python/detail/make_tuple.hpp new file mode 100644 index 0000000000..57b285be1c --- /dev/null +++ b/boost/python/detail/make_tuple.hpp @@ -0,0 +1,32 @@ +# ifndef BOOST_PYTHON_SYNOPSIS +# // Copyright David Abrahams 2002. +# // Distributed under the Boost Software License, Version 1.0. (See +# // accompanying file LICENSE_1_0.txt or copy at +# // http://www.boost.org/LICENSE_1_0.txt) + +# if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Python - do not include this file! +# endif + +# define N BOOST_PP_ITERATION() + +# define BOOST_PYTHON_MAKE_TUPLE_ARG(z, N, ignored) \ + PyTuple_SET_ITEM( \ + result.ptr() \ + , N \ + , python::incref(python::object(a##N).ptr()) \ + ); + + template <BOOST_PP_ENUM_PARAMS_Z(1, N, class A)> + tuple + make_tuple(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)) + { + tuple result((detail::new_reference)::PyTuple_New(N)); + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_MAKE_TUPLE_ARG, _) + return result; + } + +# undef BOOST_PYTHON_MAKE_TUPLE_ARG + +# undef N +# endif // BOOST_PYTHON_SYNOPSIS diff --git a/boost/python/detail/map_entry.hpp b/boost/python/detail/map_entry.hpp new file mode 100644 index 0000000000..8bf1759f9f --- /dev/null +++ b/boost/python/detail/map_entry.hpp @@ -0,0 +1,43 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef MAP_ENTRY_DWA2002118_HPP +# define MAP_ENTRY_DWA2002118_HPP + +namespace boost { namespace python { namespace detail { + +// A trivial type that works well as the value_type of associative +// vector maps +template <class Key, class Value> +struct map_entry +{ + map_entry() {} + map_entry(Key k) : key(k), value() {} + map_entry(Key k, Value v) : key(k), value(v) {} + + bool operator<(map_entry const& rhs) const + { + return this->key < rhs.key; + } + + Key key; + Value value; +}; + +template <class Key, class Value> +bool operator<(map_entry<Key,Value> const& e, Key const& k) +{ + return e.key < k; +} + +template <class Key, class Value> +bool operator<(Key const& k, map_entry<Key,Value> const& e) +{ + return k < e.key; +} + + +}}} // namespace boost::python::detail + +#endif // MAP_ENTRY_DWA2002118_HPP diff --git a/boost/python/detail/mpl_lambda.hpp b/boost/python/detail/mpl_lambda.hpp new file mode 100644 index 0000000000..a20608e710 --- /dev/null +++ b/boost/python/detail/mpl_lambda.hpp @@ -0,0 +1,12 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef MPL_LAMBDA_DWA2002122_HPP +# define MPL_LAMBDA_DWA2002122_HPP + +// this header should go away soon +# include <boost/mpl/aux_/lambda_support.hpp> +# define BOOST_PYTHON_MPL_LAMBDA_SUPPORT BOOST_MPL_AUX_LAMBDA_SUPPORT + +#endif // MPL_LAMBDA_DWA2002122_HPP diff --git a/boost/python/detail/msvc_typeinfo.hpp b/boost/python/detail/msvc_typeinfo.hpp new file mode 100644 index 0000000000..10f845058a --- /dev/null +++ b/boost/python/detail/msvc_typeinfo.hpp @@ -0,0 +1,75 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef MSVC_TYPEINFO_DWA200222_HPP +# define MSVC_TYPEINFO_DWA200222_HPP + +#include <typeinfo> +#include <boost/type.hpp> +#include <boost/type_traits/config.hpp> + +// +// Fix for MSVC's broken typeid() implementation which doesn't strip +// decoration. This fix doesn't handle cv-qualified array types. It +// could probably be done, but I haven't figured it out yet. +// + +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 700 + +namespace boost { namespace python { namespace detail { + +typedef std::type_info const& typeinfo; + +template <class T> +static typeinfo typeid_nonref(T const volatile*) { return typeid(T); } + +template <class T> +inline typeinfo typeid_ref_1(T&(*)()) +{ + return detail::typeid_nonref((T*)0); +} + +// A non-reference +template <class T> +inline typeinfo typeid_ref(type<T>*, T&(*)(type<T>)) +{ + return detail::typeid_nonref((T*)0); +} + +// A reference +template <class T> +inline typeinfo typeid_ref(type<T>*, ...) +{ + return detail::typeid_ref_1((T(*)())0); +} + +template< typename T > T&(* is_ref_tester1(type<T>) )(type<T>) { return 0; } +inline char BOOST_TT_DECL is_ref_tester1(...) { return 0; } + +template <class T> +inline typeinfo msvc_typeid(boost::type<T>*) +{ + return detail::typeid_ref( + (boost::type<T>*)0, detail::is_ref_tester1(type<T>()) + ); +} + +template <> +inline typeinfo msvc_typeid<void>(boost::type<void>*) +{ + return typeid(void); +} + +# ifndef NDEBUG +inline typeinfo assert_array_typeid_compiles() +{ + return msvc_typeid((boost::type<char const[3]>*)0) + , msvc_typeid((boost::type<char[3]>*)0); +} +# endif + +}}} // namespace boost::python::detail + +# endif // BOOST_MSVC +#endif // MSVC_TYPEINFO_DWA200222_HPP diff --git a/boost/python/detail/none.hpp b/boost/python/detail/none.hpp new file mode 100644 index 0000000000..bc3337a234 --- /dev/null +++ b/boost/python/detail/none.hpp @@ -0,0 +1,20 @@ +// (C) Copyright David Abrahams 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The author gratefully acknowleges the support of Dragon Systems, Inc., in +// producing this work. + +#ifndef NONE_DWA_052000_H_ +# define NONE_DWA_052000_H_ + +# include <boost/python/detail/prefix.hpp> + +namespace boost { namespace python { namespace detail { + +inline PyObject* none() { Py_INCREF(Py_None); return Py_None; } + +}}} // namespace boost::python::detail + +#endif // NONE_DWA_052000_H_ diff --git a/boost/python/detail/not_specified.hpp b/boost/python/detail/not_specified.hpp new file mode 100644 index 0000000000..2f7c7ad997 --- /dev/null +++ b/boost/python/detail/not_specified.hpp @@ -0,0 +1,14 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef NOT_SPECIFIED_DWA2002321_HPP +# define NOT_SPECIFIED_DWA2002321_HPP + +namespace boost { namespace python { namespace detail { + + struct not_specified {}; + +}}} // namespace boost::python::detail + +#endif // NOT_SPECIFIED_DWA2002321_HPP diff --git a/boost/python/detail/nullary_function_adaptor.hpp b/boost/python/detail/nullary_function_adaptor.hpp new file mode 100644 index 0000000000..9dcc434f8e --- /dev/null +++ b/boost/python/detail/nullary_function_adaptor.hpp @@ -0,0 +1,46 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef NULLARY_FUNCTION_ADAPTOR_DWA2003824_HPP +# define NULLARY_FUNCTION_ADAPTOR_DWA2003824_HPP + +# include <boost/python/detail/prefix.hpp> +# include <boost/preprocessor/iteration/local.hpp> +# include <boost/preprocessor/facilities/intercept.hpp> +# include <boost/preprocessor/repetition/enum_params.hpp> +# include <boost/preprocessor/repetition/enum_binary_params.hpp> + +namespace boost { namespace python { namespace detail { + +// nullary_function_adaptor -- a class template which ignores its +// arguments and calls a nullary function instead. Used for building +// error-reporting functions, c.f. pure_virtual +template <class NullaryFunction> +struct nullary_function_adaptor +{ + nullary_function_adaptor(NullaryFunction fn) + : m_fn(fn) + {} + + void operator()() const { m_fn(); } + +# define BOOST_PP_LOCAL_MACRO(i) \ + template <BOOST_PP_ENUM_PARAMS_Z(1, i, class A)> \ + void operator()( \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(1, i, A, const& BOOST_PP_INTERCEPT) \ + ) const \ + { \ + m_fn(); \ + } + +# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) +# include BOOST_PP_LOCAL_ITERATE() + + private: + NullaryFunction m_fn; +}; + +}}} // namespace boost::python::detail + +#endif // NULLARY_FUNCTION_ADAPTOR_DWA2003824_HPP diff --git a/boost/python/detail/operator_id.hpp b/boost/python/detail/operator_id.hpp new file mode 100644 index 0000000000..ecfc70f108 --- /dev/null +++ b/boost/python/detail/operator_id.hpp @@ -0,0 +1,63 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef OPERATOR_ID_DWA2002531_HPP +# define OPERATOR_ID_DWA2002531_HPP + +namespace boost { namespace python { namespace detail { + +enum operator_id +{ + op_add, + op_sub, + op_mul, + op_div, + op_mod, + op_divmod, + op_pow, + op_lshift, + op_rshift, + op_and, + op_xor, + op_or, + op_neg, + op_pos, + op_abs, + op_invert, + op_int, + op_long, + op_float, + op_str, + op_cmp, + op_gt, + op_ge, + op_lt, + op_le, + op_eq, + op_ne, + op_iadd, + op_isub, + op_imul, + op_idiv, + op_imod, + op_ilshift, + op_irshift, + op_iand, + op_ixor, + op_ior, + op_complex, +#if PY_VERSION_HEX >= 0x03000000 + op_bool, +#else + op_nonzero, +#endif + op_repr +#if PY_VERSION_HEX >= 0x03000000 + ,op_truediv +#endif +}; + +}}} // namespace boost::python::detail + +#endif // OPERATOR_ID_DWA2002531_HPP diff --git a/boost/python/detail/overloads_fwd.hpp b/boost/python/detail/overloads_fwd.hpp new file mode 100644 index 0000000000..4c7fdf292b --- /dev/null +++ b/boost/python/detail/overloads_fwd.hpp @@ -0,0 +1,18 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef OVERLOADS_FWD_DWA2002101_HPP +# define OVERLOADS_FWD_DWA2002101_HPP + +namespace boost { namespace python { namespace detail { + +// forward declarations +struct overloads_base; + +template <class OverloadsT, class NameSpaceT, class SigT> +inline void define_with_defaults(char const* name, OverloadsT const&, NameSpaceT&, SigT const&); + +}}} // namespace boost::python::detail + +#endif // OVERLOADS_FWD_DWA2002101_HPP diff --git a/boost/python/detail/pointee.hpp b/boost/python/detail/pointee.hpp new file mode 100644 index 0000000000..e18c1f49b6 --- /dev/null +++ b/boost/python/detail/pointee.hpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef POINTEE_DWA2002323_HPP +# define POINTEE_DWA2002323_HPP + +# include <boost/type_traits/object_traits.hpp> + +namespace boost { namespace python { namespace detail { + +template <bool is_ptr = true> +struct pointee_impl +{ + template <class T> struct apply : remove_pointer<T> {}; +}; + +template <> +struct pointee_impl<false> +{ + template <class T> struct apply + { + typedef typename T::element_type type; + }; +}; + +template <class T> +struct pointee + : pointee_impl<is_pointer<T>::value>::template apply<T> +{ +}; + +}}} // namespace boost::python::detail + +#endif // POINTEE_DWA2002323_HPP diff --git a/boost/python/detail/prefix.hpp b/boost/python/detail/prefix.hpp new file mode 100644 index 0000000000..8b34ed7701 --- /dev/null +++ b/boost/python/detail/prefix.hpp @@ -0,0 +1,16 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef PREFIX_DWA2003531_HPP +# define PREFIX_DWA2003531_HPP + +// The rule is that <Python.h> must be included before any system +// headers (so it can get control over some awful macros). +// Unfortunately, Boost.Python needs to #include <limits.h> first, at +// least... but this gets us as close as possible. + +# include <boost/python/detail/wrap_python.hpp> +# include <boost/python/detail/config.hpp> + +#endif // PREFIX_DWA2003531_HPP diff --git a/boost/python/detail/preprocessor.hpp b/boost/python/detail/preprocessor.hpp new file mode 100644 index 0000000000..2c1b2e84ea --- /dev/null +++ b/boost/python/detail/preprocessor.hpp @@ -0,0 +1,66 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef PREPROCESSOR_DWA200247_HPP +# define PREPROCESSOR_DWA200247_HPP + +# include <boost/preprocessor/cat.hpp> +# include <boost/preprocessor/comma_if.hpp> +# include <boost/preprocessor/repeat.hpp> +# include <boost/preprocessor/tuple/elem.hpp> + +// stuff that should be in the preprocessor library + +# define BOOST_PYTHON_APPLY(x) BOOST_PP_CAT(BOOST_PYTHON_APPLY_, x) + +# define BOOST_PYTHON_APPLY_BOOST_PYTHON_ITEM(v) v +# define BOOST_PYTHON_APPLY_BOOST_PYTHON_NIL + +// cv-qualifiers + +# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 +# define BOOST_PYTHON_CV_COUNT 4 +# else +# define BOOST_PYTHON_CV_COUNT 1 +# endif + +# ifndef BOOST_PYTHON_MAX_ARITY +# define BOOST_PYTHON_MAX_ARITY 15 +# endif + +# ifndef BOOST_PYTHON_MAX_BASES +# define BOOST_PYTHON_MAX_BASES 10 +# endif + +# define BOOST_PYTHON_CV_QUALIFIER(i) \ + BOOST_PYTHON_APPLY( \ + BOOST_PP_TUPLE_ELEM(4, i, BOOST_PYTHON_CV_QUALIFIER_I) \ + ) + +# define BOOST_PYTHON_CV_QUALIFIER_I \ + ( \ + BOOST_PYTHON_NIL, \ + BOOST_PYTHON_ITEM(const), \ + BOOST_PYTHON_ITEM(volatile), \ + BOOST_PYTHON_ITEM(const volatile) \ + ) + +// enumerators +# define BOOST_PYTHON_UNARY_ENUM(c, text) BOOST_PP_REPEAT(c, BOOST_PYTHON_UNARY_ENUM_I, text) +# define BOOST_PYTHON_UNARY_ENUM_I(z, n, text) BOOST_PP_COMMA_IF(n) text ## n + +# define BOOST_PYTHON_BINARY_ENUM(c, a, b) BOOST_PP_REPEAT(c, BOOST_PYTHON_BINARY_ENUM_I, (a, b)) +# define BOOST_PYTHON_BINARY_ENUM_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, _), n) + +# define BOOST_PYTHON_ENUM_WITH_DEFAULT(c, text, def) BOOST_PP_REPEAT(c, BOOST_PYTHON_ENUM_WITH_DEFAULT_I, (text, def)) +# define BOOST_PYTHON_ENUM_WITH_DEFAULT_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) = BOOST_PP_TUPLE_ELEM(2, 1, _) + +// fixed text (no commas) +# define BOOST_PYTHON_FIXED(z, n, text) text + +// flags +# define BOOST_PYTHON_FUNCTION_POINTER 0x0001 +# define BOOST_PYTHON_POINTER_TO_MEMBER 0x0002 + +#endif // PREPROCESSOR_DWA200247_HPP diff --git a/boost/python/detail/python22_fixed.h b/boost/python/detail/python22_fixed.h new file mode 100644 index 0000000000..32bf941fef --- /dev/null +++ b/boost/python/detail/python22_fixed.h @@ -0,0 +1,152 @@ +// This file is a modified version of Python 2.2/2.2.1 Python.h. As +// such it is: +// +// Copyright (c) 2001, 2002 Python Software Foundation; All Rights +// Reserved +// +// boostinspect:nolicense (don't complain about the lack of a Boost license) +// +// Changes from the original: +// 1. #includes <unistd.h> for Python 2.2.1 +// 2. Provides missing extern "C" wrapper for "iterobject.h" and "descrobject.h". +// + +// Changes marked with "Boost.Python modification" +#ifndef Py_PYTHON_H +#define Py_PYTHON_H +/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ + + +/* Enable compiler features; switching on C lib defines doesn't work + here, because the symbols haven't necessarily been defined yet. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +/* Forcing SUSv2 compatibility still produces problems on some + platforms, True64 and SGI IRIX begin two of them, so for now the + define is switched off. */ +#if 0 +#ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +#endif +#endif + +/* Include nearly all Python header files */ + +#include "patchlevel.h" +#include "pyconfig.h" + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +/* pyconfig.h may or may not define DL_IMPORT */ +#ifndef DL_IMPORT /* declarations for DLL import/export */ +#define DL_IMPORT(RTYPE) RTYPE +#endif +#ifndef DL_EXPORT /* declarations for DLL import/export */ +#define DL_EXPORT(RTYPE) RTYPE +#endif + +#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) +#define _SGI_MP_SOURCE +#endif + +#include <stdio.h> +#ifndef NULL +# error "Python.h requires that stdio.h define NULL." +#endif + +#include <string.h> +#include <errno.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#if PY_MICRO_VERSION == 1 // Boost.Python modification: emulate Python 2.2 +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#endif // Boost.Python modification: emulate Python 2.2 + +/* CAUTION: Build setups should ensure that NDEBUG is defined on the + * compiler command line when building Python in release mode; else + * assert() calls won't be removed. + */ +#include <assert.h> + +#include "pyport.h" + +#include "pymem.h" + +#include "object.h" +#include "objimpl.h" + +#include "pydebug.h" + +#include "unicodeobject.h" +#include "intobject.h" +#include "longobject.h" +#include "floatobject.h" +#ifndef WITHOUT_COMPLEX +#include "complexobject.h" +#endif +#include "rangeobject.h" +#include "stringobject.h" +#include "bufferobject.h" +#include "tupleobject.h" +#include "listobject.h" +#include "dictobject.h" +#include "methodobject.h" +#include "moduleobject.h" +#include "funcobject.h" +#include "classobject.h" +#include "fileobject.h" +#include "cobject.h" +#include "traceback.h" +#include "sliceobject.h" +#include "cellobject.h" +extern "C" { // Boost.Python modification: provide missing extern "C" +#include "iterobject.h" +#include "descrobject.h" +} // Boost.Python modification: provide missing extern "C" +#include "weakrefobject.h" + +#include "codecs.h" +#include "pyerrors.h" + +#include "pystate.h" + +#include "modsupport.h" +#include "pythonrun.h" +#include "ceval.h" +#include "sysmodule.h" +#include "intrcheck.h" +#include "import.h" + +#include "abstract.h" + +#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a)) +#define PyArg_NoArgs(v) PyArg_Parse(v, "") + +/* Convert a possibly signed character to a nonnegative int */ +/* XXX This assumes characters are 8 bits wide */ +#ifdef __CHAR_UNSIGNED__ +#define Py_CHARMASK(c) (c) +#else +#define Py_CHARMASK(c) ((c) & 0xff) +#endif + +#include "pyfpe.h" + +/* These definitions must match corresponding definitions in graminit.h. + There's code in compile.c that checks that they are the same. */ +#define Py_single_input 256 +#define Py_file_input 257 +#define Py_eval_input 258 + +#ifdef HAVE_PTH +/* GNU pth user-space thread support */ +#include <pth.h> +#endif +#endif /* !Py_PYTHON_H */ diff --git a/boost/python/detail/python_type.hpp b/boost/python/detail/python_type.hpp new file mode 100644 index 0000000000..f7630c175a --- /dev/null +++ b/boost/python/detail/python_type.hpp @@ -0,0 +1,37 @@ +// Copyright Nikolay Mladenov 2007. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_PYTHON_OBJECT_PYTHON_TYPE_H +#define BOOST_PYTHON_OBJECT_PYTHON_TYPE_H + +#include <boost/python/converter/registered.hpp> + +namespace boost {namespace python {namespace detail{ + + +template <class T> struct python_class : PyObject +{ + typedef python_class<T> this_type; + + typedef T type; + + static void *converter (PyObject *p){ + return p; + } + + static void register_() + { + static bool first_time = true; + + if ( !first_time ) return; + + first_time = false; + converter::registry::insert(&converter, boost::python::type_id<this_type>(), &converter::registered_pytype_direct<T>::get_pytype); + } +}; + + +}}} //namespace boost :: python :: detail + +#endif //BOOST_PYTHON_OBJECT_PYTHON_TYPE_H diff --git a/boost/python/detail/raw_pyobject.hpp b/boost/python/detail/raw_pyobject.hpp new file mode 100644 index 0000000000..194409eda4 --- /dev/null +++ b/boost/python/detail/raw_pyobject.hpp @@ -0,0 +1,32 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef RAW_PYOBJECT_DWA2002628_HPP +# define RAW_PYOBJECT_DWA2002628_HPP + +namespace boost { namespace python { namespace detail { + +// +// Define some types which we can use to get around the vagaries of +// PyObject*. We will use these to initialize object instances, and +// keep them in namespace detail to make sure they stay out of the +// hands of users. That is much simpler than trying to grant +// friendship to all the appropriate parties. +// + +// New references are normally checked for null +struct new_reference_t; +typedef new_reference_t* new_reference; + +// Borrowed references are assumed to be non-null +struct borrowed_reference_t; +typedef borrowed_reference_t* borrowed_reference; + +// New references which aren't checked for null +struct new_non_null_reference_t; +typedef new_non_null_reference_t* new_non_null_reference; + +}}} // namespace boost::python::detail + +#endif // RAW_PYOBJECT_DWA2002628_HPP diff --git a/boost/python/detail/referent_storage.hpp b/boost/python/detail/referent_storage.hpp new file mode 100644 index 0000000000..0a1ef5a04e --- /dev/null +++ b/boost/python/detail/referent_storage.hpp @@ -0,0 +1,76 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef REFERENT_STORAGE_DWA200278_HPP +# define REFERENT_STORAGE_DWA200278_HPP +# include <boost/mpl/if.hpp> +# include <cstddef> + +namespace boost { namespace python { namespace detail { + +struct alignment_dummy; +typedef void (*function_ptr)(); +typedef int (alignment_dummy::*member_ptr); +typedef int (alignment_dummy::*member_function_ptr)(); + +# define BOOST_PYTHON_ALIGNER(T, n) \ + typename mpl::if_c< \ + sizeof(T) <= size, T, char>::type t##n + +// Storage for size bytes, aligned to all fundamental types no larger than size +template <std::size_t size> +union aligned_storage +{ + BOOST_PYTHON_ALIGNER(char, 0); + BOOST_PYTHON_ALIGNER(short, 1); + BOOST_PYTHON_ALIGNER(int, 2); + BOOST_PYTHON_ALIGNER(long, 3); + BOOST_PYTHON_ALIGNER(float, 4); + BOOST_PYTHON_ALIGNER(double, 5); + BOOST_PYTHON_ALIGNER(long double, 6); + BOOST_PYTHON_ALIGNER(void*, 7); + BOOST_PYTHON_ALIGNER(function_ptr, 8); + BOOST_PYTHON_ALIGNER(member_ptr, 9); + BOOST_PYTHON_ALIGNER(member_function_ptr, 10); + char bytes[size]; +}; + +# undef BOOST_PYTHON_ALIGNER + + // Compute the size of T's referent. We wouldn't need this at all, + // but sizeof() is broken in CodeWarriors <= 8.0 + template <class T> struct referent_size; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template <class T> + struct referent_size<T&> + { + BOOST_STATIC_CONSTANT( + std::size_t, value = sizeof(T)); + }; + +# else + + template <class T> struct referent_size + { + static T f(); + BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f())); + }; + +# endif + +// A metafunction returning a POD type which can store U, where T == +// U&. If T is not a reference type, returns a POD which can store T. +template <class T> +struct referent_storage +{ + typedef aligned_storage< + ::boost::python::detail::referent_size<T>::value + > type; +}; + +}}} // namespace boost::python::detail + +#endif // REFERENT_STORAGE_DWA200278_HPP diff --git a/boost/python/detail/result.hpp b/boost/python/detail/result.hpp new file mode 100644 index 0000000000..9b8b486423 --- /dev/null +++ b/boost/python/detail/result.hpp @@ -0,0 +1,135 @@ +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +# ifndef RESULT_DWA2002521_HPP +# define RESULT_DWA2002521_HPP + +# include <boost/type.hpp> + +# include <boost/python/detail/preprocessor.hpp> + +# include <boost/type_traits/object_traits.hpp> +# include <boost/mpl/if.hpp> + +# include <boost/preprocessor/comma_if.hpp> +# include <boost/preprocessor/iterate.hpp> +# include <boost/preprocessor/debug/line.hpp> +# include <boost/preprocessor/enum_params.hpp> +# include <boost/preprocessor/repetition/enum_trailing_params.hpp> + +namespace boost { namespace python { namespace detail { + +// Defines a family of overloaded function which, given x, a function +// pointer, member [function] pointer, or an AdaptableFunction object, +// returns a pointer to type<R>*, where R is the result type of +// invoking the result of bind(x). +// +// In order to work around bugs in deficient compilers, if x might be +// an AdaptableFunction object, you must pass OL as a second argument +// to get this to work portably. + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/result.hpp>, BOOST_PYTHON_FUNCTION_POINTER)) +# include BOOST_PP_ITERATE() + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_CV_COUNT - 1, <boost/python/detail/result.hpp>, BOOST_PYTHON_POINTER_TO_MEMBER)) +# include BOOST_PP_ITERATE() + +template <class R, class T> +boost::type<R>* result(R (T::*), int = 0) { return 0; } + +# if (defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140) \ + || (defined(__GNUC__) && __GNUC__ < 3) \ + || (defined(__MWERKS__) && __MWERKS__ < 0x3000) +// This code actually works on all implementations, but why use it when we don't have to? +template <class T> +struct get_result_type +{ + typedef boost::type<typename T::result_type> type; +}; + +struct void_type +{ + typedef void type; +}; + +template <class T> +struct result_result +{ + typedef typename mpl::if_c< + is_class<T>::value + , get_result_type<T> + , void_type + >::type t1; + + typedef typename t1::type* type; +}; + +template <class X> +typename result_result<X>::type +result(X const&, short) { return 0; } + +# else // Simpler code for more-capable compilers +template <class X> +boost::type<typename X::result_type>* +result(X const&, short = 0) { return 0; } + +# endif + +}}} // namespace boost::python::detail + +# endif // RESULT_DWA2002521_HPP + +/* --------------- function pointers --------------- */ +// For gcc 4.4 compatability, we must include the +// BOOST_PP_ITERATION_DEPTH test inside an #else clause. +#else // BOOST_PP_IS_ITERATING +#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER +# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \ + && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) +# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers)) +# endif + +# define N BOOST_PP_ITERATION() + +template <class R BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)> +boost::type<R>* result(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)), int = 0) +{ + return 0; +} + +# undef N + +/* --------------- pointers-to-members --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER +// Outer over cv-qualifiers + +# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/result.hpp>)) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 +# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \ + && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) +# line BOOST_PP_LINE(__LINE__, result.hpp(pointers-to-members)) +# endif +// Inner over arities + +# define N BOOST_PP_ITERATION() +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + +template <class R, class T BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)> +boost::type<R>* result(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q, int = 0) +{ + return 0; +} + +# undef N +# undef Q + +#endif // BOOST_PP_ITERATION_DEPTH() +#endif diff --git a/boost/python/detail/scope.hpp b/boost/python/detail/scope.hpp new file mode 100644 index 0000000000..5367bbd35c --- /dev/null +++ b/boost/python/detail/scope.hpp @@ -0,0 +1,16 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef SCOPE_DWA2002927_HPP +# define SCOPE_DWA2002927_HPP + +# include <boost/python/detail/config.hpp> + +namespace boost { namespace python { namespace detail { + +void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc); + +}}} // namespace boost::python::detail + +#endif // SCOPE_DWA2002927_HPP diff --git a/boost/python/detail/sfinae.hpp b/boost/python/detail/sfinae.hpp new file mode 100644 index 0000000000..6281875111 --- /dev/null +++ b/boost/python/detail/sfinae.hpp @@ -0,0 +1,13 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef SFINAE_DWA2004723_HPP +# define SFINAE_DWA2004723_HPP + +# include <boost/python/detail/prefix.hpp> + +# if defined(BOOST_NO_SFINAE) && !defined(BOOST_MSVC) +# define BOOST_PYTHON_NO_SFINAE +# endif + +#endif // SFINAE_DWA2004723_HPP diff --git a/boost/python/detail/signature.hpp b/boost/python/detail/signature.hpp new file mode 100644 index 0000000000..11268b92cf --- /dev/null +++ b/boost/python/detail/signature.hpp @@ -0,0 +1,106 @@ +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +# ifndef SIGNATURE_DWA20021121_HPP +# define SIGNATURE_DWA20021121_HPP + +# include <boost/python/type_id.hpp> + +# include <boost/python/detail/preprocessor.hpp> +# include <boost/python/detail/indirect_traits.hpp> +# include <boost/python/converter/pytype_function.hpp> + +# include <boost/preprocessor/iterate.hpp> +# include <boost/preprocessor/iteration/local.hpp> + +# include <boost/mpl/at.hpp> +# include <boost/mpl/size.hpp> + +namespace boost { namespace python { namespace detail { + +struct signature_element +{ + char const* basename; + converter::pytype_function pytype_f; + bool lvalue; +}; + +struct py_func_sig_info +{ + signature_element const *signature; + signature_element const *ret; +}; + +template <unsigned> struct signature_arity; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/signature.hpp>)) +# include BOOST_PP_ITERATE() + +// A metafunction returning the base class used for +// +// signature<class F, class CallPolicies, class Sig>. +// +template <class Sig> +struct signature_base_select +{ + enum { arity = mpl::size<Sig>::value - 1 }; + typedef typename signature_arity<arity>::template impl<Sig> type; +}; + +template <class Sig> +struct signature + : signature_base_select<Sig>::type +{ +}; + +}}} // namespace boost::python::detail + +# endif // SIGNATURE_DWA20021121_HPP + +#else + +# define N BOOST_PP_ITERATION() + +template <> +struct signature_arity<N> +{ + template <class Sig> + struct impl + { + static signature_element const* elements() + { + static signature_element const result[N+2] = { + +#ifndef BOOST_PYTHON_NO_PY_SIGNATURES +# define BOOST_PP_LOCAL_MACRO(i) \ + { \ + type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \ + , &converter::expected_pytype_for_arg<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::get_pytype \ + , indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \ + }, +#else +# define BOOST_PP_LOCAL_MACRO(i) \ + { \ + type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \ + , 0 \ + , indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \ + }, +#endif + +# define BOOST_PP_LOCAL_LIMITS (0, N) +# include BOOST_PP_LOCAL_ITERATE() + {0,0,0} + }; + return result; + } + }; +}; + +#endif // BOOST_PP_IS_ITERATING + + diff --git a/boost/python/detail/string_literal.hpp b/boost/python/detail/string_literal.hpp new file mode 100644 index 0000000000..50193b6436 --- /dev/null +++ b/boost/python/detail/string_literal.hpp @@ -0,0 +1,88 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef STRING_LITERAL_DWA2002629_HPP +# define STRING_LITERAL_DWA2002629_HPP + +# include <cstddef> +# include <boost/type.hpp> +# include <boost/type_traits/array_traits.hpp> +# include <boost/type_traits/same_traits.hpp> +# include <boost/mpl/bool.hpp> +# include <boost/detail/workaround.hpp> + +namespace boost { namespace python { namespace detail { + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template <class T> +struct is_string_literal : mpl::false_ +{ +}; + +# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 +template <std::size_t n> +struct is_string_literal<char const[n]> : mpl::true_ +{ +}; + +# if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590040)) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) +// This compiler mistakenly gets the type of string literals as char* +// instead of char[NN]. +template <> +struct is_string_literal<char* const> : mpl::true_ +{ +}; +# endif + +# else + +// CWPro7 has trouble with the array type deduction above +template <class T, std::size_t n> +struct is_string_literal<T[n]> + : is_same<T, char const> +{ +}; +# endif +# else +template <bool is_array = true> +struct string_literal_helper +{ + typedef char (&yes_string_literal)[1]; + typedef char (&no_string_literal)[2]; + + template <class T> + struct apply + { + typedef apply<T> self; + static T x; + static yes_string_literal check(char const*); + static no_string_literal check(char*); + static no_string_literal check(void const volatile*); + + BOOST_STATIC_CONSTANT( + bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal)); + typedef mpl::bool_<value> type; + }; +}; + +template <> +struct string_literal_helper<false> +{ + template <class T> + struct apply : mpl::false_ + { + }; +}; + +template <class T> +struct is_string_literal + : string_literal_helper<is_array<T>::value>::apply<T> +{ +}; +# endif + +}}} // namespace boost::python::detail + +#endif // STRING_LITERAL_DWA2002629_HPP diff --git a/boost/python/detail/target.hpp b/boost/python/detail/target.hpp new file mode 100644 index 0000000000..137801bb2b --- /dev/null +++ b/boost/python/detail/target.hpp @@ -0,0 +1,86 @@ +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +# ifndef TARGET_DWA2002521_HPP +# define TARGET_DWA2002521_HPP + +# include <boost/python/detail/preprocessor.hpp> + +# include <boost/type.hpp> + +# include <boost/preprocessor/comma_if.hpp> +# include <boost/preprocessor/if.hpp> +# include <boost/preprocessor/iterate.hpp> +# include <boost/preprocessor/debug/line.hpp> +# include <boost/preprocessor/enum_params.hpp> +# include <boost/preprocessor/repetition/enum_trailing_params.hpp> + +namespace boost { namespace python { namespace detail { + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/target.hpp>, BOOST_PYTHON_FUNCTION_POINTER)) +# include BOOST_PP_ITERATE() + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_CV_COUNT - 1, <boost/python/detail/target.hpp>, BOOST_PYTHON_POINTER_TO_MEMBER)) +# include BOOST_PP_ITERATE() + +template <class R, class T> +T& (* target(R (T::*)) )() { return 0; } + +}}} // namespace boost::python::detail + +# endif // TARGET_DWA2002521_HPP + +/* --------------- function pointers --------------- */ +// For gcc 4.4 compatability, we must include the +// BOOST_PP_ITERATION_DEPTH test inside an #else clause. +#else // BOOST_PP_IS_ITERATING +#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER +# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \ + && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) +# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers)) +# endif + +# define N BOOST_PP_ITERATION() + +template <class R BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)> +BOOST_PP_IF(N, A0, void)(* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))) )() +{ + return 0; +} + +# undef N + +/* --------------- pointers-to-members --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER +// Outer over cv-qualifiers + +# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/target.hpp>)) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 +# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \ + && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) +# line BOOST_PP_LINE(__LINE__, target.hpp(pointers-to-members)) +# endif +// Inner over arities + +# define N BOOST_PP_ITERATION() +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + +template <class R, class T BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)> +T& (* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) )() +{ + return 0; +} + +# undef N +# undef Q + +#endif // BOOST_PP_ITERATION_DEPTH() +#endif diff --git a/boost/python/detail/translate_exception.hpp b/boost/python/detail/translate_exception.hpp new file mode 100644 index 0000000000..df7ec2dd6c --- /dev/null +++ b/boost/python/detail/translate_exception.hpp @@ -0,0 +1,69 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef TRANSLATE_EXCEPTION_TDS20091020_HPP +# define TRANSLATE_EXCEPTION_TDS20091020_HPP + +# include <boost/python/detail/exception_handler.hpp> + +# include <boost/call_traits.hpp> +# include <boost/type_traits/add_const.hpp> +# include <boost/type_traits/add_reference.hpp> +# include <boost/type_traits/remove_reference.hpp> + +# include <boost/function/function0.hpp> + +namespace boost { namespace python { namespace detail { + +// A ternary function object used to translate C++ exceptions of type +// ExceptionType into Python exceptions by invoking an object of type +// Translate. Typically the translate function will be curried with +// boost::bind(). +template <class ExceptionType, class Translate> +struct translate_exception +{ +// workaround for broken gcc that ships with SuSE 9.0 and SuSE 9.1 +# if defined(__linux__) && defined(__GNUC__) \ + && BOOST_WORKAROUND(__GNUC__, == 3) \ + && BOOST_WORKAROUND(__GNUC_MINOR__, == 3) \ + && (BOOST_WORKAROUND(__GNUC_PATCHLEVEL__, == 1) \ + || BOOST_WORKAROUND(__GNUC_PATCHLEVEL__, == 3)) + typedef typename remove_reference< + typename add_const<ExceptionType>::type + >::type exception_non_ref; +# else + typedef typename add_reference< + typename add_const<ExceptionType>::type + >::type exception_cref; +# endif + + inline bool operator()( + exception_handler const& handler + , function0<void> const& f + , typename call_traits<Translate>::param_type translate) const + { + try + { + return handler(f); + } +// workaround for broken gcc that ships with SuSE 9.0 and SuSE 9.1 +# if defined(__linux__) && defined(__GNUC__) \ + && BOOST_WORKAROUND(__GNUC__, == 3) \ + && BOOST_WORKAROUND(__GNUC_MINOR__, == 3) \ + && (BOOST_WORKAROUND(__GNUC_PATCHLEVEL__, == 1) \ + || BOOST_WORKAROUND(__GNUC_PATCHLEVEL__, == 3)) + catch(exception_non_ref& e) +# else + catch(exception_cref e) +# endif + { + translate(e); + return true; + } + } +}; + +}}} // namespace boost::python::detail + +#endif // TRANSLATE_EXCEPTION_DWA2002810_HPP diff --git a/boost/python/detail/type_list.hpp b/boost/python/detail/type_list.hpp new file mode 100644 index 0000000000..9483c1945c --- /dev/null +++ b/boost/python/detail/type_list.hpp @@ -0,0 +1,39 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef TYPE_LIST_DWA2002913_HPP +# define TYPE_LIST_DWA2002913_HPP + +# include <boost/config.hpp> +# include <boost/python/detail/preprocessor.hpp> +# include <boost/preprocessor/arithmetic/inc.hpp> + +# if BOOST_PYTHON_MAX_ARITY + 2 > BOOST_PYTHON_MAX_BASES +# define BOOST_PYTHON_LIST_SIZE BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY)) +# else +# define BOOST_PYTHON_LIST_SIZE BOOST_PYTHON_MAX_BASES +# endif + +// Compute the MPL vector header to use for lists up to BOOST_PYTHON_LIST_SIZE in length +# if BOOST_PYTHON_LIST_SIZE > 48 +# error Arities above 48 not supported by Boost.Python due to MPL internal limit +# elif BOOST_PYTHON_LIST_SIZE > 38 +# include <boost/mpl/vector/vector50.hpp> +# elif BOOST_PYTHON_LIST_SIZE > 28 +# include <boost/mpl/vector/vector40.hpp> +# elif BOOST_PYTHON_LIST_SIZE > 18 +# include <boost/mpl/vector/vector30.hpp> +# elif BOOST_PYTHON_LIST_SIZE > 8 +# include <boost/mpl/vector/vector20.hpp> +# else +# include <boost/mpl/vector/vector10.hpp> +# endif + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include <boost/python/detail/type_list_impl.hpp> +# else +# include <boost/python/detail/type_list_impl_no_pts.hpp> +# endif + +#endif // TYPE_LIST_DWA2002913_HPP diff --git a/boost/python/detail/type_list_impl.hpp b/boost/python/detail/type_list_impl.hpp new file mode 100644 index 0000000000..fdcfa85030 --- /dev/null +++ b/boost/python/detail/type_list_impl.hpp @@ -0,0 +1,57 @@ +#ifndef BOOST_PP_IS_ITERATING +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +# ifndef TYPE_LIST_IMPL_DWA2002913_HPP +# define TYPE_LIST_IMPL_DWA2002913_HPP + +# include <boost/python/detail/type_list.hpp> + +# include <boost/preprocessor/enum_params.hpp> +# include <boost/preprocessor/enum_params_with_a_default.hpp> +# include <boost/preprocessor/repetition/enum.hpp> +# include <boost/preprocessor/comma_if.hpp> +# include <boost/preprocessor/arithmetic/sub.hpp> +# include <boost/preprocessor/iterate.hpp> +# include <boost/preprocessor/repetition/enum_trailing.hpp> + +namespace boost { namespace python { namespace detail { + +template <BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_)> +struct type_list + : BOOST_PP_CAT(mpl::vector,BOOST_PYTHON_LIST_SIZE)<BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_LIST_SIZE, T)> +{ +}; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PP_DEC(BOOST_PYTHON_LIST_SIZE), <boost/python/detail/type_list_impl.hpp>)) +# include BOOST_PP_ITERATE() + + +}}} // namespace boost::python::detail + +# endif // TYPE_LIST_IMPL_DWA2002913_HPP + +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() +# define BOOST_PYTHON_VOID_ARGS BOOST_PP_SUB_D(1,BOOST_PYTHON_LIST_SIZE,N) + +template < + BOOST_PP_ENUM_PARAMS_Z(1, N, class T) + > +struct type_list< + BOOST_PP_ENUM_PARAMS_Z(1, N, T) + BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM( + BOOST_PYTHON_VOID_ARGS, BOOST_PYTHON_FIXED, mpl::void_) + > + : BOOST_PP_CAT(mpl::vector,N)<BOOST_PP_ENUM_PARAMS_Z(1, N, T)> +{ +}; + +# undef BOOST_PYTHON_VOID_ARGS +# undef N + +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/python/detail/type_list_impl_no_pts.hpp b/boost/python/detail/type_list_impl_no_pts.hpp new file mode 100644 index 0000000000..15d9252374 --- /dev/null +++ b/boost/python/detail/type_list_impl_no_pts.hpp @@ -0,0 +1,107 @@ +#ifndef BOOST_PP_IS_ITERATING +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +# ifndef TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP +# define TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP + +# include <boost/python/detail/type_list.hpp> + +# include <boost/preprocessor/enum_params.hpp> +# include <boost/preprocessor/enum_params_with_a_default.hpp> +# include <boost/preprocessor/cat.hpp> +# include <boost/preprocessor/repeat.hpp> +# include <boost/preprocessor/empty.hpp> +# include <boost/preprocessor/iterate.hpp> +# include <boost/mpl/void.hpp> + +namespace boost { namespace python { namespace detail { + +template< typename T > +struct is_list_arg +{ + enum { value = true }; +}; + +template<> +struct is_list_arg<mpl::void_> +{ + enum { value = false }; +}; + +template<int> struct type_list_impl_chooser; + +# define BOOST_PYTHON_LIST_ACTUAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,T) +# define BOOST_PYTHON_LIST_FORMAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,class T) + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_LIST_SIZE, <boost/python/detail/type_list_impl_no_pts.hpp>)) +# include BOOST_PP_ITERATE() + +# define BOOST_PYTHON_PLUS() + +# define BOOST_PYTHON_IS_LIST_ARG(z, n, data) \ + BOOST_PP_IF(n, BOOST_PYTHON_PLUS, BOOST_PP_EMPTY)() \ + is_list_arg< BOOST_PP_CAT(T,n) >::value + +template< + BOOST_PYTHON_LIST_FORMAL_PARAMS + > +struct type_list_count_args +{ + enum { value = + BOOST_PP_REPEAT_1(BOOST_PYTHON_LIST_SIZE, BOOST_PYTHON_IS_LIST_ARG, _) + }; +}; + +template< + BOOST_PYTHON_LIST_FORMAL_PARAMS + > +struct type_list_impl +{ + typedef type_list_count_args< BOOST_PYTHON_LIST_ACTUAL_PARAMS > arg_num_; + typedef typename detail::type_list_impl_chooser< arg_num_::value > + ::template result_< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type type; +}; + +template< + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_) + > +struct type_list + : detail::type_list_impl< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type +{ + typedef typename detail::type_list_impl< + BOOST_PYTHON_LIST_ACTUAL_PARAMS + >::type type; +}; + +# undef BOOST_PYTHON_IS_LIST_ARG +# undef BOOST_PYTHON_PLUS +# undef BOOST_PYTHON_LIST_FORMAL_PARAMS +# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS + +}}} // namespace boost::python::detail + +# endif // TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP + +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() + +template<> +struct type_list_impl_chooser<N> +{ + template< + BOOST_PYTHON_LIST_FORMAL_PARAMS + > + struct result_ + { + typedef typename BOOST_PP_CAT(mpl::vector,N)< + BOOST_PP_ENUM_PARAMS(N, T) + >::type type; + }; +}; + +# undef N + +#endif // BOOST_PP_IS_ITERATING diff --git a/boost/python/detail/unwind_type.hpp b/boost/python/detail/unwind_type.hpp new file mode 100644 index 0000000000..9a997c9dbd --- /dev/null +++ b/boost/python/detail/unwind_type.hpp @@ -0,0 +1,170 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef UNWIND_TYPE_DWA200222_HPP +# define UNWIND_TYPE_DWA200222_HPP + +# include <boost/python/detail/cv_category.hpp> +# include <boost/python/detail/indirect_traits.hpp> +# include <boost/type_traits/object_traits.hpp> + +namespace boost { namespace python { namespace detail { + +#ifndef _MSC_VER //if forward declared, msvc6.5 does not recognize them as inline +// forward declaration, required (at least) by Tru64 cxx V6.5-042 +template <class Generator, class U> +inline typename Generator::result_type +unwind_type(U const& p, Generator* = 0); + +// forward declaration, required (at least) by Tru64 cxx V6.5-042 +template <class Generator, class U> +inline typename Generator::result_type +unwind_type(boost::type<U>*p = 0, Generator* = 0); +#endif + +template <class Generator, class U> +inline typename Generator::result_type +unwind_type_cv(U* p, cv_unqualified, Generator* = 0) +{ + return Generator::execute(p); +} + +template <class Generator, class U> +inline typename Generator::result_type +unwind_type_cv(U const* p, const_, Generator* = 0) +{ + return unwind_type(const_cast<U*>(p), (Generator*)0); +} + +template <class Generator, class U> +inline typename Generator::result_type +unwind_type_cv(U volatile* p, volatile_, Generator* = 0) +{ + return unwind_type(const_cast<U*>(p), (Generator*)0); +} + +template <class Generator, class U> +inline typename Generator::result_type +unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0) +{ + return unwind_type(const_cast<U*>(p), (Generator*)0); +} + +template <class Generator, class U> +inline typename Generator::result_type +unwind_ptr_type(U* p, Generator* = 0) +{ + typedef typename cv_category<U>::type tag; + return unwind_type_cv<Generator>(p, tag()); +} + +template <bool is_ptr> +struct unwind_helper +{ + template <class Generator, class U> + static typename Generator::result_type + execute(U p, Generator* = 0) + { + return unwind_ptr_type(p, (Generator*)0); + } +}; + +template <> +struct unwind_helper<false> +{ + template <class Generator, class U> + static typename Generator::result_type + execute(U& p, Generator* = 0) + { + return unwind_ptr_type(&p, (Generator*)0); + } +}; + +template <class Generator, class U> +inline typename Generator::result_type +#ifndef _MSC_VER +unwind_type(U const& p, Generator*) +#else +unwind_type(U const& p, Generator* = 0) +#endif +{ + return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0); +} + +enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 }; +template <int indirection> struct unwind_helper2; + +template <> +struct unwind_helper2<direct_> +{ + template <class Generator, class U> + static typename Generator::result_type + execute(U(*)(), Generator* = 0) + { + return unwind_ptr_type((U*)0, (Generator*)0); + } +}; + +template <> +struct unwind_helper2<pointer_> +{ + template <class Generator, class U> + static typename Generator::result_type + execute(U*(*)(), Generator* = 0) + { + return unwind_ptr_type((U*)0, (Generator*)0); + } +}; + +template <> +struct unwind_helper2<reference_> +{ + template <class Generator, class U> + static typename Generator::result_type + execute(U&(*)(), Generator* = 0) + { + return unwind_ptr_type((U*)0, (Generator*)0); + } +}; + +template <> +struct unwind_helper2<reference_to_pointer_> +{ + template <class Generator, class U> + static typename Generator::result_type + execute(U&(*)(), Generator* = 0) + { + return unwind_ptr_type(U(0), (Generator*)0); + } +}; + +// Call this one with both template parameters explicitly specified +// and no function arguments: +// +// return unwind_type<my_generator,T>(); +// +// Doesn't work if T is an array type; we could handle that case, but +// why bother? +template <class Generator, class U> +inline typename Generator::result_type +#ifndef _MSC_VER +unwind_type(boost::type<U>*, Generator*) +#else +unwind_type(boost::type<U>*p =0, Generator* =0) +#endif +{ + BOOST_STATIC_CONSTANT(int, indirection + = (boost::is_pointer<U>::value ? pointer_ : 0) + + (indirect_traits::is_reference_to_pointer<U>::value + ? reference_to_pointer_ + : boost::is_reference<U>::value + ? reference_ + : 0)); + + return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0); +} + +}}} // namespace boost::python::detail + +#endif // UNWIND_TYPE_DWA200222_HPP diff --git a/boost/python/detail/unwrap_type_id.hpp b/boost/python/detail/unwrap_type_id.hpp new file mode 100644 index 0000000000..96c1f53013 --- /dev/null +++ b/boost/python/detail/unwrap_type_id.hpp @@ -0,0 +1,31 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef UNWRAP_TYPE_ID_DWA2004722_HPP +# define UNWRAP_TYPE_ID_DWA2004722_HPP + +# include <boost/python/type_id.hpp> + +# include <boost/mpl/bool.hpp> + +namespace boost { namespace python { + +template <class T> class wrapper; + +namespace detail { + +template <class T> +inline type_info unwrap_type_id(T*, ...) +{ + return type_id<T>(); +} + +template <class U, class T> +inline type_info unwrap_type_id(U*, wrapper<T>*) +{ + return type_id<T>(); +} + +}}} // namespace boost::python::detail + +#endif // UNWRAP_TYPE_ID_DWA2004722_HPP diff --git a/boost/python/detail/unwrap_wrapper.hpp b/boost/python/detail/unwrap_wrapper.hpp new file mode 100644 index 0000000000..95bc233a72 --- /dev/null +++ b/boost/python/detail/unwrap_wrapper.hpp @@ -0,0 +1,34 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef UNWRAP_WRAPPER_DWA2004723_HPP +# define UNWRAP_WRAPPER_DWA2004723_HPP + +# include <boost/python/detail/prefix.hpp> +# include <boost/python/detail/is_wrapper.hpp> +# include <boost/mpl/eval_if.hpp> +# include <boost/mpl/identity.hpp> + +namespace boost { namespace python { namespace detail { + +template <class T> +struct unwrap_wrapper_helper +{ + typedef typename T::_wrapper_wrapped_type_ type; +}; + +template <class T> +struct unwrap_wrapper_ + : mpl::eval_if<is_wrapper<T>,unwrap_wrapper_helper<T>,mpl::identity<T> > +{}; + +template <class T> +typename unwrap_wrapper_<T>::type* +unwrap_wrapper(T*) +{ + return 0; +} + +}}} // namespace boost::python::detail + +#endif // UNWRAP_WRAPPER_DWA2004723_HPP diff --git a/boost/python/detail/value_arg.hpp b/boost/python/detail/value_arg.hpp new file mode 100644 index 0000000000..747588d6fd --- /dev/null +++ b/boost/python/detail/value_arg.hpp @@ -0,0 +1,27 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef VALUE_ARG_DWA2004312_HPP +# define VALUE_ARG_DWA2004312_HPP + +# include <boost/python/detail/copy_ctor_mutates_rhs.hpp> +# include <boost/mpl/if.hpp> +# include <boost/type_traits/add_reference.hpp> +# include <boost/type_traits/add_const.hpp> + +namespace boost { namespace python { namespace detail { + +template <class T> +struct value_arg + : mpl::if_< + copy_ctor_mutates_rhs<T> + , T + , typename add_reference< + typename add_const<T>::type + >::type + > +{}; + +}}} // namespace boost::python::detail + +#endif // VALUE_ARG_DWA2004312_HPP diff --git a/boost/python/detail/value_is_shared_ptr.hpp b/boost/python/detail/value_is_shared_ptr.hpp new file mode 100644 index 0000000000..361c369b5b --- /dev/null +++ b/boost/python/detail/value_is_shared_ptr.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef VALUE_IS_SHARED_PTR_DWA2003224_HPP +# define VALUE_IS_SHARED_PTR_DWA2003224_HPP + +# include <boost/python/detail/value_is_xxx.hpp> +# include <boost/shared_ptr.hpp> + +namespace boost { namespace python { namespace detail { + +BOOST_PYTHON_VALUE_IS_XXX_DEF(shared_ptr, shared_ptr, 1) + +}}} // namespace boost::python::detail + +#endif // VALUE_IS_SHARED_PTR_DWA2003224_HPP diff --git a/boost/python/detail/value_is_xxx.hpp b/boost/python/detail/value_is_xxx.hpp new file mode 100644 index 0000000000..2b12564907 --- /dev/null +++ b/boost/python/detail/value_is_xxx.hpp @@ -0,0 +1,62 @@ +// Copyright David Abrahams 2003. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef VALUE_IS_XXX_DWA2003224_HPP +# define VALUE_IS_XXX_DWA2003224_HPP + +# include <boost/config.hpp> +# include <boost/mpl/bool.hpp> +# include <boost/preprocessor/enum_params.hpp> + +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include <boost/type_traits/is_reference.hpp> +# include <boost/type_traits/add_reference.hpp> + +# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \ +template <class X_> \ +struct value_is_##name \ +{ \ + typedef char yes; \ + typedef char (&no)[2]; \ + \ + static typename add_reference<X_>::type dummy; \ + \ + template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ + static yes test( \ + qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) > const&, int \ + ); \ + \ + template <class U> \ + static no test(U&, ...); \ + \ + BOOST_STATIC_CONSTANT( \ + bool, value \ + = (sizeof(test(dummy, 0)) == sizeof(yes))); \ + \ + typedef mpl::bool_<value> type; \ +}; + +# else + +# include <boost/type_traits/remove_reference.hpp> +# include <boost/type_traits/remove_cv.hpp> +# include <boost/python/detail/is_xxx.hpp> + +# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \ +template <class X_> \ +struct value_is_##name \ +{ \ + BOOST_PYTHON_IS_XXX_DEF(name,qualified_name,nargs) \ + BOOST_STATIC_CONSTANT(bool, value = is_##name< \ + typename remove_cv< \ + typename remove_reference<X_>::type \ + >::type \ + >::value); \ + typedef mpl::bool_<value> type; \ + \ +}; + +# endif + +#endif // VALUE_IS_XXX_DWA2003224_HPP diff --git a/boost/python/detail/void_ptr.hpp b/boost/python/detail/void_ptr.hpp new file mode 100644 index 0000000000..06f680104d --- /dev/null +++ b/boost/python/detail/void_ptr.hpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef VOID_PTR_DWA200239_HPP +# define VOID_PTR_DWA200239_HPP + +# include <boost/type_traits/remove_cv.hpp> + +namespace boost { namespace python { namespace detail { + +template <class U> +inline U& void_ptr_to_reference(void const volatile* p, U&(*)()) +{ + return *(U*)p; +} + +template <class T> +inline void write_void_ptr(void const volatile* storage, void* ptr, T*) +{ + *(T**)storage = (T*)ptr; +} + +// writes U(ptr) into the storage +template <class U> +inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)()) +{ + // stripping CV qualification suppresses warnings on older EDGs + typedef typename remove_cv<U>::type u_stripped; + write_void_ptr(storage, ptr, u_stripped(0)); +} + +}}} // namespace boost::python::detail + +#endif // VOID_PTR_DWA200239_HPP diff --git a/boost/python/detail/void_return.hpp b/boost/python/detail/void_return.hpp new file mode 100644 index 0000000000..30db825177 --- /dev/null +++ b/boost/python/detail/void_return.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef VOID_RETURN_DWA200274_HPP +# define VOID_RETURN_DWA200274_HPP + +# include <boost/config.hpp> + +namespace boost { namespace python { namespace detail { + +struct void_return +{ + void_return() {} + private: + void operator=(void_return const&); +}; + +template <class T> +struct returnable +{ + typedef T type; +}; + +# ifdef BOOST_NO_VOID_RETURNS +template <> +struct returnable<void> +{ + typedef void_return type; +}; + +# ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +template <> struct returnable<const void> : returnable<void> {}; +template <> struct returnable<volatile void> : returnable<void> {}; +template <> struct returnable<const volatile void> : returnable<void> {}; +# endif + +# endif // BOOST_NO_VOID_RETURNS + +}}} // namespace boost::python::detail + +#endif // VOID_RETURN_DWA200274_HPP diff --git a/boost/python/detail/wrap_python.hpp b/boost/python/detail/wrap_python.hpp new file mode 100644 index 0000000000..eaef7841d5 --- /dev/null +++ b/boost/python/detail/wrap_python.hpp @@ -0,0 +1,205 @@ +// (C) Copyright David Abrahams 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The author gratefully acknowleges the support of Dragon Systems, Inc., in +// producing this work. + +// This file serves as a wrapper around <Python.h> which allows it to be +// compiled with GCC 2.95.2 under Win32 and which disables the default MSVC +// behavior so that a program may be compiled in debug mode without requiring a +// special debugging build of the Python library. + + +// To use the Python debugging library, #define BOOST_DEBUG_PYTHON on the +// compiler command-line. + +// Revision History: +// 05 Mar 01 Suppress warnings under Cygwin with Python 2.0 (Dave Abrahams) +// 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) +// 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) + +#ifdef _DEBUG +# ifndef BOOST_DEBUG_PYTHON +# ifdef _MSC_VER + // VC8.0 will complain if system headers are #included both with + // and without _DEBUG defined, so we have to #include all the + // system headers used by pyconfig.h right here. +# include <stddef.h> +# include <stdarg.h> +# include <stdio.h> +# include <stdlib.h> +# include <assert.h> +# include <errno.h> +# include <ctype.h> +# include <wchar.h> +# include <basetsd.h> +# include <io.h> +# include <limits.h> +# include <float.h> +# include <string.h> +# include <math.h> +# include <time.h> +# endif +# undef _DEBUG // Don't let Python force the debug library just because we're debugging. +# define DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H +# endif +#endif + +# include <pyconfig.h> +# if defined(_SGI_COMPILER_VERSION) && _SGI_COMPILER_VERSION >= 740 +# undef _POSIX_C_SOURCE +# undef _XOPEN_SOURCE +# undef HAVE_STDINT_H // undo Python 2.5.1 define +# endif + +// +// Python's LongObject.h helpfully #defines ULONGLONG_MAX for us, +// which confuses Boost's config +// +#include <limits.h> +#ifndef ULONG_MAX +# define BOOST_PYTHON_ULONG_MAX_UNDEFINED +#endif +#ifndef LONGLONG_MAX +# define BOOST_PYTHON_LONGLONG_MAX_UNDEFINED +#endif +#ifndef ULONGLONG_MAX +# define BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED +#endif + +// +// Get ahold of Python's version number +// +#include <patchlevel.h> + +#if PY_MAJOR_VERSION<2 || PY_MAJOR_VERSION==2 && PY_MINOR_VERSION<2 +#error Python 2.2 or higher is required for this version of Boost.Python. +#endif + +// +// Some things we need in order to get Python.h to work with compilers other +// than MSVC on Win32 +// +#if defined(_WIN32) || defined(__CYGWIN__) +# if defined(__GNUC__) && defined(__CYGWIN__) + +# define SIZEOF_LONG 4 + +# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 + +typedef int pid_t; + +# define WORD_BIT 32 +# define hypot _hypot +# include <stdio.h> + +# if PY_MAJOR_VERSION < 2 +# define HAVE_CLOCK +# define HAVE_STRFTIME +# define HAVE_STRERROR +# endif + +# define NT_THREADS + +# ifndef NETSCAPE_PI +# define USE_SOCKET +# endif + +# ifdef USE_DL_IMPORT +# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE +# endif + +# ifdef USE_DL_EXPORT +# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE +# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE +# endif + +# define HAVE_LONG_LONG 1 +# define LONG_LONG long long +# endif + +# elif defined(__MWERKS__) + +# ifndef _MSC_VER +# define PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H 1 +# define _MSC_VER 900 +# endif + +# undef hypot // undo the evil #define left by Python. + +# elif defined(__BORLANDC__) +# undef HAVE_HYPOT +# define HAVE_HYPOT 1 +# endif + +#endif // _WIN32 + +#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2 && PY_MICRO_VERSION < 2 +# include <boost/python/detail/python22_fixed.h> +#else +# include <Python.h> +#endif + +#ifdef BOOST_PYTHON_ULONG_MAX_UNDEFINED +# undef ULONG_MAX +# undef BOOST_PYTHON_ULONG_MAX_UNDEFINED +#endif + +#ifdef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED +# undef LONGLONG_MAX +# undef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED +#endif + +#ifdef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED +# undef ULONGLONG_MAX +# undef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED +#endif + +#ifdef PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H +# undef _MSC_VER +#endif + +#ifdef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H +# undef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H +# define _DEBUG +# ifdef _CRT_NOFORCE_MANIFEST_DEFINED_FROM_WRAP_PYTHON_H +# undef _CRT_NOFORCE_MANIFEST_DEFINED_FROM_WRAP_PYTHON_H +# undef _CRT_NOFORCE_MANIFEST +# endif +#endif + +#if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 +# define PyObject_INIT(op, typeobj) \ + ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) +#endif + +// Define Python 3 macros for Python 2.x +#if PY_VERSION_HEX < 0x02060000 + +# define Py_TYPE(o) (((PyObject*)(o))->ob_type) +# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt) +# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size) + +# define PyVarObject_HEAD_INIT(type, size) \ + PyObject_HEAD_INIT(type) size, + +#endif + + +#ifdef __MWERKS__ +# pragma warn_possunwant off +#elif _MSC_VER +# pragma warning(disable:4786) +#endif + +#if defined(HAVE_LONG_LONG) +# if defined(PY_LONG_LONG) +# define BOOST_PYTHON_LONG_LONG PY_LONG_LONG +# elif defined(LONG_LONG) +# define BOOST_PYTHON_LONG_LONG LONG_LONG +# else +# error "HAVE_LONG_LONG defined but not PY_LONG_LONG or LONG_LONG" +# endif +#endif diff --git a/boost/python/detail/wrapper_base.hpp b/boost/python/detail/wrapper_base.hpp new file mode 100644 index 0000000000..e5b93aa449 --- /dev/null +++ b/boost/python/detail/wrapper_base.hpp @@ -0,0 +1,90 @@ +// Copyright David Abrahams 2004. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef WRAPPER_BASE_DWA2004722_HPP +# define WRAPPER_BASE_DWA2004722_HPP + +# include <boost/python/detail/prefix.hpp> +# include <boost/type_traits/is_polymorphic.hpp> +# include <boost/mpl/bool.hpp> + +namespace boost { namespace python { + +class override; + +namespace detail +{ + class BOOST_PYTHON_DECL_FORWARD wrapper_base; + + namespace wrapper_base_ // ADL disabler + { + inline PyObject* get_owner(wrapper_base const volatile& w); + + inline PyObject* + owner_impl(void const volatile* /*x*/, mpl::false_) + { + return 0; + } + + template <class T> + inline PyObject* + owner_impl(T const volatile* x, mpl::true_); + + template <class T> + inline PyObject* + owner(T const volatile* x) + { + return wrapper_base_::owner_impl(x,is_polymorphic<T>()); + } + } + + class BOOST_PYTHON_DECL wrapper_base + { + friend void initialize_wrapper(PyObject* self, wrapper_base* w); + friend PyObject* wrapper_base_::get_owner(wrapper_base const volatile& w); + protected: + wrapper_base() : m_self(0) {} + + override get_override( + char const* name, PyTypeObject* class_object) const; + + private: + void detach(); + + private: + PyObject* m_self; + }; + + namespace wrapper_base_ // ADL disabler + { + template <class T> + inline PyObject* + owner_impl(T const volatile* x, mpl::true_) + { + if (wrapper_base const volatile* w = dynamic_cast<wrapper_base const volatile*>(x)) + { + return wrapper_base_::get_owner(*w); + } + return 0; + } + + inline PyObject* get_owner(wrapper_base const volatile& w) + { + return w.m_self; + } + } + + inline void initialize_wrapper(PyObject* self, wrapper_base* w) + { + w->m_self = self; + } + + inline void initialize_wrapper(PyObject* /*self*/, ...) {} + + + +} // namespace detail + +}} // namespace boost::python + +#endif // WRAPPER_BASE_DWA2004722_HPP |