Compare commits

..

43 Commits

Author SHA1 Message Date
Peter Dimov
f78b036665 Update #if condition 2021-10-29 21:13:10 +03:00
Ed Catmur
9b0d735040 Add __attribute__((__format__)) to snprintf
This attribute will check format string bugs and is required for clean compile if -Wformat-nonliteral is enabled.
2021-10-29 11:59:03 +01:00
Peter Dimov
bfebaf53d7 Add static_assert to cmake_subdir_test 2021-10-28 23:48:03 +03:00
Peter Dimov
8338e80295 Enable syntax hightlighting 2021-10-28 23:17:20 +03:00
Peter Dimov
2b23aaab16 Add msvc-14.3 to ci.yml 2021-10-28 23:16:53 +03:00
Peter Dimov
7933300b6f Disable test on g++ 4.x because no std::io_errc 2021-10-11 03:30:50 +03:00
Peter Dimov
4ec1e54099 Enable error_code construction from enums specializing std::is_error_code_enum. Fixes #70. 2021-10-11 02:02:22 +03:00
Peter Dimov
5217e58a7d Enable implicit construction for aggregates using {{ ... }} 2021-10-02 22:07:05 +03:00
Peter Dimov
ce37e23491 Protect against dangling references in op* and value() 2021-10-02 19:16:04 +03:00
Peter Dimov
420a262733 Fix warnings_test.cpp 2021-10-02 17:25:31 +03:00
Peter Dimov
e15bccc09b Fix cmake_install_test/main.cpp 2021-10-02 16:57:38 +03:00
Peter Dimov
bb775c071a Update system_error::what to use error_code::what 2021-10-02 15:00:40 +03:00
Peter Dimov
01676ae42f Update documentation 2021-10-02 14:47:07 +03:00
Peter Dimov
eefcc5dcf6 Add error_code::what 2021-10-02 14:41:27 +03:00
Peter Dimov
f2d3a0decf Update documentation 2021-10-02 01:39:06 +03:00
Peter Dimov
0ccf08509b Add a constructor taking ErrorCodeEnum and a source location 2021-10-01 23:04:04 +03:00
Peter Dimov
7a72aee355 Merge branch 'develop' into feature/std-category-2 2021-09-24 23:54:51 +03:00
Peter Dimov
a8df99e927 Use source_location::to_string in system_error::build_message 2021-09-24 20:40:19 +03:00
Peter Dimov
85c7d92302 Avoid instantiating the system category in error_code::operator std::error_code 2021-09-24 15:24:45 +03:00
Peter Dimov
4c201d26b2 Update std_interop_test10 2021-09-24 04:29:29 +03:00
Peter Dimov
1659dfbeba Avoid instantiating generic_category in error_condition::operator std::error_condition 2021-09-24 04:27:08 +03:00
Peter Dimov
d2b8b54356 Do not use std::system_category under MinGW and g++ 4.x 2021-09-21 16:35:40 +03:00
Peter Dimov
41f7ea49cb Do not use std::system_category under VS2013 2021-09-21 16:02:12 +03:00
Peter Dimov
0b22dc595f Merge branch 'develop' into feature/std-category-2 2021-09-21 15:57:56 +03:00
Peter Dimov
aab58b0d5b Add std_interop_test10 2021-09-21 15:57:39 +03:00
Peter Dimov
ad66ea43a3 Revert addition of get_generic_std_category, get_system_std_category (they need this); do not use std::system_category on Cygwin 2021-09-21 15:45:00 +03:00
Peter Dimov
811564f186 Disable failing comparisons in std_interop_test6; stdlibs are at fault 2021-09-21 15:11:19 +03:00
Peter Dimov
a7e4879e55 Fix message comparisons in std_interop_test 2021-09-21 15:06:28 +03:00
Peter Dimov
9b11d864be Add helper functions get_generic_std_category, get_system_std_category 2021-09-21 15:01:44 +03:00
Peter Dimov
cc6a61b6c5 Convert system_category to std::system_category 2021-09-21 05:34:05 +03:00
Peter Dimov
9151633c95 Merge branch 'develop' into feature/std-category 2021-09-20 17:41:47 +03:00
Peter Dimov
5e0db22075 Include errc.hpp in system_error.hpp 2021-09-20 17:41:34 +03:00
Peter Dimov
60a20eeeb9 Retain old generic_category conversion behavior on g++ 4.8/4.9 2021-09-19 18:44:45 +03:00
Peter Dimov
1c8128e4cb Merge branch 'develop' into feature/std-category 2021-09-19 18:12:59 +03:00
Peter Dimov
1879ba6d35 Minor test update 2021-09-19 18:12:46 +03:00
Peter Dimov
b1dec88674 Convert generic_category to std::generic_category 2021-09-19 17:08:46 +03:00
Peter Dimov
5fd2535d9f Excise generic_category() references from error_condition 2021-09-19 16:04:16 +03:00
Peter Dimov
b39f239b3d Update documentation 2021-09-19 15:53:13 +03:00
Peter Dimov
abb13e707d Minor test fixes 2021-09-19 15:46:03 +03:00
Peter Dimov
bf34091cfe Add error_code_test2 2021-09-19 15:41:20 +03:00
Peter Dimov
e3f198e52c Add error_condition::to_string 2021-09-19 15:37:49 +03:00
Peter Dimov
05581aba03 Add error_condition_test3 2021-09-19 15:26:19 +03:00
Peter Dimov
47137ad116 Change predefined error_category identifiers to be contiguous for better codegen 2021-09-19 15:04:51 +03:00
32 changed files with 1379 additions and 167 deletions

View File

@@ -152,6 +152,10 @@ jobs:
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64

View File

@@ -13,6 +13,8 @@ Beman Dawes, Christopher Kohlhoff, Peter Dimov
:toclevels: 4
:idprefix:
:docinfo: private-footer
:source-highlighter: rouge
:source-language: c++
:leveloffset: +1

View File

@@ -11,7 +11,7 @@ https://www.boost.org/LICENSE_1_0.txt
## Changes in Boost 1.78
* Added support for source locations to `error_code`.
* Added `error_code::to_string`.
* Added `error_code::to_string`, `error_condition::to_string`, `error_code::what`.
* `system_error::what()` now contains the source location, if present.
* Added `result<T, E = error_code>`, a class holding either a value or an
error, defined in `<boost/system/result.hpp>`.

View File

@@ -571,9 +571,13 @@ public:
error_code( int val, const error_category & cat,
boost::source_location const * loc ) noexcept;
template <class ErrorCodeEnum>
template<class ErrorCodeEnum>
constexpr error_code( ErrorCodeEnum e ) noexcept;
template<class ErrorCodeEnum>
error_code( ErrorCodeEnum e, boost::source_location const * loc )
noexcept;
error_code( std::error_code const& ec ) noexcept;
// modifiers
@@ -583,9 +587,13 @@ public:
void assign( int val, const error_category & cat,
boost::source_location const * loc ) noexcept;
template<typename ErrorCodeEnum>
template<class ErrorCodeEnum>
constexpr error_code & operator=( ErrorCodeEnum e ) noexcept;
template<class ErrorCodeEnum>
void assign( ErrorCodeEnum e,
boost::source_location const * loc ) noexcept;
constexpr void clear() noexcept;
// observers
@@ -657,9 +665,13 @@ public:
// stream insertion
template <class charT, class traits>
template<class charT, class traits>
friend std::basic_ostream<charT, traits>&
operator<<( basic_ostream<charT, traits>& os, const error_code & ec );
// what
std::string what() const;
};
// non-member functions
@@ -699,7 +711,7 @@ Requires: :: `loc` points to a valid `boost::source_location` object with static
Ensures: :: `value() == val`; `category() == cat`; `has_location()`; `&location() == loc`.
```
template <class ErrorCodeEnum>
template<class ErrorCodeEnum>
constexpr error_code( ErrorCodeEnum e ) noexcept;
```
[none]
@@ -708,6 +720,19 @@ template <class ErrorCodeEnum>
Ensures: :: `*this == make_error_code( e )`.
Remarks: :: This constructor is only enabled when `is_error_code_enum<ErrorCodeEnum>::value` is `true`.
```
template<class ErrorCodeEnum>
error_code( ErrorCodeEnum e, boost::source_location const * loc ) noexcept;
```
[none]
* {blank}
+
Requires: :: `loc` points to a valid `boost::source_location` object with static storage duration.
Ensures: :: `*this == make_error_code( e )`.
Remarks: :: This constructor is only enabled when `is_error_code_enum<ErrorCodeEnum>::value` is `true`.
When `make_error_code( e )` is not a default-constructed `error_code` and doesn't wrap a
`std::error_code`, `has_location()` is `true` and `&location()` is `loc`.
```
error_code( std::error_code const & ec ) noexcept;
```
@@ -737,7 +762,7 @@ void assign( int val, const error_category & cat,
Effects: :: `*this = error_code( val, cat, loc )`.
```
template<typename ErrorCodeEnum>
template<class ErrorCodeEnum>
constexpr error_code & operator=( ErrorCodeEnum e ) noexcept;
```
[none]
@@ -746,6 +771,18 @@ template<typename ErrorCodeEnum>
Ensures: :: `*this == make_error_code( e )`.
Remarks: :: This operator is only enabled when `is_error_code_enum<ErrorCodeEnum>::value` is `true`.
```
template<class ErrorCodeEnum>
void assign( ErrorCodeEnum e,
boost::source_location const * loc ) noexcept;
```
[none]
* {blank}
+
Requires: :: `loc` points to a valid `boost::source_location` object with static storage duration.
Effects: :: `*this = error_code( e, loc )`.
Remarks: :: This function is only enabled when `is_error_code_enum<ErrorCodeEnum>::value` is `true`.
```
constexpr void clear() noexcept;
```
@@ -1021,6 +1058,18 @@ template <class charT, class traits>
Effects: :: `os << to_string()`.
Returns: :: `os`.
#### what
```
std::string what() const;
```
[none]
* {blank}
+
Returns: :: A string representation of `*this`, suitable for logging and
diagnostic output. Typically incorporates `message()`, `to_string()`, and
`location().to_string()` (if available.)
#### Nonmembers
```
@@ -1096,6 +1145,10 @@ public:
operator std::error_condition() const;
// to_string
std::string to_string() const;
// stream insertion
template <class charT, class traits>
@@ -1284,6 +1337,17 @@ operator std::error_condition() const;
Returns: ::
`std::error_condition( value(), category() )`.
#### to_string
```
std::string to_string() const;
```
[none]
* {blank}
+
Returns: :: The concatenation of `"cond:"`, `category().name()`, `':'`,
and the string representation of `value()`.
#### Stream Insertion
```
@@ -1294,7 +1358,7 @@ template <class charT, class traits>
[none]
* {blank}
+
Effects: :: `os << "cond:" << en.category().name() << ':' << en.value()`.
Effects: :: `os << en.to_string()`.
Returns: ::
`os`.

View File

@@ -0,0 +1,32 @@
#ifndef BOOST_SYSTEM_DETAIL_APPEND_INT_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_APPEND_INT_HPP_INCLUDED
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/system/detail/snprintf.hpp>
#include <string>
//
namespace boost
{
namespace system
{
namespace detail
{
inline void append_int( std::string& s, int v )
{
char buffer[ 32 ];
detail::snprintf( buffer, sizeof( buffer ), ":%d", v );
s += buffer;
}
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_APPEND_INT_HPP_INCLUDED

View File

@@ -173,9 +173,9 @@ public:
namespace detail
{
static const boost::ulong_long_type generic_category_id = ( boost::ulong_long_type( 0xB2AB117A ) << 32 ) + 0x257EDF0D;
static const boost::ulong_long_type system_category_id = ( boost::ulong_long_type( 0x8FAFD21E ) << 32 ) + 0x25C5E09B;
static const boost::ulong_long_type interop_category_id = ( boost::ulong_long_type( 0x943F2817 ) << 32 ) + 0xFD3A8FAF;
static const boost::ulong_long_type generic_category_id = ( boost::ulong_long_type( 0xB2AB117A ) << 32 ) + 0x257EDFD0;
static const boost::ulong_long_type system_category_id = generic_category_id + 1;
static const boost::ulong_long_type interop_category_id = generic_category_id + 2;
BOOST_SYSTEM_CONSTEXPR inline bool failed_impl( int ev, error_category const & cat )
{

View File

@@ -20,7 +20,6 @@
namespace boost
{
namespace system
{
@@ -91,7 +90,6 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
}
} // namespace system
} // namespace boost
// interoperability with std::error_code, std::error_condition
@@ -100,28 +98,54 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
#include <boost/system/detail/std_category.hpp>
inline boost::system::error_category::operator std::error_category const & () const
namespace boost
{
if( id_ == boost::system::detail::system_category_id )
namespace system
{
inline error_category::operator std::error_category const & () const
{
if( id_ == detail::generic_category_id )
{
static const boost::system::detail::std_category system_instance( this, 0x1F4D7 );
return system_instance;
// This condition must be the same as the one in error_condition.hpp
#if defined(BOOST_GCC) && BOOST_GCC < 50000
static const boost::system::detail::std_category generic_instance( this, 0x1F4D3 );
return generic_instance;
#else
return std::generic_category();
#endif
}
if( id_ == boost::system::detail::generic_category_id )
if( id_ == detail::system_category_id )
{
static const boost::system::detail::std_category generic_instance( this, 0x1F4D3 );
return generic_instance;
// This condition must be the same as the one in error_code.hpp
#if defined(__CYGWIN__) || defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER == 1800) || (defined(BOOST_GCC) && BOOST_GCC < 50000)
// Under Cygwin (and MinGW!), std::system_category() is POSIX
// Under VS2013, std::system_category() isn't quite right
static const boost::system::detail::std_category system_instance( this, 0x1F4D7 );
return system_instance;
#else
return std::system_category();
#endif
}
boost::system::detail::std_category* p = ps_.load( std::memory_order_acquire );
detail::std_category* p = ps_.load( std::memory_order_acquire );
if( p != 0 )
{
return *p;
}
boost::system::detail::std_category* q = new detail::std_category( this, 0 );
detail::std_category* q = new detail::std_category( this, 0 );
if( ps_.compare_exchange_strong( p, q, std::memory_order_release, std::memory_order_acquire ) )
{
@@ -134,6 +158,9 @@ inline boost::system::error_category::operator std::error_category const & () co
}
}
} // namespace system
} // namespace boost
#endif // #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CATEGORY_IMPL_HPP_INCLUDED

View File

@@ -18,6 +18,7 @@
#include <boost/system/detail/interop_category.hpp>
#include <boost/system/detail/enable_if.hpp>
#include <boost/system/detail/is_same.hpp>
#include <boost/system/detail/append_int.hpp>
#include <boost/system/detail/snprintf.hpp>
#include <boost/system/detail/config.hpp>
#include <boost/assert/source_location.hpp>
@@ -106,10 +107,30 @@ public:
}
template<class ErrorCodeEnum> BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e,
typename detail::enable_if<
is_error_code_enum<ErrorCodeEnum>::value
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|| std::is_error_code_enum<ErrorCodeEnum>::value
#endif
>::type* = 0 ) BOOST_NOEXCEPT: d1_(), lc_flags_( 0 )
{
*this = make_error_code( e );
}
template<class ErrorCodeEnum> error_code( ErrorCodeEnum e, source_location const * loc,
typename detail::enable_if<is_error_code_enum<ErrorCodeEnum>::value>::type* = 0 ) BOOST_NOEXCEPT:
d1_(), lc_flags_( 0 )
{
*this = make_error_code( e );
error_code e2 = make_error_code( e );
if( e2.lc_flags_ == 0 || e2.lc_flags_ == 1 )
{
*this = e2;
}
else
{
*this = error_code( e2.d1_.val_, *e2.d1_.cat_, loc );
}
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
@@ -142,6 +163,13 @@ public:
return *this;
}
template<typename ErrorCodeEnum>
typename detail::enable_if<is_error_code_enum<ErrorCodeEnum>::value, void>::type
assign( ErrorCodeEnum val, source_location const * loc ) BOOST_NOEXCEPT
{
*this = error_code( val, loc );
}
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
{
*this = error_code();
@@ -503,8 +531,16 @@ public:
}
else if( lc_flags_ == 0 )
{
//return std::error_code();
// This condition must be the same as the one in error_category_impl.hpp
#if defined(__CYGWIN__) || defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER == 1800) || (defined(BOOST_GCC) && BOOST_GCC < 50000)
return std::error_code( 0, boost::system::system_category() );
#else
return std::error_code();
#endif
}
else
{
@@ -549,18 +585,18 @@ public:
{
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( d2_ );
char buffer[ 32 ];
detail::snprintf( buffer, sizeof( buffer ), "%d", e2.value() );
std::string r( "std:" );
r += e2.category().name();
detail::append_int( r, e2.value() );
return std::string( "std:" ) + e2.category().name() + ":" + buffer;
return r;
}
else
#endif
{
char buffer[ 32 ];
detail::snprintf( buffer, sizeof( buffer ), "%d", value() );
return std::string( category().name() ) + ":" + buffer;
std::string r = category().name();
detail::append_int( r, value() );
return r;
}
}
@@ -570,6 +606,23 @@ public:
{
return os << ec.to_string();
}
std::string what() const
{
std::string r = message();
r += " [";
r += to_string();
if( has_location() )
{
r += " at ";
r += location().to_string();
}
r += "]";
return r;
}
};
inline std::size_t hash_value( error_code const & ec )

View File

@@ -15,6 +15,7 @@
#include <boost/system/detail/enable_if.hpp>
#include <boost/system/detail/is_same.hpp>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/append_int.hpp>
#include <boost/system/is_error_condition_enum.hpp>
#include <boost/system/detail/config.hpp>
#include <boost/config.hpp>
@@ -129,7 +130,7 @@ public:
}
else
{
return generic_category().message( value() );
return detail::generic_error_category_message( value() );
}
}
@@ -141,7 +142,7 @@ public:
}
else
{
return generic_category().message( value(), buffer, len );
return detail::generic_error_category_message( value(), buffer, len );
}
}
@@ -221,7 +222,23 @@ public:
operator std::error_condition () const
{
// This condition must be the same as the one in error_category_impl.hpp
#if defined(BOOST_GCC) && BOOST_GCC < 50000
return std::error_condition( value(), category() );
#else
if( cat_ )
{
return std::error_condition( val_, *cat_ );
}
else
{
return std::error_condition( val_, std::generic_category() );
}
#endif
}
inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT
@@ -246,14 +263,29 @@ public:
#endif
std::string to_string() const
{
std::string r( "cond:" );
if( cat_ )
{
r += cat_->name();
}
else
{
r += "generic";
}
detail::append_int( r, value() );
return r;
}
template<class Ch, class Tr>
inline friend std::basic_ostream<Ch, Tr>&
operator<< (std::basic_ostream<Ch, Tr>& os, error_condition const & en)
{
{
os << "cond:" << en.category().name() << ':' << en.value();
}
os << en.to_string();
return os;
}
};

View File

@@ -49,6 +49,9 @@ inline void snprintf( char * buffer, std::size_t len, char const * format, ... )
#else
#if defined(__GNUC__) && __GNUC__ >= 3
__attribute__((__format__ (__printf__, 3, 4)))
#endif
inline void snprintf( char * buffer, std::size_t len, char const * format, ... )
{
va_list args;

View File

@@ -62,35 +62,10 @@ public:
{
}
// explicit, value
template<class A, class En = typename std::enable_if<
std::is_constructible<T, A>::value &&
!std::is_convertible<A, T>::value &&
!std::is_constructible<E, A>::value
>::type>
explicit constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<T, A>::value )
: v_( in_place_value, std::forward<A>(a) )
{
}
// explicit, error
template<class A, class En2 = void, class En = typename std::enable_if<
std::is_constructible<E, A>::value &&
!std::is_convertible<A, E>::value &&
!std::is_constructible<T, A>::value
>::type>
explicit constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// implicit, value
template<class A, class En2 = void, class En3 = void, class En = typename std::enable_if<
template<class A = T, typename std::enable_if<
std::is_convertible<A, T>::value &&
!std::is_constructible<E, A>::value
>::type>
!std::is_constructible<E, A>::value, int>::type = 0>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<T, A>::value )
: v_( in_place_value, std::forward<A>(a) )
@@ -98,35 +73,32 @@ public:
}
// implicit, error
template<class A, class En2 = void, class En3 = void, class En4 = void, class En = typename std::enable_if<
template<class A = E, class = void, typename std::enable_if<
std::is_convertible<A, E>::value &&
!std::is_constructible<T, A>::value
>::type>
!std::is_constructible<T, A>::value, int>::type = 0>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// more than one arg, value
// explicit, value
template<class... A, class En = typename std::enable_if<
std::is_constructible<T, A...>::value &&
!std::is_constructible<E, A...>::value &&
sizeof...(A) >= 2
!std::is_constructible<E, A...>::value
>::type>
constexpr result( A&&... a )
explicit constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<T, A...>::value )
: v_( in_place_value, std::forward<A>(a)... )
{
}
// more than one arg, error
// 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 &&
sizeof...(A) >= 2
std::is_constructible<E, A...>::value
>::type>
constexpr result( A&&... a )
explicit constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
: v_( in_place_error, std::forward<A>(a)... )
{
@@ -210,12 +182,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 +265,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);
}

View File

@@ -6,9 +6,8 @@
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/errc.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/error_category_impl.hpp>
#include <boost/system/detail/snprintf.hpp>
#include <string>
#include <stdexcept>
#include <cassert>
@@ -26,14 +25,6 @@ private:
private:
static std::string to_string( int v )
{
char buffer[ 32 ];
detail::snprintf( buffer, sizeof( buffer ), "%d", v );
return buffer;
}
static std::string build_message( char const * prefix, error_code const & ec )
{
std::string r;
@@ -44,32 +35,7 @@ private:
r += ": ";
}
r += ec.message();
if( ec.has_location() )
{
r += " [";
r += ec.to_string();
r += " at ";
boost::source_location loc = ec.location();
r += loc.file_name();
r += ':';
r += to_string( loc.line() );
if( loc.column() != 0 )
{
r += ':';
r += to_string( loc.column() );
}
r += " in function '";
r += loc.function_name();
r += "\']";
}
r += ec.what();
return r;
}

View File

@@ -101,6 +101,17 @@ boost_test(TYPE run SOURCES std_interop_test9.cpp)
boost_test(TYPE run SOURCES ec_location_test.cpp)
boost_test(TYPE run SOURCES error_condition_test3.cpp)
boost_test(TYPE run SOURCES error_code_test2.cpp)
boost_test(TYPE run SOURCES system_error_test2.cpp)
boost_test(TYPE run SOURCES std_interop_test10.cpp)
boost_test(TYPE run SOURCES ec_location_test2.cpp)
boost_test(TYPE run SOURCES ec_what_test.cpp)
boost_test(TYPE run SOURCES system_error_test3.cpp)
boost_test(TYPE run SOURCES std_interop_test11.cpp)
# result
set(BOOST_TEST_COMPILE_FEATURES cxx_std_11)
@@ -116,3 +127,6 @@ 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)
boost_test(TYPE run SOURCES result_value_construct2.cpp)
boost_test(TYPE run SOURCES result_error_construct2.cpp)

View File

@@ -73,8 +73,8 @@ system-run failed_constexpr_test.cpp ;
# Quick (CI) test
run quick.cpp ;
compile warnings_test.cpp
: <warnings>pedantic
run warnings_test.cpp
: : : <warnings>pedantic
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
@@ -123,6 +123,17 @@ run std_interop_test9.cpp ;
run ec_location_test.cpp ;
run error_condition_test3.cpp ;
run error_code_test2.cpp ;
run system_error_test2.cpp ;
run std_interop_test10.cpp ;
run ec_location_test2.cpp ;
run ec_what_test.cpp ;
run system_error_test3.cpp ;
run std_interop_test11.cpp ;
# result
import ../../config/checks/config : requires ;
@@ -140,3 +151,6 @@ 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) ;
run result_value_construct2.cpp : : : $(CPP11) ;
run result_error_construct2.cpp : : : $(CPP11) ;

View File

@@ -40,5 +40,5 @@ int main()
boost::system::system_error x( bc, "prefix" );
BOOST_TEST_EQ( x.code(), bc );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.message() );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.what() );
}

View File

@@ -12,6 +12,7 @@ add_subdirectory(../../../config boostorg/config)
add_subdirectory(../../../core boostorg/core)
add_subdirectory(../../../mp11 boostorg/mp11)
add_subdirectory(../../../predef boostorg/predef)
add_subdirectory(../../../static_assert boostorg/static_assert)
add_subdirectory(../../../throw_exception boostorg/throw_exception)
add_subdirectory(../../../variant2 boostorg/variant2)
add_subdirectory(../../../winapi boostorg/winapi)

287
test/ec_location_test2.cpp Normal file
View File

@@ -0,0 +1,287 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
namespace sys = boost::system;
enum E
{
none = 0,
einval = EINVAL
};
namespace boost
{
namespace system
{
template<> struct is_error_code_enum< ::E >
{
static const bool value = true;
};
} // namespace system
} // namespace boost
sys::error_code make_error_code( E e )
{
return e == 0? sys::error_code(): sys::error_code( e, sys::generic_category() );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
enum E2
{
e2inval = EINVAL
};
namespace boost
{
namespace system
{
template<> struct is_error_code_enum< ::E2 >
{
static const bool value = true;
};
} // namespace system
} // namespace boost
std::error_code make_error_code( E2 e )
{
return std::error_code( e, std::generic_category() );
}
#endif
int main()
{
{
sys::error_code ec( einval );
BOOST_TEST_EQ( ec.value(), EINVAL );
BOOST_TEST_EQ( &ec.category(), &sys::generic_category() );
BOOST_TEST( ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
sys::error_code ec( einval, &loc );
BOOST_TEST_EQ( ec.value(), EINVAL );
BOOST_TEST_EQ( &ec.category(), &sys::generic_category() );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 77 );
}
{
sys::error_code ec( none );
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
sys::error_code ec( none, &loc );
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec = sys::error_code( einval, &loc );
BOOST_TEST_EQ( ec.value(), EINVAL );
BOOST_TEST_EQ( &ec.category(), &sys::generic_category() );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 127 );
}
{
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec = sys::error_code( none, &loc );
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( einval, &loc );
BOOST_TEST_EQ( ec.value(), EINVAL );
BOOST_TEST_EQ( &ec.category(), &sys::generic_category() );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 175 );
}
{
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( none, &loc );
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
sys::error_code ec( e2inval );
BOOST_TEST_EQ( ec, std::error_code( EINVAL, std::generic_category() ) );
BOOST_TEST( ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
sys::error_code ec( e2inval, &loc );
BOOST_TEST_EQ( ec, std::error_code( EINVAL, std::generic_category() ) );
BOOST_TEST( ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec = sys::error_code( e2inval, &loc );
BOOST_TEST_EQ( ec, std::error_code( EINVAL, std::generic_category() ) );
BOOST_TEST( ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &sys::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( e2inval, &loc );
BOOST_TEST_EQ( ec, std::error_code( EINVAL, std::generic_category() ) );
BOOST_TEST( ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
#endif
return boost::report_errors();
}

91
test/ec_what_test.cpp Normal file
View File

@@ -0,0 +1,91 @@
// Copyright 2020, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/system/generic_category.hpp>
#include <boost/system/system_category.hpp>
#include <boost/core/lightweight_test.hpp>
namespace sys = boost::system;
int main()
{
{
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST( ec.category() == sys::system_category() );
BOOST_TEST_EQ( ec.what(), ec.message() + " [system:0]" );
}
{
sys::error_code ec( 5, sys::generic_category() );
BOOST_TEST_EQ( ec.value(), 5 );
BOOST_TEST( ec.category() == sys::generic_category() );
BOOST_TEST_EQ( ec.what(), ec.message() + " [generic:5]" );
}
{
sys::error_code ec( 5, sys::system_category() );
BOOST_TEST_EQ( ec.value(), 5 );
BOOST_TEST( ec.category() == sys::system_category() );
BOOST_TEST_EQ( ec.what(), ec.message() + " [system:5]" );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
sys::error_code ec( 5, sys::generic_category(), &loc );
BOOST_TEST_EQ( ec.value(), 5 );
BOOST_TEST( ec.category() == sys::generic_category() );
BOOST_TEST_EQ( &ec.location(), &loc );
BOOST_TEST_EQ( ec.what(), ec.message() + " [generic:5 at " + loc.to_string() + "]" );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
sys::error_code ec( 5, sys::system_category(), &loc );
BOOST_TEST_EQ( ec.value(), 5 );
BOOST_TEST( ec.category() == sys::system_category() );
BOOST_TEST_EQ( &ec.location(), &loc );
BOOST_TEST_EQ( ec.what(), ec.message() + " [system:5 at " + loc.to_string() + "]" );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code ec;
sys::error_code ec2( ec );
BOOST_TEST_EQ( ec2.what(), ec2.message() + " [std:system:0]" );
}
{
std::error_code ec( 5, std::generic_category() );
sys::error_code ec2( ec );
BOOST_TEST_EQ( ec2.what(), ec2.message() + " [std:generic:5]" );
}
{
std::error_code ec( 5, std::system_category() );
sys::error_code ec2( ec );
BOOST_TEST_EQ( ec2.what(), ec2.message() + " [std:system:5]" );
}
#endif
return boost::report_errors();
}

94
test/error_code_test2.cpp Normal file
View File

@@ -0,0 +1,94 @@
// Copyright 2020, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/system/generic_category.hpp>
#include <boost/system/system_category.hpp>
#include <boost/core/lightweight_test.hpp>
namespace sys = boost::system;
int main()
{
char buffer[ 1024 ];
sys::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST( ec.category() == sys::system_category() );
BOOST_TEST_EQ( ec.message(), ec.category().message( ec.value() ) );
BOOST_TEST_CSTR_EQ( ec.message( buffer, sizeof( buffer ) ), ec.category().message( ec.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec );
BOOST_TEST_EQ( ec.to_string(), std::string( "system:0" ) );
{
sys::error_code ec2( ec );
BOOST_TEST_EQ( ec2.value(), 0 );
BOOST_TEST( ec2.category() == sys::system_category() );
BOOST_TEST_EQ( ec2.message(), ec2.category().message( ec2.value() ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( !ec2.failed() );
BOOST_TEST( !ec2 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST_NOT( ec != ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "system:0" ) );
}
{
sys::error_code ec2( ec.value(), ec.category() );
BOOST_TEST_EQ( ec2.value(), 0 );
BOOST_TEST( ec2.category() == sys::system_category() );
BOOST_TEST_EQ( ec2.message(), ec2.category().message( ec2.value() ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( !ec2.failed() );
BOOST_TEST( !ec2 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST_NOT( ec != ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "system:0" ) );
}
{
sys::error_code ec2( 5, sys::generic_category() );
BOOST_TEST_EQ( ec2.value(), 5 );
BOOST_TEST( ec2.category() == sys::generic_category() );
BOOST_TEST_EQ( ec2.message(), ec2.category().message( ec2.value() ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( ec2.failed() );
BOOST_TEST( ec2 );
BOOST_TEST_NOT( !ec2 );
BOOST_TEST_NE( ec, ec2 );
BOOST_TEST_NOT( ec == ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "generic:5" ) );
}
{
sys::error_code ec2( 5, sys::system_category() );
BOOST_TEST_EQ( ec2.value(), 5 );
BOOST_TEST( ec2.category() == sys::system_category() );
BOOST_TEST_EQ( ec2.message(), ec2.category().message( ec2.value() ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( ec2.failed() );
BOOST_TEST( ec2 );
BOOST_TEST_NOT( !ec2 );
BOOST_TEST_NE( ec, ec2 );
BOOST_TEST_NOT( ec == ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "system:5" ) );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,94 @@
// Copyright 2020, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_condition.hpp>
#include <boost/system/generic_category.hpp>
#include <boost/system/system_category.hpp>
#include <boost/core/lightweight_test.hpp>
namespace sys = boost::system;
int main()
{
char buffer[ 1024 ];
sys::error_condition en;
BOOST_TEST_EQ( en.value(), 0 );
BOOST_TEST( en.category() == sys::generic_category() );
BOOST_TEST_EQ( en.message(), en.category().message( en.value() ) );
BOOST_TEST_CSTR_EQ( en.message( buffer, sizeof( buffer ) ), en.category().message( en.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( !en.failed() );
BOOST_TEST( !en );
BOOST_TEST_EQ( en.to_string(), std::string( "cond:generic:0" ) );
{
sys::error_condition en2( en );
BOOST_TEST_EQ( en2.value(), 0 );
BOOST_TEST( en2.category() == sys::generic_category() );
BOOST_TEST_EQ( en2.message(), en2.category().message( en2.value() ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( !en2.failed() );
BOOST_TEST( !en2 );
BOOST_TEST_EQ( en, en2 );
BOOST_TEST_NOT( en != en2 );
BOOST_TEST_EQ( en2.to_string(), std::string( "cond:generic:0" ) );
}
{
sys::error_condition en2( en.value(), en.category() );
BOOST_TEST_EQ( en2.value(), 0 );
BOOST_TEST( en2.category() == sys::generic_category() );
BOOST_TEST_EQ( en2.message(), en2.category().message( en2.value() ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( !en2.failed() );
BOOST_TEST( !en2 );
BOOST_TEST_EQ( en, en2 );
BOOST_TEST_NOT( en != en2 );
BOOST_TEST_EQ( en2.to_string(), std::string( "cond:generic:0" ) );
}
{
sys::error_condition en2( 5, sys::generic_category() );
BOOST_TEST_EQ( en2.value(), 5 );
BOOST_TEST( en2.category() == sys::generic_category() );
BOOST_TEST_EQ( en2.message(), en2.category().message( en2.value() ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( en2.failed() );
BOOST_TEST( en2 );
BOOST_TEST_NOT( !en2 );
BOOST_TEST_NE( en, en2 );
BOOST_TEST_NOT( en == en2 );
BOOST_TEST_EQ( en2.to_string(), std::string( "cond:generic:5" ) );
}
{
sys::error_condition en2( 5, sys::system_category() );
BOOST_TEST_EQ( en2.value(), 5 );
BOOST_TEST( en2.category() == sys::system_category() );
BOOST_TEST_EQ( en2.message(), en2.category().message( en2.value() ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer, sizeof( buffer ) ) );
BOOST_TEST( en2.failed() );
BOOST_TEST( en2 );
BOOST_TEST_NOT( !en2 );
BOOST_TEST_NE( en, en2 );
BOOST_TEST_NOT( en == en2 );
BOOST_TEST_EQ( en2.to_string(), std::string( "cond:system:5" ) );
}
return boost::report_errors();
}

View File

@@ -37,7 +37,7 @@ int main()
boost::system::system_error x( bc, "prefix" );
BOOST_TEST_EQ( x.code(), bc );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.message() );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.what() );
return boost::report_errors();
}

View File

@@ -0,0 +1,57 @@
// 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 <string>
using namespace boost::system;
struct X
{
int a, b;
};
result<X> fx1()
{
return {{ EINVAL, generic_category() }};
}
struct Y
{
std::string v;
};
struct E
{
int v;
};
result<Y, E> fy1()
{
return {{ 42 }};
}
int main()
{
{
result<X> r = fx1();
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), std::error_code( EINVAL, generic_category() ) );
}
{
result<Y, E> r = fy1();
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v, 42 );
}
return boost::report_errors();
}

30
test/result_range_for.cpp Normal file
View 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();
}

View File

@@ -0,0 +1,152 @@
// 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>
#include <string>
using namespace boost::system;
struct X
{
int a;
};
struct Y
{
int a, b;
};
struct E
{
std::string v;
};
result<X> fx0()
{
return {};
}
result<X> fx1()
{
return {{ 1 }};
}
result<Y> fy0()
{
return {};
}
result<Y> fy2()
{
return {{ 1, 2 }};
}
result<X, E> fxe0()
{
return {};
}
result<X, E> fxe1()
{
return {{ 1 }};
}
result<std::vector<int>> fv0()
{
return {};
}
result<std::vector<int>> fv1()
{
return {{ 1 }};
}
result<std::vector<int>> fv2()
{
return {{ 1, 2 }};
}
int main()
{
{
result<X> r = fx0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 0 );
}
{
result<X> r = fx1();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 1 );
}
{
result<Y> r = fy0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 0 );
BOOST_TEST_EQ( r->b, 0 );
}
{
result<Y> r = fy2();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 1 );
BOOST_TEST_EQ( r->b, 2 );
}
{
result<X, E> r = fxe0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 0 );
}
{
result<X, E> r = fxe1();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 1 );
}
{
result<std::vector<int>> r = fv0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->size(), 0 );
}
{
result<std::vector<int>> r = fv1();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->size(), 1 );
BOOST_TEST_EQ( r->at(0), 1 );
}
{
result<std::vector<int>> r = fv2();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->size(), 2 );
BOOST_TEST_EQ( r->at(0), 1 );
BOOST_TEST_EQ( r->at(1), 2 );
}
return boost::report_errors();
}

View File

@@ -44,7 +44,8 @@ static void test_generic_category()
int ev = ENOENT;
BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
// Under MSVC, it's "no such file or directory" instead of "No such file or directory"
BOOST_TEST_EQ( bt.message( ev ).substr( 1 ), st.message( ev ).substr( 1 ) );
{
boost::system::error_code bc( ev, bt );
@@ -82,34 +83,13 @@ static void test_system_category()
BOOST_TEST_CSTR_EQ( bt.name(), st.name() );
for( int ev = 1; ev < 6; ++ev )
{
int ev = 5;
BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
std::string bm = bt.message( ev );
std::string sm = st.message( ev );
{
boost::system::error_code bc( ev, bt );
BOOST_TEST_EQ( bc.value(), ev );
BOOST_TEST_EQ( &bc.category(), &bt );
std::error_code sc( bc );
BOOST_TEST_EQ( sc.value(), ev );
BOOST_TEST_EQ( &sc.category(), &st );
}
{
boost::system::error_condition bn = bt.default_error_condition( ev );
BOOST_TEST( bt.equivalent( ev, bn ) );
std::error_condition sn( bn );
BOOST_TEST( st.equivalent( ev, sn ) );
}
}
{
int ev = 4;
BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
// We strip whitespace and the trailing dot, MSVC not so much
BOOST_TEST_EQ( bm, sm.substr( 0, bm.size() ) );
{
boost::system::error_code bc( ev, bt );

View File

@@ -0,0 +1,66 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <cerrno>
#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" )
int main() {}
#else
#include <system_error>
int main()
{
{
boost::system::error_code e1;
boost::system::error_code e2( 0, boost::system::system_category() );
BOOST_TEST_EQ( e1, e2 );
std::error_code e3( e1 );
std::error_code e4( e2 );
BOOST_TEST_EQ( e3, e4 );
}
{
boost::system::error_code e1;
std::error_code e2( e1 );
std::error_code e3( e1.value(), e1.category() );
BOOST_TEST_EQ( e2, e3 );
}
{
boost::system::error_condition e1;
boost::system::error_condition e2( 0, boost::system::generic_category() );
BOOST_TEST_EQ( e1, e2 );
std::error_condition e3( e1 );
std::error_condition e4( e2 );
BOOST_TEST( e3 == e4 );
}
{
boost::system::error_condition e1;
std::error_condition e2( e1 );
std::error_condition e3( e1.value(), e1.category() );
BOOST_TEST( e2 == e3 );
}
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,47 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.hpp>
#include <ios>
#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined" )
int main() {}
#elif defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 50000
BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_LIBSTDCXX_VERSION < 50000" )
int main() {}
#else
#include <system_error>
int main()
{
{
boost::system::error_code ec = std::io_errc::stream;
BOOST_TEST( ec == std::io_errc::stream );
BOOST_TEST_NOT( ec != std::io_errc::stream );
ec.clear();
BOOST_TEST_NOT( ec == std::io_errc::stream );
BOOST_TEST( ec != std::io_errc::stream );
ec = std::io_errc::stream;
BOOST_TEST( ec == std::io_errc::stream );
BOOST_TEST_NOT( ec != std::io_errc::stream );
}
return boost::report_errors();
}
#endif

View File

@@ -30,13 +30,20 @@ int main()
BOOST_TEST_EQ( e2, e1 );
BOOST_TEST_NOT( e2 != e1 );
BOOST_TEST( e2 == en );
#if defined(_LIBCPP_VERSION)
// Under MS STL and libstdc++, std::error_code() does not compare
// equal to std::error_condition(). Go figure.
BOOST_TEST_EQ( e2, en );
BOOST_TEST_NOT( e2 != en );
boost::system::error_code e3( e2 );
BOOST_TEST_EQ( e3, en );
BOOST_TEST_NOT( e3 != en );
#endif
}
{
@@ -51,13 +58,17 @@ int main()
BOOST_TEST_EQ( e2, e1 );
BOOST_TEST_NOT( e2 != e1 );
BOOST_TEST( e2 == en );
#if defined(_LIBCPP_VERSION)
BOOST_TEST_EQ( e2, en );
BOOST_TEST_NOT( e2 != en );
boost::system::error_code e3( e2 );
BOOST_TEST_EQ( e3, en );
BOOST_TEST_NOT( e3 != en );
#endif
}
{
@@ -72,7 +83,7 @@ int main()
BOOST_TEST_EQ( e2, e1 );
BOOST_TEST_NOT( e2 != e1 );
BOOST_TEST( e2 == en );
BOOST_TEST_EQ( e2, en );
BOOST_TEST_NOT( e2 != en );
boost::system::error_code e3( e2 );
@@ -93,7 +104,7 @@ int main()
BOOST_TEST_EQ( e2, e1 );
BOOST_TEST_NOT( e2 != e1 );
BOOST_TEST( e2 == en );
BOOST_TEST_EQ( e2, en );
BOOST_TEST_NOT( e2 != en );
boost::system::error_code e3( e2 );
@@ -114,7 +125,7 @@ int main()
BOOST_TEST_EQ( e2, e1 );
BOOST_TEST_NOT( e2 != e1 );
BOOST_TEST( e2 == en );
BOOST_TEST_EQ( e2, en );
BOOST_TEST_NOT( e2 != en );
boost::system::error_code e3( e2 );

View File

@@ -81,27 +81,25 @@ int main( int, char *[] )
system_error c6_0( 0, system_category(), "c6_0" );
system_error c6_1( 1, system_category(), "c6_1" );
TEST( c1_0, 0, "The operation completed successfully" );
TEST( c1_1, 1, "Incorrect function" );
TEST( c1_2u, 2, "The system cannot find the file specified" );
TEST( c1_0, 0, "The operation completed successfully [system:0]" );
TEST( c1_1, 1, "Incorrect function [system:1]" );
TEST( c1_2u, 2, "The system cannot find the file specified [system:2]" );
TEST( c2_0, 0, "c2_0: The operation completed successfully" );
TEST( c2_1, 1, "c2_1: Incorrect function" );
TEST( c2_0, 0, "c2_0: The operation completed successfully [system:0]" );
TEST( c2_1, 1, "c2_1: Incorrect function [system:1]" );
TEST( c3_0, 0, "c3_0: The operation completed successfully" );
TEST( c3_1, 1, "c3_1: Incorrect function" );
TEST( c3_0, 0, "c3_0: The operation completed successfully [system:0]" );
TEST( c3_1, 1, "c3_1: Incorrect function [system:1]" );
TEST( c4_0, 0, "The operation completed successfully" );
TEST( c4_1, 1, "Incorrect function" );
TEST( c4_2u, 2, "The system cannot find the file specified" );
TEST( c4_0, 0, "The operation completed successfully [system:0]" );
TEST( c4_1, 1, "Incorrect function [system:1]" );
TEST( c4_2u, 2, "The system cannot find the file specified [system:2]" );
TEST( c5_0, 0, "c5_0: The operation completed successfully" );
TEST( c5_1, 1, "c5_1: Incorrect function" );
TEST( c5_0, 0, "c5_0: The operation completed successfully [system:0]" );
TEST( c5_1, 1, "c5_1: Incorrect function [system:1]" );
TEST( c6_0, 0, "c6_0: The operation completed successfully" );
TEST( c6_1, 1, "c6_1: Incorrect function" );
TEST( c6_0, 0, "c6_0: The operation completed successfully [system:0]" );
TEST( c6_1, 1, "c6_1: Incorrect function [system:1]" );
return ::boost::report_errors();
}

View File

@@ -0,0 +1,41 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/system_error.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
namespace sys = boost::system;
int main()
{
{
sys::error_code ec( 5, sys::generic_category() );
sys::system_error x1( ec );
(void)x1;
}
{
sys::error_code ec( 5, sys::system_category() );
sys::system_error x1( ec );
(void)x1;
}
{
sys::system_error x1( make_error_code( sys::errc::invalid_argument ) );
(void)x1;
}
{
sys::system_error x1( 5, sys::generic_category() );
(void)x1;
}
{
sys::system_error x1( 5, sys::system_category() );
(void)x1;
}
return boost::report_errors();
}

View File

@@ -0,0 +1,42 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/system_error.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
namespace sys = boost::system;
int main()
{
{
sys::error_code ec( 5, sys::generic_category() );
sys::system_error x1( ec );
BOOST_TEST_EQ( std::string( x1.what() ), ec.what() );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
sys::error_code ec( 5, sys::system_category(), &loc );
sys::system_error x1( ec, "prefix" );
BOOST_TEST_EQ( std::string( x1.what() ), "prefix: " + ec.what() );
}
{
sys::system_error x1( 5, sys::generic_category() );
BOOST_TEST_EQ( std::string( x1.what() ), sys::error_code( 5, sys::generic_category() ).what() );
}
{
sys::system_error x1( 5, sys::system_category(), "prefix" );
BOOST_TEST_EQ( std::string( x1.what() ), "prefix: " + sys::error_code( 5, sys::system_category() ).what() );
}
return boost::report_errors();
}

View File

@@ -46,7 +46,7 @@ int main()
boost::system::system_error x( bc, "prefix" );
BOOST_TEST_EQ( x.code(), bc );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.message() );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.what() );
return boost::report_errors();
}