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() );
|
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() );
|
return std::move( value() );
|
||||||
}
|
}
|
||||||
@ -274,12 +293,31 @@ public:
|
|||||||
return *p;
|
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);
|
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);
|
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_error_access.cpp)
|
||||||
boost_test(TYPE run SOURCES result_swap.cpp)
|
boost_test(TYPE run SOURCES result_swap.cpp)
|
||||||
boost_test(TYPE run SOURCES result_eq.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_error_access.cpp : : : $(CPP11) ;
|
||||||
run result_swap.cpp : : : $(CPP11) <toolset>gcc-10:<cxxflags>"-Wno-maybe-uninitialized" ;
|
run result_swap.cpp : : : $(CPP11) <toolset>gcc-10:<cxxflags>"-Wno-maybe-uninitialized" ;
|
||||||
run result_eq.cpp : : : $(CPP11) ;
|
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