forked from boostorg/core
Add implicit conversion between compatible reference wrappers (refs #83)
This commit is contained in:
@ -10,6 +10,7 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/config/workaround.hpp>
|
#include <boost/config/workaround.hpp>
|
||||||
#include <boost/core/addressof.hpp>
|
#include <boost/core/addressof.hpp>
|
||||||
|
#include <boost/core/enable_if.hpp>
|
||||||
|
|
||||||
//
|
//
|
||||||
// ref.hpp - ref/cref, useful helper functions
|
// ref.hpp - ref/cref, useful helper functions
|
||||||
@ -46,6 +47,26 @@ namespace boost
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class Y, class T > struct ref_convertible
|
||||||
|
{
|
||||||
|
typedef char (&yes) [1];
|
||||||
|
typedef char (&no) [2];
|
||||||
|
|
||||||
|
static yes f( T* );
|
||||||
|
static no f( ... );
|
||||||
|
|
||||||
|
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ref_empty
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
// reference_wrapper
|
// reference_wrapper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,6 +108,14 @@ public:
|
|||||||
public:
|
public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<class Y> friend class reference_wrapper;
|
||||||
|
|
||||||
|
template<class Y> reference_wrapper( reference_wrapper<Y> r,
|
||||||
|
typename enable_if_c<boost::detail::ref_convertible<Y, T>::value,
|
||||||
|
boost::detail::ref_empty>::type = boost::detail::ref_empty() ): t_( r.t_ )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@return The stored reference.
|
@return The stored reference.
|
||||||
@remark Does not throw.
|
@remark Does not throw.
|
||||||
|
@ -35,7 +35,10 @@ compile-fail ref_rv_fail4.cpp ;
|
|||||||
compile-fail ref_rv_fail5.cpp ;
|
compile-fail ref_rv_fail5.cpp ;
|
||||||
compile-fail ref_implicit_fail.cpp ;
|
compile-fail ref_implicit_fail.cpp ;
|
||||||
compile-fail ref_implicit_fail2.cpp ;
|
compile-fail ref_implicit_fail2.cpp ;
|
||||||
|
compile-fail ref_implicit_fail3.cpp ;
|
||||||
|
compile-fail ref_implicit_fail4.cpp ;
|
||||||
run ref_cv_test.cpp ;
|
run ref_cv_test.cpp ;
|
||||||
|
run ref_conversion_test.cpp ;
|
||||||
|
|
||||||
run eif_constructors.cpp ;
|
run eif_constructors.cpp ;
|
||||||
run eif_dummy_arg_disambiguation.cpp ;
|
run eif_dummy_arg_disambiguation.cpp ;
|
||||||
|
39
test/ref_conversion_test.cpp
Normal file
39
test/ref_conversion_test.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Implicit conversions between compatible reference wrappers
|
||||||
|
//
|
||||||
|
// Copyright 2020 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
void f1( boost::reference_wrapper<X> r, Y * p )
|
||||||
|
{
|
||||||
|
BOOST_TEST_EQ( r.get_pointer(), p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2( boost::reference_wrapper<int const> r, int * p )
|
||||||
|
{
|
||||||
|
BOOST_TEST_EQ( r.get_pointer(), p );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Y y;
|
||||||
|
f1( boost::ref(y), &y );
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
f2( boost::ref(i), &i );
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
29
test/ref_implicit_fail3.cpp
Normal file
29
test/ref_implicit_fail3.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Incompatible reference_wrappers must not implicitly convert to each other
|
||||||
|
//
|
||||||
|
// Copyright 2020 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
void f( boost::reference_wrapper<X> )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Y y;
|
||||||
|
f( boost::ref(y) ); // should fail
|
||||||
|
}
|
21
test/ref_implicit_fail4.cpp
Normal file
21
test/ref_implicit_fail4.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Incompatible reference_wrappers must not implicitly convert to each other
|
||||||
|
//
|
||||||
|
// Copyright 2020 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
|
void f( boost::reference_wrapper< int const > )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
long y = 0;
|
||||||
|
f( boost::ref(y) ); // should fail
|
||||||
|
}
|
Reference in New Issue
Block a user