diff --git a/include/boost/core/lightweight_test.hpp b/include/boost/core/lightweight_test.hpp index 2cd02e7..f5943b3 100644 --- a/include/boost/core/lightweight_test.hpp +++ b/include/boost/core/lightweight_test.hpp @@ -90,6 +90,7 @@ template inline void test_eq_impl( char const * expr1, char co { if( t == u ) { + report_errors_remind(); } else { @@ -106,6 +107,7 @@ template inline void test_ne_impl( char const * expr1, char co { if( t != u ) { + report_errors_remind(); } else { diff --git a/include/boost/core/lightweight_test_trait.hpp b/include/boost/core/lightweight_test_trait.hpp index ff03e37..0e2aab4 100644 --- a/include/boost/core/lightweight_test_trait.hpp +++ b/include/boost/core/lightweight_test_trait.hpp @@ -31,6 +31,7 @@ template< class T > inline void test_trait_impl( char const * trait, void (*)( T { if( T::value == expected ) { + report_errors_remind(); } else { @@ -41,7 +42,7 @@ template< class T > inline void test_trait_impl( char const * trait, void (*)( T << "' (should have been " << ( expected? "true": "false" ) << ")" << std::endl; - ++boost::detail::test_errors(); + ++test_errors(); } } diff --git a/include/boost/core/ref.hpp b/include/boost/core/ref.hpp index 414dd1a..8ae1140 100644 --- a/include/boost/core/ref.hpp +++ b/include/boost/core/ref.hpp @@ -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 @@ -38,6 +39,12 @@ namespace boost { +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + struct ref_workaround_tag {}; + +#endif + // reference_wrapper /** @@ -65,6 +72,20 @@ public: */ BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {} + +#endif + +#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. @@ -94,11 +115,11 @@ private: /** @cond */ -# if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) +#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) # define BOOST_REF_CONST -# else +#else # define BOOST_REF_CONST const -# endif +#endif /** @endcond */ @@ -109,7 +130,24 @@ private: */ template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref( T & t ) { - return reference_wrapper(t); +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + return reference_wrapper( t, ref_workaround_tag() ); + +#else + + return reference_wrapper( t ); + +#endif +} + +/** + @return `ref(t.get())` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref( reference_wrapper t ) +{ + return t; } // cref @@ -123,7 +161,44 @@ template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST c return reference_wrapper(t); } -# undef BOOST_REF_CONST +/** + @return `cref(t.get())` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST cref( reference_wrapper t ) +{ + return reference_wrapper(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 void ref(T const&& t) BOOST_REF_DELETE; + +/** + @remark Construction from a temporary object is disabled. +*/ +template void cref(T const&& t) BOOST_REF_DELETE; + +#undef BOOST_REF_DELETE + +#endif // is_reference_wrapper diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 66fbdd3..ba8a83a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -19,6 +19,15 @@ compile-fail checked_delete_fail2.cpp ; compile ref_ct_test.cpp ; run ref_test.cpp ; +run ref_ref_test.cpp ; +run ref_fn_test.cpp ; +compile-fail ref_rv_fail1.cpp ; +compile-fail ref_rv_fail2.cpp ; +compile-fail ref_rv_fail3.cpp ; +compile-fail ref_rv_fail4.cpp ; +compile-fail ref_rv_fail5.cpp ; +compile-fail ref_implicit_fail.cpp ; +compile-fail ref_implicit_fail2.cpp ; run eif_constructors.cpp ; run eif_dummy_arg_disambiguation.cpp ; diff --git a/test/ref_ct_test.cpp b/test/ref_ct_test.cpp index 34a79d2..731d62d 100644 --- a/test/ref_ct_test.cpp +++ b/test/ref_ct_test.cpp @@ -7,7 +7,7 @@ // see 'ref_test.cpp' for run-time part #include -#include +#include #include #include @@ -17,8 +17,8 @@ template< typename T, typename U > void ref_test(boost::reference_wrapper) { typedef typename boost::reference_wrapper::type type; - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); + BOOST_STATIC_ASSERT((boost::core::is_same::value)); + BOOST_STATIC_ASSERT((boost::core::is_same::value)); } template< typename T > @@ -36,14 +36,14 @@ void is_reference_wrapper_test(T) template< typename R, typename Ref > void cxx_reference_test(Ref) { - BOOST_STATIC_ASSERT((boost::is_same::value)); + BOOST_STATIC_ASSERT((boost::core::is_same::value)); } template< typename R, typename Ref > void unwrap_reference_test(Ref) { typedef typename boost::unwrap_reference::type type; - BOOST_STATIC_ASSERT((boost::is_same::value)); + BOOST_STATIC_ASSERT((boost::core::is_same::value)); } } // namespace diff --git a/test/ref_fn_test.cpp b/test/ref_fn_test.cpp new file mode 100644 index 0000000..aec54e8 --- /dev/null +++ b/test/ref_fn_test.cpp @@ -0,0 +1,81 @@ +#include + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// ref_fn_test.cpp: ref( f ) +// +// Copyright (c) 2008 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 +#include + + +void f0() +{ +} + +void f1(int) +{ +} + +void f2(int, int) +{ +} + +void f3(int, int, int) +{ +} + +void f4(int, int, int, int) +{ +} + +void f5(int, int, int, int, int) +{ +} + +void f6(int, int, int, int, int, int) +{ +} + +void f7(int, int, int, int, int, int, int) +{ +} + +void f8(int, int, int, int, int, int, int, int) +{ +} + +void f9(int, int, int, int, int, int, int, int, int) +{ +} + +#define BOOST_TEST_REF( f ) BOOST_TEST( &boost::ref( f ).get() == &f ) + +int main() +{ + int v = 0; + BOOST_TEST_REF( v ); + + BOOST_TEST_REF( f0 ); + BOOST_TEST_REF( f1 ); + BOOST_TEST_REF( f2 ); + BOOST_TEST_REF( f3 ); + BOOST_TEST_REF( f4 ); + BOOST_TEST_REF( f5 ); + BOOST_TEST_REF( f6 ); + BOOST_TEST_REF( f7 ); + BOOST_TEST_REF( f8 ); + BOOST_TEST_REF( f9 ); + + return boost::report_errors(); +} diff --git a/test/ref_implicit_fail.cpp b/test/ref_implicit_fail.cpp new file mode 100644 index 0000000..a012f52 --- /dev/null +++ b/test/ref_implicit_fail.cpp @@ -0,0 +1,20 @@ +// +// Rvalues should not implicitly convert to a reference_wrapper +// +// Copyright 2014 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 + +void f( boost::reference_wrapper< int > ) +{ +} + +int main() +{ + f( 1 ); // should fail +} diff --git a/test/ref_implicit_fail2.cpp b/test/ref_implicit_fail2.cpp new file mode 100644 index 0000000..ff67630 --- /dev/null +++ b/test/ref_implicit_fail2.cpp @@ -0,0 +1,20 @@ +// +// Rvalues should not implicitly convert to a reference_wrapper +// +// Copyright 2014 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 + +void f( boost::reference_wrapper< int const > ) +{ +} + +int main() +{ + f( 1 ); // should fail +} diff --git a/test/ref_ref_test.cpp b/test/ref_ref_test.cpp new file mode 100644 index 0000000..b667a7f --- /dev/null +++ b/test/ref_ref_test.cpp @@ -0,0 +1,39 @@ +// +// Test for ref(ref(x)) +// +// Copyright 2014 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 +#include + +int main() +{ + int x = 0; + + { + boost::reference_wrapper< int > r = boost::ref( boost::ref( x ) ); + BOOST_TEST_EQ( &r.get(), &x ); + } + + { + boost::reference_wrapper< int const > r = boost::ref( boost::cref( x ) ); + BOOST_TEST_EQ( &r.get(), &x ); + } + + { + boost::reference_wrapper< int const > r = boost::cref( boost::ref( x ) ); + BOOST_TEST_EQ( &r.get(), &x ); + } + + { + boost::reference_wrapper< int const > r = boost::cref( boost::cref( x ) ); + BOOST_TEST_EQ( &r.get(), &x ); + } + + return boost::report_errors(); +} diff --git a/test/ref_rv_fail1.cpp b/test/ref_rv_fail1.cpp new file mode 100644 index 0000000..a2e708d --- /dev/null +++ b/test/ref_rv_fail1.cpp @@ -0,0 +1,22 @@ +// +// Test that a reference_wrapper can't be constructed from an rvalue +// +// 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 + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +int main() +{ + boost::reference_wrapper r( 1 ); // this should produce an ERROR +} + +#else +# error To fail, this test requires rvalue references +#endif diff --git a/test/ref_rv_fail2.cpp b/test/ref_rv_fail2.cpp new file mode 100644 index 0000000..7258411 --- /dev/null +++ b/test/ref_rv_fail2.cpp @@ -0,0 +1,16 @@ +// +// Test that an rvalue can't be passed to ref() +// +// 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 + +int main() +{ + boost::reference_wrapper r = boost::ref( 2 ); // this should produce an ERROR +} diff --git a/test/ref_rv_fail3.cpp b/test/ref_rv_fail3.cpp new file mode 100644 index 0000000..fff6508 --- /dev/null +++ b/test/ref_rv_fail3.cpp @@ -0,0 +1,26 @@ +// +// Test that a const rvalue can't be passed to ref() +// +// 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 + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +struct X {}; + +X const crv() { return X(); } + +int main() +{ + boost::reference_wrapper r = boost::ref( crv() ); // this should produce an ERROR +} + +#else +# error To fail, this test requires rvalue references +#endif diff --git a/test/ref_rv_fail4.cpp b/test/ref_rv_fail4.cpp new file mode 100644 index 0000000..7f49123 --- /dev/null +++ b/test/ref_rv_fail4.cpp @@ -0,0 +1,23 @@ +// +// Test that an rvalue can't be passed to cref() +// +// Copyright 2014 Agustin Berge +// Copyright 2014 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 + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +int main() +{ + boost::reference_wrapper r = boost::cref( 2 ); // should fail +} + +#else +# error To fail, this test requires rvalue references. +#endif diff --git a/test/ref_rv_fail5.cpp b/test/ref_rv_fail5.cpp new file mode 100644 index 0000000..84bc467 --- /dev/null +++ b/test/ref_rv_fail5.cpp @@ -0,0 +1,27 @@ +// +// Test that a const rvalue can't be passed to cref() +// +// Copyright 2014 Agustin Berge +// Copyright 2014 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 + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +struct X {}; + +X const crv() { return X(); } + +int main() +{ + boost::reference_wrapper r = boost::cref( crv() ); // must fail +} + +#else +# error To fail, this test requires rvalue references. +#endif