176 lines
4.9 KiB
C++
176 lines
4.9 KiB
C++
// 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 KEYWORDS_DWA2002323_HPP
|
|
# define KEYWORDS_DWA2002323_HPP
|
|
|
|
# include <boost/python/detail/prefix.hpp>
|
|
|
|
# include <boost/python/args_fwd.hpp>
|
|
# include <boost/config.hpp>
|
|
# include <boost/python/detail/preprocessor.hpp>
|
|
# include <boost/python/detail/type_list.hpp>
|
|
|
|
# include <boost/type_traits/is_reference.hpp>
|
|
# include <boost/type_traits/remove_reference.hpp>
|
|
# include <boost/type_traits/remove_cv.hpp>
|
|
|
|
# include <boost/preprocessor/enum_params.hpp>
|
|
# include <boost/preprocessor/repeat.hpp>
|
|
# include <boost/preprocessor/facilities/intercept.hpp>
|
|
# include <boost/preprocessor/iteration/local.hpp>
|
|
|
|
# include <boost/python/detail/mpl_lambda.hpp>
|
|
# include <boost/python/object_core.hpp>
|
|
|
|
# include <boost/mpl/bool.hpp>
|
|
|
|
# include <cstddef>
|
|
# include <algorithm>
|
|
|
|
namespace boost { namespace python {
|
|
|
|
typedef detail::keywords<1> arg;
|
|
typedef arg arg_; // gcc 2.96 workaround
|
|
|
|
namespace detail
|
|
{
|
|
template <std::size_t nkeywords>
|
|
struct keywords_base
|
|
{
|
|
BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
|
|
|
|
keyword_range range() const
|
|
{
|
|
return keyword_range(elements, elements + nkeywords);
|
|
}
|
|
|
|
keyword elements[nkeywords];
|
|
|
|
keywords<nkeywords+1>
|
|
operator,(python::arg const &k) const;
|
|
|
|
keywords<nkeywords + 1>
|
|
operator,(char const *name) const;
|
|
};
|
|
|
|
template <std::size_t nkeywords>
|
|
struct keywords : keywords_base<nkeywords>
|
|
{
|
|
};
|
|
|
|
template <>
|
|
struct keywords<1> : keywords_base<1>
|
|
{
|
|
explicit keywords(char const *name)
|
|
{
|
|
elements[0].name = name;
|
|
}
|
|
|
|
template <class T>
|
|
python::arg& operator=(T const& value)
|
|
{
|
|
object z(value);
|
|
elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
|
|
return *this;
|
|
}
|
|
|
|
operator detail::keyword const&() const
|
|
{
|
|
return elements[0];
|
|
}
|
|
};
|
|
|
|
template <std::size_t nkeywords>
|
|
inline
|
|
keywords<nkeywords+1>
|
|
keywords_base<nkeywords>::operator,(python::arg const &k) const
|
|
{
|
|
keywords<nkeywords> const& l = *static_cast<keywords<nkeywords> const*>(this);
|
|
python::detail::keywords<nkeywords+1> res;
|
|
std::copy(l.elements, l.elements+nkeywords, res.elements);
|
|
res.elements[nkeywords] = k.elements[0];
|
|
return res;
|
|
}
|
|
|
|
template <std::size_t nkeywords>
|
|
inline
|
|
keywords<nkeywords + 1>
|
|
keywords_base<nkeywords>::operator,(char const *name) const
|
|
{
|
|
return this->operator,(python::arg(name));
|
|
}
|
|
|
|
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
template<typename T>
|
|
struct is_keywords
|
|
{
|
|
BOOST_STATIC_CONSTANT(bool, value = false);
|
|
};
|
|
|
|
template<std::size_t nkeywords>
|
|
struct is_keywords<keywords<nkeywords> >
|
|
{
|
|
BOOST_STATIC_CONSTANT(bool, value = true);
|
|
};
|
|
template <class T>
|
|
struct is_reference_to_keywords
|
|
{
|
|
BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
|
|
typedef typename remove_reference<T>::type deref;
|
|
typedef typename remove_cv<deref>::type key_t;
|
|
BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
|
|
BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
|
|
|
|
typedef mpl::bool_<value> type;
|
|
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
|
|
};
|
|
# else
|
|
typedef char (&yes_keywords_t)[1];
|
|
typedef char (&no_keywords_t)[2];
|
|
|
|
no_keywords_t is_keywords_test(...);
|
|
|
|
template<std::size_t nkeywords>
|
|
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords>&));
|
|
|
|
template<std::size_t nkeywords>
|
|
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords> const&));
|
|
|
|
template<typename T>
|
|
class is_reference_to_keywords
|
|
{
|
|
public:
|
|
BOOST_STATIC_CONSTANT(
|
|
bool, value = (
|
|
sizeof(detail::is_keywords_test( (void (*)(T))0 ))
|
|
== sizeof(detail::yes_keywords_t)));
|
|
|
|
typedef mpl::bool_<value> type;
|
|
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
|
|
};
|
|
# endif
|
|
}
|
|
|
|
inline detail::keywords<1> args(char const* name)
|
|
{
|
|
return detail::keywords<1>(name);
|
|
}
|
|
|
|
# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
|
|
# define BOOST_PP_LOCAL_MACRO(n) \
|
|
inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
|
|
{ \
|
|
detail::keywords<n> result; \
|
|
BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
|
|
return result; \
|
|
}
|
|
# define BOOST_PP_LOCAL_LIMITS (2, BOOST_PYTHON_MAX_ARITY)
|
|
# include BOOST_PP_LOCAL_ITERATE()
|
|
|
|
}} // namespace boost::python
|
|
|
|
|
|
# endif // KEYWORDS_DWA2002323_HPP
|