mirror of
https://github.com/boostorg/system.git
synced 2025-12-25 08:18:05 +01:00
Compare commits
8 Commits
feature/is
...
feature/is
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f332a52597 | ||
|
|
c92d50abbd | ||
|
|
805b260a7a | ||
|
|
f32ffcba48 | ||
|
|
8ce2a9f835 | ||
|
|
6a58b03eab | ||
|
|
f0b27c5826 | ||
|
|
456b3c2dad |
@@ -85,6 +85,10 @@ template<class T> using remove_cvref = typename std::remove_cv< typename std::re
|
||||
|
||||
template<class... T> using is_errc_t = std::is_same<mp11::mp_list<remove_cvref<T>...>, mp11::mp_list<errc::errc_t>>;
|
||||
|
||||
template<class T, class... A> struct is_constructible: std::is_constructible<T, A...> {};
|
||||
template<class A> struct is_constructible<bool, A>: std::is_convertible<A, bool> {};
|
||||
template<class A> struct is_constructible<bool const, A>: std::is_convertible<A, bool> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// result
|
||||
@@ -122,7 +126,7 @@ public:
|
||||
template<class A = T, typename std::enable_if<
|
||||
std::is_convertible<A, T>::value &&
|
||||
!(detail::is_errc_t<A>::value && std::is_arithmetic<T>::value) &&
|
||||
!std::is_constructible<E, A>::value, int>::type = 0>
|
||||
!std::is_convertible<A, E>::value, int>::type = 0>
|
||||
constexpr result( A&& a )
|
||||
noexcept( std::is_nothrow_constructible<T, A>::value )
|
||||
: v_( in_place_value, std::forward<A>(a) )
|
||||
@@ -132,7 +136,7 @@ public:
|
||||
// implicit, error
|
||||
template<class A = E, class = void, typename std::enable_if<
|
||||
std::is_convertible<A, E>::value &&
|
||||
!std::is_constructible<T, A>::value, int>::type = 0>
|
||||
!std::is_convertible<A, T>::value, int>::type = 0>
|
||||
constexpr result( A&& a )
|
||||
noexcept( std::is_nothrow_constructible<E, A>::value )
|
||||
: v_( in_place_error, std::forward<A>(a) )
|
||||
@@ -141,9 +145,9 @@ public:
|
||||
|
||||
// explicit, value
|
||||
template<class... A, class En = typename std::enable_if<
|
||||
std::is_constructible<T, A...>::value &&
|
||||
detail::is_constructible<T, A...>::value &&
|
||||
!(detail::is_errc_t<A...>::value && std::is_arithmetic<T>::value) &&
|
||||
!std::is_constructible<E, A...>::value &&
|
||||
!detail::is_constructible<E, A...>::value &&
|
||||
sizeof...(A) >= 1
|
||||
>::type>
|
||||
explicit constexpr result( A&&... a )
|
||||
@@ -154,8 +158,8 @@ public:
|
||||
|
||||
// explicit, error
|
||||
template<class... A, class En2 = void, class En = typename std::enable_if<
|
||||
!std::is_constructible<T, A...>::value &&
|
||||
std::is_constructible<E, A...>::value &&
|
||||
!detail::is_constructible<T, A...>::value &&
|
||||
detail::is_constructible<E, A...>::value &&
|
||||
sizeof...(A) >= 1
|
||||
>::type>
|
||||
explicit constexpr result( A&&... a )
|
||||
@@ -187,7 +191,8 @@ public:
|
||||
// converting
|
||||
template<class T2, class E2, class En = typename std::enable_if<
|
||||
std::is_convertible<T2, T>::value &&
|
||||
std::is_convertible<E2, E>::value
|
||||
std::is_convertible<E2, E>::value &&
|
||||
!std::is_convertible<result<T2, E2> const&, T>::value
|
||||
>::type>
|
||||
BOOST_CXX14_CONSTEXPR result( result<T2, E2> const& r2 )
|
||||
noexcept(
|
||||
@@ -205,7 +210,8 @@ public:
|
||||
|
||||
template<class T2, class E2, class En = typename std::enable_if<
|
||||
std::is_convertible<T2, T>::value &&
|
||||
std::is_convertible<E2, E>::value
|
||||
std::is_convertible<E2, E>::value &&
|
||||
!std::is_convertible<result<T2, E2>&&, T>::value
|
||||
>::type>
|
||||
BOOST_CXX14_CONSTEXPR result( result<T2, E2>&& r2 )
|
||||
noexcept(
|
||||
|
||||
@@ -154,7 +154,12 @@ boost_test(TYPE run SOURCES result_eq.cpp)
|
||||
boost_test(TYPE run SOURCES result_range_for.cpp)
|
||||
boost_test(TYPE run SOURCES result_value_construct2.cpp)
|
||||
boost_test(TYPE run SOURCES result_error_construct2.cpp)
|
||||
boost_test(TYPE run SOURCES result_errc_construct.cpp)
|
||||
boost_test(TYPE run SOURCES result_convert_construct.cpp)
|
||||
boost_test(TYPE run SOURCES result_typedefs.cpp)
|
||||
boost_test(TYPE run SOURCES result_value_construct3.cpp)
|
||||
boost_test(TYPE run SOURCES result_error_construct3.cpp)
|
||||
boost_test(TYPE run SOURCES result_emplace.cpp)
|
||||
boost_test(TYPE run SOURCES result_error_construct4.cpp)
|
||||
boost_test(TYPE run SOURCES result_value_construct4.cpp)
|
||||
boost_test(TYPE run SOURCES result_value_construct5.cpp)
|
||||
|
||||
@@ -190,3 +190,6 @@ run result_typedefs.cpp : : : $(CPP11) ;
|
||||
run result_value_construct3.cpp : : : $(CPP11) ;
|
||||
run result_error_construct3.cpp : : : $(CPP11) ;
|
||||
run result_emplace.cpp : : : $(CPP11) ;
|
||||
run result_error_construct4.cpp : : : $(CPP11) ;
|
||||
run result_value_construct4.cpp : : : $(CPP11) ;
|
||||
run result_value_construct5.cpp : : : $(CPP11) ;
|
||||
|
||||
@@ -146,8 +146,14 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<std::string, X>, int>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<std::string, X>>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, X>, int>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<int, X>>));
|
||||
// We'd like this to be false due to the ambiguity caused by X having
|
||||
// an explicit constructor taking an int, which should be viable in this
|
||||
// context, but the implicit constructor is enabled, and there's no way to
|
||||
// disallow it
|
||||
//
|
||||
// BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, X>, int>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_convertible<int, result<int, X>>));
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
49
test/result_error_construct4.cpp
Normal file
49
test/result_error_construct4.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2023 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>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
// Eigen::Matrix4d has an explicit templated constructor
|
||||
// https://github.com/boostorg/system/issues/103
|
||||
// https://github.com/boostorg/json/issues/843
|
||||
|
||||
struct X
|
||||
{
|
||||
X() {}
|
||||
template<class T> explicit X( T const& ) {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
auto ec = make_error_code( errc::invalid_argument );
|
||||
|
||||
result<X> r = ec;
|
||||
|
||||
BOOST_TEST( !r.has_value() );
|
||||
BOOST_TEST( r.has_error() );
|
||||
|
||||
BOOST_TEST_EQ( r.error(), ec );
|
||||
}
|
||||
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
{
|
||||
auto ec = make_error_code( std::errc::invalid_argument );
|
||||
|
||||
result<X> r = ec;
|
||||
|
||||
BOOST_TEST( !r.has_value() );
|
||||
BOOST_TEST( r.has_error() );
|
||||
|
||||
BOOST_TEST_EQ( r.error(), ec );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
59
test/result_value_construct4.cpp
Normal file
59
test/result_value_construct4.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2023 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>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
// Tricky mixed construction cases
|
||||
// https://github.com/boostorg/system/issues/104
|
||||
// https://brevzin.github.io//c++/2023/01/18/optional-construction/
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int> r( make_error_code( errc::invalid_argument ) );
|
||||
result<result<int>> r2( r );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r( 5 );
|
||||
result<result<int>> r2( r );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( make_error_code( errc::invalid_argument ) );
|
||||
result<result<int>> r2( r );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( 5 );
|
||||
result<result<int>> r2( r );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r( make_error_code( errc::invalid_argument ) );
|
||||
result<result<int>> r2( std::move( r ) );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r( 5 );
|
||||
result<result<int>> r2( std::move( r ) );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
86
test/result_value_construct5.cpp
Normal file
86
test/result_value_construct5.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright 2023 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||
# pragma warning( disable: 4800 ) // forcing value to bool 'true' or 'false'
|
||||
#endif
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
// Tricky mixed construction cases
|
||||
// https://github.com/boostorg/system/issues/104
|
||||
// https://brevzin.github.io//c++/2023/01/18/optional-construction/
|
||||
|
||||
template<class R1, class R2> void test()
|
||||
{
|
||||
{
|
||||
R1 r1( make_error_code( errc::invalid_argument ) );
|
||||
R2 r2( r1 );
|
||||
|
||||
BOOST_TEST( !r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
R1 r1( 0 );
|
||||
R2 r2( r1 );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), false );
|
||||
}
|
||||
|
||||
{
|
||||
R1 r1( 1 );
|
||||
R2 r2( r1 );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), true );
|
||||
}
|
||||
|
||||
{
|
||||
R1 r1( make_error_code( errc::invalid_argument ) );
|
||||
R2 r2( std::move( r1 ) );
|
||||
|
||||
BOOST_TEST( !r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
R1 r1( 0 );
|
||||
R2 r2( std::move( r1 ) );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), false );
|
||||
}
|
||||
|
||||
{
|
||||
R1 r1( 1 );
|
||||
R2 r2( std::move( r1 ) );
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), true );
|
||||
}
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
test< result<int>, result<bool> >();
|
||||
test< result<int> const, result<bool> >();
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X>&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X> const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X>&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X> const&&>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X>&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X> const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X>&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X> const&&>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
Reference in New Issue
Block a user