1
0
forked from boostorg/core

Merge pull request #6 from K-ballo/ref-do-not-bind-to-temporaries

Disable binding ref to temporaries when rvalue references are supported
This commit is contained in:
Peter Dimov
2014-06-10 03:08:35 +03:00
5 changed files with 119 additions and 0 deletions

View File

@@ -20,6 +20,7 @@
//
// Copyright (C) 2014 Glen Joseph Fernandes
// glenfe at live dot com
// Copyright (C) 2014 Agustin Berge
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -65,6 +66,14 @@ public:
*/
BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
/**
@remark Construction from a temporary object is disabled.
*/
BOOST_DELETED_FUNCTION(reference_wrapper(T&& t))
public:
# endif
/**
@return The stored reference.
@remark Does not throw.
@@ -112,6 +121,15 @@ template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T
return reference_wrapper<T>(t);
}
/**
@return `ref(t.get())`
@remark Does not throw.
*/
template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( reference_wrapper<T> t )
{
return reference_wrapper<T>(t.get());
}
// cref
/**
@@ -123,8 +141,45 @@ template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST c
return reference_wrapper<T const>(t);
}
/**
@return `cref(t.get())`
@remark Does not throw.
*/
template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( reference_wrapper<T> t )
{
return reference_wrapper<T const>(t.get());
}
# undef BOOST_REF_CONST
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
/**
@cond
*/
# if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
# define BOOST_REF_DELETE
# else
# define BOOST_REF_DELETE = delete
# endif
/**
@endcond
*/
/**
@remark Construction from a temporary object is disabled.
*/
template<class T> void ref(T const&& t) BOOST_REF_DELETE;
/**
@remark Construction from a temporary object is disabled.
*/
template<class T> void cref(T const&& t) BOOST_REF_DELETE;
# undef BOOST_REF_DELETE
# endif
// is_reference_wrapper
/**

View File

@@ -19,6 +19,9 @@ compile-fail checked_delete_fail2.cpp ;
compile ref_ct_test.cpp ;
run ref_test.cpp ;
compile-fail ref_rv_fail1.cpp ;
compile-fail ref_rv_fail2.cpp ;
compile-fail ref_rv_fail3.cpp ;
run eif_constructors.cpp ;
run eif_dummy_arg_disambiguation.cpp ;

21
test/ref_rv_fail1.cpp Normal file
View File

@@ -0,0 +1,21 @@
// Copyright 2002-2004 David Abrahams and Aleksey Gurtovoy
// Copyright 2014 Agustin Berge
//
// 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>
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
int main()
{
boost::reference_wrapper<int const> r(1); // this should produce an ERROR
return 0;
}
# else
# error To fail, this test requires rvalue references
# endif

15
test/ref_rv_fail2.cpp Normal file
View File

@@ -0,0 +1,15 @@
// Copyright 2002-2004 David Abrahams and Aleksey Gurtovoy
// Copyright 2014 Agustin Berge
//
// 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>
int main()
{
boost::reference_wrapper<int> r = boost::ref(2); // this should produce an ERROR
return 0;
}

25
test/ref_rv_fail3.cpp Normal file
View File

@@ -0,0 +1,25 @@
// Copyright 2002-2004 David Abrahams and Aleksey Gurtovoy
// Copyright 2014 Agustin Berge
//
// 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>
# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
struct X {};
X const crv() { return X(); }
int main()
{
boost::reference_wrapper<X const> r = boost::ref(crv()); // this should produce an ERROR
return 0;
}
# else
# error To fail, this test requires rvalue references
# endif