forward.hpp 2.2 KB

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