forked from boostorg/system
Protect against dangling references in op* and value()
This commit is contained in:
@ -210,12 +210,31 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR T&& value() &&
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<std::is_move_constructible<U>::value, T>::type
|
||||
value() &&
|
||||
{
|
||||
return std::move( value() );
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR T const&& value() const&&
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<!std::is_move_constructible<U>::value, T&&>::type
|
||||
value() &&
|
||||
{
|
||||
return std::move( value() );
|
||||
}
|
||||
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<std::is_move_constructible<U>::value, T>::type
|
||||
value() const && = delete;
|
||||
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<!std::is_move_constructible<U>::value, T const&&>::type
|
||||
value() const &&
|
||||
{
|
||||
return std::move( value() );
|
||||
}
|
||||
@ -274,12 +293,31 @@ public:
|
||||
return *p;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR T&& operator*() && noexcept
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<std::is_move_constructible<U>::value, T>::type
|
||||
operator*() && noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
{
|
||||
return std::move(**this);
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR T const&& operator*() const && noexcept
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<!std::is_move_constructible<U>::value, T&&>::type
|
||||
operator*() && noexcept
|
||||
{
|
||||
return std::move(**this);
|
||||
}
|
||||
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<std::is_move_constructible<U>::value, T>::type
|
||||
operator*() const && noexcept = delete;
|
||||
|
||||
template<class U = T>
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
typename std::enable_if<!std::is_move_constructible<U>::value, T const&&>::type
|
||||
operator*() const && noexcept
|
||||
{
|
||||
return std::move(**this);
|
||||
}
|
||||
|
@ -125,3 +125,4 @@ boost_test(TYPE run SOURCES result_value_access.cpp)
|
||||
boost_test(TYPE run SOURCES result_error_access.cpp)
|
||||
boost_test(TYPE run SOURCES result_swap.cpp)
|
||||
boost_test(TYPE run SOURCES result_eq.cpp)
|
||||
boost_test(TYPE run SOURCES result_range_for.cpp)
|
||||
|
@ -149,3 +149,4 @@ run result_value_access.cpp : : : $(CPP11) ;
|
||||
run result_error_access.cpp : : : $(CPP11) ;
|
||||
run result_swap.cpp : : : $(CPP11) <toolset>gcc-10:<cxxflags>"-Wno-maybe-uninitialized" ;
|
||||
run result_eq.cpp : : : $(CPP11) ;
|
||||
run result_range_for.cpp : : : $(CPP11) ;
|
||||
|
30
test/result_range_for.cpp
Normal file
30
test/result_range_for.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
result<std::vector<int>> f()
|
||||
{
|
||||
return std::vector<int>{ 1, 2, 3 };
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
for( int x: f().value() )
|
||||
{
|
||||
s += x;
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( s, 6 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user