Skip to content

Commit b601ba5

Browse files
committed
Yet another bug reported by Peter Bienstman is now fixed.
[SVN r13370]
1 parent 8de3571 commit b601ba5

File tree

8 files changed

+355
-234
lines changed

8 files changed

+355
-234
lines changed

include/boost/python/object/forward.hpp

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,99 @@
1010
# include <boost/type_traits/object_traits.hpp>
1111
# include <boost/type_traits/composite_traits.hpp>
1212
# include <boost/type_traits/transform_traits.hpp>
13+
# include <boost/ref.hpp>
1314

1415
namespace boost { namespace python { namespace objects {
1516

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+
1628
// A little metaprogram which selects the type to pass through an
1729
// intermediate forwarding function when the destination argument type
1830
// is T.
1931
template <class T>
2032
struct forward
33+
: mpl::select_type<
34+
is_scalar<T>::value
35+
, T
36+
, reference_to_value<T> >
2137
{
22-
BOOST_STATIC_CONSTANT(
23-
bool, by_value = (is_scalar<T>::value | is_reference<T>::value)
24-
);
38+
};
2539

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;
3346
};
3447

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+
35106
}}} // namespace boost::python::objects
36107

37108
#endif // FORWARD_DWA20011215_HPP

0 commit comments

Comments
 (0)