Compare commits

...

195 Commits

Author SHA1 Message Date
9e1ea0296e glob headers 2022-07-05 10:48:40 +02:00
96b876d91a Add README.md 2022-06-19 02:19:58 +03:00
eb9ae4ac69 Update revision history 2022-06-19 01:30:17 +03:00
8fd487d496 Update documentation 2022-06-19 01:28:36 +03:00
5223c94aa9 Disable throws_assign_fail.cpp for GCC/release, because gcc-12 fails it at compile time 2022-06-18 23:07:41 +03:00
a5ee3f291c Update ci.yml 2022-06-18 21:47:57 +03:00
4200b00973 Add converting constructor to result (refs #82) 2022-06-18 18:12:06 +03:00
533dfe1688 Update revision history 2022-05-05 21:17:09 +03:00
7dec756a6f Update documentation 2022-05-05 21:15:03 +03:00
648a35838b Remove unnecessary overloads 2022-05-05 05:12:08 +03:00
256fe92dbb Add error_code(error_code const& ec, source_location const* loc) and a corresponding assign 2022-05-05 05:02:37 +03:00
5debb8a041 Update revision history 2022-05-05 02:30:07 +03:00
a97e5a0546 Move BOOST_NOINLINE to operator std::error_category 2022-04-22 22:41:26 +03:00
dc17edfa07 Remove clang-win from appveyor.yml 2022-04-22 21:16:09 +03:00
65da7dfd56 Update result_error_construct tests to use sys::error_code instead of (erroneously) std::error_code 2022-04-22 19:52:19 +03:00
9279001b8c Check BOOST_NO_CXX11_HDR_MUTEX when enabling <system_error> integration 2022-04-22 16:49:03 +03:00
616e652bd7 Suppress strict-aliasing warning for gcc 4.8 to 6 2022-04-21 21:06:14 +03:00
98439855bd Use static_cast instead of reinterpret_cast 2022-04-21 20:52:02 +03:00
986efb1420 Rework conversion to std::error_category to not allocate (closes #78) 2022-04-21 20:32:25 +03:00
28a13571b9 Restore the original system::error_code from std::error_code (refs #79) 2022-03-18 18:24:01 +02:00
65ed1eef66 Add std_interop_test14.cpp (refs #79) 2022-03-18 08:12:05 +02:00
6de20eeebc Add std_interop_test13 2022-03-18 08:12:05 +02:00
0a9266ea7e Add a comment explaining the one-time allocation in error_category_impl.hpp. Fixes #78. 2022-03-18 08:11:16 +02:00
adb9fc54cb Remove msvc-14.1 from ci.yml 2022-03-18 07:51:38 +02:00
e197c5e803 Update documentation 2022-02-18 19:43:08 +02:00
6d7a57a970 Add throw_exception_from_error overload for std::exception_ptr 2022-02-18 02:55:34 +02:00
00c71cf388 Add throw_exception_from_error overloads for boost::system::errc, std::errc 2022-02-17 21:55:47 +02:00
d930cea481 Update documentation 2022-02-14 02:05:44 +02:00
4f09f4adde Use throw_with_location in throw_exception_from_error 2022-02-13 22:50:20 +02:00
abd62362ef Update documentation 2022-02-09 20:52:23 +02:00
8d8e6a90de Add an errc::make_error_code overload taking a source location 2022-02-09 20:41:34 +02:00
716c2ed8ef Disable result tests on GCC 4.7 2022-02-07 21:40:26 +02:00
46a5ecd490 Do not include boost/system/result.hpp on GCC 4.7 2022-02-07 21:38:14 +02:00
79f4ef0416 Remove .drone.star 2022-02-07 21:34:11 +02:00
d0a8f7fbb7 Squash-merge feature/drone-jsonnet into develop 2022-02-07 21:33:48 +02:00
bc07ab1e25 Update .drone.star 2022-02-07 05:09:49 +02:00
c6bff94709 Update std_interop_test12.cpp 2022-02-07 04:35:44 +02:00
ae079810be Add std_interop_test12.cpp 2022-02-07 04:30:50 +02:00
928de55563 Update .drone.star 2022-02-07 03:47:42 +02:00
442138de0a Update .drone.star 2022-02-07 03:41:35 +02:00
de610efd53 Move conditions to detail/config.hpp 2022-02-07 03:16:23 +02:00
4b143cdacc Use BOOST_LIBSTDCXX_VERSION instead of BOOST_GCC; update syscat condition 2022-02-07 03:02:57 +02:00
a1cb578f52 Update .drone.star 2022-02-07 02:55:54 +02:00
96b5073b79 Update .drone.star 2022-02-07 02:03:13 +02:00
2bff5c7071 Update .drone.star 2022-02-07 01:27:59 +02:00
137128176d Update .drone.star 2022-02-07 01:14:28 +02:00
e0e0f56eae Update .drone.star 2022-02-07 00:54:07 +02:00
58d55a67e5 Update .drone.star 2022-02-07 00:01:53 +02:00
34dcb59ee8 Update drone.bat 2022-02-06 23:30:19 +02:00
33f6ecba31 Update Drone files 2022-02-06 23:21:40 +02:00
23fbfb1ffa Update .drone.star 2022-02-06 22:55:48 +02:00
5366407135 Add Windows jobs to Drone 2022-02-06 22:42:19 +02:00
72a79b1dcb Disable -Wsign-compare for GCC 4.4 2022-02-06 22:29:28 +02:00
a5c1ab042e Update Drone files 2022-02-06 22:25:45 +02:00
c2beb75d66 Merge pull request #59 from sdarwin/drone
Drone config
2022-02-06 22:08:07 +02:00
54d9f4f38a Update documentation 2022-02-05 19:25:43 +02:00
b92be6417a Add a source_location parameter to throw_exception_from_error 2022-02-05 05:24:29 +02:00
245fff8af3 Update ci.yml 2022-02-05 03:11:09 +02:00
c359af3141 Update system_error constructors 2022-02-04 21:34:14 +02:00
50cad72fac Update system_error_test3.cpp 2022-02-04 21:22:35 +02:00
9554d8bbd3 Suppress incorrect warnings from GCC 7/8 2022-02-03 19:02:19 +02:00
cf9d986871 Update documentation 2022-02-03 18:47:53 +02:00
a5d68e52e6 Add throw_exception_from_error overload for std::error_code 2022-02-03 18:35:42 +02:00
9c6a09f41d Mark throw_exception_from_error as noinline 2022-02-03 09:37:59 +02:00
b9c26b9fa0 Add detail::system_error_category_message, use it in error_code::message 2022-02-03 05:47:43 +02:00
2e2430c4fa Add error_code::category_name helper, use it in to_string 2022-02-03 04:36:58 +02:00
4b1caad727 Avoid sign conversion warnings in error_code::value 2022-01-19 17:30:56 +02:00
5b96abbaa8 Undeprecate linux_error.hpp (closes #77) 2021-12-27 02:53:04 +02:00
2e1c800d82 Update appveyor.yml 2021-12-21 22:35:10 +02:00
04a79d710f Merge branch 'fix_error_code_wostream' of https://github.com/MarcelRaad/system into feature/pr-76 2021-12-21 19:51:50 +02:00
5700936367 Add ec_wstream_test (refs #76) 2021-12-21 19:51:08 +02:00
86b031cab9 Fix error_code's operator<< for arbitrary basic_ostream specializations
This fixes a regression from commit
a9b64a888a.
Calling `operator<<` with `std::string` only works for `std::ostream`.
Use `c_str()` to restore the previous behavior of using `const char*`,
which works for any `basic_ostream` specialization.
2021-12-21 13:17:26 +01:00
204e65f725 Add msvc-14.0 to GHA 2021-12-11 03:42:52 +02:00
01ce081470 Disable errc_t -> arithmetic conversions when initializing result (closes #74) 2021-12-11 01:22:08 +02:00
8c9ceba775 Add negative test for constructing result<int> from errc_t (refs #74) 2021-12-09 20:19:05 +02:00
91c0dd9a74 Merge pull request #73 from kpushkaryov/patch-1
Fix a typo
2021-11-17 06:24:18 +02:00
189fff42fe Fix a typo 2021-11-17 10:59:03 +07:00
3b4045c149 Minor doc update 2021-11-17 04:11:15 +02:00
3d877a1fca Update meta/libraries.json 2021-11-11 04:51:03 +02:00
128bdf9db2 Minor usage section changes 2021-11-11 04:33:06 +02:00
0e84860604 Add another usage subsection 2021-11-11 04:09:49 +02:00
83a306f3bf Update introduction 2021-11-10 20:36:57 +02:00
7dce2e3f42 Change 'wrapping' to 'adapting' 2021-11-10 18:52:41 +02:00
292c6825c6 Add another usage subsection 2021-11-09 22:05:45 +02:00
0d90d3d883 Add myimg_category implementation to usage example 2021-11-08 20:50:41 +02:00
81fec2b171 Add another usage subsection 2021-11-07 23:45:25 +02:00
4e15afe5be Add error handling and programming categories to libraries.json 2021-11-07 20:32:42 +02:00
8d1a866920 Add a usage subsection on wrapping zlib errors 2021-11-05 22:05:23 +02:00
09466c85b4 Add another usage subsection 2021-11-05 20:38:03 +02:00
baef8e50ea Rename 'Usage Examples' to 'Usage', add another subsection 2021-11-05 16:48:33 +02:00
5034f11a3a Add usage examples 2021-11-02 03:12:26 +02:00
f78b036665 Update #if condition 2021-10-29 21:13:10 +03:00
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
bfebaf53d7 Add static_assert to cmake_subdir_test 2021-10-28 23:48:03 +03:00
8338e80295 Enable syntax hightlighting 2021-10-28 23:17:20 +03:00
2b23aaab16 Add msvc-14.3 to ci.yml 2021-10-28 23:16:53 +03:00
7933300b6f Disable test on g++ 4.x because no std::io_errc 2021-10-11 03:30:50 +03:00
4ec1e54099 Enable error_code construction from enums specializing std::is_error_code_enum. Fixes #70. 2021-10-11 02:02:22 +03:00
5217e58a7d Enable implicit construction for aggregates using {{ ... }} 2021-10-02 22:07:05 +03:00
ce37e23491 Protect against dangling references in op* and value() 2021-10-02 19:16:04 +03:00
420a262733 Fix warnings_test.cpp 2021-10-02 17:25:31 +03:00
e15bccc09b Fix cmake_install_test/main.cpp 2021-10-02 16:57:38 +03:00
bb775c071a Update system_error::what to use error_code::what 2021-10-02 15:00:40 +03:00
01676ae42f Update documentation 2021-10-02 14:47:07 +03:00
eefcc5dcf6 Add error_code::what 2021-10-02 14:41:27 +03:00
f2d3a0decf Update documentation 2021-10-02 01:39:06 +03:00
0ccf08509b Add a constructor taking ErrorCodeEnum and a source location 2021-10-01 23:04:04 +03:00
7a72aee355 Merge branch 'develop' into feature/std-category-2 2021-09-24 23:54:51 +03:00
a8df99e927 Use source_location::to_string in system_error::build_message 2021-09-24 20:40:19 +03:00
85c7d92302 Avoid instantiating the system category in error_code::operator std::error_code 2021-09-24 15:24:45 +03:00
4c201d26b2 Update std_interop_test10 2021-09-24 04:29:29 +03:00
1659dfbeba Avoid instantiating generic_category in error_condition::operator std::error_condition 2021-09-24 04:27:08 +03:00
d2b8b54356 Do not use std::system_category under MinGW and g++ 4.x 2021-09-21 16:35:40 +03:00
41f7ea49cb Do not use std::system_category under VS2013 2021-09-21 16:02:12 +03:00
0b22dc595f Merge branch 'develop' into feature/std-category-2 2021-09-21 15:57:56 +03:00
aab58b0d5b Add std_interop_test10 2021-09-21 15:57:39 +03:00
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
811564f186 Disable failing comparisons in std_interop_test6; stdlibs are at fault 2021-09-21 15:11:19 +03:00
a7e4879e55 Fix message comparisons in std_interop_test 2021-09-21 15:06:28 +03:00
9b11d864be Add helper functions get_generic_std_category, get_system_std_category 2021-09-21 15:01:44 +03:00
cc6a61b6c5 Convert system_category to std::system_category 2021-09-21 05:34:05 +03:00
9151633c95 Merge branch 'develop' into feature/std-category 2021-09-20 17:41:47 +03:00
5e0db22075 Include errc.hpp in system_error.hpp 2021-09-20 17:41:34 +03:00
60a20eeeb9 Retain old generic_category conversion behavior on g++ 4.8/4.9 2021-09-19 18:44:45 +03:00
1c8128e4cb Merge branch 'develop' into feature/std-category 2021-09-19 18:12:59 +03:00
1879ba6d35 Minor test update 2021-09-19 18:12:46 +03:00
b1dec88674 Convert generic_category to std::generic_category 2021-09-19 17:08:46 +03:00
5fd2535d9f Excise generic_category() references from error_condition 2021-09-19 16:04:16 +03:00
b39f239b3d Update documentation 2021-09-19 15:53:13 +03:00
abb13e707d Minor test fixes 2021-09-19 15:46:03 +03:00
bf34091cfe Add error_code_test2 2021-09-19 15:41:20 +03:00
e3f198e52c Add error_condition::to_string 2021-09-19 15:37:49 +03:00
05581aba03 Add error_condition_test3 2021-09-19 15:26:19 +03:00
47137ad116 Change predefined error_category identifiers to be contiguous for better codegen 2021-09-19 15:04:51 +03:00
c02cd2b004 Add private error_code::equals, use it in error_category::equivalent 2021-09-19 05:24:08 +03:00
c8c5ad1ce5 Rework error_condition::op== to not require the generic_category() instance 2021-09-19 04:49:35 +03:00
361834e49c Minor documentation corrections 2021-09-18 16:57:21 +03:00
360effcf1d Remove static/shared tests, System is header-only 2021-09-18 02:23:21 +03:00
aaa893b5d6 Add mp11 to cmake_subdir_test/CMakeLists.txt 2021-09-18 00:08:30 +03:00
ff0bd3294f Add back predef, winapi needs it 2021-09-17 23:54:33 +03:00
aedadc27ce Update test/cmake_subdir_test/CMakeLists.txt 2021-09-17 21:31:13 +03:00
aad1212cfd Update tests/CMakeLists.txt 2021-09-17 21:15:13 +03:00
c15c2eeb74 Update dependencies in CMakeLists.txt 2021-09-17 21:10:53 +03:00
0ea47dd886 Add CMake jobs to ci.yml 2021-09-17 21:00:18 +03:00
08c12e8ad5 Document result<void, E> 2021-09-17 20:16:01 +03:00
7d3cfdd09a Update test/result_value_construct 2021-09-17 19:54:53 +03:00
15f94537a6 Update test/result_value_access 2021-09-17 19:53:11 +03:00
c0f38e2f3e Update test/result_swap 2021-09-17 19:46:56 +03:00
ac28a8cec9 Update test/result_move_assign 2021-09-17 19:44:58 +03:00
4169ef3ce6 Update test/result_error_construct 2021-09-17 19:36:58 +03:00
ce49a7d1be Update test/result_move_construct 2021-09-17 19:35:20 +03:00
1a4eb29719 Update test/result_error_access 2021-09-17 19:35:05 +03:00
465f6c57da Update test/result_eq 2021-09-17 19:34:44 +03:00
cb8db34d7b Update test/result_copy_assign 2021-09-17 19:34:26 +03:00
2b6a708070 Update test/result_copy_construct 2021-09-17 19:25:20 +03:00
50f84f16dc Add result<void, E> specialization 2021-09-17 19:22:15 +03:00
fd21395802 Minor indentation fixes 2021-09-17 18:50:30 +03:00
cebb011a58 Update indentation in reference 2021-09-17 18:43:30 +03:00
3f67d3def5 Rename throw_exception_from_error_code to throw_exception_from_error 2021-09-17 18:33:04 +03:00
f2b3ae7e2b Document throw_exception_from_error_code 2021-09-17 18:28:53 +03:00
48e56b9874 Update revision history 2021-09-17 18:19:24 +03:00
967b7cbc98 Add result to reference 2021-09-17 18:16:54 +03:00
c8492a705d Use unsafe_get instead of *get_if 2021-09-17 15:47:35 +03:00
a3187439e3 Disable warning in after_main_test 2021-09-16 19:49:17 +03:00
19f9d0c5b4 Fix unused parameter error 2021-09-16 19:43:32 +03:00
d17f7d7fe6 Fix unused variable warning 2021-09-16 19:32:22 +03:00
36843a4e2d Fix unused variable warnings 2021-09-16 19:30:28 +03:00
a6c988181e Include result.hpp in <boost/system.hpp> 2021-09-16 19:25:26 +03:00
10572b7a59 Trim includes in system_error.hpp 2021-09-16 19:21:27 +03:00
fe3d0e6c14 Update all references to <system_error> to refer to Boost.System 2021-09-16 19:16:30 +03:00
ae77563039 Define result in boost::system instead of in boost::result 2021-09-16 18:56:35 +03:00
fd852c675e Add <boost/system/result.hpp> 2021-09-16 18:47:05 +03:00
6156076dab Specify assign in terms of construction and assignment 2021-09-16 18:13:55 +03:00
984f8f1a92 Reorder constructor overloads 2021-09-16 18:04:27 +03:00
b507b2294e Unbreak the loc == 0 case, even though the specification disallows it 2021-09-16 03:12:20 +03:00
39ad22d660 Update reference 2021-09-16 03:07:32 +03:00
3b70265ced Rearrange error_code::failed to improve codegen 2021-09-15 16:42:47 +03:00
a65b91b3fb Merge branch 'develop' into feature/source-location 2021-09-15 16:06:55 +03:00
bed0d59d22 Disable failing tests under g++ 7 -std=c++17 2021-09-15 15:23:52 +03:00
5e642b1d43 Remove error_condition::failed_ in order to prioritise construction efficiency over failed() efficiency (latter is rare for conditions) 2021-09-15 14:54:26 +03:00
b35b47d8c2 Reformat what() message slightly 2021-09-15 13:42:54 +03:00
f21035f8af Move location to the end of what() 2021-09-15 07:58:24 +03:00
cd98f4edd7 Update system_error to incorporate the source location in what() 2021-09-15 07:42:57 +03:00
a9b64a888a Add support for source_location to error_code 2021-09-15 07:03:18 +03:00
bb4b500cfc Update Windows error mapping to match msvc-14.2 <system_error> 2021-09-08 00:48:55 +03:00
d44dab91dc Merge pull request #62 from rohitk5252/patch-2
Update index.html
2021-09-08 00:24:46 +03:00
2b6498ad80 Merge pull request #63 from rohitk5252/patch-3
Update system.adoc
2021-09-08 00:24:30 +03:00
22072bfbc9 Merge pull request #64 from rohitk5252/patch-5
Update Jamfile.v2
2021-09-08 00:24:08 +03:00
65f644d5de Switch ubuntu-16.04 jobs to ubuntu-18.04 2021-09-07 21:57:40 +03:00
f967081d7e Merge pull request #69 from marc-groundctl/map-broken-pipe
Map ERROR_BROKEN_PIPE to errc_t::broken_pipe
2021-09-07 21:34:22 +03:00
19e9f08666 Map ERROR_BROKEN_PIPE to errc_t::broken_pipe 2021-09-07 12:02:02 -04:00
a688d7834a add drone config [ci skip] 2021-01-21 19:45:47 +00:00
1ba5c9efc4 Update Jamfile.v2 2021-01-20 16:35:23 +05:30
23db4e8d69 Update system.adoc 2021-01-20 16:31:00 +05:30
189cc0c185 Update index.html
Changed http:// to https://
2021-01-20 16:28:26 +05:30
79 changed files with 9727 additions and 716 deletions

253
.drone.jsonnet Normal file
View File

@ -0,0 +1,253 @@
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
local library = "system";
local triggers =
{
branch: [ "master", "develop", "feature/*" ]
};
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
local asan = { ASAN: '1' };
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "linux",
arch: arch
},
steps:
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'set -e',
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "exec",
trigger: triggers,
platform: {
"os": "darwin",
"arch": arch
},
node: {
"os": osx_version
},
steps: [
{
name: "everything",
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
commands:
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local windows_pipeline(name, image, environment, arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "windows",
arch: arch
},
"steps":
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'cmd /C .drone\\\\drone.bat ' + library,
]
}
]
};
[
linux_pipeline(
"Linux 14.04 GCC 4.4",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.4', CXXSTD: '98,0x' },
"g++-4.4",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 14.04 GCC 4.6",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.6', CXXSTD: '98,0x' },
"g++-4.6",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 14.04 GCC 4.7",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.7', CXXSTD: '98,0x' },
"g++-4.7",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 14.04 GCC 4.8*",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11' },
),
linux_pipeline(
"Linux 14.04 GCC 4.9",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '03,11' },
"g++-4.9",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 16.04 GCC 5*",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14' },
),
linux_pipeline(
"Linux 18.04 GCC 6",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '03,11,14' },
"g++-6",
),
linux_pipeline(
"Linux 18.04 GCC 7* 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 18.04 GCC 8",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '03,11,14,17' },
"g++-8",
),
linux_pipeline(
"Linux 20.04 GCC 9* 32",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32' },
),
linux_pipeline(
"Linux 20.04 GCC 9* 64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '64' },
),
linux_pipeline(
"Linux 20.04 GCC 9 ARM64 32/64",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' },
arch="arm64",
),
linux_pipeline(
"Linux 20.04 GCC 10 32 ASAN",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '32' } + asan,
"g++-10-multilib",
),
linux_pipeline(
"Linux 20.04 GCC 10 64 ASAN",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '64' } + asan,
"g++-10-multilib",
),
linux_pipeline(
"Linux 20.04 Clang 13",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '03,11,14,17,20' },
"clang-13",
["deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main"],
),
linux_pipeline(
"Linux 20.04 Clang 14 UBSAN",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20' } + ubsan,
"clang-14",
["deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main"],
),
linux_pipeline(
"Linux 20.04 Clang 14 ASAN",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20' } + asan,
"clang-14",
["deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main"],
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + ubsan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
),
windows_pipeline(
"Windows VS2015 msvc-14.0",
"cppalliance/dronevs2015",
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest' },
),
windows_pipeline(
"Windows VS2017 msvc-14.1",
"cppalliance/dronevs2017",
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
),
windows_pipeline(
"Windows VS2019 msvc-14.2",
"cppalliance/dronevs2019",
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
),
windows_pipeline(
"Windows VS2022 msvc-14.3",
"cppalliance/dronevs2022:1",
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
),
]

23
.drone/drone.bat Normal file
View File

@ -0,0 +1,23 @@
@REM Copyright 2022 Peter Dimov
@REM Distributed under the Boost Software License, Version 1.0.
@REM https://www.boost.org/LICENSE_1_0.txt
@ECHO ON
set LIBRARY=%1
set DRONE_BUILD_DIR=%CD%
set BOOST_BRANCH=develop
if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init tools/boostdep
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
python tools/boostdep/depinst/depinst.py %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

24
.drone/drone.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
set -ex
DRONE_BUILD_DIR=$(pwd)
BOOST_BRANCH=develop
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init tools/boostdep
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py $LIBRARY
./bootstrap.sh
./b2 -d0 headers
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}

View File

@ -17,24 +17,17 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-16.04
os: ubuntu-18.04
install: g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
os: ubuntu-18.04
install: g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
os: ubuntu-18.04
install: g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
@ -45,48 +38,33 @@ jobs:
install: g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-20.04
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-20.04
install: g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-20.04
install: g++-11
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11"
os: ubuntu-16.04
install: clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.8
- toolset: gcc-12
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install: g++-12
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-16.04
os: ubuntu-18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-16.04
os: ubuntu-18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
os: ubuntu-18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
@ -118,8 +96,18 @@ jobs:
os: ubuntu-20.04
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,2a"
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install: clang-14
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
@ -170,14 +158,22 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
@ -214,4 +210,163 @@ jobs:
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Use library with add_subdirectory
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error

View File

@ -1,7 +1,9 @@
# Copyright 2018-2020 Peter Dimov
# Copyright 2018-2021 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
if(NOT DEFINED IDF_TARGET)
cmake_minimum_required(VERSION 3.5...3.16)
project(boost_system VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
@ -13,7 +15,10 @@ target_include_directories(boost_system INTERFACE include)
target_link_libraries(boost_system
INTERFACE
Boost::assert
Boost::config
Boost::throw_exception
Boost::variant2
Boost::winapi
)
@ -22,3 +27,23 @@ if(BUILD_TESTING)
add_subdirectory(test)
endif()
else()
FILE(GLOB_RECURSE headers include/*.h include/*.hpp)
idf_component_register(
SRCS
${headers}
INCLUDE_DIRS
include
REQUIRES
boost_assert
boost_config
boost_throw_exception
boost_variant2
# boost_winapi
)
endif()

25
README.md Normal file
View File

@ -0,0 +1,25 @@
# Boost.System
The Boost.System library, part of [Boost C++ Libraries](https://boost.org),
implements an extensible framework for error reporting in the form of an
`error_code` class and supporting facilities.
It has been proposed for the C++11 standard, has been accepted, and
is now available as part of the standard library in the `<system_error>`
header. However, the Boost implementation has continued to evolve and
gain enhancements and additional functionality, such as support for
attaching [source locations](https://www.boost.org/doc/libs/release/libs/assert/doc/html/assert.html#source_location_support)
to `error_code`, and a `result<T>` class that can carry either a value
or an error code.
See [the documentation of System](http://boost.org/libs/system) for more
information.
Since `<system_error>` is a relatively undocumented portion of the C++
standard library, the documentation of Boost.System may be useful to you
even if you use the standard components.
## License
Distributed under the
[Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).

View File

@ -22,20 +22,8 @@ environment:
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
CXXSTD: 14,17
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14,17,latest
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
CXXSTD: 14,17,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc

View File

@ -5,7 +5,7 @@
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or www.boost.org/LICENSE_1_0.txt)
# See library home page at http://www.boost.org/libs/system
# See library home page at https://www.boost.org/libs/system
project boost/system
: source-location ../src

View File

@ -4,7 +4,7 @@ Copyright 2018 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
https://www.boost.org/LICENSE_1_0.txt
////
# Boost.System: Extensible Error Reporting
@ -13,10 +13,13 @@ Beman Dawes, Christopher Kohlhoff, Peter Dimov
:toclevels: 4
:idprefix:
:docinfo: private-footer
:source-highlighter: rouge
:source-language: c++
:leveloffset: +1
include::system/introduction.adoc[]
include::system/usage.adoc[]
include::system/changes.adoc[]
include::system/rationale.adoc[]
include::system/reference.adoc[]

View File

@ -1,16 +1,40 @@
////
Copyright 2018-2021 Peter Dimov
Copyright 2018-2022 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
https://www.boost.org/LICENSE_1_0.txt
////
[#changes]
# Revision History
:idprefix:
## Changes in Boost 1.80
* When an `error_code` is converted to `std::error_code` and then back
to `error_code`, the original is now restored, if possible.
* Reworked the conversion from `error_category` to `std::error_category`
to avoid the one-time allocation that shows up on leak checkers.
* Added a constructor that allows replacing the source location of an
`error_code`, and a corresponding `assign`.
* Added a converting constructor to `result`.
## Changes in Boost 1.79
* Added a `boost::source_location` parameter to `throw_exception_from_error`.
* Added `throw_exception_from_error` overloads for `errc::errc_t`,
`std::error_code`, `std::errc`, `std::exception_ptr`.
* `result<T>::value` now automatically supplies `BOOST_CURRENT_LOCATION` to
`throw_exception_from_error` via a default argument.
* Added an `errc::make_error_code` overload taking a source location.
## Changes in Boost 1.78
* Added support for source locations to `error_code`.
* 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>`.
## Changes in Boost 1.77
* The conversion operator from `error_category` to `std::error_category`

View File

@ -14,6 +14,6 @@ http://www.boost.org/LICENSE_1_0.txt
This documentation is
* Copyright 2003-2017 Beman Dawes
* Copyright 2018-2021 Peter Dimov
* Copyright 2018-2022 Peter Dimov
and is distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].

View File

@ -1,6 +1,6 @@
////
Copyright 2003-2017 Beman Dawes
Copyright 2018 Peter Dimov
Copyright 2018, 2021 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
@ -12,39 +12,67 @@ http://www.boost.org/LICENSE_1_0.txt
# Introduction
:idprefix: intro_
Error conditions originating from the operating system or other low-level
application program interfaces (API's) are typically reported via an integer
representing an error code. When these low-level API calls are wrapped in
portable code, such as in a portable library, some users want to deal with the
error codes in portable ways. Other users need to get at the system specific
error codes, so they can deal with system specific needs. The Boost System
library provides simple, light-weight `error_code` objects that encapsulate
system-specific error code values, yet also provide access to more abstract
and portable error conditions via `error_condition` objects.
Errors originating from the operating system or other low-level application
program interfaces (APIs) are typically reported via an integer representing
an error code, either by returning the code directly from the function (e.g.
`pthread_mutex_init`) or by using a side channel such as the `errno`
pseudo-variable under POSIX or `GetLastError()` under Windows.
Because `error_code` objects can represent errors from sources other than the
operating system, including user-defined sources, each `error_code` and
`error_condition` has an associated `error_category`.
However, these integer error values can only be interpreted when their source
is known. The value 5 under Windows means `ERROR_ACCESS_DENIED` when returned
by `GetLastError()`, but `EIO` when retrieved from `errno`. And conversely,
the same error condition "access denied" is represented by the value 5 when
returned by `GetLastError()` and 13 (`EACCES`) when retrieved from `errno`.
An exception class, `system_error`, is provided. Derived from
`std::runtime_error`, it captures the underlying `error_code` for the problem
causing the exception so that this important information is not lost.
This means that in order for code to be able to handle errors from both
sources (to retrieve a text message describing the error, or to check whether
the error means "access denied"), it needs to know where the integer error
value originated. For this to be possible, the integer error value needs to
be accompanied by a piece of information identifying the source.
While exceptions are the preferred {cpp} default error code reporting
mechanism, users of libraries dependent on low-level API's often need overloads
reporting error conditions via error code arguments and/or return values rather
than via throwing exceptions. Otherwise, when errors are not exceptional
occurrences and must be dealt with as they arise, programs become littered with
try/catch blocks, unreadable, and inefficient. The Boost System library
supports both error reporting by exception and by error code.
Boost.System provides a framework in which this is possible. Errors are
represented by a class `error_code` which contains both the error value and
a pointer to their source (called "category"), represented as a class derived
from `error_category`.
In addition to portable errors codes and conditions supported by the
`error_code.hpp` header, system-specific headers support the Cygwin, Linux,
and Windows platforms. These headers are effectively no-ops if included for
platforms other than their intended target.
The category provides member functions such as `message`, which returns a text
message for a specific error value, and `equivalent`, which can be used to test
whether a specific error value correspond to an error condition such as "access
denied". `error_code` uses these category-provided functions in the
implementation of its `message` and `operator==` member functions.
Boost.System is part of the {cpp}11 Standard Library.
A number of changes, particularly to names, were made by the C++ committee
during standardization. The Boost implementation has been tracking those changes.
See <<#ref_deprecated_names,Deprecated Names>> for synonyms provided to prevent
breakage of existing user code.
Boost.System contains two predefined category classes, the generic category
(a reference to which is returned by `generic_category()`) and the system
category (`system_category()`). The generic category represents the error
values of the portable subset of `errno` values defined by the POSIX standard,
whereas the system category is OS dependent. Under POSIX, the system category
represents the `errno` values returned by the OS APIs (a superset of those in
the generic category), whereas under Windows, the system category represents
the error values returned by `GetLastError()`.
The framework is extensible. Users can define their own categories by
deriving a class from `error_category` and implementing a function that
returns a reference to an instance of it. This capability is useful both for
describing library-defined error values, and for adapting existing C API
libraries that return integer error values.
For those who prefer error reporting via exceptions, Boost.System provides
a standard exception class `system_error` that stores an `error_code`.
Boost.System was standardized in {cpp}11 as `<system_error>`. For a while,
the two were equivalent, but Boost.System has evolved since then and now
contains a number of extensions over its standard sibling:
* A non-allocating overload of `message`;
* Support for nonzero error codes meaning success, via the `failed` member
functions;
* Support for 64 bit category identifiers, as a solution to the problem
that sometimes it's not possible to ensure that only one instance of a
category exists in the program;
* Support for attaching source locations (file/line/function) to error codes;
* A class `result<T>` that can be used to return either a value or an error
code from a function;
* Various other minor improvements.
`boost::system::error_code` can be converted to, and constructed from,
`std::error_code`.

File diff suppressed because it is too large Load Diff

1414
doc/system/usage.adoc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,5 +9,10 @@
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/config.hpp>
#if (__cplusplus >= 201103L) && !(defined(BOOST_GCC) && BOOST_GCC < 40800) || (defined(_MSC_VER) && _MSC_VER >= 1900)
# include <boost/system/result.hpp>
#endif
#endif // #ifndef BOOST_SYSTEM_HPP_INCLUDED

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

@ -1,7 +1,7 @@
#ifndef BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED
// Copyright 2018 Peter Dimov
// Copyright 2018-2022 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)
@ -13,7 +13,7 @@
// BOOST_SYSTEM_HAS_SYSTEM_ERROR
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_CXX11_HDR_ATOMIC)
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_CXX11_HDR_ATOMIC) && !defined(BOOST_NO_CXX11_HDR_MUTEX)
# define BOOST_SYSTEM_HAS_SYSTEM_ERROR
#endif
@ -62,4 +62,20 @@
# define BOOST_SYSTEM_CLANG_6
#endif
//
#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 50000
# define BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY
#endif
#if defined(__CYGWIN__) || defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER == 1800) || (defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 90000)
// Under Cygwin (and MinGW!), std::system_category() is POSIX
// Under VS2013, std::system_category() isn't quite right
// Under libstdc++ before 7.4, before 8.3, before 9.1, default_error_condition
// for the system category returns a condition from the system category
# define BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY
#endif
#endif // BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED

View File

@ -48,6 +48,11 @@ class std_category;
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable: 4351) // new behavior: elements of array will be default initialized
#endif
class BOOST_SYMBOL_VISIBLE error_category
{
private:
@ -55,6 +60,9 @@ private:
friend std::size_t hash_value( error_code const & ec );
friend BOOST_SYSTEM_CONSTEXPR bool detail::failed_impl( int ev, error_category const & cat );
friend class error_code;
friend class error_condition;
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
public:
@ -73,13 +81,21 @@ private:
boost::ulong_long_type id_;
static std::size_t const stdcat_size_ = 4 * sizeof( void const* );
union
{
mutable unsigned char stdcat_[ stdcat_size_ ];
void const* stdcat_align_;
};
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
mutable std::atomic< boost::system::detail::std_category* > ps_;
mutable std::atomic< unsigned > sc_init_;
#else
boost::system::detail::std_category* ps_;
unsigned sc_init_;
#endif
@ -100,11 +116,11 @@ protected:
#endif
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 ), ps_()
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 ), stdcat_(), sc_init_()
{
}
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id ), ps_()
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id ), stdcat_(), sc_init_()
{
}
@ -155,14 +171,22 @@ public:
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
void init_stdcat() const;
# if defined(__SUNPRO_CC) // trailing __global is not supported
operator std::error_category const & () const;
# else
operator std::error_category const & () const BOOST_SYMBOL_VISIBLE;
# endif
#endif
};
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
#pragma GCC diagnostic pop
#endif
@ -170,9 +194,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

@ -14,13 +14,13 @@
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/snprintf.hpp>
#include <boost/system/detail/config.hpp>
#include <boost/config.hpp>
#include <string>
#include <cstring>
namespace boost
{
namespace system
{
@ -38,7 +38,7 @@ inline bool error_category::equivalent( int code, const error_condition & condit
inline bool error_category::equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT
{
return *this == code.category() && code.value() == condition;
return code.equals( condition, *this );
}
inline char const * error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
@ -91,49 +91,106 @@ 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
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#include <boost/system/detail/std_category.hpp>
#include <boost/system/detail/std_category_impl.hpp>
#include <mutex>
#include <new>
inline boost::system::error_category::operator std::error_category const & () const
namespace boost
{
namespace system
{
if( id_ == boost::system::detail::system_category_id )
{
static const boost::system::detail::std_category system_instance( this, 0x1F4D7 );
return system_instance;
}
if( id_ == boost::system::detail::generic_category_id )
{
static const boost::system::detail::std_category generic_instance( this, 0x1F4D3 );
return generic_instance;
}
namespace detail
{
boost::system::detail::std_category* p = ps_.load( std::memory_order_acquire );
template<class = void> struct stdcat_mx_holder
{
static std::mutex mx_;
};
if( p != 0 )
{
return *p;
}
template<class T> std::mutex stdcat_mx_holder<T>::mx_;
boost::system::detail::std_category* q = new detail::std_category( this, 0 );
} // namespace detail
if( ps_.compare_exchange_strong( p, q, std::memory_order_release, std::memory_order_acquire ) )
inline void error_category::init_stdcat() const
{
static_assert( sizeof( stdcat_ ) >= sizeof( boost::system::detail::std_category ), "sizeof(stdcat_) is not enough for std_category" );
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
// no alignof
#else
static_assert( alignof( decltype(stdcat_align_) ) >= alignof( boost::system::detail::std_category ), "alignof(stdcat_) is not enough for std_category" );
#endif
std::lock_guard<std::mutex> lk( boost::system::detail::stdcat_mx_holder<>::mx_ );
if( sc_init_.load( std::memory_order_acquire ) == 0 )
{
return *q;
}
else
{
delete q;
return *p;
::new( static_cast<void*>( stdcat_ ) ) boost::system::detail::std_category( this, 0 );
sc_init_.store( 1, std::memory_order_release );
}
}
#if defined( BOOST_GCC ) && BOOST_GCC >= 40800 && BOOST_GCC < 70000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
inline BOOST_NOINLINE error_category::operator std::error_category const & () const
{
if( id_ == detail::generic_category_id )
{
// This condition must be the same as the one in error_condition.hpp
#if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
static const boost::system::detail::std_category generic_instance( this, 0x1F4D3 );
return generic_instance;
#else
return std::generic_category();
#endif
}
if( id_ == detail::system_category_id )
{
// This condition must be the same as the one in error_code.hpp
#if defined(BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY)
static const boost::system::detail::std_category system_instance( this, 0x1F4D7 );
return system_instance;
#else
return std::system_category();
#endif
}
if( sc_init_.load( std::memory_order_acquire ) == 0 )
{
init_stdcat();
}
return *static_cast<boost::system::detail::std_category const*>( static_cast<void const*>( stdcat_ ) );
}
#if defined( BOOST_GCC ) && BOOST_GCC >= 40800 && BOOST_GCC < 70000
#pragma GCC diagnostic pop
#endif
} // namespace system
} // namespace boost
#endif // #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CATEGORY_IMPL_HPP_INCLUDED

View File

@ -3,7 +3,7 @@
// Copyright Beman Dawes 2006, 2007
// Copyright Christoper Kohlhoff 2007
// Copyright Peter Dimov 2017, 2018
// Copyright Peter Dimov 2017-2021
//
// 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)
@ -18,12 +18,20 @@
#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>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <boost/system/detail/std_category.hpp>
#endif
#include <boost/assert/source_location.hpp>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#include <ostream>
#include <new>
#include <cstdio>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <system_error>
@ -77,36 +85,94 @@ private:
// 1: holds std::error_code in d2_
// 2: holds error code in d1_, failed == false
// 3: holds error code in d1_, failed == true
unsigned flags_;
// >3: pointer to source_location, failed_ in lsb
boost::uintptr_t lc_flags_;
private:
char const* category_name() const BOOST_NOEXCEPT
{
// return category().name();
if( lc_flags_ == 0 )
{
// must match detail::system_error_category::name()
return "system";
}
else if( lc_flags_ == 1 )
{
// must match detail::interop_error_category::name()
return "std:unknown";
}
else
{
return d1_.cat_->name();
}
}
public:
// constructors:
BOOST_SYSTEM_CONSTEXPR error_code() BOOST_NOEXCEPT:
d1_(), flags_( 0 )
d1_(), lc_flags_( 0 )
{
}
BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_NOEXCEPT:
d1_(), flags_( 2 + detail::failed_impl( val, cat ) )
d1_(), lc_flags_( 2 + detail::failed_impl( val, cat ) )
{
d1_.val_ = val;
d1_.cat_ = &cat;
}
error_code( int val, const error_category & cat, source_location const * loc ) BOOST_NOEXCEPT:
d1_(), lc_flags_( ( loc? reinterpret_cast<boost::uintptr_t>( loc ): 2 ) | +detail::failed_impl( val, cat ) )
{
d1_.val_ = val;
d1_.cat_ = &cat;
}
template<class ErrorCodeEnum> BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e,
typename detail::enable_if<is_error_code_enum<ErrorCodeEnum>::value>::type* = 0 ) BOOST_NOEXCEPT
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 );
}
error_code( error_code const& ec, source_location const * loc ) BOOST_NOEXCEPT:
d1_(), lc_flags_( 0 )
{
*this = ec;
if( ec.lc_flags_ != 0 && ec.lc_flags_ != 1 )
{
lc_flags_ = ( loc? reinterpret_cast<boost::uintptr_t>( loc ): 2 ) | ( ec.lc_flags_ & 1 );
}
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
error_code( std::error_code const& ec ) BOOST_NOEXCEPT:
flags_( 1 )
d1_(), lc_flags_( 0 )
{
::new( d2_ ) std::error_code( ec );
#ifndef BOOST_NO_RTTI
if( detail::std_category const* pc2 = dynamic_cast< detail::std_category const* >( &ec.category() ) )
{
*this = boost::system::error_code( ec.value(), pc2->original_category() );
}
else
#endif
{
::new( d2_ ) std::error_code( ec );
lc_flags_ = 1;
}
}
#endif
@ -118,6 +184,16 @@ public:
*this = error_code( val, cat );
}
void assign( int val, const error_category & cat, source_location const * loc ) BOOST_NOEXCEPT
{
*this = error_code( val, cat, loc );
}
void assign( error_code const& ec, source_location const * loc ) BOOST_NOEXCEPT
{
*this = error_code( ec, loc );
}
template<typename ErrorCodeEnum>
BOOST_SYSTEM_CONSTEXPR typename detail::enable_if<is_error_code_enum<ErrorCodeEnum>::value, error_code>::type &
operator=( ErrorCodeEnum val ) BOOST_NOEXCEPT
@ -135,7 +211,7 @@ public:
BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT
{
if( flags_ != 1 )
if( lc_flags_ != 1 )
{
return d1_.val_;
}
@ -144,7 +220,11 @@ public:
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
return ec.value() + 1000 * static_cast<unsigned>( reinterpret_cast<boost::uintptr_t>( &ec.category() ) % 2097143 ); // 2^21-9, prime
unsigned cv = static_cast<unsigned>( ec.value() );
unsigned ch = static_cast<unsigned>( reinterpret_cast<boost::uintptr_t>( &ec.category() ) % 2097143 ); // 2^21-9, prime
return static_cast<int>( cv + 1000 * ch );
#else
return -1;
@ -154,11 +234,11 @@ public:
BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT
{
if( flags_ == 0 )
if( lc_flags_ == 0 )
{
return system_category();
}
else if( flags_ == 1 )
else if( lc_flags_ == 1 )
{
return detail::interop_category();
}
@ -178,7 +258,7 @@ public:
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( flags_ == 1 )
if( lc_flags_ == 1 )
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
return ec.message();
@ -186,47 +266,66 @@ public:
#endif
return category().message( value() );
if( lc_flags_ == 0 )
{
return detail::system_error_category_message( value() );
}
else
{
return category().message( value() );
}
}
char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( flags_ == 1 )
if( lc_flags_ == 1 )
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
#if !defined(BOOST_NO_EXCEPTIONS)
try
#endif
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
detail::snprintf( buffer, len, "%s", ec.message().c_str() );
return buffer;
}
#if !defined(BOOST_NO_EXCEPTIONS)
catch( ... )
{
detail::snprintf( buffer, len, "No message text available for error std:%s:%d", ec.category().name(), ec.value() );
return buffer;
}
#endif
}
#endif
return category().message( value(), buffer, len );
if( lc_flags_ == 0 )
{
return detail::system_error_category_message( value(), buffer, len );
}
else
{
return category().message( value(), buffer, len );
}
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( flags_ == 1 )
if( lc_flags_ & 1 )
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
return ec.value() != 0;
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( lc_flags_ == 1 )
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
return ec.value() != 0;
}
#endif
return true;
}
else
#endif
{
return (flags_ & 1) != 0;
return false;
}
}
@ -254,8 +353,43 @@ public:
#endif
bool has_location() const BOOST_NOEXCEPT
{
return lc_flags_ >= 4;
}
source_location const & location() const BOOST_NOEXCEPT
{
BOOST_STATIC_CONSTEXPR source_location loc;
return lc_flags_ >= 4? *reinterpret_cast<source_location const*>( lc_flags_ &~ static_cast<boost::uintptr_t>( 1 ) ): loc;
}
// relationals:
private:
// private equality for use in error_category::equivalent
friend class error_category;
BOOST_SYSTEM_CONSTEXPR bool equals( int val, error_category const& cat ) const BOOST_NOEXCEPT
{
if( lc_flags_ == 0 )
{
return val == 0 && cat.id_ == detail::system_category_id;
}
else if( lc_flags_ == 1 )
{
return cat.id_ == detail::interop_category_id && val == value();
}
else
{
return val == d1_.val_ && cat == *d1_.cat_;
}
}
public:
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
@ -263,7 +397,7 @@ public:
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( lhs.flags_ == 1 && rhs.flags_ == 1 )
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
{
std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
@ -281,7 +415,7 @@ public:
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( lhs.flags_ == 1 && rhs.flags_ == 1 )
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
{
std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
@ -304,7 +438,7 @@ public:
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( code.flags_ == 1 )
if( code.lc_flags_ == 1 )
{
return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
}
@ -320,7 +454,7 @@ public:
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( code.flags_ == 1 )
if( code.lc_flags_ == 1 )
{
return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
}
@ -444,14 +578,22 @@ public:
operator std::error_code () const
{
if( flags_ == 1 )
if( lc_flags_ == 1 )
{
return *reinterpret_cast<std::error_code const*>( d2_ );
}
else if( flags_ == 0 )
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(BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY)
return std::error_code( 0, boost::system::system_category() );
#else
return std::error_code();
#endif
}
else
{
@ -468,11 +610,11 @@ public:
class E = typename detail::enable_if<detail::is_same<T, std::error_code>::value>::type>
operator T& ()
{
if( flags_ != 1 )
if( lc_flags_ != 1 )
{
std::error_code e2( *this );
::new( d2_ ) std::error_code( e2 );
flags_ = 1;
lc_flags_ = 1;
}
return *reinterpret_cast<std::error_code*>( d2_ );
@ -488,24 +630,51 @@ public:
#endif
template<class Ch, class Tr>
inline friend std::basic_ostream<Ch, Tr>&
operator<< (std::basic_ostream<Ch, Tr>& os, error_code const & ec)
std::string to_string() const
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( ec.flags_ == 1 )
if( lc_flags_ == 1 )
{
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( ec.d2_ );
os << "std:" << e2.category().name() << ':' << e2.value();
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( d2_ );
std::string r( "std:" );
r += e2.category().name();
detail::append_int( r, e2.value() );
return r;
}
else
#endif
{
os << ec.category().name() << ':' << ec.value();
std::string r = category_name();
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_code const & ec)
{
return os << ec.to_string().c_str();
}
std::string what() const
{
std::string r = message();
r += " [";
r += to_string();
if( has_location() )
{
r += " at ";
r += location().to_string();
}
return os;
r += "]";
return r;
}
};
@ -513,7 +682,7 @@ inline std::size_t hash_value( error_code const & ec )
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( ec.flags_ == 1 )
if( ec.lc_flags_ == 1 )
{
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( ec.d2_ );
return std::hash<std::error_code>()( e2 );

View File

@ -3,7 +3,7 @@
// Copyright Beman Dawes 2006, 2007
// Copyright Christoper Kohlhoff 2007
// Copyright Peter Dimov 2017, 2018
// Copyright Peter Dimov 2017-2021
//
// 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)
@ -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>
@ -45,25 +46,31 @@ class error_condition
private:
int val_;
bool failed_;
error_category const * cat_;
private:
boost::ulong_long_type cat_id() const BOOST_NOEXCEPT
{
return cat_? cat_->id_: detail::generic_category_id;
}
public:
// constructors:
BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT:
val_( 0 ), failed_( false ), cat_( 0 )
val_( 0 ), cat_( 0 )
{
}
BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT:
val_( val ), failed_( detail::failed_impl( val, cat ) ), cat_( &cat )
val_( val ), cat_( &cat )
{
}
BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) BOOST_NOEXCEPT:
val_( vt.value ), failed_( vt.value != 0 ), cat_( 0 )
val_( vt.value ), cat_( 0 )
{
}
@ -77,7 +84,7 @@ public:
template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e,
typename detail::enable_if<boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value>::type* = 0) BOOST_NOEXCEPT:
val_( e ), failed_( e != 0 ), cat_( 0 )
val_( e ), cat_( 0 )
{
}
@ -86,7 +93,6 @@ public:
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT
{
val_ = val;
failed_ = detail::failed_impl( val, cat );
cat_ = &cat;
}
@ -101,7 +107,6 @@ public:
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
{
val_ = 0;
failed_ = false;
cat_ = 0;
}
@ -125,7 +130,7 @@ public:
}
else
{
return generic_category().message( value() );
return detail::generic_error_category_message( value() );
}
}
@ -137,20 +142,27 @@ public:
}
else
{
return generic_category().message( value(), buffer, len );
return detail::generic_error_category_message( value(), buffer, len );
}
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
{
return failed_;
if( cat_ )
{
return detail::failed_impl( val_, *cat_ );
}
else
{
return val_ != 0;
}
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error
{
return failed_;
return failed();
}
#else
@ -160,12 +172,12 @@ public:
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{
return failed_? unspecified_bool_true: 0;
return failed()? unspecified_bool_true: 0;
}
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{
return !failed_;
return !failed();
}
#endif
@ -176,7 +188,22 @@ public:
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return lhs.val_ == rhs.val_ && lhs.category() == rhs.category();
if( lhs.val_ != rhs.val_ )
{
return false;
}
else if( lhs.cat_ == 0 )
{
return rhs.cat_id() == detail::generic_category_id;
}
else if( rhs.cat_ == 0 )
{
return lhs.cat_id() == detail::generic_category_id;
}
else
{
return *lhs.cat_ == *rhs.cat_;
}
}
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
@ -195,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_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
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
@ -220,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

@ -11,9 +11,6 @@
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/error_category.hpp>
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/generic_category.hpp>
#include <system_error>
//
@ -33,6 +30,13 @@ private:
boost::system::error_category const * pc_;
public:
boost::system::error_category const & original_category() const BOOST_NOEXCEPT
{
return *pc_;
}
public:
explicit std_category( boost::system::error_category const * pc, unsigned id ): pc_( pc )
@ -66,72 +70,10 @@ public:
return pc_->default_error_condition( ev );
}
bool equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
bool equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
inline bool equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
inline bool equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
};
inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT
{
if( condition.category() == *this )
{
boost::system::error_condition bn( condition.value(), *pc_ );
return pc_->equivalent( code, bn );
}
else if( condition.category() == std::generic_category() || condition.category() == boost::system::generic_category() )
{
boost::system::error_condition bn( condition.value(), boost::system::generic_category() );
return pc_->equivalent( code, bn );
}
#ifndef BOOST_NO_RTTI
else if( std_category const* pc2 = dynamic_cast< std_category const* >( &condition.category() ) )
{
boost::system::error_condition bn( condition.value(), *pc2->pc_ );
return pc_->equivalent( code, bn );
}
#endif
else
{
return default_error_condition( code ) == condition;
}
}
inline bool std_category::equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT
{
if( code.category() == *this )
{
boost::system::error_code bc( code.value(), *pc_ );
return pc_->equivalent( bc, condition );
}
else if( code.category() == std::generic_category() || code.category() == boost::system::generic_category() )
{
boost::system::error_code bc( code.value(), boost::system::generic_category() );
return pc_->equivalent( bc, condition );
}
#ifndef BOOST_NO_RTTI
else if( std_category const* pc2 = dynamic_cast< std_category const* >( &code.category() ) )
{
boost::system::error_code bc( code.value(), *pc2->pc_ );
return pc_->equivalent( bc, condition );
}
#endif
else if( *pc_ == boost::system::generic_category() )
{
return std::generic_category().equivalent( code, condition );
}
else
{
return false;
}
}
} // namespace detail
} // namespace system

View File

@ -0,0 +1,97 @@
#ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_IMPL_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_STD_CATEGORY_IMPL_HPP_INCLUDED
// Support for interoperability between Boost.System and <system_error>
//
// Copyright 2018, 2021 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)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/std_category.hpp>
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/generic_category.hpp>
//
namespace boost
{
namespace system
{
namespace detail
{
inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT
{
if( condition.category() == *this )
{
boost::system::error_condition bn( condition.value(), *pc_ );
return pc_->equivalent( code, bn );
}
else if( condition.category() == std::generic_category() || condition.category() == boost::system::generic_category() )
{
boost::system::error_condition bn( condition.value(), boost::system::generic_category() );
return pc_->equivalent( code, bn );
}
#ifndef BOOST_NO_RTTI
else if( std_category const* pc2 = dynamic_cast< std_category const* >( &condition.category() ) )
{
boost::system::error_condition bn( condition.value(), *pc2->pc_ );
return pc_->equivalent( code, bn );
}
#endif
else
{
return default_error_condition( code ) == condition;
}
}
inline bool std_category::equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT
{
if( code.category() == *this )
{
boost::system::error_code bc( code.value(), *pc_ );
return pc_->equivalent( bc, condition );
}
else if( code.category() == std::generic_category() || code.category() == boost::system::generic_category() )
{
boost::system::error_code bc( code.value(), boost::system::generic_category() );
return pc_->equivalent( bc, condition );
}
#ifndef BOOST_NO_RTTI
else if( std_category const* pc2 = dynamic_cast< std_category const* >( &code.category() ) )
{
boost::system::error_code bc( code.value(), *pc2->pc_ );
return pc_->equivalent( bc, condition );
}
#endif
else if( *pc_ == boost::system::generic_category() )
{
return std::generic_category().equivalent( code, condition );
}
else
{
return false;
}
}
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_IMPL_HPP_INCLUDED

View File

@ -58,7 +58,9 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_ACCESS_DENIED_: return permission_denied;
case ERROR_ALREADY_EXISTS_: return file_exists;
case ERROR_BAD_NETPATH_: return no_such_file_or_directory;
case ERROR_BAD_UNIT_: return no_such_device;
case ERROR_BROKEN_PIPE_: return broken_pipe;
case ERROR_BUFFER_OVERFLOW_: return filename_too_long;
case ERROR_BUSY_: return device_or_resource_busy;
case ERROR_BUSY_DRIVE_: return device_or_resource_busy;
@ -80,7 +82,8 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_INVALID_DRIVE_: return no_such_device;
case ERROR_INVALID_FUNCTION_: return function_not_supported;
case ERROR_INVALID_HANDLE_: return invalid_argument;
case ERROR_INVALID_NAME_: return invalid_argument;
case ERROR_INVALID_NAME_: return no_such_file_or_directory;
case ERROR_INVALID_PARAMETER_: return invalid_argument;
case ERROR_LOCK_VIOLATION_: return no_lock_available;
case ERROR_LOCKED_: return no_lock_available;
case ERROR_NEGATIVE_SEEK_: return invalid_argument;
@ -94,6 +97,7 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_OUTOFMEMORY_: return not_enough_memory;
case ERROR_PATH_NOT_FOUND_: return no_such_file_or_directory;
case ERROR_READ_FAULT_: return io_error;
case ERROR_REPARSE_TAG_INVALID_: return invalid_argument;
case ERROR_RETRY_: return resource_unavailable_try_again;
case ERROR_SEEK_: return io_error;
case ERROR_SHARING_VIOLATION_: return permission_denied;

View File

@ -11,6 +11,7 @@
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/system_category.hpp>
#include <boost/system/detail/system_category_message.hpp>
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/api_config.hpp>
@ -22,7 +23,6 @@
#if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/system_category_message_win32.hpp>
#include <boost/system/detail/system_category_condition_win32.hpp>
inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT
@ -39,35 +39,23 @@ inline boost::system::error_condition boost::system::detail::system_error_catego
}
}
inline std::string boost::system::detail::system_error_category::message( int ev ) const
{
return system_category_message_win32( ev );
}
inline char const * boost::system::detail::system_error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
return system_category_message_win32( ev, buffer, len );
}
#else // #if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/generic_category_message.hpp>
inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT
{
return error_condition( boost::system::detail::generic_value_tag( ev ) );
}
#endif // #if defined(BOOST_WINDOWS_API)
inline std::string boost::system::detail::system_error_category::message( int ev ) const
{
return generic_error_category_message( ev );
return system_error_category_message( ev );
}
inline char const * boost::system::detail::system_error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
return generic_error_category_message( ev, buffer, len );
return system_error_category_message( ev, buffer, len );
}
#endif // #if defined(BOOST_WINDOWS_API)
#endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_IMPL_HPP_INCLUDED

View File

@ -0,0 +1,71 @@
#ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_HPP_INCLUDED
// Implementation of system_error_category_message
//
// Copyright 2018, 2022 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)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/api_config.hpp>
#if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API)
# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined
#endif
#if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/system_category_message_win32.hpp>
namespace boost
{
namespace system
{
namespace detail
{
inline std::string system_error_category_message( int ev )
{
return system_category_message_win32( ev );
}
inline char const * system_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
{
return system_category_message_win32( ev, buffer, len );
}
} // namespace detail
} // namespace system
} // namespace boost
#else // #if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/generic_category_message.hpp>
namespace boost
{
namespace system
{
namespace detail
{
inline std::string system_error_category_message( int ev )
{
return generic_error_category_message( ev );
}
inline char const * system_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
{
return generic_error_category_message( ev, buffer, len );
}
} // namespace detail
} // namespace system
} // namespace boost
#endif // #if defined(BOOST_WINDOWS_API)
#endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_HPP_INCLUDED

View File

@ -16,6 +16,7 @@
#include <boost/system/detail/generic_category.hpp>
#include <boost/system/detail/error_category_impl.hpp>
#include <boost/system/detail/config.hpp>
#include <boost/assert/source_location.hpp>
#include <boost/config.hpp>
namespace boost
@ -35,6 +36,12 @@ BOOST_SYSTEM_CONSTEXPR inline error_code make_error_code( errc_t e ) BOOST_NOEXC
return error_code( e, generic_category() );
}
// explicit conversion:
inline error_code make_error_code( errc_t e, boost::source_location const * loc ) BOOST_NOEXCEPT
{
return error_code( e, generic_category(), loc );
}
// implicit conversion:
BOOST_SYSTEM_CONSTEXPR inline error_condition make_error_condition( errc_t e ) BOOST_NOEXCEPT
{

View File

@ -10,13 +10,6 @@
#ifndef BOOST_SYSTEM_LINUX_ERROR_HPP
#define BOOST_SYSTEM_LINUX_ERROR_HPP
#include <boost/config/pragma_message.hpp>
#if !defined(BOOST_ALLOW_DEPRECATED_HEADERS)
BOOST_PRAGMA_MESSAGE("This header is deprecated and is slated for removal."
" If you want it retained, please open an issue in github.com/boostorg/system.")
#endif
// This header is effectively empty for compiles on operating systems where
// it is not applicable.

View File

@ -0,0 +1,604 @@
#ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED
#define BOOST_SYSTEM_RESULT_HPP_INCLUDED
// Copyright 2017, 2021, 2022 Peter Dimov.
// 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/system_error.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/error_category_impl.hpp>
#include <boost/variant2/variant.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert/source_location.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <type_traits>
#include <utility>
#include <iosfwd>
#include <system_error>
#include <exception>
//
namespace boost
{
namespace system
{
// throw_exception_from_error
#if defined(__GNUC__) && __GNUC__ >= 7 && __GNUC__ <= 8
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wattributes"
#endif
BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( error_code const & e, boost::source_location const& loc )
{
boost::throw_with_location( system_error( e ), loc );
}
BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( errc::errc_t const & e, boost::source_location const& loc )
{
boost::throw_with_location( system_error( make_error_code( e ) ), loc );
}
BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( std::error_code const & e, boost::source_location const& loc )
{
boost::throw_with_location( std::system_error( e ), loc );
}
BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( std::errc const & e, boost::source_location const& loc )
{
boost::throw_with_location( std::system_error( make_error_code( e ) ), loc );
}
BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( std::exception_ptr const & p, boost::source_location const& loc )
{
if( p )
{
std::rethrow_exception( p );
}
else
{
boost::throw_with_location( std::bad_exception(), loc );
}
}
#if defined(__GNUC__) && __GNUC__ >= 7 && __GNUC__ <= 8
# pragma GCC diagnostic pop
#endif
// in_place_*
using in_place_value_t = variant2::in_place_index_t<0>;
constexpr in_place_value_t in_place_value{};
using in_place_error_t = variant2::in_place_index_t<1>;
constexpr in_place_error_t in_place_error{};
namespace detail
{
template<class T> using remove_cvref = typename std::remove_cv< typename std::remove_reference<T>::type >::type;
template<class... T> using is_errc_t = std::is_same<mp11::mp_list<remove_cvref<T>...>, mp11::mp_list<errc::errc_t>>;
} // namespace detail
// result
template<class T, class E = error_code> class result
{
private:
variant2::variant<T, E> v_;
public:
// constructors
// default
template<class En2 = void, class En = typename std::enable_if<
std::is_void<En2>::value &&
std::is_default_constructible<T>::value
>::type>
constexpr result()
noexcept( std::is_nothrow_default_constructible<T>::value )
: v_( in_place_value )
{
}
// implicit, value
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>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<T, A>::value )
: v_( in_place_value, std::forward<A>(a) )
{
}
// 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>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// explicit, value
template<class... A, class En = typename std::enable_if<
std::is_constructible<T, A...>::value &&
!(detail::is_errc_t<A...>::value && std::is_arithmetic<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<T, A...>::value &&
std::is_constructible<E, A...>::value
>::type>
explicit constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
: v_( in_place_error, std::forward<A>(a)... )
{
}
// tagged, value
template<class... A, class En = typename std::enable_if<
std::is_constructible<T, A...>::value
>::type>
constexpr result( in_place_value_t, A&&... a )
noexcept( std::is_nothrow_constructible<T, A...>::value )
: v_( in_place_value, std::forward<A>(a)... )
{
}
// tagged, error
template<class... A, class En = typename std::enable_if<
std::is_constructible<E, A...>::value
>::type>
constexpr result( in_place_error_t, A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
: v_( in_place_error, std::forward<A>(a)... )
{
}
// converting
template<class T2, class E2, class En = typename std::enable_if<
std::is_convertible<T2, T>::value &&
std::is_convertible<E2, E>::value
>::type>
BOOST_CXX14_CONSTEXPR result( result<T2, E2> const& r2 )
noexcept(
std::is_nothrow_constructible<T, T2 const&>::value &&
std::is_nothrow_constructible<E, E2>::value &&
std::is_nothrow_default_constructible<E2>::value &&
std::is_nothrow_copy_constructible<E2>::value )
: v_( in_place_error, r2.error() )
{
if( r2 )
{
v_.template emplace<0>( *r2 );
}
}
template<class T2, class E2, class En = typename std::enable_if<
std::is_convertible<T2, T>::value &&
std::is_convertible<E2, E>::value
>::type>
BOOST_CXX14_CONSTEXPR result( result<T2, E2>&& r2 )
noexcept(
std::is_nothrow_constructible<T, T2&&>::value &&
std::is_nothrow_constructible<E, E2>::value &&
std::is_nothrow_default_constructible<E2>::value &&
std::is_nothrow_copy_constructible<E2>::value )
: v_( in_place_error, r2.error() )
{
if( r2 )
{
v_.template emplace<0>( std::move( *r2 ) );
}
}
// queries
constexpr bool has_value() const noexcept
{
return v_.index() == 0;
}
constexpr bool has_error() const noexcept
{
return v_.index() != 0;
}
constexpr explicit operator bool() const noexcept
{
return v_.index() == 0;
}
// checked value access
#if defined( BOOST_NO_CXX11_REF_QUALIFIERS )
BOOST_CXX14_CONSTEXPR T value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const
{
if( has_value() )
{
return variant2::unsafe_get<0>( v_ );
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc );
}
}
#else
BOOST_CXX14_CONSTEXPR T& value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) &
{
if( has_value() )
{
return variant2::unsafe_get<0>( v_ );
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc );
}
}
BOOST_CXX14_CONSTEXPR T const& value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const&
{
if( has_value() )
{
return variant2::unsafe_get<0>( v_ );
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc );
}
}
template<class U = T>
BOOST_CXX14_CONSTEXPR
typename std::enable_if<std::is_move_constructible<U>::value, T>::type
value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) &&
{
return std::move( value( loc ) );
}
template<class U = T>
BOOST_CXX14_CONSTEXPR
typename std::enable_if<!std::is_move_constructible<U>::value, T&&>::type
value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) &&
{
return std::move( value( loc ) );
}
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( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const &&
{
return std::move( value( loc ) );
}
#endif
// unchecked value access
BOOST_CXX14_CONSTEXPR T* operator->() noexcept
{
return variant2::get_if<0>( &v_ );
}
BOOST_CXX14_CONSTEXPR T const* operator->() const noexcept
{
return variant2::get_if<0>( &v_ );
}
#if defined( BOOST_NO_CXX11_REF_QUALIFIERS )
BOOST_CXX14_CONSTEXPR T& operator*() noexcept
{
T* p = operator->();
BOOST_ASSERT( p != 0 );
return *p;
}
BOOST_CXX14_CONSTEXPR T const& operator*() const noexcept
{
T const* p = operator->();
BOOST_ASSERT( p != 0 );
return *p;
}
#else
BOOST_CXX14_CONSTEXPR T& operator*() & noexcept
{
T* p = operator->();
BOOST_ASSERT( p != 0 );
return *p;
}
BOOST_CXX14_CONSTEXPR T const& operator*() const & noexcept
{
T const* p = operator->();
BOOST_ASSERT( p != 0 );
return *p;
}
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);
}
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);
}
#endif
// error access
constexpr E error() const
noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value )
{
return has_error()? variant2::unsafe_get<1>( v_ ): E();
}
// swap
BOOST_CXX14_CONSTEXPR void swap( result& r )
noexcept( noexcept( v_.swap( r.v_ ) ) )
{
v_.swap( r.v_ );
}
friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 )
noexcept( noexcept( r1.swap( r2 ) ) )
{
r1.swap( r2 );
}
// equality
friend constexpr bool operator==( result const & r1, result const & r2 )
noexcept( noexcept( r1.v_ == r2.v_ ) )
{
return r1.v_ == r2.v_;
}
friend constexpr bool operator!=( result const & r1, result const & r2 )
noexcept( noexcept( !( r1 == r2 ) ) )
{
return !( r1 == r2 );
}
};
template<class Ch, class Tr, class T, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<T, E> const & r )
{
if( r.has_value() )
{
os << "value:" << *r;
}
else
{
os << "error:" << r.error();
}
return os;
}
// result<void>
template<class E> class result<void, E>
{
private:
variant2::variant<variant2::monostate, E> v_;
public:
// constructors
// default
constexpr result() noexcept
: v_( in_place_value )
{
}
// explicit, error
template<class A, class En = typename std::enable_if<
std::is_constructible<E, A>::value &&
!std::is_convertible<A, E>::value
>::type>
explicit constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// implicit, error
template<class A, class En2 = void, class En = typename std::enable_if<
std::is_convertible<A, E>::value
>::type>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// more than one arg, error
template<class... A, class En2 = void, class En3 = void, class En = typename std::enable_if<
std::is_constructible<E, A...>::value &&
sizeof...(A) >= 2
>::type>
constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
: v_( in_place_error, std::forward<A>(a)... )
{
}
// tagged, value
constexpr result( in_place_value_t ) noexcept
: v_( in_place_value )
{
}
// tagged, error
template<class... A, class En = typename std::enable_if<
std::is_constructible<E, A...>::value
>::type>
constexpr result( in_place_error_t, A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
: v_( in_place_error, std::forward<A>(a)... )
{
}
// queries
constexpr bool has_value() const noexcept
{
return v_.index() == 0;
}
constexpr bool has_error() const noexcept
{
return v_.index() != 0;
}
constexpr explicit operator bool() const noexcept
{
return v_.index() == 0;
}
// checked value access
BOOST_CXX14_CONSTEXPR void value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const
{
if( has_value() )
{
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc );
}
}
// unchecked value access
BOOST_CXX14_CONSTEXPR void* operator->() noexcept
{
return variant2::get_if<0>( &v_ );
}
BOOST_CXX14_CONSTEXPR void const* operator->() const noexcept
{
return variant2::get_if<0>( &v_ );
}
BOOST_CXX14_CONSTEXPR void operator*() const noexcept
{
BOOST_ASSERT( has_value() );
}
// error access
constexpr E error() const
noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value )
{
return has_error()? variant2::unsafe_get<1>( v_ ): E();
}
// swap
BOOST_CXX14_CONSTEXPR void swap( result& r )
noexcept( noexcept( v_.swap( r.v_ ) ) )
{
v_.swap( r.v_ );
}
friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 )
noexcept( noexcept( r1.swap( r2 ) ) )
{
r1.swap( r2 );
}
// equality
friend constexpr bool operator==( result const & r1, result const & r2 )
noexcept( noexcept( r1.v_ == r2.v_ ) )
{
return r1.v_ == r2.v_;
}
friend constexpr bool operator!=( result const & r1, result const & r2 )
noexcept( noexcept( !( r1 == r2 ) ) )
{
return !( r1 == r2 );
}
};
template<class Ch, class Tr, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<void, E> const & r )
{
if( r.has_value() )
{
os << "value:void";
}
else
{
os << "error:" << r.error();
}
return os;
}
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED

View File

@ -1,84 +1,55 @@
// Boost system_error.hpp --------------------------------------------------//
// Copyright Beman Dawes 2006
// 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)
#ifndef BOOST_SYSTEM_SYSTEM_ERROR_HPP
#define BOOST_SYSTEM_SYSTEM_ERROR_HPP
#include <boost/system/error_code.hpp>
// Copyright Beman Dawes 2006
// Copyright Peter Dimov 2021
// 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 <string>
#include <stdexcept>
#include <cassert>
namespace boost
{
namespace system
{
// class system_error ------------------------------------------------------------//
namespace system
{
class BOOST_SYMBOL_VISIBLE system_error : public std::runtime_error
// BOOST_SYMBOL_VISIBLE is needed by GCC to ensure system_error thrown from a shared
// library can be caught. See svn.boost.org/trac/boost/ticket/3697
class BOOST_SYMBOL_VISIBLE system_error: public std::runtime_error
{
private:
error_code code_;
public:
explicit system_error( error_code const & ec ):
std::runtime_error( ec.what() ), code_( ec ) {}
system_error( error_code const & ec, std::string const & prefix ):
std::runtime_error( prefix + ": " + ec.what() ), code_( ec ) {}
system_error( error_code const & ec, char const * prefix ):
std::runtime_error( std::string( prefix ) + ": " + ec.what() ), code_( ec ) {}
system_error( int ev, error_category const & ecat ):
std::runtime_error( error_code( ev, ecat ).what() ), code_( ev, ecat ) {}
system_error( int ev, error_category const & ecat, std::string const & prefix ):
std::runtime_error( prefix + ": " + error_code( ev, ecat ).what() ), code_( ev, ecat ) {}
system_error( int ev, error_category const & ecat, char const * prefix ):
std::runtime_error( std::string( prefix ) + ": " + error_code( ev, ecat ).what() ), code_( ev, ecat ) {}
error_code code() const BOOST_NOEXCEPT
{
public:
explicit system_error( error_code ec )
: std::runtime_error(""), m_error_code(ec) {}
system_error( error_code ec, const std::string & what_arg )
: std::runtime_error(what_arg), m_error_code(ec) {}
system_error( error_code ec, const char* what_arg )
: std::runtime_error(what_arg), m_error_code(ec) {}
system_error( int ev, const error_category & ecat )
: std::runtime_error(""), m_error_code(ev,ecat) {}
system_error( int ev, const error_category & ecat,
const std::string & what_arg )
: std::runtime_error(what_arg), m_error_code(ev,ecat) {}
system_error( int ev, const error_category & ecat,
const char * what_arg )
: std::runtime_error(what_arg), m_error_code(ev,ecat) {}
virtual ~system_error() BOOST_NOEXCEPT_OR_NOTHROW {}
error_code code() const BOOST_NOEXCEPT { return m_error_code; }
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE;
private:
error_code m_error_code;
mutable std::string m_what;
};
// implementation ------------------------------------------------------//
inline const char * system_error::what() const BOOST_NOEXCEPT_OR_NOTHROW
// see http://www.boost.org/more/error_handling.html for lazy build rationale
{
if ( m_what.empty() )
{
#ifndef BOOST_NO_EXCEPTIONS
try
#endif
{
m_what = this->std::runtime_error::what();
if ( !m_what.empty() ) m_what += ": ";
m_what += m_error_code.message();
}
#ifndef BOOST_NO_EXCEPTIONS
catch (...) { return std::runtime_error::what(); }
#endif
}
return m_what.c_str();
return code_;
}
};
} // namespace system
} // namespace system
} // namespace boost
#endif // BOOST_SYSTEM_SYSTEM_ERROR_HPP

View File

@ -8,8 +8,8 @@ Automatic redirection failed, please go to
</body>
</html>
<!--
<EFBFBD> Copyright Beman Dawes, 2001
© Copyright Beman Dawes, 2001
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
https://www.boost.org/LICENSE_1_0.txt
-->

View File

@ -4,9 +4,14 @@
"authors": [
"Beman Dawes"
],
"description": "Operating system support, including the diagnostics support that will be part of the C++0x standard library.",
"maintainers": [
"Peter Dimov <pdimov -at- gmail.com>"
],
"description": "Extensible error reporting.",
"category": [
"System"
"System",
"Error-handling",
"Programming"
],
"cxxstd": "03"
}

View File

@ -98,3 +98,48 @@ boost_test(TYPE run SOURCES std_interop_test6.cpp)
boost_test(TYPE run SOURCES std_interop_test7.cpp)
boost_test(TYPE run SOURCES std_interop_test8.cpp)
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)
boost_test(TYPE run SOURCES ec_wstream_test.cpp)
boost_test(TYPE run SOURCES std_interop_test12.cpp)
boost_test(TYPE run SOURCES errc_test4.cpp)
boost_test(TYPE run SOURCES std_interop_test13.cpp)
boost_test(TYPE run SOURCES std_interop_test14.cpp)
boost_test(TYPE run SOURCES ec_location_test3.cpp)
boost_test(TYPE run SOURCES ec_location_test4.cpp)
# result
set(BOOST_TEST_COMPILE_FEATURES cxx_std_11)
boost_test(TYPE run SOURCES result_default_construct.cpp)
boost_test(TYPE run SOURCES result_value_construct.cpp)
boost_test(TYPE run SOURCES result_error_construct.cpp)
boost_test(TYPE run SOURCES result_copy_construct.cpp)
boost_test(TYPE run SOURCES result_move_construct.cpp)
boost_test(TYPE run SOURCES result_copy_assign.cpp)
boost_test(TYPE run SOURCES result_move_assign.cpp)
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)
boost_test(TYPE run SOURCES result_convert_construct.cpp)

View File

@ -1,7 +1,7 @@
# Boost System Library test Jamfile
# Copyright Beman Dawes 2003, 2006
# Copyright 2017-2019 Peter Dimov
# Copyright 2017-2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
@ -10,6 +10,20 @@
import testing ;
project
: default-build
<warnings>extra
: requirements
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
<toolset>gcc-4.4:<cxxflags>-Wno-sign-compare
;
rule system-run ( sources + )
{
local result ;
@ -47,7 +61,11 @@ run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : <li
run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : <link>shared : single_instance_lib_shared ;
system-run before_main_test.cpp ;
run-fail throws_assign_fail.cpp ;
run-fail throws_assign_fail.cpp : : :
# GCC 12 catches this at compile time with a warning
<toolset>gcc,<variant>release:<build>no ;
system-run constexpr_test.cpp ;
system-run win32_hresult_test.cpp ;
@ -61,8 +79,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 ;
@ -108,3 +126,51 @@ run std_interop_test6.cpp ;
run std_interop_test7.cpp ;
run std_interop_test8.cpp ;
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 ;
run ec_wstream_test.cpp ;
run std_interop_test12.cpp ;
run errc_test4.cpp ;
run std_interop_test13.cpp ;
run std_interop_test14.cpp ;
run ec_location_test3.cpp ;
run ec_location_test4.cpp ;
# result
import ../../config/checks/config : requires ;
CPP11 = [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr cxx11_noexcept ] <toolset>gcc-4.7:<build>no ;
run result_default_construct.cpp : : : $(CPP11) ;
run result_value_construct.cpp : : : $(CPP11) ;
run result_error_construct.cpp : : : $(CPP11) ;
run result_copy_construct.cpp : : : $(CPP11) ;
run result_move_construct.cpp : : : $(CPP11) ;
run result_copy_assign.cpp : : : $(CPP11) ;
run result_move_assign.cpp : : : $(CPP11) ;
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) ;
run result_errc_construct.cpp : : : $(CPP11) ;
run result_convert_construct.cpp : : : $(CPP11) ;

View File

@ -5,8 +5,13 @@
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/quick_exit.hpp>
#include <boost/config.hpp>
#include <cerrno>
#if defined(BOOST_MSVC)
# pragma warning(disable: 4722) // Z::~Z never returns
#endif
using namespace boost::system;
struct Z
@ -27,4 +32,6 @@ static error_code e2( ENOENT, generic_category() );
int main()
{
(void)e1;
(void)e2;
}

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

@ -1,8 +1,8 @@
# Copyright 2018, 2019 Peter Dimov
# Copyright 2018-2021 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
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.5...3.20)
project(cmake_subdir_test LANGUAGES CXX)
@ -10,7 +10,11 @@ add_subdirectory(../.. boostorg/system)
add_subdirectory(../../../assert boostorg/assert)
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)
add_executable(quick ../quick.cpp)
@ -19,4 +23,4 @@ target_link_libraries(quick Boost::system Boost::core)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --no-tests=error -C $<CONFIG>)

116
test/ec_location_test.cpp Normal file
View File

@ -0,0 +1,116 @@
// 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>
int main()
{
int const val = ENOENT;
boost::system::error_category const & cat = boost::system::generic_category();
{
boost::system::error_code ec( val, cat );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
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;
boost::system::error_code ec( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 27 );
}
{
boost::system::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &boost::system::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 = boost::system::error_code( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 51 );
}
{
boost::system::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &boost::system::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( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 75 );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
boost::system::error_code ec( e2 );
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( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 100 );
}
#endif
return boost::report_errors();
}

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();
}

View File

@ -0,0 +1,90 @@
// Copyright 2021, 2022 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>
int main()
{
int const val = ENOENT;
boost::system::error_category const & cat = boost::system::generic_category();
{
boost::system::error_code ec;
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
boost::system::error_code ec2( ec, &loc );
BOOST_TEST_EQ( ec2, ec );
BOOST_TEST( !ec2.has_location() );
BOOST_TEST_EQ( ec2.location(), boost::source_location() );
boost::system::error_code ec3( ec2, 0 );
BOOST_TEST_EQ( ec3, ec2 );
BOOST_TEST( !ec3.has_location() );
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
{
boost::system::error_code ec( val, cat );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
boost::system::error_code ec2( ec, &loc );
BOOST_TEST_EQ( ec2, ec );
BOOST_TEST( ec2.has_location() );
BOOST_TEST_EQ( ec2.location(), loc );
boost::system::error_code ec3( ec2, 0 );
BOOST_TEST_EQ( ec3, ec2 );
BOOST_TEST( !ec3.has_location() );
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
boost::system::error_code ec( e2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
boost::system::error_code ec2( ec, &loc );
BOOST_TEST_EQ( ec2, ec );
BOOST_TEST( !ec2.has_location() );
BOOST_TEST_EQ( ec2.location(), boost::source_location() );
boost::system::error_code ec3( ec2, 0 );
BOOST_TEST_EQ( ec3, ec2 );
BOOST_TEST( !ec3.has_location() );
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
#endif
return boost::report_errors();
}

View File

@ -0,0 +1,93 @@
// Copyright 2021, 2022 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>
int main()
{
int const val = ENOENT;
boost::system::error_category const & cat = boost::system::generic_category();
{
boost::system::error_code ec;
boost::system::error_code ec2( ec );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( ec, &loc );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
ec.assign( ec, 0 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
{
boost::system::error_code ec( val, cat );
boost::system::error_code ec2( ec );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( ec, &loc );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location(), loc );
ec.assign( ec, 0 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
boost::system::error_code ec( e2 );
boost::system::error_code ec2( ec );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( ec, &loc );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
ec.assign( ec, 0 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
#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();
}

21
test/ec_wstream_test.cpp Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2022 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 <sstream>
namespace sys = boost::system;
int main()
{
{
std::wostringstream os;
os << sys::error_code();
BOOST_TEST( os.str() == L"system:0" );
}
return boost::report_errors();
}

17
test/errc_test4.cpp Normal file
View File

@ -0,0 +1,17 @@
// Copyright 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/errc.hpp>
#include <boost/assert/source_location.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
BOOST_TEST( make_error_code( boost::system::errc::no_such_file_or_directory, &loc ).has_location() );
BOOST_TEST_EQ( make_error_code( boost::system::errc::no_such_file_or_directory, &loc ).location().to_string(), loc.to_string() );
return boost::report_errors();
}

View File

@ -108,6 +108,7 @@ int main( int, char ** )
std::cout << "Conversion use cases...\n";
error_condition x1( errc::file_exists );
(void)x1;
//error_code x2( errc::file_exists ); // should fail to compile
make_error_code(errc::file_exists);
make_error_condition(errc::file_exists);

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

@ -33,6 +33,12 @@ BOOST_STATIC_ASSERT( !ec3.failed() );
BOOST_STATIC_ASSERT( ec3? false: true );
BOOST_STATIC_ASSERT( !ec3 );
#if defined(__GNUC__) && __GNUC__ == 7 && __cplusplus == 201703L
// 'cat_' is not a constant expression
#else
constexpr error_condition en1( 1, system_category() );
BOOST_STATIC_ASSERT( en1.failed() );
@ -51,6 +57,8 @@ BOOST_STATIC_ASSERT( !en3.failed() );
BOOST_STATIC_ASSERT( en3? false: true );
BOOST_STATIC_ASSERT( !en3 );
#endif
int main()
{
}

View File

@ -16,8 +16,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <boost/system/error_code.hpp>
int main( int, char*[] )
int main()
{
boost::system::error_code ec( 0, boost::system::system_category() );
return ::boost::report_errors();
boost::system::error_code ec( 0, boost::system::system_category() );
(void)ec;
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,202 @@
// Copyright 2017, 2021, 2022 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 <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
X( int v ): v_( v ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
int main()
{
{
result<int> r( 5 );
result<long> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 5 );
}
{
result<int> const r( 6 );
result<long> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 6 );
}
{
result<long> r2 = result<int>( 7 );
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 7 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> r( 5 );
result<X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 5 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> const r( 6 );
result<X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 6 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r2 = result<int>( 7 );
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 7 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<long> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<long> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<long> r2 = result<int>( ec );
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> r( "test" );
result<std::string, X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, std::string( "test" ) );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> const r( "test" );
result<std::string, X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, std::string( "test" ) );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r2 = result<char const*, int>( "test" );
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, std::string( "test" ) );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> r( 5 );
result<std::string, X> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(5) );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> const r( 6 );
result<std::string, X> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(6) );
BOOST_TEST_EQ( X::instances, 1 );
}
{
result<std::string, X> r2 = result<char const*, int>( 7 );
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(7) );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<long>, result<int>>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<result<int>, result<long>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int>, result<void*>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<void*>, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int>, result<void>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<void>, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<void>, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<int>, result<void>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, void*>, result<int, int>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<int, int>, result<int, void*>>));
}
return boost::report_errors();
}

686
test/result_copy_assign.cpp Normal file
View File

@ -0,0 +1,686 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
#include <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v = 0 ): v_( v ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = default;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y& operator=( Y const& ) = default;
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
// default-initialized lhs
{
result<int> r;
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r;
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r;
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r;
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r;
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r;
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
// value lhs
{
result<int> r( 0 );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 0 );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 0 );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 0 );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 0 );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 0 );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( 2 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2( 2 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
// error lhs
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2;
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 0 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> const r( ec );
result<X> r2;
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> const r( ec );
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> const r( ec );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 0 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
//
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( "str" );
BOOST_TEST_EQ( Y::instances, 1 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> const r( 1 );
result<std::string, Y> r2( 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> const r( 1 );
result<std::string, Y> r2( "str" );
BOOST_TEST_EQ( Y::instances, 1 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
// void
{
result<void> r;
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<void> r;
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<void> const r;
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<void> const r;
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
return boost::report_errors();
}

View File

@ -0,0 +1,181 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
int main()
{
{
result<int> r;
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> r( 1 );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 1 );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r( 1 );
result<std::string, X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> const r( 1 );
result<std::string, X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<void> r;
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
result<void> const r;
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
return boost::report_errors();
}

View File

@ -0,0 +1,41 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
};
int main()
{
{
result<int> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<X> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
result<void> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
return boost::report_errors();
}

153
test/result_eq.cpp Normal file
View File

@ -0,0 +1,153 @@
// Copyright 2017, 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 <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v ): v_( v ) { ++instances; }
X( X const& r ) = delete;
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
X& operator=( X&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y( Y&& r ) noexcept: v_( r.v_ ) { r.v_ = 0; ++instances; }
Y& operator=( Y const& ) = default;
Y& operator=( Y&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
{
result<int> r1( 1 );
result<int> r2( 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<int> r1( 1, generic_category() );
result<int> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<int> r1( 1 );
result<int> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<X, Y> r1( in_place_value, 1 );
result<X, Y> r2( in_place_value, 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<X, Y> r1( in_place_error, 1 );
result<X, Y> r2( in_place_error, 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<X, Y> r1( in_place_value, 1 );
result<X, Y> r2( in_place_error, 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<void> r1;
result<void> r2;
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_EQ( r1, r2 );
}
{
result<void> r1( 1, generic_category() );
result<void> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
return boost::report_errors();
}

View File

@ -0,0 +1,23 @@
// 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_trait.hpp>
#include <type_traits>
using namespace boost::system;
int main()
{
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int>, errc::errc_t>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<double>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<double>, errc::errc_t>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<bool>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, errc::errc_t>));
return boost::report_errors();
}

View File

@ -0,0 +1,212 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
#include <string>
using namespace boost::system;
struct X
{
int v_;
explicit X( int v = 0 ): v_( v ) {}
X( X const& ) = default;
X& operator=( X const& ) = delete;
};
int main()
{
{
result<int> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
result<int> const r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
BOOST_TEST( result<int>().has_value() );
BOOST_TEST( !result<int>().has_error() );
BOOST_TEST_EQ( result<int>().error(), error_code() );
}
{
result<int> r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
result<int> const r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
BOOST_TEST( result<int>( 1 ).has_value() );
BOOST_TEST( !result<int>( 1 ).has_error() );
BOOST_TEST_EQ( result<int>( 1 ).error(), error_code() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
BOOST_TEST( !result<int>( ec ).has_value() );
BOOST_TEST( result<int>( ec ).has_error() );
BOOST_TEST_EQ( result<int>( ec ).error(), ec );
}
{
result<std::string, X> r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1 );
}
{
result<std::string, X> const r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1 );
}
{
BOOST_TEST(( !result<std::string, X>( 1 ).has_value() ));
BOOST_TEST(( result<std::string, X>( 1 ).has_error() ));
BOOST_TEST_EQ( (result<std::string, X>( 1 ).error().v_), 1 );
}
{
result<std::string, X> r( "s" );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error().v_, 0 );
}
{
result<std::string, X> const r( "s" );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error().v_, 0 );
}
{
BOOST_TEST(( result<std::string, X>( "s" ).has_value() ));
BOOST_TEST(( !result<std::string, X>( "s" ).has_error() ));
BOOST_TEST_EQ( (result<std::string, X>( "s" ).error().v_), 0 );
}
{
result<void> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
result<void> const r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
BOOST_TEST( result<void>().has_value() );
BOOST_TEST( !result<void>().has_error() );
BOOST_TEST_EQ( result<void>().error(), error_code() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
BOOST_TEST( !result<void>( ec ).has_value() );
BOOST_TEST( result<void>( ec ).has_error() );
BOOST_TEST_EQ( result<void>( ec ).error(), ec );
}
return boost::report_errors();
}

View File

@ -0,0 +1,185 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
#include <string>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
int X::instances = 0;
int main()
{
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r = ec;
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
result<int> r( EINVAL, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<error_code> r( in_place_error, ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
result<error_code> r( in_place_error, EINVAL, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int, X> r( 1, 2 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1+2 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int, X> r( 1, 2, 3 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1+2+3 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X, X> r( in_place_error, 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int>, error_code>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<error_code, result<int>>));
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>>));
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r = ec;
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
result<void> r( EINVAL, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
}
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(), 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();
}

604
test/result_move_assign.cpp Normal file
View File

@ -0,0 +1,604 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
#include <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v = 0 ): v_( v ) { ++instances; }
X( X const& r ) = delete;
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
X& operator=( X&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y( Y&& r ) noexcept: v_( r.v_ ) { r.v_ = 0; ++instances; }
Y& operator=( Y const& ) = default;
Y& operator=( Y&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
// default-initialized lhs
{
result<int> r;
result<int> r2;
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2;
r2 = result<int>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r;
result<int> r2( 1 );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2( 1 );
r2 = result<int>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r;
result<int> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2( ENOENT, generic_category() );
r2 = result<int>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
}
BOOST_TEST_EQ( X::instances, 0 );
// value lhs
{
result<int> r( 1 );
result<int> r2;
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 1 );
result<int> r2( 2 );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 1 );
result<int> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( r.value().v_, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( 2 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( r.value().v_, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( r.value().v_, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
// error lhs
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2;
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2;
r2 = result<int>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( 1 );
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2( 1 );
r2 = result<int>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2( ENOENT, generic_category() );
r2 = result<int>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2;
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 0 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
//
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( r.error().v_, 0 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( "str" );
BOOST_TEST_EQ( Y::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( r.error().v_, 0 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<void> r;
result<void> r2;
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r2;
r2 = result<void>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r;
result<void> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r2( ENOENT, generic_category() );
r2 = result<void>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2;
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r2;
r2 = result<void>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r2( ENOENT, generic_category() );
r2 = result<void>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
return boost::report_errors();
}

View File

@ -0,0 +1,249 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
int main()
{
{
result<int> r;
result<int> r2( std::move( r ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2( result<int>{} );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( std::move( r ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r2( result<X>{} );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> r( 1 );
result<int> r2( std::move( r ) );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 1 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
}
{
result<int> r2( result<int>( 1 ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( std::move( r ) );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 0 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r2( result<X>( 1 ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( std::move( r ) );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2( result<int>{ ec } );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r( 1 );
result<std::string, X> r2( std::move( r ) );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r2( result<std::string, X>( 1 ) );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<void> r;
result<void> r2( std::move( r ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r2( result<void>{} );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( std::move( r ) );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r2( result<void>{ ec } );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
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();
}

263
test/result_swap.cpp Normal file
View File

@ -0,0 +1,263 @@
// Copyright 2017, 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 <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v ): v_( v ) { ++instances; }
X( X const& r ) = delete;
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
X& operator=( X&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y( Y&& r ) noexcept: v_( r.v_ ) { r.v_ = 0; ++instances; }
Y& operator=( Y const& ) = default;
Y& operator=( Y&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
{
result<int> r1( 1 ), r1c( r1 );
result<int> r2( 2 ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<int> r1( 1, generic_category() ), r1c( r1 );
result<int> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<int> r1( 1 ), r1c( r1 );
result<int> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<X, Y> r1( in_place_value, 1 ), r1c( in_place_value, 1 );
result<X, Y> r2( in_place_value, 2 ), r2c( in_place_value, 2 );
BOOST_TEST_EQ( X::instances, 4 );
BOOST_TEST_EQ( Y::instances, 0 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
BOOST_TEST_EQ( X::instances, 4 );
BOOST_TEST_EQ( Y::instances, 0 );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
BOOST_TEST_EQ( X::instances, 4 );
BOOST_TEST_EQ( Y::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<X, Y> r1( in_place_error, 1 ), r1c( in_place_error, 1 );
result<X, Y> r2( in_place_error, 2 ), r2c( in_place_error, 2 );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 4 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 4 );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 4 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<X, Y> r1( in_place_value, 1 ), r1c( in_place_value, 1 );
result<X, Y> r2( in_place_error, 2 ), r2c( in_place_error, 2 );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( Y::instances, 2 );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( Y::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<void> r1, r1c( r1 );
result<void> r2, r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<void> r1( 1, generic_category() ), r1c( r1 );
result<void> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<void> r1, r1c( r1 );
result<void> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
return boost::report_errors();
}

View File

@ -0,0 +1,494 @@
// Copyright 2017, 2021, 2022 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 <boost/core/lightweight_test_trait.hpp>
#include <system_error>
using namespace boost::system;
struct X
{
int v_;
explicit X( int v ): v_( v ) {}
X( X const& ) = delete;
X& operator=( X const& ) = delete;
};
struct Y
{
};
struct E
{
};
BOOST_NORETURN void throw_exception_from_error( Y const &, boost::source_location const& )
{
throw E();
}
struct E2
{
};
int main()
{
{
result<int> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_EQ( r.value(), 0 );
BOOST_TEST_EQ( *r, 0 );
BOOST_TEST_EQ( r.operator->(), &*r );
}
{
result<int> const r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_EQ( r.value(), 0 );
BOOST_TEST_EQ( *r, 0 );
BOOST_TEST_EQ( r.operator->(), &*r );
}
{
BOOST_TEST( result<int>().has_value() );
BOOST_TEST( !result<int>().has_error() );
BOOST_TEST( result<int>() );
BOOST_TEST_NOT( !result<int>() );
BOOST_TEST_EQ( result<int>().value(), 0 );
BOOST_TEST_EQ( *result<int>(), 0 );
BOOST_TEST( result<int>().operator->() != 0 );
}
{
result<int> r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_EQ( r.value(), 1 );
BOOST_TEST_EQ( *r, 1 );
BOOST_TEST_EQ( r.operator->(), &*r );
}
{
result<int> const r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_EQ( r.value(), 1 );
BOOST_TEST_EQ( *r, 1 );
BOOST_TEST_EQ( r.operator->(), &*r );
}
{
BOOST_TEST( result<int>( 1 ).has_value() );
BOOST_TEST( !result<int>( 1 ).has_error() );
BOOST_TEST( result<int>( 1 ) );
BOOST_TEST_NOT( !result<int>( 1 ) );
BOOST_TEST_EQ( result<int>( 1 ).value(), 1 );
BOOST_TEST_EQ( *result<int>( 1 ), 1 );
BOOST_TEST( result<int>( 1 ).operator->() != 0 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
{
auto ec = make_error_code( errc::invalid_argument );
BOOST_TEST( !result<int>( ec ).has_value() );
BOOST_TEST( result<int>( ec ).has_error() );
BOOST_TEST_NOT( result<int>( ec ) );
BOOST_TEST( !result<int>( ec ) );
BOOST_TEST_THROWS( result<int>( ec ).value(), system_error );
BOOST_TEST_EQ( result<int>( ec ).operator->(), static_cast<int*>(0) );
}
{
auto ec = make_error_code( std::errc::invalid_argument );
result<int, std::error_code> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), std::system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
{
result<int, errc::errc_t> const r( in_place_error, errc::invalid_argument );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
{
result<int, std::errc> const r( std::errc::invalid_argument );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), std::system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
{
result<int, std::exception_ptr> const r( std::make_exception_ptr( E2() ) );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), E2 );
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
{
result<int, std::exception_ptr> const r( in_place_error );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), std::bad_exception );
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
{
result<X> r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_EQ( r.value().v_, 1 );
BOOST_TEST_EQ( (*r).v_, 1 );
BOOST_TEST_EQ( r->v_, 1 );
BOOST_TEST_EQ( r.operator->(), &*r );
}
{
result<X> const r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_EQ( r.value().v_, 1 );
BOOST_TEST_EQ( (*r).v_, 1 );
BOOST_TEST_EQ( r->v_, 1 );
BOOST_TEST_EQ( r.operator->(), &*r );
}
{
BOOST_TEST( result<X>( 1 ).has_value() );
BOOST_TEST( !result<X>( 1 ).has_error() );
BOOST_TEST( result<X>( 1 ) );
BOOST_TEST_NOT( !result<X>( 1 ) );
BOOST_TEST_EQ( result<X>( 1 ).value().v_, 1 );
BOOST_TEST_EQ( (*result<X>( 1 )).v_, 1 );
BOOST_TEST_EQ( result<X>( 1 )->v_, 1 );
}
{
auto ec = Y();
result<X, Y> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), E );
BOOST_TEST_EQ( r.operator->(), static_cast<X*>(0) );
}
{
auto ec = Y();
result<X, Y> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), E );
BOOST_TEST_EQ( r.operator->(), static_cast<X*>(0) );
}
{
auto ec = Y();
BOOST_TEST(( !result<X, Y>( ec ).has_value() ));
BOOST_TEST(( result<X, Y>( ec ).has_error() ));
BOOST_TEST_NOT(( result<X, Y>( ec ) ));
BOOST_TEST(( !result<X, Y>( ec ) ));
BOOST_TEST_THROWS( (result<X, Y>( ec ).value()), E );
BOOST_TEST_EQ( (result<X, Y>( ec ).operator->()), static_cast<X*>(0) );
}
{
result<void> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_NO_THROW( r.value() );
BOOST_TEST( r.operator->() != 0 );
}
{
result<void> const r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST( r );
BOOST_TEST_NOT( !r );
BOOST_TEST_NO_THROW( r.value() );
BOOST_TEST( r.operator->() != 0 );
}
{
BOOST_TEST( result<void>().has_value() );
BOOST_TEST( !result<void>().has_error() );
BOOST_TEST( result<void>() );
BOOST_TEST_NOT( !result<void>() );
BOOST_TEST_NO_THROW( result<void>().value() );
BOOST_TEST( result<void>().operator->() != 0 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
{
auto ec = make_error_code( errc::invalid_argument );
BOOST_TEST( !result<void>( ec ).has_value() );
BOOST_TEST( result<void>( ec ).has_error() );
BOOST_TEST_NOT( result<void>( ec ) );
BOOST_TEST( !result<void>( ec ) );
BOOST_TEST_THROWS( result<void>( ec ).value(), system_error );
BOOST_TEST_EQ( result<void>( ec ).operator->(), static_cast<void*>(0) );
}
{
auto ec = make_error_code( std::errc::invalid_argument );
result<void, std::error_code> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), std::system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
{
result<void, errc::errc_t> const r( in_place_error, errc::invalid_argument );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
{
result<void, std::errc> const r( std::errc::invalid_argument );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), std::system_error );
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
{
result<void, std::exception_ptr> const r( std::make_exception_ptr( E2() ) );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), E2 );
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
{
result<void, std::exception_ptr> const r( in_place_error );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
BOOST_TEST_THROWS( r.value(), std::bad_exception );
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
return boost::report_errors();
}

View File

@ -0,0 +1,132 @@
// Copyright 2017, 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 <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& ) = delete;
X& operator=( X const& ) = delete;
~X() { --instances; }
};
int X::instances = 0;
int main()
{
{
result<int> r( 0 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<int> r = 0;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<int, int> r( in_place_value, 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( *r, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1, 2 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 1+2 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1, 2, 3 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 1+2+3 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X, X> r( in_place_value, 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r->v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int>, int>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<int, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, int>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, float>, int>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<X>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<X>>));
}
{
result<void> r( in_place_value );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
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

127
test/std_interop_test12.cpp Normal file
View File

@ -0,0 +1,127 @@
// Copyright 2021, 2022 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/error_category.hpp>
#include <boost/system/errc.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.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>
enum my_errc
{
my_enoent = ENOENT
};
class my_category: public boost::system::error_category
{
public:
char const* name() const BOOST_NOEXCEPT
{
return "mycat";
}
boost::system::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT
{
switch( ev )
{
case my_enoent:
return boost::system::error_condition( ENOENT, boost::system::generic_category() );
default:
return boost::system::error_condition( ev, *this );
}
}
std::string message( int ev ) const
{
switch( ev )
{
case my_enoent:
return "No such entity";
default:
return "Unknown error";
}
}
};
#if defined(BOOST_GCC) && BOOST_GCC < 70000
// g++ 6 and earlier do not allow specializations outside the namespace
namespace boost
{
namespace system
{
template<> struct is_error_code_enum<my_errc>: std::true_type {};
} // namespace system
} // namespace boost
namespace std
{
template<> struct is_error_code_enum<my_errc>: std::true_type {};
} // namespace std
#else
template<> struct boost::system::is_error_code_enum<my_errc>: std::true_type {};
template<> struct std::is_error_code_enum<my_errc>: std::true_type {};
#endif
boost::system::error_code make_error_code( my_errc e )
{
// If `cat` is declared constexpr or const, msvc-14.1 and
// msvc-14.2 before 19.29 put it in read-only memory,
// despite the `ps_` member being mutable. So it crashes.
static /*BOOST_SYSTEM_CONSTEXPR*/ my_category cat;
return boost::system::error_code( e, cat );
}
int main()
{
{
boost::system::error_code e1 = my_enoent;
BOOST_TEST( e1 == my_enoent );
BOOST_TEST_NOT( e1 != my_enoent );
BOOST_TEST( e1 == boost::system::errc::no_such_file_or_directory );
BOOST_TEST( e1 == std::errc::no_such_file_or_directory );
}
{
std::error_code e1 = my_enoent;
BOOST_TEST( e1 == my_enoent );
BOOST_TEST_NOT( e1 != my_enoent );
BOOST_TEST( e1 == std::errc::no_such_file_or_directory );
}
return boost::report_errors();
}
#endif

View File

@ -0,0 +1,77 @@
// Copyright 2021, 2022 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/error_category.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.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>
class my_category_impl: public std::error_category
{
public:
char const* name() const BOOST_NOEXCEPT
{
return "mycat";
}
std::string message( int /*ev*/ ) const
{
return "Unknown error";
}
};
std::error_category const& my_category()
{
static my_category_impl mycat;
return mycat;
}
int main()
{
{
std::error_code e1( 5, boost::system::system_category() );
boost::system::error_code e2( e1 );
std::error_code e3( e2 );
BOOST_TEST_EQ( e1, e3 );
BOOST_TEST_EQ( e1.value(), e3.value() );
BOOST_TEST_EQ( &e1.category(), &e3.category() );
}
{
std::error_code e1( 5, boost::system::generic_category() );
boost::system::error_code e2( e1 );
std::error_code e3( e2 );
BOOST_TEST_EQ( e1, e3 );
BOOST_TEST_EQ( e1.value(), e3.value() );
BOOST_TEST_EQ( &e1.category(), &e3.category() );
}
{
std::error_code e1( 5, my_category() );
boost::system::error_code e2( e1 );
std::error_code e3( e2 );
BOOST_TEST_EQ( e1, e3 );
BOOST_TEST_EQ( e1.value(), e3.value() );
BOOST_TEST_EQ( &e1.category(), &e3.category() );
}
return boost::report_errors();
}
#endif

View File

@ -0,0 +1,57 @@
// Copyright 2021, 2022 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/error_category.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.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>
class my_category_impl: public boost::system::error_category
{
public:
char const* name() const BOOST_NOEXCEPT
{
return "mycat";
}
std::string message( int /*ev*/ ) const
{
return "Unknown error";
}
};
boost::system::error_category const& my_category()
{
static my_category_impl mycat;
return mycat;
}
int main()
{
{
boost::system::error_code e1( 5, my_category() );
std::error_code e2( e1 );
boost::system::error_code e3( e2 );
BOOST_TEST_EQ( e1, e3 );
BOOST_TEST_EQ( e1.value(), e3.value() );
BOOST_TEST_EQ( &e1.category(), &e3.category() );
}
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

@ -59,6 +59,7 @@ std::string sys_strerror( int ev )
};
local_free lf_ = { lpMsgBuf };
(void)lf_;
if( retval == 0 )
{

View File

@ -51,6 +51,7 @@ namespace
<< ex.what() << "\"\n";
}
# endif
(void)str;
}
const boost::uint_least32_t uvalue = 2u;
@ -80,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,62 @@
// Copyright 2021, 2022 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() );
}
{
sys::error_code ec( 5, sys::generic_category() );
sys::system_error x1( ec, "prefix" );
BOOST_TEST_EQ( std::string( x1.what() ), "prefix: " + ec.what() );
}
{
sys::error_code ec( 5, sys::generic_category() );
sys::system_error x1( ec, std::string( "prefix2" ) );
BOOST_TEST_EQ( std::string( x1.what() ), "prefix2: " + ec.what() );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
sys::error_code ec( 5, sys::generic_category(), &loc );
sys::system_error x1( ec, "prefix3" );
BOOST_TEST_EQ( std::string( x1.what() ), "prefix3: " + ec.what() );
}
{
sys::system_error x1( 5, sys::system_category() );
BOOST_TEST_EQ( std::string( x1.what() ), sys::error_code( 5, sys::system_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() );
}
{
sys::system_error x1( 5, sys::system_category(), std::string( "prefix2" ) );
BOOST_TEST_EQ( std::string( x1.what() ), "prefix2: " + 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();
}