// 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 |