forward.hpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright David Abrahams 2001.
  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 FORWARD_DWA20011215_HPP
  6. # define FORWARD_DWA20011215_HPP
  7. # include <boost/mpl/if.hpp>
  8. # include <boost/ref.hpp>
  9. # include <boost/python/detail/value_arg.hpp>
  10. # include <boost/python/detail/type_traits.hpp>
  11. # include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
  12. # include <boost/mpl/or.hpp>
  13. namespace boost { namespace python { namespace objects {
  14. // Very much like boost::reference_wrapper<T>, except that in this
  15. // case T can be a reference already without causing a
  16. // reference-to-reference error.
  17. template <class T>
  18. struct reference_to_value
  19. {
  20. typedef typename boost::python::detail::add_lvalue_reference<typename
  21. boost::python::detail::add_const<T>::type>::type reference;
  22. reference_to_value(reference x) : m_value(x) {}
  23. reference get() const { return m_value; }
  24. private:
  25. reference m_value;
  26. };
  27. // A little metaprogram which selects the type to pass through an
  28. // intermediate forwarding function when the destination argument type
  29. // is T.
  30. template <class T>
  31. struct forward
  32. : mpl::if_<
  33. mpl::or_<python::detail::copy_ctor_mutates_rhs<T>, boost::python::detail::is_scalar<T> >
  34. , T
  35. , reference_to_value<T>
  36. >
  37. {
  38. };
  39. template<typename T>
  40. struct unforward
  41. {
  42. typedef typename unwrap_reference<T>::type& type;
  43. };
  44. template<typename T>
  45. struct unforward<reference_to_value<T> >
  46. {
  47. typedef T type;
  48. };
  49. template <typename T>
  50. struct unforward_cref
  51. : python::detail::value_arg<
  52. typename unwrap_reference<T>::type
  53. >
  54. {
  55. };
  56. template<typename T>
  57. struct unforward_cref<reference_to_value<T> >
  58. : boost::python::detail::add_lvalue_reference<typename boost::python::detail::add_const<T>::type>
  59. {
  60. };
  61. template <class T>
  62. typename reference_to_value<T>::reference
  63. do_unforward(reference_to_value<T> const& x, int)
  64. {
  65. return x.get();
  66. }
  67. template <class T>
  68. typename reference_wrapper<T>::type&
  69. do_unforward(reference_wrapper<T> const& x, int)
  70. {
  71. return x.get();
  72. }
  73. template <class T>
  74. T const& do_unforward(T const& x, ...)
  75. {
  76. return x;
  77. }
  78. }}} // namespace boost::python::objects
  79. #endif // FORWARD_DWA20011215_HPP