|
10 | 10 | # include <boost/type_traits/object_traits.hpp> |
11 | 11 | # include <boost/type_traits/composite_traits.hpp> |
12 | 12 | # include <boost/type_traits/transform_traits.hpp> |
| 13 | +# include <boost/ref.hpp> |
13 | 14 |
|
14 | 15 | namespace boost { namespace python { namespace objects { |
15 | 16 |
|
| 17 | +template <class T> |
| 18 | +struct reference_to_value |
| 19 | +{ |
| 20 | + typedef typename add_reference<typename add_const<T>::type>::type reference; |
| 21 | + |
| 22 | + reference_to_value(reference x) : m_value(x) {} |
| 23 | + operator reference() const { return m_value; } |
| 24 | + private: |
| 25 | + reference m_value; |
| 26 | +}; |
| 27 | + |
16 | 28 | // A little metaprogram which selects the type to pass through an |
17 | 29 | // intermediate forwarding function when the destination argument type |
18 | 30 | // is T. |
19 | 31 | template <class T> |
20 | 32 | struct forward |
| 33 | + : mpl::select_type< |
| 34 | + is_scalar<T>::value |
| 35 | + , T |
| 36 | + , reference_to_value<T> > |
21 | 37 | { |
22 | | - BOOST_STATIC_CONSTANT( |
23 | | - bool, by_value = (is_scalar<T>::value | is_reference<T>::value) |
24 | | - ); |
| 38 | +}; |
25 | 39 |
|
26 | | - typedef typename mpl::select_type< |
27 | | - by_value |
28 | | - , T |
29 | | - , reference_wrapper< |
30 | | - typename add_const<T>::type |
31 | | - > |
32 | | - >::type type; |
| 40 | +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
| 41 | +template<typename T> |
| 42 | +class unforward |
| 43 | +{ |
| 44 | + public: |
| 45 | + typedef typename unwrap_reference<T>::type& type; |
33 | 46 | }; |
34 | 47 |
|
| 48 | +template<typename T> |
| 49 | +class unforward<reference_to_value<T> > |
| 50 | +{ |
| 51 | + public: |
| 52 | + typedef T type; |
| 53 | +}; |
| 54 | +# else // no partial specialization |
| 55 | + |
| 56 | +namespace detail |
| 57 | +{ |
| 58 | + typedef char (&yes_reference_to_value_t)[1]; |
| 59 | + typedef char (&no_reference_to_value_t)[2]; |
| 60 | + |
| 61 | + no_reference_to_value_t is_reference_to_value_test(...); |
| 62 | + |
| 63 | + template<typename T> |
| 64 | + yes_reference_to_value_t is_reference_to_value_test(type< reference_to_value<T> >); |
| 65 | + |
| 66 | + template<bool wrapped> |
| 67 | + struct unforwarder |
| 68 | + { |
| 69 | + template <class T> |
| 70 | + struct apply |
| 71 | + { |
| 72 | + typedef typename unwrap_reference<T>::type& type; |
| 73 | + }; |
| 74 | + }; |
| 75 | + |
| 76 | + template<> |
| 77 | + struct unforwarder<true> |
| 78 | + { |
| 79 | + template <class T> |
| 80 | + struct apply |
| 81 | + { |
| 82 | + typedef typename T::reference type; |
| 83 | + }; |
| 84 | + }; |
| 85 | + |
| 86 | + template<typename T> |
| 87 | + class is_reference_to_value |
| 88 | + { |
| 89 | + public: |
| 90 | + BOOST_STATIC_CONSTANT( |
| 91 | + bool, value = ( |
| 92 | + sizeof(is_reference_to_value_test(type<T>())) |
| 93 | + == sizeof(yes_reference_to_value_t))); |
| 94 | + }; |
| 95 | +} |
| 96 | + |
| 97 | +template <typename T> |
| 98 | +class unforward |
| 99 | + : public detail::unforwarder< |
| 100 | + detail::is_reference_to_value<T>::value |
| 101 | + >::template apply<T> |
| 102 | +{}; |
| 103 | + |
| 104 | +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
| 105 | + |
35 | 106 | }}} // namespace boost::python::objects |
36 | 107 |
|
37 | 108 | #endif // FORWARD_DWA20011215_HPP |
0 commit comments