args.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright David Abrahams 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef KEYWORDS_DWA2002323_HPP
  6. # define KEYWORDS_DWA2002323_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/args_fwd.hpp>
  9. # include <boost/config.hpp>
  10. # include <boost/python/detail/preprocessor.hpp>
  11. # include <boost/python/detail/type_list.hpp>
  12. # include <boost/type_traits/is_reference.hpp>
  13. # include <boost/type_traits/remove_reference.hpp>
  14. # include <boost/type_traits/remove_cv.hpp>
  15. # include <boost/preprocessor/enum_params.hpp>
  16. # include <boost/preprocessor/repeat.hpp>
  17. # include <boost/preprocessor/facilities/intercept.hpp>
  18. # include <boost/preprocessor/iteration/local.hpp>
  19. # include <boost/python/detail/mpl_lambda.hpp>
  20. # include <boost/python/object_core.hpp>
  21. # include <boost/mpl/bool.hpp>
  22. # include <cstddef>
  23. # include <algorithm>
  24. namespace boost { namespace python {
  25. typedef detail::keywords<1> arg;
  26. typedef arg arg_; // gcc 2.96 workaround
  27. namespace detail
  28. {
  29. template <std::size_t nkeywords>
  30. struct keywords_base
  31. {
  32. BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
  33. keyword_range range() const
  34. {
  35. return keyword_range(elements, elements + nkeywords);
  36. }
  37. keyword elements[nkeywords];
  38. keywords<nkeywords+1>
  39. operator,(python::arg const &k) const;
  40. keywords<nkeywords + 1>
  41. operator,(char const *name) const;
  42. };
  43. template <std::size_t nkeywords>
  44. struct keywords : keywords_base<nkeywords>
  45. {
  46. };
  47. template <>
  48. struct keywords<1> : keywords_base<1>
  49. {
  50. explicit keywords(char const *name)
  51. {
  52. elements[0].name = name;
  53. }
  54. template <class T>
  55. python::arg& operator=(T const& value)
  56. {
  57. object z(value);
  58. elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
  59. return *this;
  60. }
  61. operator detail::keyword const&() const
  62. {
  63. return elements[0];
  64. }
  65. };
  66. template <std::size_t nkeywords>
  67. inline
  68. keywords<nkeywords+1>
  69. keywords_base<nkeywords>::operator,(python::arg const &k) const
  70. {
  71. keywords<nkeywords> const& l = *static_cast<keywords<nkeywords> const*>(this);
  72. python::detail::keywords<nkeywords+1> res;
  73. std::copy(l.elements, l.elements+nkeywords, res.elements);
  74. res.elements[nkeywords] = k.elements[0];
  75. return res;
  76. }
  77. template <std::size_t nkeywords>
  78. inline
  79. keywords<nkeywords + 1>
  80. keywords_base<nkeywords>::operator,(char const *name) const
  81. {
  82. return this->operator,(python::arg(name));
  83. }
  84. # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  85. template<typename T>
  86. struct is_keywords
  87. {
  88. BOOST_STATIC_CONSTANT(bool, value = false);
  89. };
  90. template<std::size_t nkeywords>
  91. struct is_keywords<keywords<nkeywords> >
  92. {
  93. BOOST_STATIC_CONSTANT(bool, value = true);
  94. };
  95. template <class T>
  96. struct is_reference_to_keywords
  97. {
  98. BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
  99. typedef typename remove_reference<T>::type deref;
  100. typedef typename remove_cv<deref>::type key_t;
  101. BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
  102. BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
  103. typedef mpl::bool_<value> type;
  104. BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
  105. };
  106. # else
  107. typedef char (&yes_keywords_t)[1];
  108. typedef char (&no_keywords_t)[2];
  109. no_keywords_t is_keywords_test(...);
  110. template<std::size_t nkeywords>
  111. yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords>&));
  112. template<std::size_t nkeywords>
  113. yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords> const&));
  114. template<typename T>
  115. class is_reference_to_keywords
  116. {
  117. public:
  118. BOOST_STATIC_CONSTANT(
  119. bool, value = (
  120. sizeof(detail::is_keywords_test( (void (*)(T))0 ))
  121. == sizeof(detail::yes_keywords_t)));
  122. typedef mpl::bool_<value> type;
  123. BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
  124. };
  125. # endif
  126. }
  127. inline detail::keywords<1> args(char const* name)
  128. {
  129. return detail::keywords<1>(name);
  130. }
  131. # define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
  132. # define BOOST_PP_LOCAL_MACRO(n) \
  133. inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
  134. { \
  135. detail::keywords<n> result; \
  136. BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
  137. return result; \
  138. }
  139. # define BOOST_PP_LOCAL_LIMITS (2, BOOST_PYTHON_MAX_ARITY)
  140. # include BOOST_PP_LOCAL_ITERATE()
  141. }} // namespace boost::python
  142. # endif // KEYWORDS_DWA2002323_HPP