Compare commits

...

167 Commits

Author SHA1 Message Date
a664cd1de6 Update .drone.jsonnet 2024-08-18 11:46:25 +03:00
e8a089b664 Update ci.yml 2024-08-17 18:22:21 +03:00
5d5ecb74a7 Update .drone.jsonnet 2024-06-03 03:01:59 +03:00
41ff095c0a Try to fix the false positive with GCC ASAN 2024-06-03 02:40:13 +03:00
38d63aaf7c strerror_r(ev, tmp, 0) may return tmp 2024-06-02 23:03:24 +03:00
d1fb7554c5 Update error_code_test2, error_condition_test3 2024-06-02 22:41:48 +03:00
c63bca6eda Update error_condition_test3.cpp 2024-06-02 22:33:43 +03:00
bef2c5ef6a Update error_code_test2.cpp 2024-06-02 22:26:01 +03:00
4d4f906548 strerror_r requires non-null buffer pointer
Fixes -Wnonnull warnings when calling message with a nullptr buffer
2024-06-02 18:21:07 +00:00
8a92683012 Add tests for calling message with nullptr buffer 2024-06-02 18:20:16 +00:00
be5a8ffa80 Disable -Wformat-truncation for Clang in snprintf_test 2024-06-02 19:45:18 +03:00
d032ab91fd Update ci.yml 2024-06-02 18:59:05 +03:00
8f319f30c6 Update revision history 2024-04-17 03:41:33 +03:00
01d46f597e Update test/result_and_fn1v.cpp 2024-04-09 03:07:07 +03:00
93852d1a7e Support result<void> &= fv. Refs #119. 2024-04-09 03:01:38 +03:00
4aeebd2173 Avoid Appveyor timeout 2024-04-08 21:47:32 +03:00
96fef94580 Support result<void> & fv, where fv returns void. Refs #119. 2024-04-08 18:01:41 +03:00
75ab18c9fd Support result<X> & fv, where fv returns void. Refs #119. 2024-04-08 17:55:50 +03:00
f9a4655ae7 Merge pull request #120 from klemens-morgenstern/patch-1
declared global constants as inline with BOOST_INLINE_CONSTEXPR
2024-04-06 21:48:49 +03:00
f6fcb1b690 declared global constants as inline with BOOST_INLINE_CONSTEXPR 2024-04-06 21:54:33 +08:00
2fc720a1cb Update documentation 2024-02-03 04:07:53 +02:00
73de83b8f7 Update documentation 2024-02-02 08:28:41 +02:00
310bf1d544 Add operator|=(result&, fn0r) 2024-02-01 07:18:41 +02:00
f18edb3d24 Add operator|=(result&, fn0v) 2024-02-01 06:49:23 +02:00
a9659f4318 Add operator|=(result&, value) 2024-02-01 06:40:47 +02:00
2b14b9a96a Update documentation 2024-02-01 03:24:33 +02:00
c7a0ce3349 Enable result<void> &= fr. Refs #117. 2024-02-01 02:39:31 +02:00
cedf6eb581 Update test/result_and_fn1r.cpp 2024-02-01 02:22:05 +02:00
ab368822a6 Update documentation 2024-01-31 11:35:41 +02:00
293174a1d3 Enable result<void> & fr. Refs #117. 2024-01-31 05:36:52 +02:00
5c1d0df893 Enable result<void> & fv. Refs #117. 2024-01-31 05:26:01 +02:00
3f2f87f734 Update ci.yml 2024-01-26 01:35:05 +02:00
6caa346ba5 Update documentation 2024-01-25 22:13:49 +02:00
a5aec941ca Remove boost/system/cygwin_error.hpp 2024-01-18 20:21:45 +02:00
7f640b92fe Update appveyor.yml 2024-01-18 19:42:44 +02:00
626263c23f Update CMakeLists.txt 2024-01-17 07:45:05 +02:00
53ce7e9f53 Update meta/libraries.json 2024-01-17 07:18:04 +02:00
ff47c6782f Include and test unconditionally result.hpp 2024-01-17 07:17:30 +02:00
abbfd46517 Remove uses of BOOST_NOEXCEPT 2024-01-17 07:14:05 +02:00
128fd9341f Remove uses of BOOST_CONSTEXPR 2024-01-17 07:09:31 +02:00
e0b0118406 Remove msvc-12.0 from Appveyor 2024-01-17 07:07:25 +02:00
3ded81eed0 Remove uses of BOOST_SYSTEM_HAS_SYSTEM_ERROR 2024-01-17 06:49:19 +02:00
80e019069c Use snprintf in error_category_impl.hpp 2024-01-17 05:18:23 +02:00
e368c2863d Disable -Wformat-truncation in snprintf_test.cpp 2024-01-17 05:13:10 +02:00
00fb79f174 Remove requires_cxx11.hpp 2024-01-17 04:47:46 +02:00
44582f3c3c Use std::snprintf in detail/snprintf.hpp 2024-01-17 04:34:11 +02:00
f08e363c0e Use std::is_same in detail/is_same.hpp 2024-01-17 04:33:14 +02:00
1474498ccf Use std::enable_if in detail/enable_if.hpp 2024-01-17 04:32:29 +02:00
b0304ad0b2 Remove msvc-9.0, 10.0, 11.0 from Appveyor 2024-01-17 04:31:25 +02:00
9974d92675 Remove GCC 4.4, 4.6, 4.7 from Drone 2024-01-17 04:30:55 +02:00
945b0591dd Unconditionally enable BOOST_SYSTEM_HAS_SYSTEM_ERROR 2024-01-17 04:14:23 +02:00
1f1e4e0400 Remove NO_CXX11 macros from config_test.cpp 2024-01-17 04:12:51 +02:00
1a0b9a46a8 Remove static_assert workaround 2024-01-17 04:12:13 +02:00
f132dca4a9 Remove =default/=delete workarounds 2024-01-17 04:11:19 +02:00
81a9952695 Remove BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS workarounds 2024-01-17 03:57:53 +02:00
b877f65f80 Remove C++03 from appveyor.yml 2024-01-17 03:54:47 +02:00
aa80e0bdcd Remove C++03 from .drone.jsonnet 2024-01-17 03:53:54 +02:00
0b60b13618 Remove C++03 from ci.yml 2024-01-17 03:51:39 +02:00
7dacf5be11 Update .drone.jsonnet 2024-01-01 19:42:54 +02:00
c3cd1d5ea9 Disable failed_constexpr_test for GCC/UBSAN 2023-12-31 02:25:26 +02:00
2bea482605 Update .drone.jsonnet 2023-12-31 01:26:31 +02:00
48f95f0035 Update .drone.jsonnet 2023-12-31 01:11:31 +02:00
16d20175bc Update .drone.jsonnet 2023-12-28 16:18:53 +02:00
2aa5d4d97f Add definitions of ::in_place_* for result specializations. Fixes #115. 2023-12-15 03:17:21 +02:00
18edbf75d0 Test ::in_place_* for result specializations. Refs #115. 2023-12-15 02:44:14 +02:00
52220a0351 Add definitions of result<T, E>::in_place_*. Refs #115. 2023-12-15 02:24:18 +02:00
ffa67ab005 Add test for ODR-use of ::in_place_* (refs #115) 2023-12-15 02:11:19 +02:00
d8399efcac Update ci.yml 2023-12-15 01:42:22 +02:00
8bc32b7267 Update documentation 2023-10-31 04:20:33 +02:00
d11dd4b396 Add operator&=( result&, unary-returning-result ) 2023-10-31 03:08:02 +02:00
ca5bca39ce Add operator&=( result&, unary-returning-value ) 2023-10-31 02:44:45 +02:00
a58115cb50 Reorder operator& code for better codegen 2023-10-31 01:51:38 +02:00
1bc08296de Update documentation 2023-10-30 21:03:39 +02:00
25479216b3 Fix test file names 2023-10-30 00:52:38 +02:00
54d3b253b1 Add operator&( result, unary-returning-result ) 2023-10-29 20:57:29 +02:00
194b84e663 Add operator&( result, unary-returning-value ) 2023-10-29 19:37:43 +02:00
47a08cb35b Update documentation 2023-10-29 19:14:13 +02:00
7ffd63d54c Fix rvalue result<void> cases 2023-10-29 19:13:11 +02:00
92c24da9a1 Document operator| 2023-10-29 03:10:27 +02:00
dc73ca428b Add operator|( result, nullary-returning-result ) 2023-10-29 03:20:08 +03:00
c1fa3619b6 Add operator|( result, nullary-returning-value ) 2023-10-29 02:32:19 +03:00
0cd351014b Remove C++14-ism 2023-10-29 01:41:50 +03:00
d38e54d4c3 Add operator|( result, value ) 2023-10-29 01:30:01 +03:00
fa3331412d Update ci.yml 2023-10-28 20:53:44 +03:00
b899c49ae8 Update .drone.jsonnet 2023-10-21 04:17:30 +03:00
61a0e244da Add some more test cases exercising result initialization from {} 2023-10-20 21:49:20 +03:00
eb788615de Update ci.yml 2023-10-20 03:04:29 +03:00
84fd43e14a Update C++03 deprecation message 2023-10-19 18:15:05 +03:00
b0ef682e3d Update documentation 2023-09-14 02:20:46 +03:00
c360ff1b1c Add a converting constructor to result<void> 2023-09-12 04:48:45 +03:00
951b3fe7b4 Add result<U&, E> specialization. Fixes #72. 2023-09-12 03:34:24 +03:00
a57c568324 Do not use <shared_mutex> when BOOST_USE_WINAPI_VERSION is 0x5xx (Windows XP). Fixes #113. 2023-09-04 16:28:34 +03:00
4843453528 Update ci.yml 2023-09-04 13:04:34 +03:00
2e7e46a802 Update C++03 deprecation message 2023-06-03 02:31:27 +03:00
32dbf1b992 Disable use of <shared_mutex> under the XP toolsets (v140_xp and v141_xp). Fixes #110. 2023-04-30 18:44:56 +03:00
707b24bfa1 Update reference 2023-03-18 05:30:43 +02:00
bb1caae0d5 Update test/result_error_move.cpp 2023-03-18 05:25:44 +02:00
c5c49894e6 Made result::error movable.
Closes #108.
2023-03-17 12:53:14 +08:00
ee80491cab Add C++03 deprecation notice 2023-03-06 07:49:33 +02:00
a83319fde1 Update ci.yml 2023-03-06 06:22:31 +02:00
4b90524729 Disable the constexpr constructors on GCC 4.7 2023-03-01 05:18:23 +02:00
6ac5f23999 Make error_category constructors unconditionally constexpr 2023-03-01 03:36:07 +02:00
f332a52597 Disable C4800 under msvc-14.0 2023-01-22 04:54:46 +02:00
c92d50abbd Do not consider types with explicit operator bool (such as result itself) constructible from bool for the purposes of result construction. Refs #104. 2023-01-22 02:07:28 +02:00
805b260a7a Add test/result_value_construct5.cpp. Refs #104. 2023-01-22 01:58:29 +02:00
f32ffcba48 Update result_value_construct4.cpp 2023-01-22 01:25:30 +02:00
8ce2a9f835 Disable result converting constructor when T is convertible from the rhs result<T2, E2>. Refs #104. 2023-01-22 01:22:02 +02:00
6a58b03eab Add test/result_value_construct4.cpp. Refs #104. 2023-01-22 01:15:08 +02:00
f0b27c5826 Enable implicit construction when the alternative is explicitly constructible from the argument. Fixes #103. 2023-01-21 20:09:53 +02:00
456b3c2dad Add test/result_error_construct4.cpp. Refs #103. 2023-01-21 19:45:32 +02:00
eb3f3a8e41 Use boost::core::snprintf in std_interop_test16 as well 2023-01-20 04:39:08 +02:00
e6986a51d5 Merge branch 'develop' into feature/issue-102 2023-01-20 04:38:15 +02:00
fb648760b5 Change uses of std::sprintf in tests to boost::core::snprintf, to avoid deprecation warnings 2023-01-20 02:29:38 +02:00
71ee26c188 Move the stdcat mutex into init_stdcat() as a local static to fix msvc-12.0 2023-01-20 01:22:42 +02:00
8449c62162 Update detail/mutex.hpp to use std::shared_mutex under the MS STL 2023-01-19 18:05:21 +02:00
4bca94ffc4 Merge branch 'develop' into feature/issue-102 2023-01-19 16:35:05 +02:00
3e6af15652 Add system/detail/mutex.hpp, use it in error_category_impl.hpp 2023-01-19 12:04:06 +02:00
86ff47ff63 Update std_interop_test16.cpp to not use asio/error.hpp. 2023-01-19 11:13:40 +02:00
06ddfdb4a6 Add std_interop_test16.cpp. Refs #102. 2023-01-19 05:46:11 +02:00
bb60a27b18 Update appveyor.yml 2023-01-12 20:38:54 +02:00
e478ba1a2b Update appveyor.yml 2023-01-12 15:18:11 +02:00
50100b0e81 Update CMakeLists.txt 2023-01-12 10:37:55 +02:00
bb502f5d67 Merge branch 'develop' into feature/pr-90 2023-01-12 10:36:56 +02:00
fa2349eee7 Add CMake tests to Appveyor 2023-01-12 05:45:30 +02:00
3d9acaf082 Update CMakeLists.txt 2023-01-12 05:41:30 +02:00
c6795eb9d0 Merge branch 'natvis' of https://github.com/vinniefalco/boost-system into feature/pr-90 2023-01-12 05:39:37 +02:00
57c295bbf7 Work around Clang 3.5 failures in result_value_access 2023-01-10 05:46:57 +02:00
36e3b2c6ae Work around Clang 3.5..3.8 failure in constexpr_test2 2023-01-10 05:14:36 +02:00
583cd8dba2 Update .drone.jsonnet 2023-01-10 04:36:37 +02:00
0c2de4cb2a Update .drone.jsonnet 2023-01-10 04:19:25 +02:00
3d595a6e79 Update ci.yml 2023-01-10 04:06:30 +02:00
b3faedfe3e Extend Clang 6 workaround to Clang 7 under Android. Fixes #100. 2023-01-10 03:09:20 +02:00
32bf67f748 error_code wrapping std::error_code should never compare equal to error_code not wrapping std (because of hash_value.) Fixes #101. 2023-01-07 19:56:34 +02:00
5d15aa1267 Add ec_hash_value_test 2023-01-07 19:42:59 +02:00
36e1236a0f Remove _Addr assignment from the constructor of std_category. Fixes #98. 2022-12-10 22:17:51 +02:00
2c20b6e7e5 Work around ERROR_INVALID_NAME failure on msvc-14.0, msvc-14.1 2022-12-10 19:45:14 +02:00
103f3b4f00 Print original error code in win32_generic_test 2022-12-10 18:47:54 +02:00
14f779e234 Update Win32 translation table. Closes #97. 2022-12-10 18:38:19 +02:00
bfccd4b4d9 Add win32_generic_test. Refs #97. 2022-12-10 18:24:34 +02:00
7ae6b317f3 Only disable C4351 on msvc-12.0 and earlier (refs #96) 2022-10-26 15:52:18 +03:00
9a6d79b841 Update revision history 2022-10-18 04:17:17 +03:00
ece71199a9 Document result<>::emplace 2022-10-18 04:15:40 +03:00
1e4c050d6c Add result<>::emplace (refs #85) 2022-10-18 00:46:59 +03:00
21115121bb Update ci.yml 2022-10-15 04:17:12 +03:00
956fa92a53 Update revision history 2022-09-27 20:32:03 +03:00
ee318f937f Document result<>::value_type, error_type, in_place_value, in_place_error. Closes #93. 2022-09-27 20:23:28 +03:00
19f99264de Document BOOST_SYSTEM_DISABLE_THREADS 2022-09-27 20:20:36 +03:00
3261bae6de Update .drone.jsonnet 2022-09-27 18:58:14 +03:00
20ce51858b Add in_place_value, in_place_error to result<>. Refs #93. 2022-09-27 18:18:16 +03:00
52d7429473 Add value_type, error_type typedefs to result. Refs #93. 2022-09-26 21:20:40 +03:00
53c00841fc Add support for BOOST_SYSTEM_DISABLE_THREADS (refs #92) 2022-09-08 18:32:26 +03:00
19e27a73e9 Disable failing test for msvc-12.0 2022-08-25 17:38:59 +03:00
19020ce925 Disable std_interop_test15 on g++ 4.8/4.9 2022-08-24 23:37:03 +03:00
3faf415026 Resolve ambiguities when comparing error_condition with std enums (refs #91) 2022-08-24 22:56:15 +03:00
a2df4d09da Update error_code_test3.cpp 2022-08-24 21:41:38 +03:00
455c6a6332 Add std_interop_test15.cpp 2022-08-24 21:40:20 +03:00
efb7634666 Move code/condition comparisons back outside class error_code; fixes #91 2022-08-24 21:10:05 +03:00
2bba3fd5e2 Add error_code_test3.cpp 2022-08-24 20:54:20 +03:00
8c740705e6 Add missing include 2022-08-21 19:42:10 +03:00
4708d95e80 Merge branch 'constexpr-default-ctor' of https://github.com/vinniefalco/boost-system into feature/pr-89 2022-08-21 19:13:48 +03:00
867f6d06d0 Add constexpr_test2.cpp 2022-08-21 19:13:12 +03:00
ac1ed1ecc1 error_code default ctor is constexpr in c++11 2022-08-21 08:17:54 -07:00
fe48c3058d add boost_system.natvis and interface source files 2022-08-19 11:40:36 -07:00
cc7c2f7ee4 Return v_.index() == 1 from has_error() to avoid -Wmaybe-uninitialized in error() 2022-08-02 22:44:34 +03:00
f2e1db8021 Constrain explicit value and error constructors to not accept zero arguments. Fixes #86. 2022-07-26 21:49:13 +03:00
ede243c42f Add (negative) tests for default constructability (refs #86) 2022-07-26 21:35:33 +03:00
1558aaa789 Update ci.yml 2022-07-26 20:41:24 +03:00
110 changed files with 8086 additions and 1034 deletions

View File

@ -32,6 +32,8 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
commands:
[
'set -e',
'uname -a',
'echo $DRONE_STAGE_MACHINE',
'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 []) +
@ -97,140 +99,249 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
[
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 16.04 GCC 4.8",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '11' },
"g++-4.8",
),
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' },
"Linux 16.04 GCC 4.9",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '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' },
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14' },
),
linux_pipeline(
"Linux 18.04 GCC 6",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '03,11,14' },
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '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' },
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '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' },
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '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' },
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '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' },
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '64' },
),
linux_pipeline(
"Linux 20.04 GCC 9 ARM64 32/64",
"Linux 20.04 GCC 9* ARM64",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' },
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="arm64",
),
linux_pipeline(
"Linux 20.04 GCC 10 32 ASAN",
"Linux 20.04 GCC 9* S390x",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="s390x",
),
linux_pipeline(
"Linux 20.04 GCC 10 32",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '32' } + asan,
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '32' },
"g++-10-multilib",
),
linux_pipeline(
"Linux 20.04 GCC 10 64 ASAN",
"Linux 20.04 GCC 10 64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '64' } + asan,
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '64' },
"g++-10-multilib",
),
linux_pipeline(
"Linux 20.04 Clang 13",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '03,11,14,17,20' },
"Linux 22.04 GCC 11* 32",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32' },
),
linux_pipeline(
"Linux 22.04 GCC 11* 64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '64' },
),
linux_pipeline(
"Linux 22.04 GCC 12 32",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' },
"g++-12-multilib",
),
linux_pipeline(
"Linux 22.04 GCC 12 64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' },
"g++-12-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 64 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 ASAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + asan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 16.04 Clang 3.5",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '11' },
"clang-3.5",
),
linux_pipeline(
"Linux 16.04 Clang 3.6",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' },
"clang-3.6",
),
linux_pipeline(
"Linux 16.04 Clang 3.7",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '11,14' },
"clang-3.7",
),
linux_pipeline(
"Linux 16.04 Clang 3.8",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '11,14' },
"clang-3.8",
),
linux_pipeline(
"Linux 22.04 Clang 13",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '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,
"Linux 22.04 Clang 14",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14,17,20' },
"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"],
"Linux 22.04 Clang 15",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '11,14,17,20,2b' },
"clang-15",
),
linux_pipeline(
"Linux 23.04 Clang 16",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' },
"clang-16",
),
linux_pipeline(
"Linux 23.10 Clang 17",
"cppalliance/droneubuntu2310:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' },
"clang-17",
),
linux_pipeline(
"Linux 24.04 Clang 18 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + ubsan,
"clang-18",
),
linux_pipeline(
"Linux 24.04 Clang 18 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + asan,
"clang-18",
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + ubsan,
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan,
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + ubsan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + asan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
windows_pipeline(
"Windows VS2015 msvc-14.0",
"cppalliance/dronevs2015",
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest' },
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' },
),
windows_pipeline(

View File

@ -5,6 +5,7 @@
# https://www.boost.org/LICENSE_1_0.txt
set -ex
export PATH=~/.local/bin:/usr/local/bin:$PATH
DRONE_BUILD_DIR=$(pwd)

View File

@ -18,108 +18,173 @@ jobs:
matrix:
include:
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-18.04
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-4.8
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: g++-11
cxxstd: "11,14,17,2a"
os: ubuntu-22.04
- toolset: gcc-12
cxxstd: "03,11,14,17,20"
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: g++-12
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:23.04
install: g++-13
- toolset: gcc-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
install: g++-14
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17"
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17"
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxstd: "11,14,17,20"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-14
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
container: ubuntu:23.04
os: ubuntu-latest
install: clang-16
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,2b"
container: ubuntu:23.10
os: ubuntu-latest
install: clang-17
- toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-18
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-12
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: Enable Node 16
run: |
echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV
- uses: actions/checkout@v3
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: |
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@ -139,7 +204,7 @@ jobs:
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
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
@ -171,18 +236,18 @@ jobs:
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
@ -217,19 +282,20 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
- os: macos-12
- os: macos-13
- os: macos-14
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@ -264,19 +330,20 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
- os: macos-12
- os: macos-13
- os: macos-14
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@ -321,19 +388,20 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
- os: macos-12
- os: macos-13
- os: macos-14
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@ -370,3 +438,183 @@ jobs:
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error
windows-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %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 (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use library with add_subdirectory (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- name: Install (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Debug
- name: Install (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Release
- name: Use the installed library (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use the installed library (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON ..
- name: Build tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Debug
- name: Run tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Debug
- name: Build tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Release
- name: Run tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Release

View File

@ -1,8 +1,8 @@
# 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
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.8...3.20)
project(boost_system VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
@ -20,7 +20,18 @@ target_link_libraries(boost_system
Boost::winapi
)
if(BUILD_TESTING)
target_compile_features(boost_system INTERFACE cxx_std_11)
if(CMAKE_VERSION VERSION_GREATER 3.18 AND CMAKE_GENERATOR MATCHES "Visual Studio")
file(GLOB_RECURSE boost_system_IDEFILES CONFIGURE_DEPENDS include/*.hpp)
source_group(TREE ${PROJECT_SOURCE_DIR}/include FILES ${boost_system_IDEFILES} PREFIX "Header Files")
list(APPEND boost_system_IDEFILES extra/boost_system.natvis)
target_sources(boost_system PRIVATE ${boost_system_IDEFILES})
endif()
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)

View File

@ -14,32 +14,27 @@ branches:
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-12.0,msvc-14.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17,latest
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin;
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_SUBDIR: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_INSTALL: 1
install:
- set BOOST_BRANCH=develop
@ -59,4 +54,27 @@ test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 libs/system/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
- if "%CMAKE%%CMAKE_SUBDIR%%CMAKE_INSTALL%" == "" b2 -j3 libs/system/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
- if not "%CMAKE%" == "" mkdir __build__ && cd __build__
- if not "%CMAKE%" == "" cmake -DBUILD_TESTING=ON -DBOOST_INCLUDE_LIBRARIES=system -DBoost_VERBOSE=ON ..
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config Debug & ctest --output-on-failure --no-tests=error -j 3 -C Debug
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config Release & ctest --output-on-failure --no-tests=error -j 3 -C Release
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config MinSizeRel & ctest --output-on-failure --no-tests=error -j 3 -C MinSizeRel
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config RelWithDebInfo & ctest --output-on-failure --no-tests=error -j 3 -C RelWithDebInfo
- if not "%CMAKE_SUBDIR%" == "" cd libs/system/test/cmake_subdir_test && mkdir __build__ && cd __build__
- if not "%CMAKE_SUBDIR%" == "" cmake ..
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Release && cmake --build . --target check --config Release
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config MinSizeRel && cmake --build . --target check --config MinSizeRel
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config RelWithDebInfo && cmake --build . --target check --config RelWithDebInfo
- if not "%CMAKE_INSTALL%" == "" mkdir __build__ && cd __build__
- if not "%CMAKE_INSTALL%" == "" cmake -DBOOST_INCLUDE_LIBRARIES=system -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Debug
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Release
- if not "%CMAKE_INSTALL%" == "" cd ../libs/system/test/cmake_install_test && mkdir __build__ && cd __build__
- if not "%CMAKE_INSTALL%" == "" cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Release && cmake --build . --target check --config Release

View File

@ -8,6 +8,34 @@ https://www.boost.org/LICENSE_1_0.txt
# Revision History
:idprefix:
## Changes in Boost 1.86
* Support `result<T> & fv`, where `fv` returns `void`.
* Support `result<void> &= fv;`, where `fv` returns `void`.
## Changes in Boost 1.85
* {cpp}03 is no longer supported; a {cpp}11 compiler is required. (This includes GCC 4.8 or later, and MSVC 14.0 (VS 2015) or later.)
* The deprecated header `boost/system/cygwin_error.hpp` has been removed.
* The original and obsolete (32 bit) MinGW is no longer supported. MinGW-w64 (both 64 and 32 bit) is still supported.
* `operator&` now works for `result<void>` (by way of taking a nullary function.)
* Added `operator|=` for `result`.
## Changes in Boost 1.84
* Added support for `result<U&, E>`.
* Added `operator|` for `result`.
* Added `operator&` for `result`.
* Added `operator&=` for `result`.
## Changes in Boost 1.81
* The macro `BOOST_SYSTEM_DISABLE_THREADS` can now be defined to disable
the use of `<mutex>` (e.g. on single-threaded libstdc++).
* Added `value_type`, `error_type`, `in_place_value`, `in_place_error`
to `result<>`.
* Added `emplace` to `result<>`.
## Changes in Boost 1.80
* When an `error_code` is converted to `std::error_code` and then back

View File

@ -12,13 +12,6 @@ http://www.boost.org/LICENSE_1_0.txt
# Reference
:idprefix: ref_
## Use of {cpp}11 and {cpp}14 Features
The library is documented to use several {cpp}11 and {cpp}14 features,
including `noexcept`, explicit conversion operators and `constexpr`. The
actual implementation uses {cpp}11 and {cpp}14 features only when they are
available, and otherwise falls back on {cpp}03 features.
## Macros
When `BOOST_SYSTEM_ENABLE_DEPRECATED` is defined, the library provides
@ -29,6 +22,11 @@ When `BOOST_SYSTEM_USE_UTF8` is defined, on Windows the library returns
UTF-8 messages using code page `CP_UTF8` instead of the default `CP_ACP`.
This macro has no effect on POSIX.
When `BOOST_SYSTEM_DISABLE_THREADS` is defined, the library assumes that
the current platform doesn't support multiple threads and disables the use
of the standard header `<mutex>`, eliminating the mutex locks. The single
threaded `libstdc++` is one such platform.
## Deprecated Names
In the process of adding Boost.System to the {cpp}11 standard library, the
@ -1512,6 +1510,38 @@ constexpr in_place_error_t in_place_error{};
template<class T, class E = error_code> class result;
template<class E> class result<void, E>;
template<class U, class E> class result<U&, E>;
// operator|
template<class T, class E, class U> T operator|( result<T, E> const& r, U&& u );
template<class T, class E, class U> T operator|( result<T, E>&& r, U&& u );
template<class T, class E, class F> T operator|( result<T, E> const& r, F&& f );
template<class T, class E, class F> T operator|( result<T, E>&& r, F&& f );
template<class T, class E, class F, class R = ...> R operator|( result<T, E> const& r, F&& f );
template<class T, class E, class F, class R = ...> R operator|( result<T, E>&& r, F&& f );
template<class E, class F, class R = ...> R operator|( result<void, E> const& r, F&& f );
template<class E, class F, class R = ...> R operator|( result<void, E>&& r, F&& f );
// operator&
template<class T, class E, class F, class U = ...>
result<U, E> operator&( result<T, E> const& r, F&& f );
template<class T, class E, class F, class U = ...>
result<U, E> operator&( result<T, E>&& r, F&& f );
template<class T, class E, class F, class R = ...> R operator&( result<T, E> const& r, F&& f );
template<class T, class E, class F, class R = ...> R operator&( result<T, E>&& r, F&& f );
// operator&=
template<class T, class E, class F, class U = ...>
result<T, E>& operator&=( result<T, E>& r, F&& f );
template<class T, class E, class F, class R = ...>
result<T, E>& operator&=( result<T, E>& r, F&& f );
} // namespace system
} // namespace boost
@ -1595,6 +1625,12 @@ template<class T, class E = error_code> class result
{
public:
using value_type = T;
using error_type = E;
static constexpr in_place_value_t in_place_value{};
static constexpr in_place_error_t in_place_error{};
// constructors
constexpr result();
@ -1646,7 +1682,13 @@ public:
// error access
constexpr E error() const;
constexpr E error() const &;
constexpr E error() &&;
// emplace
template<class... A>
constexpr T& emplace( A&&... a );
// swap
@ -1696,7 +1738,7 @@ Effects: ::
ensures that `*this` holds the error `E( std::forward<A>(a)... )`.
- Otherwise, this constructor does not participate in overload resolution.
Remarks: ::
This constructor is only enabled when `sizeof...(T) > 0`.
This constructor is only enabled when `sizeof...(A) > 0`.
```
template<class... A>
@ -1730,7 +1772,7 @@ template<class T2, class E2>
* {blank}
+
Ensures: ::
If `r2.has_value()` is `true`, `*this` holds the value `T( *r2 )`, otherwise `*this` holds the value `E( r2.error() )`.
If `r2.has_value()` is `true`, `*this` holds the value `T( *r2 )`, otherwise `*this` holds the error `E( r2.error() )`.
Remarks: ::
This constructor is only enabled when `std::is_convertible<T2, T>::value && std::is_convertible<E2, E>::value` is `true`.
@ -1742,7 +1784,7 @@ template<class T2, class E2>
* {blank}
+
Ensures: ::
If `r2.has_value()` is `true`, `*this` holds the value `T( std::move( *r2 ) )`, otherwise `*this` holds the value `E( r2.error() )`.
If `r2.has_value()` is `true`, `*this` holds the value `T( std::move( *r2 ) )`, otherwise `*this` holds the error `E( r2.error() )`.
Remarks: ::
This constructor is only enabled when `std::is_convertible<T2, T>::value && std::is_convertible<E2, E>::value` is `true`.
@ -1835,7 +1877,8 @@ Returns: ::
#### Error Access
```
constexpr E error() const;
constexpr E error() const &;
constexpr E error() &&;
```
[none]
* {blank}
@ -1843,6 +1886,20 @@ constexpr E error() const;
Effects: ::
If `*this` holds an error, returns it. Otherwise, returns `E()`.
#### emplace
```
template<class... A>
constexpr T& emplace( A&&... a );
```
[none]
* {blank}
+
Ensures: ::
`*this` holds the value `T( std::forward<A>(a)... )`.
Returns: ::
A reference to the contained value.
#### swap
```
@ -1911,6 +1968,12 @@ template<class E> class result<void, E>
{
public:
using value_type = void;
using error_type = E;
static constexpr in_place_value_t in_place_value{};
static constexpr in_place_error_t in_place_error{};
// constructors
constexpr result() noexcept;
@ -1923,6 +1986,9 @@ public:
template<class... A>
constexpr result( in_place_error_t, A&&... a );
template<class E2>
constexpr result( result<void, E2> const& r2 );
// queries
constexpr bool has_value() const noexcept;
@ -1943,7 +2009,12 @@ public:
// error access
constexpr E error() const;
constexpr E error() const &;
constexpr E error() &&;
// emplace
constexpr void emplace();
// swap
@ -1989,7 +2060,7 @@ Effects: ::
ensures that `*this` holds the error `E( std::forward<A>(a)... )`.
- Otherwise, this constructor does not participate in overload resolution.
Remarks: ::
This constructor is only enabled when `sizeof...(T) > 0`.
This constructor is only enabled when `sizeof...(A) > 0`.
```
template<class... A>
@ -2013,6 +2084,18 @@ Ensures: ::
Remarks: ::
This constructor is only enabled when `std::is_constructible<E, A...>::value` is `true`.
```
template<class E2>
constexpr result( result<void, E2> const& r2 );
```
[none]
* {blank}
+
Ensures: ::
If `r2.has_value()` is `true`, `*this` holds an unspecified value, otherwise `*this` holds the error `E( r2.error() )`.
Remarks: ::
This constructor is only enabled when `std::is_convertible<E2, E>::value` is `true`.
#### Queries
```
@ -2080,7 +2163,8 @@ Effects: ::
#### Error Access
```
constexpr E error() const;
constexpr E error() const &;
constexpr E error() &&;
```
[none]
* {blank}
@ -2088,6 +2172,17 @@ constexpr E error() const;
Effects: ::
If `*this` holds an error, returns it. Otherwise, returns `E()`.
#### emplace
```
constexpr void emplace();
```
[none]
* {blank}
+
Ensures: ::
`*this` holds an unspecified value.
#### swap
```
@ -2146,6 +2241,637 @@ Effects: ::
Returns: ::
`os`.
### result<U&, E>
```
namespace boost {
namespace system {
template<class U, class E> class result<U&, E>
{
public:
using value_type = U&;
using error_type = E;
static constexpr in_place_value_t in_place_value{};
static constexpr in_place_error_t in_place_error{};
// constructors
template<class A>
constexpr result( A&& a ) noexcept;
template<class... A>
constexpr result( A&&... a );
template<class A>
constexpr result( in_place_value_t, A&& a ) noexcept;
template<class... A>
constexpr result( in_place_error_t, A&&... a );
template<class U2, class E2>
constexpr result( result<U2&, E2> const& r2 );
// queries
constexpr bool has_value() const noexcept;
constexpr bool has_error() const noexcept;
constexpr explicit operator bool() const noexcept;
// checked value access
constexpr U& value( boost::source_location const & loc =
BOOST_CURRENT_LOCATION ) const;
// unchecked value access
constexpr U* operator->() const noexcept;
constexpr U& operator*() const noexcept;
// error access
constexpr E error() const &;
constexpr E error() &&;
// emplace
template<class A>
constexpr U& emplace( A&& a ) noexcept;
// swap
constexpr void swap( result& r );
friend constexpr void swap( result & r1, result & r2 );
// equality
friend constexpr bool operator==( result const & r1, result const & r2 );
friend constexpr bool operator!=( result const & r1, result const & r2 );
};
} // namespace system
} // namespace boost
```
#### Constructors
```
template<class A>
constexpr result( A&& a ) noexcept;
```
[none]
* {blank}
+
Ensures: ::
`*this` holds the reference `static_cast<U&>( std::forward<A>(a) )`.
Remarks: ::
This constructor is only enabled when `A` is `B&` and `std::is_convertible<B*, U*>::value` is `true`.
```
template<class... A>
constexpr result( A&&... a );
```
[none]
* {blank}
+
Effects: ::
- If `std::is_constructible<E, A...>::value && !std::is_constructible<U&, A...>::value`,
ensures that `*this` holds the error `E( std::forward<A>(a)... )`.
- Otherwise, this constructor does not participate in overload resolution.
Remarks: ::
This constructor is only enabled when `sizeof...(A) > 0`.
```
template<class A>
constexpr result( in_place_value_t, A&& a ) noexcept;
```
[none]
* {blank}
+
Ensures: ::
`*this` holds the reference `static_cast<U&>( std::forward<A>(a) )`.
Remarks: ::
This constructor is only enabled when `A` is `B&` and `std::is_convertible<B*, U*>::value` is `true`.
```
template<class... A>
constexpr result( in_place_error_t, A&&... a );
```
[none]
* {blank}
+
Ensures: ::
`*this` holds the error `E( std::forward<A>(a)... )`.
Remarks: ::
This constructor is only enabled when `std::is_constructible<E, A...>::value` is `true`.
```
template<class U2, class E2>
constexpr result( result<U2&, E2> const& r2 );
```
[none]
* {blank}
+
Ensures: ::
If `r2.has_value()` is `true`, `*this` holds the reference `static_cast<U&>( *r2 )`, otherwise `*this` holds the error `E( r2.error() )`.
Remarks: ::
This constructor is only enabled when `std::is_convertible<U2*, U*>::value && std::is_convertible<E2, E>::value` is `true`.
#### Queries
```
constexpr bool has_value() const noexcept;
```
[none]
* {blank}
+
Returns: ::
`true` when `*this` holds a value, `false` otherwise.
```
constexpr bool has_error() const noexcept;
```
[none]
* {blank}
+
Returns: ::
`!has_value()`.
```
constexpr explicit operator bool() const noexcept;
```
[none]
* {blank}
+
Returns: ::
`has_value()`.
#### Checked Value Access
```
constexpr U& value(
boost::source_location const & loc = BOOST_CURRENT_LOCATION ) const;
```
[none]
* {blank}
+
Effects: ::
If `*this` holds a reference, returns it. Otherwise,
calls `throw_exception_from_error`, passing it a reference to
the held error, and `loc`.
#### Unchecked Value Access
```
constexpr U* operator->() const noexcept;
```
[none]
* {blank}
+
Returns: ::
If `*this` holds a reference, a pointer to its referent. Otherwise, `nullptr`.
```
constexpr U& operator*() const noexcept;
```
[none]
* {blank}
+
Requires: :: `*this` holds a reference.
Returns: ::
`*operator\->()`.
#### Error Access
```
constexpr E error() const &;
constexpr E error() &&;
```
[none]
* {blank}
+
Effects: ::
If `*this` holds an error, returns it. Otherwise, returns `E()`.
#### emplace
```
template<class A>
constexpr U& emplace( A&& a ) noexcept;
```
[none]
* {blank}
+
Ensures: ::
`*this` holds the reference `static_cast<U&>( std::forward<A>(a)... )`.
Returns: ::
The contained reference.
Remarks: ::
This function is only enabled when `A` is `B&` and `std::is_convertible<B*, U*>::value` is `true`.
#### swap
```
constexpr void swap( result& r );
```
[none]
* {blank}
+
Effects: ::
Exchanges the contents of `*this` and `r`.
```
friend constexpr void swap( result & r1, result & r2 );
```
[none]
* {blank}
+
Effects: ::
Exchanges the contents of `r1` and `r2`.
#### Equality
```
friend constexpr bool operator==( result const & r1, result const & r2 );
```
[none]
* {blank}
+
Effects: ::
- If `r1` holds a reference `t1` and `r2` holds a reference `t2`, returns `t1 == t2`.
- If `r1` holds an error `e1` and `r2` holds an error `e2`, returns `e1 == e2`.
- Otherwise, returns `false`.
```
friend constexpr bool operator!=( result const & r1, result const & r2 );
```
[none]
* {blank}
+
Returns: ::
`!( r1 == r2 )`.
### Chaining
#### operator|
```
template<class T, class E, class U> T operator|( result<T, E> const& r, U&& u );
template<class T, class E, class U> T operator|( result<T, E>&& r, U&& u );
```
[none]
* {blank}
+
Returns the value in `r`, or if `r` contains an error, a default value `u`.
+
Effects: ::
- If `r.has_value()` is `true`, returns `*r`.
- Otherwise, returns `u`.
Remarks: ::
Only enabled when `U` is convertible to `T`.
Example: ::
+
```
result<int> get_server_port(); // can fail
int get_port()
{
return get_server_port() | 443;
}
```
```
template<class T, class E, class F> T operator|( result<T, E> const& r, F&& f );
template<class T, class E, class F> T operator|( result<T, E>&& r, F&& f );
```
[none]
* {blank}
+
Returns the value in `r`, or if `r` contains an error, a default value obtained
by invoking the function `f`.
+
Effects: ::
- If `r.has_value()` is `true`, returns `*r`.
- Otherwise, returns `f()`.
Remarks: ::
Only enabled when `f()` is convertible to `T`.
Example: ::
+
```
result<int> get_server_port(); // can fail
int get_default_port();
int get_port()
{
return get_server_port() | get_default_port;
}
```
+
Note that the right hand side is `get_default_port` and not `get_default_port()`.
This is important; spelled this way, the function `get_default_port` is called
only when `get_server_port_impl()` fails. If it were
+
```
return get_server_port() | get_default_port();
```
+
the function would have been called unconditionally.
+
Another, equivalent, way is to use a lambda
+
```
return get_server_port() | []{ return get_default_port(); };
```
+
which isn't necessary here, but would be needed for more complex expressions.
```
template<class T, class E, class F, class R = ...> R operator|( result<T, E> const& r, F&& f );
template<class T, class E, class F, class R = ...> R operator|( result<T, E>&& r, F&& f );
template<class E, class F, class R = ...> R operator|( result<void, E> const& r, F&& f );
template<class E, class F, class R = ...> R operator|( result<void, E>&& r, F&& f );
```
[none]
* {blank}
+
Returns the value in `r`, or if `r` contains an error, another `result` obtained
by invoking the function `f`.
+
Let `R` be the type of `f()`.
+
Effects: ::
- If `r.has_value()` is `true`, returns `*r`.
- Otherwise, returns `f()`.
Remarks: ::
Only enabled when `R` is an instance of `result` and `T` is convertible to `R::value_type`.
Example: ::
+
```
result<int> get_server_port(); // can fail
result<int> get_default_port(); // can fail
int get_port()
{
return get_server_port() | get_default_port | 443;
}
```
#### operator|=
```
template<class T, class E, class U> result<T, E>& operator|=( result<T, E>& r, U&& u );
```
[none]
* {blank}
+
If `r` contains an error, assigns a value to it, constructed from `u`.
+
Effects: ::
If `r.has_value()` is `false`, assigns `u` to `r`.
Returns: ::
`r`.
Remarks: ::
Only enabled when `U` is convertible to `T`.
```
template<class T, class E, class F> result<T, E>& operator|=( result<T, E>& r, F&& f );
```
[none]
* {blank}
+
If `r` contains an error, assigns `f()` to it.
+
Effects: ::
If `r.has_value()` is `false`, assigns `f()` to `r`.
Returns: ::
`r`.
Remarks: ::
Only enabled when the type of `f()` is either
- convertible to `T` or
- an instance of `result` convertible to `result<T, E>`.
Example: ::
+
```
result<response> query_impl( std::string_view server, request const& req );
result<response> query( std::vector<std::string_view> const& servers, request const& req )
{
result<response> r = make_error_code( errc::invalid_argument );
for( auto const& server: servers )
{
r |= std::bind( query_impl, server, std::ref( req ) );
}
return r;
}
```
#### operator&
```
template<class T, class E, class F, class U = ...>
result<U, E> operator&( result<T, E> const& r, F&& f );
template<class T, class E, class F, class U = ...>
result<U, E> operator&( result<T, E>&& r, F&& f );
```
[none]
* {blank}
+
Returns the error in `r`, or if `r` contains a value, transforms the value by calling `f` on it.
+
Let `U` be the type of `f(*r)`.
+
Effects: ::
- If `r.has_value()` is `true`, returns `f(*r)`.
- Otherwise, returns `r.error()`.
Remarks: ::
Only enabled when `U` is not an instance of `result`.
Example: ::
+
```
struct currency_type
{
char code_[ 4 ] = {};
};
result<double> get_exchange_rate( currency_type from, currency_type to );
result<double> convert( double amount, currency_type from, currency_type to )
{
return get_exchange_rate( from, to ) & [&](double rate){ return rate * amount; };
}
```
```
template<class E, class F, class U = ...>
result<U, E> operator&( result<void, E> const& r, F&& f );
```
[none]
* {blank}
+
Returns the error in `r`, or if `r` contains a value, replaces it with the result of calling `f`.
+
Let `U` be the type of `f()`.
+
Effects: ::
- If `r.has_value()` is `true`, returns `f()`.
- Otherwise, returns `r.error()`.
Remarks: ::
Only enabled when `U` is not an instance of `result`.
```
template<class T, class E, class F, class R = ...> R operator&( result<T, E> const& r, F&& f );
template<class T, class E, class F, class R = ...> R operator&( result<T, E>&& r, F&& f );
```
[none]
* {blank}
+
Returns the error in `r`, or if `r` contains a value, another `result` obtained
by invoking the function `f` on the value in `r`.
+
Let `R` be the type of `f(*r)`.
+
Effects: ::
- If `r.has_value()` is `true`, returns `f(*r)`.
- Otherwise, returns `r.error()`.
Remarks: ::
Only enabled when `R` is an instance of `result` and `E` is convertible to `R::error_type`.
Example: ::
+
```
struct JsonValue
{
result<JsonValue const&> at( std::size_t i ) const noexcept;
result<JsonValue const&> at( std::string_view key ) const noexcept;
template<class T> result<T> to_number() const noexcept;
};
namespace helpers
{
inline auto at( std::size_t i ) {
return [=](JsonValue const& jv){ return jv.at( i ); }; }
inline auto at( std::string_view key ) {
return [=](JsonValue const& jv){ return jv.at( key ); }; }
template<class T> inline auto to_number() {
return [](JsonValue const& jv){ return jv.to_number<T>(); }; }
} // namespace helpers
int get_port( JsonValue const& config, int def )
{
using namespace helpers;
return config.at( "servers" ) & at( 0 ) & at( "port" ) & to_number<int>() | def;
}
```
```
template<class E, class F, class R = ...> R operator&( result<void, E> const& r, F&& f );
```
[none]
* {blank}
+
Returns the error in `r`, or if `r` contains a value, another `result` obtained
by invoking the function `f`.
+
Let `R` be the type of `f()`.
+
Effects: ::
- If `r.has_value()` is `true`, returns `f()`.
- Otherwise, returns `r.error()`.
Remarks: ::
Only enabled when `R` is an instance of `result` and `E` is convertible to `R::error_type`.
#### operator&=
```
template<class T, class E, class F, class U = ...>
result<T, E>& operator&=( result<T, E>& r, F&& f );
```
[none]
* {blank}
+
If `r` contains a value, replaces it with the result of invoking the function `f` on the value in `r`.
+
Let `U` be the type of `f(*r)`.
+
Effects: :: If `r.has_value()` is `true`, assigns `f(*std::move(r))` to `r`.
Returns: :: `r`.
Remarks: ::
Only enabled when `U` is not an instance of `result` and is convertible to `T`.
```
template<class T, class E, class F, class R = ...>
result<T, E>& operator&=( result<T, E>& r, F&& f );
```
[none]
* {blank}
+
If `r` contains a value, replaces `r` with the result of invoking the function `f` on the value in `r`.
+
Let `R` be the type of `f(*r)`.
+
Effects: :: If `r.has_value()` is `true`, assigns `f(*std::move(r))` to `r`.
Returns: :: `r`.
Remarks: ::
Only enabled when `R` is an instance of `result` and is convertible to `result<T, E>`.
Example: ::
+
```
struct JsonValue
{
result<JsonValue const&> at( std::string_view key ) const noexcept;
};
namespace helpers
{
inline auto at( std::string_view key ) {
return [=](JsonValue const& jv){ return jv.at( key ); }; }
} // namespace helpers
result<JsonValue const&> at_path( JsonValue const& jv,
std::initializer_list<std::string_view> path )
{
result<JsonValue const&> r( jv );
using namespace helpers;
for( auto key: path )
{
r &= at( key );
}
return r;
}
```
```
template<class E, class F, class R = ...>
result<void, E>& operator&=( result<void, E>& r, F&& f );
```
[none]
* {blank}
+
If `r` contains a value, replaces `r` with the result of invoking the function `f`.
+
Let `R` be the type of `f()`.
+
Effects: :: If `r.has_value()` is `true`, assigns `f()` to `r`.
Returns: :: `r`.
Remarks: ::
Only enabled when `R` is an instance of `result<void, E2>` and `E2` is convertible to `E`.
## <boost/system.hpp>
This convenience header includes all the headers previously described.

53
extra/boost_system.natvis Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="boost::system::error_category">
<DisplayString Condition="id_ == 0xb2ab117a257edfd0">[generic]</DisplayString>
<DisplayString Condition="id_ == 0xb2ab117a257edfd1">[system]</DisplayString>
<DisplayString Condition="id_ == 0xb2ab117a257edfd2">[interop]</DisplayString>
<DisplayString Condition="id_ != 0">[{id_,x}]</DisplayString>
<DisplayString>@{((uintptr_t)this),x}</DisplayString>
</Type>
<Type Name="boost::system::error_code">
<DisplayString Condition="lc_flags_ == 0">{d1_.val_} [system] ✓</DisplayString>
<DisplayString Condition="lc_flags_ == 1 &amp;&amp; ((std::error_code*)d2_)->_Mycat->_Addr==1">{((std::error_code*)d2_)->_Myval} [std:future]</DisplayString>
<DisplayString Condition="lc_flags_ == 1 &amp;&amp; ((std::error_code*)d2_)->_Mycat->_Addr==3">{((std::error_code*)d2_)->_Myval} [std:generic]</DisplayString>
<DisplayString Condition="lc_flags_ == 1 &amp;&amp; ((std::error_code*)d2_)->_Mycat->_Addr==5">{((std::error_code*)d2_)->_Myval} [std:iostream]</DisplayString>
<DisplayString Condition="lc_flags_ == 1 &amp;&amp; ((std::error_code*)d2_)->_Mycat->_Addr==7">{((std::error_code*)d2_)->_Myval} [std:system]</DisplayString>
<DisplayString Condition="lc_flags_ == 1">{((std::error_code*)d2_)->_Myval} std@{((uintptr_t)((std::error_code*)d2_)->_Mycat),x}</DisplayString>
<DisplayString Condition="d1_.cat_->id_ == 0xb2ab117a257edfd0 &amp;&amp;
(lc_flags_ == 2 || (lc_flags_ &gt; 3 &amp;&amp; ( lc_flags_ % 2 == 0 )))">{d1_.val_} [generic] ✓</DisplayString>
<DisplayString Condition="d1_.cat_->id_ == 0xb2ab117a257edfd1 &amp;&amp;
(lc_flags_ == 2 || (lc_flags_ &gt; 3 &amp;&amp; ( lc_flags_ % 2 == 0 )))">{d1_.val_} [system] ✓</DisplayString>
<DisplayString Condition="d1_.cat_->id_ == 0xb2ab117a257edfd2 &amp;&amp;
(lc_flags_ == 2 || (lc_flags_ &gt; 3 &amp;&amp; ( lc_flags_ % 2 == 0 )))">{d1_.val_} [interop] ✓</DisplayString>
<DisplayString Condition="d1_.cat_->id_ != 0 &amp;&amp;
(lc_flags_ == 2 || (lc_flags_ &gt; 3 &amp;&amp; ( lc_flags_ % 2 == 0 )))">{d1_.val_} [{d1_.cat_->id_,x}] ✓</DisplayString>
<DisplayString Condition=
"lc_flags_ == 2 || (lc_flags_ &gt; 3 &amp;&amp; ( lc_flags_ % 2 == 0 ))">{d1_.val_} @{((uintptr_t)d1_.cat_),x} ✓</DisplayString>
<DisplayString Condition="d1_.cat_->id_ == 0xb2ab117a257edfd0 &amp;&amp;
(lc_flags_ &gt;= 3 &amp;&amp; ( lc_flags_ % 2 == 1 ))">{d1_.val_} [generic]</DisplayString>
<DisplayString Condition="d1_.cat_->id_ == 0xb2ab117a257edfd1 &amp;&amp;
(lc_flags_ &gt;= 3 &amp;&amp; ( lc_flags_ % 2 == 1 ))">{d1_.val_} [system]</DisplayString>
<DisplayString Condition="d1_.cat_->id_ == 0xb2ab117a257edfd2 &amp;&amp;
(lc_flags_ &gt;= 3 &amp;&amp; ( lc_flags_ % 2 == 1 ))">{d1_.val_} [interop]</DisplayString>
<DisplayString Condition="d1_.cat_->id_ != 0 &amp;&amp;
(lc_flags_ &gt;= 3 &amp;&amp; ( lc_flags_ % 2 == 1 ))">{d1_.val_} [{d1_.cat_->id_,x}]</DisplayString>
<DisplayString Condition=
"lc_flags_ &gt;= 3 &amp;&amp; ( lc_flags_ % 2 == 1 )">{d1_.val_} @{((uintptr_t)d1_.cat_),x}</DisplayString>
<Expand>
<Item Name="std::error_code" Condition="lc_flags_ == 1">(std::error_code*)d2_</Item>
<Item Name="[location]" Condition="lc_flags_ &gt; 3">*((boost::source_location*)(lc_flags_ &amp; ~1))</Item>
</Expand>
</Type>
<Type Name="boost::system::result&lt;*,*&gt;">
<DisplayString>{v_}</DisplayString>
</Type>
</AutoVisualizer>

View File

@ -9,10 +9,6 @@
#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
#include <boost/system/result.hpp>
#endif // #ifndef BOOST_SYSTEM_HPP_INCLUDED

View File

@ -1,63 +0,0 @@
// boost/system/cygwin_error.hpp -------------------------------------------//
// Copyright Beman Dawes 2007
// 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
#ifndef BOOST_SYSTEM_CYGWIN_ERROR_HPP
#define BOOST_SYSTEM_CYGWIN_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.
# ifdef __CYGWIN__
#include <boost/system/error_code.hpp>
namespace boost
{
namespace system
{
// To construct an error_code after a API error:
//
// error_code( errno, system_category() )
// User code should use the portable "posix" enums for POSIX errors; this
// allows such code to be portable to non-POSIX systems. For the non-POSIX
// errno values that POSIX-based systems typically provide in addition to
// POSIX values, use the system specific enums below.
namespace cygwin_error
{
enum cygwin_errno
{
no_net = ENONET,
no_package = ENOPKG,
no_share = ENOSHARE
};
} // namespace cygwin_error
template<> struct is_error_code_enum<cygwin_error::cygwin_errno>
{ static const bool value = true; };
namespace cygwin_error
{
inline error_code make_error_code( cygwin_errno e )
{ return error_code( e, system_category() ); }
}
}
}
#endif // __CYGWIN__
#endif // BOOST_SYSTEM_CYGWIN_ERROR_HPP

View File

@ -11,16 +11,16 @@
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
// BOOST_SYSTEM_HAS_SYSTEM_ERROR
#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
// The macro BOOST_SYSTEM_DISABLE_THREADS can be defined on configurations
// that provide <system_error> and <atomic>, but not <mutex>, such as the
// single-threaded libstdc++.
//
// https://github.com/boostorg/system/issues/92
// BOOST_SYSTEM_NOEXCEPT
// Retained for backward compatibility
#define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT
#define BOOST_SYSTEM_NOEXCEPT noexcept
// BOOST_SYSTEM_HAS_CONSTEXPR
@ -58,7 +58,9 @@
// BOOST_SYSTEM_CLANG_6
#if defined(__clang__) && (__clang_major__ < 7 || (defined(__APPLE__) && __clang_major__ < 11))
// Android NDK r18b has Clang 7.0.2 that still needs the workaround
// https://github.com/boostorg/system/issues/100
#if defined(__clang__) && (__clang_major__ < 7 || (defined(__APPLE__) && __clang_major__ < 11) || (defined(__ANDROID__) && __clang_major__ == 7))
# define BOOST_SYSTEM_CLANG_6
#endif

View File

@ -5,28 +5,19 @@
// Distributed under the Boost Software License, Version 1.0
// http://www.boost.org/LICENSE_1_0.txt
#include <type_traits>
namespace boost
{
namespace system
{
namespace detail
{
template<bool C, class T = void> struct enable_if
{
typedef T type;
};
template<class T> struct enable_if<false, T>
{
};
using std::enable_if;
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_ENABLE_IF_HPP_INCLUDED

View File

@ -13,14 +13,12 @@
#include <boost/system/detail/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <string>
#include <functional>
#include <cstddef>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <system_error>
# include <atomic>
#endif
#include <system_error>
#include <atomic>
namespace boost
{
@ -48,7 +46,7 @@ class std_category;
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
#if defined(BOOST_MSVC)
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
#pragma warning(push)
#pragma warning(disable: 4351) // new behavior: elements of array will be default initialized
#endif
@ -63,20 +61,11 @@ private:
friend class error_code;
friend class error_condition;
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
public:
error_category( error_category const & ) = delete;
error_category& operator=( error_category const & ) = delete;
#else
private:
error_category( error_category const & );
error_category& operator=( error_category const & );
#endif
private:
boost::ulong_long_type id_;
@ -89,68 +78,47 @@ private:
void const* stdcat_align_;
};
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
mutable std::atomic< unsigned > sc_init_;
#else
unsigned sc_init_;
#endif
protected:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
~error_category() = default;
#else
// We'd like to make the destructor protected, to make code that deletes
// an error_category* not compile; unfortunately, doing the below makes
// the destructor user-provided and hence breaks use after main, as the
// categories may get destroyed before code that uses them
// ~error_category() {}
#endif
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 ), stdcat_(), sc_init_()
constexpr error_category() noexcept: id_( 0 ), stdcat_(), sc_init_()
{
}
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id ), stdcat_(), sc_init_()
explicit constexpr error_category( boost::ulong_long_type id ) noexcept: id_( id ), stdcat_(), sc_init_()
{
}
public:
virtual const char * name() const BOOST_NOEXCEPT = 0;
virtual const char * name() const noexcept = 0;
virtual error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT;
virtual bool equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT;
virtual bool equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT;
virtual error_condition default_error_condition( int ev ) const noexcept;
virtual bool equivalent( int code, const error_condition & condition ) const noexcept;
virtual bool equivalent( const error_code & code, int condition ) const noexcept;
virtual std::string message( int ev ) const = 0;
virtual char const * message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT;
virtual char const * message( int ev, char * buffer, std::size_t len ) const noexcept;
virtual bool failed( int ev ) const BOOST_NOEXCEPT
virtual bool failed( int ev ) const noexcept
{
return ev != 0;
}
friend BOOST_SYSTEM_CONSTEXPR bool operator==( error_category const & lhs, error_category const & rhs ) BOOST_NOEXCEPT
friend BOOST_SYSTEM_CONSTEXPR bool operator==( error_category const & lhs, error_category const & rhs ) noexcept
{
return rhs.id_ == 0? &lhs == &rhs: lhs.id_ == rhs.id_;
}
friend BOOST_SYSTEM_CONSTEXPR bool operator!=( error_category const & lhs, error_category const & rhs ) BOOST_NOEXCEPT
friend BOOST_SYSTEM_CONSTEXPR bool operator!=( error_category const & lhs, error_category const & rhs ) noexcept
{
return !( lhs == rhs );
}
friend BOOST_SYSTEM_CONSTEXPR bool operator<( error_category const & lhs, error_category const & rhs ) BOOST_NOEXCEPT
friend BOOST_SYSTEM_CONSTEXPR bool operator<( error_category const & lhs, error_category const & rhs ) noexcept
{
if( lhs.id_ < rhs.id_ )
{
@ -170,8 +138,6 @@ public:
return std::less<error_category const *>()( &lhs, &rhs );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
void init_stdcat() const;
# if defined(__SUNPRO_CC) // trailing __global is not supported
@ -179,11 +145,9 @@ public:
# else
operator std::error_category const & () const BOOST_SYMBOL_VISIBLE;
# endif
#endif
};
#if defined(BOOST_MSVC)
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
#pragma warning(pop)
#endif

View File

@ -26,22 +26,22 @@ namespace system
// error_category default implementation
inline error_condition error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT
inline error_condition error_category::default_error_condition( int ev ) const noexcept
{
return error_condition( ev, *this );
}
inline bool error_category::equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT
inline bool error_category::equivalent( int code, const error_condition & condition ) const noexcept
{
return default_error_condition( code ) == condition;
}
inline bool error_category::equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT
inline bool error_category::equivalent( const error_code & code, int condition ) const noexcept
{
return code.equals( condition, *this );
}
inline char const * error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
inline char const * error_category::message( int ev, char * buffer, std::size_t len ) const noexcept
{
if( len == 0 )
{
@ -58,27 +58,7 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
try
#endif
{
std::string m = this->message( ev );
# if defined( BOOST_MSVC )
# pragma warning( push )
# pragma warning( disable: 4996 )
# elif defined(__clang__) && defined(__has_warning)
# pragma clang diagnostic push
# if __has_warning("-Wdeprecated-declarations")
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
# endif
# endif
std::strncpy( buffer, m.c_str(), len - 1 );
buffer[ len-1 ] = 0;
# if defined( BOOST_MSVC )
# pragma warning( pop )
# elif defined(__clang__) && defined(__has_warning)
# pragma clang diagnostic pop
# endif
detail::snprintf( buffer, len, "%s", this->message( ev ).c_str() );
return buffer;
}
#if !defined(BOOST_NO_EXCEPTIONS)
@ -95,10 +75,8 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
// interoperability with std::error_code, std::error_condition
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#include <boost/system/detail/std_category_impl.hpp>
#include <mutex>
#include <boost/system/detail/mutex.hpp>
#include <new>
namespace boost
@ -106,18 +84,6 @@ namespace boost
namespace system
{
namespace detail
{
template<class = void> struct stdcat_mx_holder
{
static std::mutex mx_;
};
template<class T> std::mutex stdcat_mx_holder<T>::mx_;
} // namespace detail
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" );
@ -130,11 +96,17 @@ inline void error_category::init_stdcat() const
#endif
std::lock_guard<std::mutex> lk( boost::system::detail::stdcat_mx_holder<>::mx_ );
// detail::mutex has a constexpr default constructor,
// and therefore guarantees static initialization, on
// everything except VS 2013 (msvc-12.0)
static system::detail::mutex mx_;
system::detail::lock_guard<system::detail::mutex> lk( mx_ );
if( sc_init_.load( std::memory_order_acquire ) == 0 )
{
::new( static_cast<void*>( stdcat_ ) ) boost::system::detail::std_category( this, 0 );
::new( static_cast<void*>( stdcat_ ) ) boost::system::detail::std_category( this, system::detail::id_wrapper<0>() );
sc_init_.store( 1, std::memory_order_release );
}
}
@ -151,7 +123,7 @@ inline BOOST_NOINLINE error_category::operator std::error_category const & () co
// 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 );
static const boost::system::detail::std_category generic_instance( this, system::detail::id_wrapper<0x1F4D3>() );
return generic_instance;
#else
@ -166,7 +138,7 @@ inline BOOST_NOINLINE error_category::operator std::error_category const & () co
// 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 );
static const boost::system::detail::std_category system_instance( this, system::detail::id_wrapper<0x1F4D7>() );
return system_instance;
#else
@ -191,6 +163,4 @@ inline BOOST_NOINLINE error_category::operator std::error_category const & () co
} // namespace system
} // namespace boost
#endif // #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CATEGORY_IMPL_HPP_INCLUDED

View File

@ -21,21 +21,15 @@
#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/system/detail/std_category.hpp>
#include <boost/assert/source_location.hpp>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <ostream>
#include <new>
#include <cstdio>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <system_error>
#endif
#include <system_error>
#if defined(BOOST_GCC) && BOOST_GCC >= 40600 && BOOST_GCC < 70000
# pragma GCC diagnostic push
@ -57,12 +51,14 @@ namespace system
// and error_code containing a pointer to an object of a type derived
// from error_category.
bool operator==( const error_code & code, const error_condition & condition ) noexcept;
std::size_t hash_value( error_code const & ec );
class error_code
{
private:
friend bool operator==( const error_code & code, const error_condition & condition ) noexcept;
friend std::size_t hash_value( error_code const & ec );
private:
@ -76,9 +72,7 @@ private:
union
{
data d1_;
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
unsigned char d2_[ sizeof(std::error_code) ];
#endif
};
// 0: default constructed, d1_ value initialized
@ -90,7 +84,7 @@ private:
private:
char const* category_name() const BOOST_NOEXCEPT
char const* category_name() const noexcept
{
// return category().name();
@ -114,19 +108,19 @@ public:
// constructors:
BOOST_SYSTEM_CONSTEXPR error_code() BOOST_NOEXCEPT:
constexpr error_code() noexcept:
d1_(), lc_flags_( 0 )
{
}
BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_NOEXCEPT:
BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) noexcept:
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:
error_code( int val, const error_category & cat, source_location const * loc ) noexcept:
d1_(), lc_flags_( ( loc? reinterpret_cast<boost::uintptr_t>( loc ): 2 ) | +detail::failed_impl( val, cat ) )
{
d1_.val_ = val;
@ -136,15 +130,13 @@ public:
template<class ErrorCodeEnum> BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e,
typename detail::enable_if<
is_error_code_enum<ErrorCodeEnum>::value
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|| std::is_error_code_enum<ErrorCodeEnum>::value
#endif
>::type* = 0 ) BOOST_NOEXCEPT: d1_(), lc_flags_( 0 )
>::type* = 0 ) noexcept: d1_(), lc_flags_( 0 )
{
*this = make_error_code( e );
}
error_code( error_code const& ec, source_location const * loc ) BOOST_NOEXCEPT:
error_code( error_code const& ec, source_location const * loc ) noexcept:
d1_(), lc_flags_( 0 )
{
*this = ec;
@ -155,9 +147,7 @@ public:
}
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
error_code( std::error_code const& ec ) BOOST_NOEXCEPT:
error_code( std::error_code const& ec ) noexcept:
d1_(), lc_flags_( 0 )
{
#ifndef BOOST_NO_RTTI
@ -175,41 +165,39 @@ public:
}
}
#endif
// modifiers:
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) noexcept
{
*this = error_code( val, cat );
}
void assign( int val, const error_category & cat, source_location const * loc ) BOOST_NOEXCEPT
void assign( int val, const error_category & cat, source_location const * loc ) noexcept
{
*this = error_code( val, cat, loc );
}
void assign( error_code const& ec, source_location const * loc ) BOOST_NOEXCEPT
void assign( error_code const& ec, source_location const * loc ) 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
operator=( ErrorCodeEnum val ) noexcept
{
*this = make_error_code( val );
return *this;
}
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR void clear() noexcept
{
*this = error_code();
}
// observers:
BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR int value() const noexcept
{
if( lc_flags_ != 1 )
{
@ -217,22 +205,16 @@ public:
}
else
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
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;
#endif
}
}
BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR const error_category & category() const noexcept
{
if( lc_flags_ == 0 )
{
@ -249,24 +231,19 @@ public:
}
// deprecated?
error_condition default_error_condition() const BOOST_NOEXCEPT
error_condition default_error_condition() const noexcept
{
return category().default_error_condition( value() );
}
std::string message() const
{
#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.message();
}
#endif
if( lc_flags_ == 0 )
else if( lc_flags_ == 0 )
{
return detail::system_error_category_message( value() );
}
@ -276,9 +253,8 @@ public:
}
}
char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
char const * message( char * buffer, std::size_t len ) const noexcept
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( lc_flags_ == 1 )
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
@ -298,9 +274,7 @@ public:
}
#endif
}
#endif
if( lc_flags_ == 0 )
else if( lc_flags_ == 0 )
{
return detail::system_error_category_message( value(), buffer, len );
}
@ -310,17 +284,16 @@ public:
}
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR bool failed() const noexcept
{
if( lc_flags_ & 1 )
{
#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
@ -329,36 +302,17 @@ public:
}
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const noexcept // true if error
{
return failed();
}
#else
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{
return failed()? unspecified_bool_true: 0;
}
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{
return !failed();
}
#endif
bool has_location() const BOOST_NOEXCEPT
bool has_location() const noexcept
{
return lc_flags_ >= 4;
}
source_location const & location() const BOOST_NOEXCEPT
source_location const & location() const 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;
@ -372,7 +326,7 @@ private:
friend class error_category;
BOOST_SYSTEM_CONSTEXPR bool equals( int val, error_category const& cat ) const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR bool equals( int val, error_category const& cat ) const noexcept
{
if( lc_flags_ == 0 )
{
@ -393,11 +347,14 @@ public:
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, const error_code & rhs ) noexcept
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
bool s1 = lhs.lc_flags_ == 1;
bool s2 = rhs.lc_flags_ == 1;
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
if( s1 != s2 ) return false;
if( s1 && s2 )
{
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_ );
@ -405,17 +362,20 @@ public:
return e1 == e2;
}
else
#endif
{
return lhs.value() == rhs.value() && lhs.category() == rhs.category();
}
}
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_code & lhs, const error_code & rhs ) noexcept
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
bool s1 = lhs.lc_flags_ == 1;
bool s2 = rhs.lc_flags_ == 1;
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
if( s1 < s2 ) return true;
if( s2 < s1 ) return false;
if( s1 && s2 )
{
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_ );
@ -423,77 +383,32 @@ public:
return e1 < e2;
}
else
#endif
{
return lhs.category() < rhs.category() || (lhs.category() == rhs.category() && lhs.value() < rhs.value());
}
}
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_code & lhs, const error_code & rhs ) noexcept
{
return !( lhs == rhs );
}
inline friend bool operator==( const error_code & code, const error_condition & condition ) BOOST_NOEXCEPT
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( code.lc_flags_ == 1 )
{
return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
}
else
#endif
{
return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
}
}
inline friend bool operator==( const error_condition & condition, const error_code & code ) BOOST_NOEXCEPT
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( code.lc_flags_ == 1 )
{
return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
}
else
#endif
{
return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
}
}
inline friend bool operator!=( const error_code & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
inline friend bool operator!=( const error_condition & lhs, const error_code & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
inline friend bool operator==( std::error_code const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator==( std::error_code const & lhs, error_code const & rhs ) noexcept
{
return lhs == static_cast< std::error_code >( rhs );
}
inline friend bool operator==( error_code const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator==( error_code const & lhs, std::error_code const & rhs ) noexcept
{
return static_cast< std::error_code >( lhs ) == rhs;
}
inline friend bool operator!=( std::error_code const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( std::error_code const & lhs, error_code const & rhs ) noexcept
{
return !( lhs == rhs );
}
inline friend bool operator!=( error_code const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( error_code const & lhs, std::error_code const & rhs ) noexcept
{
return !( lhs == rhs );
}
@ -501,25 +416,25 @@ public:
//
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
inline friend bool operator==( error_code const & lhs, E rhs ) BOOST_NOEXCEPT
inline friend bool operator==( error_code const & lhs, E rhs ) noexcept
{
return lhs == make_error_condition( rhs );
}
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
inline friend bool operator==( E lhs, error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator==( E lhs, error_code const & rhs ) noexcept
{
return make_error_condition( lhs ) == rhs;
}
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
inline friend bool operator!=( error_code const & lhs, E rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( error_code const & lhs, E rhs ) noexcept
{
return !( lhs == rhs );
}
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
inline friend bool operator!=( E lhs, error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( E lhs, error_code const & rhs ) noexcept
{
return !( lhs == rhs );
}
@ -527,47 +442,47 @@ public:
//
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( error_code const & lhs, E rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( error_code const & lhs, E rhs ) noexcept
{
return lhs == make_error_code( rhs );
}
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( E lhs, error_code const & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( E lhs, error_code const & rhs ) noexcept
{
return make_error_code( lhs ) == rhs;
}
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( error_code const & lhs, E rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( error_code const & lhs, E rhs ) noexcept
{
return !( lhs == rhs );
}
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( E lhs, error_code const & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( E lhs, error_code const & rhs ) noexcept
{
return !( lhs == rhs );
}
#if defined(BOOST_SYSTEM_CLANG_6)
inline friend bool operator==( error_code const & lhs, std::error_condition const & rhs ) BOOST_NOEXCEPT
inline friend bool operator==( error_code const & lhs, std::error_condition const & rhs ) noexcept
{
return static_cast< std::error_code >( lhs ) == rhs;
}
inline friend bool operator==( std::error_condition const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator==( std::error_condition const & lhs, error_code const & rhs ) noexcept
{
return lhs == static_cast< std::error_code >( rhs );
}
inline friend bool operator!=( error_code const & lhs, std::error_condition const & rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( error_code const & lhs, std::error_condition const & rhs ) noexcept
{
return !( lhs == rhs );
}
inline friend bool operator!=( std::error_condition const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( std::error_condition const & lhs, error_code const & rhs ) noexcept
{
return !( lhs == rhs );
}
@ -626,14 +541,10 @@ public:
class E = typename std::enable_if<std::is_same<T, std::error_code>::value>::type>
operator T const& () = delete;
#endif
#endif
std::string to_string() const
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( lc_flags_ == 1 )
{
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( d2_ );
@ -645,7 +556,6 @@ public:
return r;
}
else
#endif
{
std::string r = category_name();
detail::append_int( r, value() );
@ -678,18 +588,41 @@ public:
}
};
inline bool operator==( const error_code & code, const error_condition & condition ) noexcept
{
if( code.lc_flags_ == 1 )
{
return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
}
else
{
return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
}
}
inline bool operator==( const error_condition & condition, const error_code & code ) noexcept
{
return code == condition;
}
inline bool operator!=( const error_code & lhs, const error_condition & rhs ) noexcept
{
return !( lhs == rhs );
}
inline bool operator!=( const error_condition & lhs, const error_code & rhs ) noexcept
{
return !( lhs == rhs );
}
inline std::size_t hash_value( error_code const & ec )
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
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 );
}
#endif
error_category const & cat = ec.category();
boost::ulong_long_type id_ = cat.id_;

View File

@ -50,7 +50,7 @@ private:
private:
boost::ulong_long_type cat_id() const BOOST_NOEXCEPT
boost::ulong_long_type cat_id() const noexcept
{
return cat_? cat_->id_: detail::generic_category_id;
}
@ -59,17 +59,17 @@ public:
// constructors:
BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT:
BOOST_SYSTEM_CONSTEXPR error_condition() noexcept:
val_( 0 ), cat_( 0 )
{
}
BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT:
BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) noexcept:
val_( val ), cat_( &cat )
{
}
BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) BOOST_NOEXCEPT:
BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) noexcept:
val_( vt.value ), cat_( 0 )
{
}
@ -77,20 +77,20 @@ public:
template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e,
typename detail::enable_if<
is_error_condition_enum<ErrorConditionEnum>::value && !boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value
>::type* = 0) BOOST_NOEXCEPT
>::type* = 0) noexcept
{
*this = make_error_condition( e );
}
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:
typename detail::enable_if<boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value>::type* = 0) noexcept:
val_( e ), cat_( 0 )
{
}
// modifiers:
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) noexcept
{
val_ = val;
cat_ = &cat;
@ -98,13 +98,13 @@ public:
template<typename ErrorConditionEnum>
BOOST_SYSTEM_CONSTEXPR typename detail::enable_if<is_error_condition_enum<ErrorConditionEnum>::value, error_condition>::type &
operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT
operator=( ErrorConditionEnum val ) noexcept
{
*this = error_condition( val );
return *this;
}
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR void clear() noexcept
{
val_ = 0;
cat_ = 0;
@ -112,12 +112,12 @@ public:
// observers:
BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR int value() const noexcept
{
return val_;
}
BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR const error_category & category() const noexcept
{
return cat_? *cat_: generic_category();
}
@ -134,7 +134,7 @@ public:
}
}
char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
char const * message( char * buffer, std::size_t len ) const noexcept
{
if( cat_ )
{
@ -146,7 +146,7 @@ public:
}
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR bool failed() const noexcept
{
if( cat_ )
{
@ -158,35 +158,16 @@ public:
}
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const noexcept // true if error
{
return failed();
}
#else
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{
return failed()? unspecified_bool_true: 0;
}
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{
return !failed();
}
#endif
// relationals:
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) noexcept
{
if( lhs.val_ != rhs.val_ )
{
@ -206,20 +187,18 @@ public:
}
}
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) noexcept
{
error_category const& lcat = lhs.category();
error_category const& rcat = rhs.category();
return lcat < rcat || ( lcat == rcat && lhs.val_ < rhs.val_ );
}
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_condition & lhs, const error_condition & rhs ) noexcept
{
return !( lhs == rhs );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
operator std::error_condition () const
{
// This condition must be the same as the one in error_category_impl.hpp
@ -241,27 +220,77 @@ public:
#endif
}
inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT
inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) noexcept
{
return lhs == static_cast< std::error_condition >( rhs );
}
inline friend bool operator==( error_condition const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator==( error_condition const & lhs, std::error_code const & rhs ) noexcept
{
return static_cast< std::error_condition >( lhs ) == rhs;
}
inline friend bool operator!=( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( std::error_code const & lhs, error_condition const & rhs ) noexcept
{
return !( lhs == rhs );
}
inline friend bool operator!=( error_condition const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
inline friend bool operator!=( error_condition const & lhs, std::error_code const & rhs ) noexcept
{
return !( lhs == rhs );
}
#endif
//
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( error_condition const & lhs, E rhs ) noexcept
{
return lhs == make_error_condition( rhs );
}
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( E lhs, error_condition const & rhs ) noexcept
{
return make_error_condition( lhs ) == rhs;
}
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( error_condition const & lhs, E rhs ) noexcept
{
return !( lhs == rhs );
}
template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( E lhs, error_condition const & rhs ) noexcept
{
return !( lhs == rhs );
}
//
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
inline friend bool operator==( error_condition const & lhs, E rhs ) noexcept
{
return lhs == make_error_code( rhs );
}
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
inline friend bool operator==( E lhs, error_condition const & rhs ) noexcept
{
return make_error_code( lhs ) == rhs;
}
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
inline friend bool operator!=( error_condition const & lhs, E rhs ) noexcept
{
return !( lhs == rhs );
}
template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
inline friend bool operator!=( E lhs, error_condition const & rhs ) noexcept
{
return !( lhs == rhs );
}
std::string to_string() const
{

View File

@ -35,18 +35,18 @@ class BOOST_SYMBOL_VISIBLE generic_error_category: public error_category
{
public:
BOOST_SYSTEM_CONSTEXPR generic_error_category() BOOST_NOEXCEPT:
BOOST_SYSTEM_CONSTEXPR generic_error_category() noexcept:
error_category( detail::generic_category_id )
{
}
const char * name() const BOOST_NOEXCEPT BOOST_OVERRIDE
const char * name() const noexcept BOOST_OVERRIDE
{
return "generic";
}
std::string message( int ev ) const BOOST_OVERRIDE;
char const * message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
char const * message( int ev, char * buffer, std::size_t len ) const noexcept BOOST_OVERRIDE;
};
#if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
@ -55,7 +55,7 @@ public:
// generic_error_category::message
inline char const * generic_error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
inline char const * generic_error_category::message( int ev, char * buffer, std::size_t len ) const noexcept
{
return generic_error_category_message( ev, buffer, len );
}
@ -86,7 +86,7 @@ template<class T> constexpr generic_error_category generic_cat_holder<T>::instan
} // namespace detail
constexpr error_category const & generic_category() BOOST_NOEXCEPT
constexpr error_category const & generic_category() noexcept
{
return detail::generic_cat_holder<void>::instance;
}
@ -94,10 +94,10 @@ constexpr error_category const & generic_category() BOOST_NOEXCEPT
#else // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR)
#if !defined(__SUNPRO_CC) // trailing __global is not supported
inline error_category const & generic_category() BOOST_NOEXCEPT BOOST_SYMBOL_VISIBLE;
inline error_category const & generic_category() noexcept BOOST_SYMBOL_VISIBLE;
#endif
inline error_category const & generic_category() BOOST_NOEXCEPT
inline error_category const & generic_category() noexcept
{
static const detail::generic_error_category instance;
return instance;

View File

@ -27,19 +27,31 @@ namespace detail
// glibc has two incompatible strerror_r definitions
inline char const * strerror_r_helper( char const * r, char const * ) BOOST_NOEXCEPT
inline char const * strerror_r_helper( char const * r, char const * ) noexcept
{
return r;
}
inline char const * strerror_r_helper( int r, char const * buffer ) BOOST_NOEXCEPT
inline char const * strerror_r_helper( int r, char const * buffer ) noexcept
{
return r == 0? buffer: "Unknown error";
}
inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) noexcept
{
return strerror_r_helper( strerror_r( ev, buffer, len ), buffer );
if( buffer != nullptr )
{
return strerror_r_helper( strerror_r( ev, buffer, len ), buffer );
}
else
{
// strerror_r requires non-null buffer pointer
char tmp[ 1 ] = {};
char const* r = strerror_r_helper( strerror_r( ev, tmp, 0 ), buffer );
return r == tmp? nullptr: r;
}
}
inline std::string generic_error_category_message( int ev )
@ -68,7 +80,7 @@ inline std::string generic_error_category_message( int ev )
return m? m: "Unknown error";
}
inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) noexcept
{
if( len == 0 )
{

View File

@ -35,25 +35,25 @@ class BOOST_SYMBOL_VISIBLE interop_error_category: public error_category
{
public:
BOOST_SYSTEM_CONSTEXPR interop_error_category() BOOST_NOEXCEPT:
BOOST_SYSTEM_CONSTEXPR interop_error_category() noexcept:
error_category( detail::interop_category_id )
{
}
const char * name() const BOOST_NOEXCEPT BOOST_OVERRIDE
const char * name() const noexcept BOOST_OVERRIDE
{
return "std:unknown";
}
std::string message( int ev ) const BOOST_OVERRIDE;
char const * message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
char const * message( int ev, char * buffer, std::size_t len ) const noexcept BOOST_OVERRIDE;
};
#if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
#pragma GCC diagnostic pop
#endif
inline char const * interop_error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
inline char const * interop_error_category::message( int ev, char * buffer, std::size_t len ) const noexcept
{
detail::snprintf( buffer, len, "Unknown interop error %d", ev );
return buffer;
@ -79,7 +79,7 @@ template<class T> struct BOOST_SYMBOL_VISIBLE interop_cat_holder
template<class T> constexpr interop_error_category interop_cat_holder<T>::instance;
#endif
constexpr error_category const & interop_category() BOOST_NOEXCEPT
constexpr error_category const & interop_category() noexcept
{
return interop_cat_holder<void>::instance;
}
@ -87,10 +87,10 @@ constexpr error_category const & interop_category() BOOST_NOEXCEPT
#else // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR)
#if !defined(__SUNPRO_CC) // trailing __global is not supported
inline error_category const & interop_category() BOOST_NOEXCEPT BOOST_SYMBOL_VISIBLE;
inline error_category const & interop_category() noexcept BOOST_SYMBOL_VISIBLE;
#endif
inline error_category const & interop_category() BOOST_NOEXCEPT
inline error_category const & interop_category() noexcept
{
static const detail::interop_error_category instance;
return instance;

View File

@ -5,29 +5,19 @@
// Distributed under the Boost Software License, Version 1.0
// http://www.boost.org/LICENSE_1_0.txt
#include <type_traits>
namespace boost
{
namespace system
{
namespace detail
{
template<class T1, class T2> struct is_same
{
enum _vt { value = 0 };
};
template<class T> struct is_same<T, T>
{
enum _vt { value = 1 };
};
using std::is_same;
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_IS_SAME_HPP_INCLUDED

View File

@ -0,0 +1,128 @@
#ifndef BOOST_SYSTEM_DETAIL_MUTEX_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_MUTEX_HPP_INCLUDED
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined(BOOST_SYSTEM_DISABLE_THREADS)
namespace boost
{
namespace system
{
namespace detail
{
struct mutex
{
void lock()
{
}
void unlock()
{
}
};
} // namespace detail
} // namespace system
} // namespace boost
#else // defined(BOOST_SYSTEM_DISABLE_THREADS)
#if defined(BOOST_MSSTL_VERSION) && BOOST_MSSTL_VERSION >= 140
// Under the MS STL, std::mutex::mutex() is not constexpr, as is
// required by the standard, which leads to initialization order
// issues. However, shared_mutex is based on SRWLock and its
// default constructor is constexpr, so we use that instead.
#include <boost/winapi/config.hpp>
// SRWLOCK is not available when targeting Windows XP
#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
#include <shared_mutex>
#if BOOST_MSSTL_VERSION >= 142 || _HAS_SHARED_MUTEX
# define BOOST_SYSTEM_HAS_MSSTL_SHARED_MUTEX
#endif
#endif // BOOST_MSSTL_VERSION >= 142 || _HAS_SHARED_MUTEX
#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
#if defined(BOOST_SYSTEM_HAS_MSSTL_SHARED_MUTEX)
namespace boost
{
namespace system
{
namespace detail
{
typedef std::shared_mutex mutex;
} // namespace detail
} // namespace system
} // namespace boost
#else // defined(BOOST_SYSTEM_HAS_MSSTL_SHARED_MUTEX)
#include <mutex>
namespace boost
{
namespace system
{
namespace detail
{
using std::mutex;
} // namespace detail
} // namespace system
} // namespace boost
#endif // defined(BOOST_SYSTEM_HAS_MSSTL_SHARED_MUTEX)
#endif // defined(BOOST_SYSTEM_DISABLE_THREADS)
namespace boost
{
namespace system
{
namespace detail
{
template<class Mtx> class lock_guard
{
private:
Mtx& mtx_;
private:
lock_guard( lock_guard const& );
lock_guard& operator=( lock_guard const& );
public:
explicit lock_guard( Mtx& mtx ): mtx_( mtx )
{
mtx_.lock();
}
~lock_guard()
{
mtx_.unlock();
}
};
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_MUTEX_HPP_INCLUDED

View File

@ -8,66 +8,21 @@
//
// See library home page at http://www.boost.org/libs/system
#include <boost/config.hpp>
#include <cstdio>
#include <cstdarg>
//
namespace boost
{
namespace system
{
namespace detail
{
#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
inline void snprintf( char * buffer, std::size_t len, char const * format, ... )
{
# if defined( BOOST_MSVC )
# pragma warning( push )
# pragma warning( disable: 4996 )
# endif
if( len == 0 ) return;
va_list args;
va_start( args, format );
_vsnprintf( buffer, len - 1, format, args );
buffer[ len - 1 ] = 0;
va_end( args );
# if defined( BOOST_MSVC )
# pragma warning( pop )
# endif
}
#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;
va_start( args, format );
std::vsnprintf( buffer, len, format, args );
va_end( args );
}
#endif
using std::snprintf;
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_SNPRINTF_HPP_INCLUDED

View File

@ -11,6 +11,7 @@
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/error_category.hpp>
#include <boost/config.hpp>
#include <system_error>
//
@ -24,6 +25,8 @@ namespace system
namespace detail
{
template<unsigned Id> struct id_wrapper {};
class BOOST_SYMBOL_VISIBLE std_category: public std::error_category
{
private:
@ -32,30 +35,28 @@ private:
public:
boost::system::error_category const & original_category() const BOOST_NOEXCEPT
boost::system::error_category const & original_category() const noexcept
{
return *pc_;
}
public:
explicit std_category( boost::system::error_category const * pc, unsigned id ): pc_( pc )
template<unsigned Id>
explicit std_category( boost::system::error_category const * pc, id_wrapper<Id> ): pc_( pc )
{
if( id != 0 )
{
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
// Poking into the protected _Addr member of std::error_category
// is not a particularly good programming practice, but what can
// you do
// We used to assign to the protected _Addr member of std::error_category
// here when Id != 0, but this should never happen now because this code
// path is no longer used
_Addr = id;
static_assert( Id == 0, "This constructor should only be called with Id == 0 under MS STL 14.0+" );
#endif
}
}
const char * name() const BOOST_NOEXCEPT BOOST_OVERRIDE
const char * name() const noexcept BOOST_OVERRIDE
{
return pc_->name();
}
@ -65,13 +66,13 @@ public:
return pc_->message( ev );
}
std::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT BOOST_OVERRIDE
std::error_condition default_error_condition( int ev ) const noexcept BOOST_OVERRIDE
{
return pc_->default_error_condition( ev );
}
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 equivalent( int code, const std::error_condition & condition ) const noexcept BOOST_OVERRIDE;
inline bool equivalent( const std::error_code & code, int condition ) const noexcept BOOST_OVERRIDE;
};
} // namespace detail

View File

@ -26,7 +26,7 @@ namespace system
namespace detail
{
inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT
inline bool std_category::equivalent( int code, const std::error_condition & condition ) const noexcept
{
if( condition.category() == *this )
{
@ -55,7 +55,7 @@ inline bool std_category::equivalent( int code, const std::error_condition & con
}
}
inline bool std_category::equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT
inline bool std_category::equivalent( const std::error_code & code, int condition ) const noexcept
{
if( code.category() == *this )
{

View File

@ -34,20 +34,20 @@ class BOOST_SYMBOL_VISIBLE system_error_category: public error_category
{
public:
BOOST_SYSTEM_CONSTEXPR system_error_category() BOOST_NOEXCEPT:
BOOST_SYSTEM_CONSTEXPR system_error_category() noexcept:
error_category( detail::system_category_id )
{
}
const char * name() const BOOST_NOEXCEPT BOOST_OVERRIDE
const char * name() const noexcept BOOST_OVERRIDE
{
return "system";
}
error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
error_condition default_error_condition( int ev ) const noexcept BOOST_OVERRIDE;
std::string message( int ev ) const BOOST_OVERRIDE;
char const * message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
char const * message( int ev, char * buffer, std::size_t len ) const noexcept BOOST_OVERRIDE;
};
#if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
@ -75,7 +75,7 @@ template<class T> constexpr system_error_category system_cat_holder<T>::instance
} // namespace detail
constexpr error_category const & system_category() BOOST_NOEXCEPT
constexpr error_category const & system_category() noexcept
{
return detail::system_cat_holder<void>::instance;
}
@ -83,10 +83,10 @@ constexpr error_category const & system_category() BOOST_NOEXCEPT
#else // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR)
#if !defined(__SUNPRO_CC) // trailing __global is not supported
inline error_category const & system_category() BOOST_NOEXCEPT BOOST_SYMBOL_VISIBLE;
inline error_category const & system_category() noexcept BOOST_SYMBOL_VISIBLE;
#endif
inline error_category const & system_category() BOOST_NOEXCEPT
inline error_category const & system_category() noexcept
{
static const detail::system_error_category instance;
return instance;

View File

@ -25,7 +25,7 @@ namespace system
namespace detail
{
inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
inline int system_category_condition_win32( int ev ) noexcept
{
// When using the Windows Runtime, most system errors are reported as HRESULTs.
// We want to map the common Win32 errors to their equivalent error condition,
@ -59,6 +59,7 @@ 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_NET_NAME_: 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;
@ -75,6 +76,7 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_DIR_NOT_EMPTY_: return directory_not_empty;
case ERROR_DIRECTORY_: return invalid_argument; // WinError.h: "The directory name is invalid"
case ERROR_DISK_FULL_: return no_space_on_device;
case ERROR_FILENAME_EXCED_RANGE_: return filename_too_long;
case ERROR_FILE_EXISTS_: return file_exists;
case ERROR_FILE_NOT_FOUND_: return no_such_file_or_directory;
case ERROR_HANDLE_DISK_FULL_: return no_space_on_device;
@ -100,12 +102,16 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_REPARSE_TAG_INVALID_: return invalid_argument;
case ERROR_RETRY_: return resource_unavailable_try_again;
case ERROR_SEEK_: return io_error;
case ERROR_SEM_TIMEOUT_: return timed_out;
case ERROR_SHARING_VIOLATION_: return permission_denied;
case ERROR_NOT_SUPPORTED_: return not_supported; // WinError.h: "The request is not supported."
case ERROR_TIMEOUT_: return timed_out;
case ERROR_TOO_MANY_OPEN_FILES_: return too_many_files_open;
case ERROR_WRITE_FAULT_: return io_error;
case ERROR_WRITE_PROTECT_: return permission_denied;
case 258: return timed_out; // WAIT_TIMEOUT
case WSAEACCES_: return permission_denied;
case WSAEADDRINUSE_: return address_in_use;
case WSAEADDRNOTAVAIL_: return address_not_available;

View File

@ -25,7 +25,7 @@
#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
inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const noexcept
{
int e2 = system_category_condition_win32( ev );
@ -41,7 +41,7 @@ inline boost::system::error_condition boost::system::detail::system_error_catego
#else // #if defined(BOOST_WINDOWS_API)
inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT
inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const noexcept
{
return error_condition( boost::system::detail::generic_value_tag( ev ) );
}
@ -53,7 +53,7 @@ inline std::string boost::system::detail::system_error_category::message( int 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
inline char const * boost::system::detail::system_error_category::message( int ev, char * buffer, std::size_t len ) const noexcept
{
return system_error_category_message( ev, buffer, len );
}

View File

@ -32,7 +32,7 @@ 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
inline char const * system_error_category_message( int ev, char * buffer, std::size_t len ) noexcept
{
return system_category_message_win32( ev, buffer, len );
}
@ -57,7 +57,7 @@ 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
inline char const * system_error_category_message( int ev, char * buffer, std::size_t len ) noexcept
{
return generic_error_category_message( ev, buffer, len );
}

View File

@ -47,7 +47,7 @@ inline boost::winapi::UINT_ message_cp_win32()
#endif
}
inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) noexcept
{
if( len == 0 )
{

View File

@ -31,19 +31,19 @@ namespace errc
{
// explicit conversion:
BOOST_SYSTEM_CONSTEXPR inline error_code make_error_code( errc_t e ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline error_code make_error_code( errc_t e ) noexcept
{
return error_code( e, generic_category() );
}
// explicit conversion:
inline error_code make_error_code( errc_t e, boost::source_location const * loc ) BOOST_NOEXCEPT
inline error_code make_error_code( errc_t e, boost::source_location const * loc ) noexcept
{
return error_code( e, generic_category(), loc );
}
// implicit conversion:
BOOST_SYSTEM_CONSTEXPR inline error_condition make_error_condition( errc_t e ) BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR inline error_condition make_error_condition( errc_t e ) noexcept
{
return error_condition( e, generic_category() );
}

View File

@ -73,10 +73,10 @@ BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( std::excep
// in_place_*
using in_place_value_t = variant2::in_place_index_t<0>;
constexpr in_place_value_t in_place_value{};
BOOST_INLINE_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{};
BOOST_INLINE_CONSTEXPR in_place_error_t in_place_error{};
namespace detail
{
@ -85,6 +85,10 @@ template<class T> using remove_cvref = typename std::remove_cv< typename std::re
template<class... T> using is_errc_t = std::is_same<mp11::mp_list<remove_cvref<T>...>, mp11::mp_list<errc::errc_t>>;
template<class T, class... A> struct is_constructible: std::is_constructible<T, A...> {};
template<class A> struct is_constructible<bool, A>: std::is_convertible<A, bool> {};
template<class A> struct is_constructible<bool const, A>: std::is_convertible<A, bool> {};
} // namespace detail
// result
@ -95,6 +99,14 @@ private:
variant2::variant<T, E> v_;
public:
using value_type = T;
using error_type = E;
static constexpr in_place_value_t in_place_value{};
static constexpr in_place_error_t in_place_error{};
public:
// constructors
@ -114,7 +126,7 @@ public:
template<class A = T, typename std::enable_if<
std::is_convertible<A, T>::value &&
!(detail::is_errc_t<A>::value && std::is_arithmetic<T>::value) &&
!std::is_constructible<E, A>::value, int>::type = 0>
!std::is_convertible<A, E>::value, int>::type = 0>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<T, A>::value )
: v_( in_place_value, std::forward<A>(a) )
@ -124,7 +136,7 @@ public:
// implicit, error
template<class A = E, class = void, typename std::enable_if<
std::is_convertible<A, E>::value &&
!std::is_constructible<T, A>::value, int>::type = 0>
!std::is_convertible<A, T>::value, int>::type = 0>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
@ -133,9 +145,10 @@ public:
// explicit, value
template<class... A, class En = typename std::enable_if<
std::is_constructible<T, A...>::value &&
detail::is_constructible<T, A...>::value &&
!(detail::is_errc_t<A...>::value && std::is_arithmetic<T>::value) &&
!std::is_constructible<E, A...>::value
!detail::is_constructible<E, A...>::value &&
sizeof...(A) >= 1
>::type>
explicit constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<T, A...>::value )
@ -145,8 +158,9 @@ public:
// explicit, error
template<class... A, class En2 = void, class En = typename std::enable_if<
!std::is_constructible<T, A...>::value &&
std::is_constructible<E, A...>::value
!detail::is_constructible<T, A...>::value &&
detail::is_constructible<E, A...>::value &&
sizeof...(A) >= 1
>::type>
explicit constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
@ -177,7 +191,8 @@ public:
// converting
template<class T2, class E2, class En = typename std::enable_if<
std::is_convertible<T2, T>::value &&
std::is_convertible<E2, E>::value
std::is_convertible<E2, E>::value &&
!std::is_convertible<result<T2, E2> const&, T>::value
>::type>
BOOST_CXX14_CONSTEXPR result( result<T2, E2> const& r2 )
noexcept(
@ -195,7 +210,8 @@ public:
template<class T2, class E2, class En = typename std::enable_if<
std::is_convertible<T2, T>::value &&
std::is_convertible<E2, E>::value
std::is_convertible<E2, E>::value &&
!std::is_convertible<result<T2, E2>&&, T>::value
>::type>
BOOST_CXX14_CONSTEXPR result( result<T2, E2>&& r2 )
noexcept(
@ -220,7 +236,7 @@ public:
constexpr bool has_error() const noexcept
{
return v_.index() != 0;
return v_.index() == 1;
}
constexpr explicit operator bool() const noexcept
@ -385,12 +401,26 @@ public:
// error access
constexpr E error() const
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();
}
BOOST_CXX14_CONSTEXPR E error() &&
noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value )
{
return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E();
}
// emplace
template<class... A>
BOOST_CXX14_CONSTEXPR T& emplace( A&&... a )
{
return v_.template emplace<0>( std::forward<A>(a)... );
}
// swap
BOOST_CXX14_CONSTEXPR void swap( result& r )
@ -420,6 +450,13 @@ public:
}
};
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
template<class T, class E> constexpr in_place_value_t result<T, E>::in_place_value;
template<class T, class E> constexpr in_place_error_t result<T, E>::in_place_error;
#endif
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() )
@ -442,6 +479,14 @@ private:
variant2::variant<variant2::monostate, E> v_;
public:
using value_type = void;
using error_type = E;
static constexpr in_place_value_t in_place_value{};
static constexpr in_place_error_t in_place_error{};
public:
// constructors
@ -500,6 +545,23 @@ public:
{
}
// converting
template<class E2, class En = typename std::enable_if<
std::is_convertible<E2, E>::value
>::type>
BOOST_CXX14_CONSTEXPR result( result<void, E2> const& r2 )
noexcept(
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 )
{
this->emplace();
}
}
// queries
constexpr bool has_value() const noexcept
@ -509,7 +571,7 @@ public:
constexpr bool has_error() const noexcept
{
return v_.index() != 0;
return v_.index() == 1;
}
constexpr explicit operator bool() const noexcept
@ -549,12 +611,25 @@ public:
// error access
constexpr E error() const
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();
}
BOOST_CXX14_CONSTEXPR E error() &&
noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value )
{
return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E();
}
// emplace
BOOST_CXX14_CONSTEXPR void emplace()
{
v_.template emplace<0>();
}
// swap
BOOST_CXX14_CONSTEXPR void swap( result& r )
@ -584,6 +659,13 @@ public:
}
};
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
template<class E> constexpr in_place_value_t result<void, E>::in_place_value;
template<class E> constexpr in_place_error_t result<void, E>::in_place_error;
#endif
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() )
@ -598,6 +680,670 @@ template<class Ch, class Tr, class E> std::basic_ostream<Ch, Tr>& operator<<( st
return os;
}
// result<T&, E>
namespace detail
{
template<class U, class A> struct reference_to_temporary: std::integral_constant<bool,
!std::is_reference<A>::value ||
!std::is_convertible<typename std::remove_reference<A>::type*, U*>::value
> {};
} // namespace detail
template<class U, class E> class result<U&, E>
{
private:
variant2::variant<U*, E> v_;
public:
using value_type = U&;
using error_type = E;
static constexpr in_place_value_t in_place_value{};
static constexpr in_place_error_t in_place_error{};
public:
// constructors
// implicit, value
template<class A, typename std::enable_if<
std::is_convertible<A, U&>::value &&
!detail::reference_to_temporary<U, A>::value &&
!std::is_convertible<A, E>::value, int>::type = 0>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<U&, A>::value )
: v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) )
{
}
// implicit, error
template<class A = E, class = void, typename std::enable_if<
std::is_convertible<A, E>::value &&
!std::is_convertible<A, U&>::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<
detail::is_constructible<U&, A>::value &&
!std::is_convertible<A, U&>::value &&
!detail::reference_to_temporary<U, A>::value &&
!detail::is_constructible<E, A>::value
>::type>
explicit constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<U&, A>::value )
: v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) )
{
}
// explicit, error
template<class... A, class En2 = void, class En = typename std::enable_if<
!detail::is_constructible<U&, A...>::value &&
detail::is_constructible<E, A...>::value &&
sizeof...(A) >= 1
>::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<U&, A>::value &&
!detail::reference_to_temporary<U, A>::value
>::type>
constexpr result( in_place_value_t, A&& a )
noexcept( std::is_nothrow_constructible<U&, A>::value )
: v_( in_place_value, &static_cast<U&>( 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 U2, class E2, class En = typename std::enable_if<
std::is_convertible<U2&, U&>::value &&
!detail::reference_to_temporary<U, U2&>::value &&
std::is_convertible<E2, E>::value &&
!std::is_convertible<result<U2&, E2> const&, U&>::value
>::type>
BOOST_CXX14_CONSTEXPR result( result<U2&, E2> const& r2 )
noexcept(
std::is_nothrow_constructible<U&, U2&>::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 )
{
this->emplace( *r2 );
}
}
// queries
constexpr bool has_value() const noexcept
{
return v_.index() == 0;
}
constexpr bool has_error() const noexcept
{
return v_.index() == 1;
}
constexpr explicit operator bool() const noexcept
{
return v_.index() == 0;
}
// checked value access
BOOST_CXX14_CONSTEXPR U& 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 );
}
}
// unchecked value access
BOOST_CXX14_CONSTEXPR U* operator->() const noexcept
{
return has_value()? variant2::unsafe_get<0>( v_ ): 0;
}
BOOST_CXX14_CONSTEXPR U& operator*() const noexcept
{
U* p = operator->();
BOOST_ASSERT( p != 0 );
return *p;
}
// 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();
}
BOOST_CXX14_CONSTEXPR E error() &&
noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value )
{
return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E();
}
// emplace
template<class A, class En = typename std::enable_if<
detail::is_constructible<U&, A>::value &&
!detail::reference_to_temporary<U, A>::value
>::type>
BOOST_CXX14_CONSTEXPR U& emplace( A&& a )
{
return *v_.template emplace<0>( &static_cast<U&>( a ) );
}
// 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 && r2? *r1 == *r2: r1.v_ == r2.v_ ) )
{
return r1 && r2? *r1 == *r2: r1.v_ == r2.v_;
}
friend constexpr bool operator!=( result const & r1, result const & r2 )
noexcept( noexcept( !( r1 == r2 ) ) )
{
return !( r1 == r2 );
}
};
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
template<class U, class E> constexpr in_place_value_t result<U&, E>::in_place_value;
template<class U, class E> constexpr in_place_error_t result<U&, E>::in_place_error;
#endif
// operator|
namespace detail
{
// is_value_convertible_to
template<class T, class U> struct is_value_convertible_to: std::is_convertible<T, U>
{
};
template<class T, class U> struct is_value_convertible_to<T, U&>:
std::integral_constant<bool,
std::is_lvalue_reference<T>::value &&
std::is_convertible<typename std::remove_reference<T>::type*, U*>::value>
{
};
// is_result
template<class T> struct is_result: std::false_type {};
template<class T, class E> struct is_result< result<T, E> >: std::true_type {};
} // namespace detail
// result | value
template<class T, class E, class U,
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
>
T operator|( result<T, E> const& r, U&& u )
{
if( r )
{
return *r;
}
else
{
return std::forward<U>( u );
}
}
template<class T, class E, class U,
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
>
T operator|( result<T, E>&& r, U&& u )
{
if( r )
{
return *std::move( r );
}
else
{
return std::forward<U>( u );
}
}
// result | nullary-returning-value
template<class T, class E, class F,
class U = decltype( std::declval<F>()() ),
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
>
T operator|( result<T, E> const& r, F&& f )
{
if( r )
{
return *r;
}
else
{
return std::forward<F>( f )();
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()() ),
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
>
T operator|( result<T, E>&& r, F&& f )
{
if( r )
{
return *std::move( r );
}
else
{
return std::forward<F>( f )();
}
}
// result | nullary-returning-result
template<class T, class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type
>
U operator|( result<T, E> const& r, F&& f )
{
if( r )
{
return *r;
}
else
{
return std::forward<F>( f )();
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type
>
U operator|( result<T, E>&& r, F&& f )
{
if( r )
{
return *std::move( r );
}
else
{
return std::forward<F>( f )();
}
}
template<class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type
>
U operator|( result<void, E> const& r, F&& f )
{
if( r )
{
return {};
}
else
{
return std::forward<F>( f )();
}
}
template<class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type
>
U operator|( result<void, E>&& r, F&& f )
{
if( r )
{
return {};
}
else
{
return std::forward<F>( f )();
}
}
// operator|=
// result |= value
template<class T, class E, class U,
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
>
result<T, E>& operator|=( result<T, E>& r, U&& u )
{
if( !r )
{
r = std::forward<U>( u );
}
return r;
}
// result |= nullary-returning-value
template<class T, class E, class F,
class U = decltype( std::declval<F>()() ),
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
>
result<T, E>& operator|=( result<T, E>& r, F&& f )
{
if( !r )
{
r = std::forward<F>( f )();
}
return r;
}
// result |= nullary-returning-result
template<class T, class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<detail::is_value_convertible_to<typename U::value_type, T>::value>::type,
class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type
>
result<T, E>& operator|=( result<T, E>& r, F&& f )
{
if( !r )
{
r = std::forward<F>( f )();
}
return r;
}
// operator&
// result & unary-returning-value
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T const&>() ) ),
class En1 = typename std::enable_if<!detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<!std::is_void<U>::value>::type
>
result<U, E> operator&( result<T, E> const& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
return std::forward<F>( f )( *r );
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
class En1 = typename std::enable_if<!detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<!std::is_void<U>::value>::type
>
result<U, E> operator&( result<T, E>&& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
return std::forward<F>( f )( *std::move( r ) );
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T const&>() ) ),
class En = typename std::enable_if<std::is_void<U>::value>::type
>
result<U, E> operator&( result<T, E> const& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
std::forward<F>( f )( *r );
return {};
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
class En = typename std::enable_if<std::is_void<U>::value>::type
>
result<U, E> operator&( result<T, E>&& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
std::forward<F>( f )( *std::move( r ) );
return {};
}
}
template<class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<!detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<!std::is_void<U>::value>::type
>
result<U, E> operator&( result<void, E> const& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
return std::forward<F>( f )();
}
}
template<class E, class F,
class U = decltype( std::declval<F>()() ),
class En = typename std::enable_if<std::is_void<U>::value>::type
>
result<U, E> operator&( result<void, E> const& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
std::forward<F>( f )();
return {};
}
}
// result & unary-returning-result
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T const&>() ) ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type
>
U operator&( result<T, E> const& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
return std::forward<F>( f )( *r );
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type
>
U operator&( result<T, E>&& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
return std::forward<F>( f )( *std::move( r ) );
}
}
template<class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type
>
U operator&( result<void, E> const& r, F&& f )
{
if( r.has_error() )
{
return r.error();
}
else
{
return std::forward<F>( f )();
}
}
// operator&=
// result &= unary-returning-value
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
class En1 = typename std::enable_if<!detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
>
result<T, E>& operator&=( result<T, E>& r, F&& f )
{
if( r )
{
r = std::forward<F>( f )( *std::move( r ) );
}
return r;
}
template<class E, class F,
class U = decltype( std::declval<F>()() ),
class En = typename std::enable_if<!detail::is_result<U>::value>::type
>
result<void, E>& operator&=( result<void, E>& r, F&& f )
{
if( r )
{
std::forward<F>( f )();
}
return r;
}
// result &= unary-returning-result
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<detail::is_value_convertible_to<typename U::value_type, T>::value>::type,
class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type
>
result<T, E>& operator&=( result<T, E>& r, F&& f )
{
if( r )
{
r = std::forward<F>( f )( *std::move( r ) );
}
return r;
}
template<class E, class F,
class U = decltype( std::declval<F>()() ),
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type,
class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type
>
result<void, E>& operator&=( result<void, E>& r, F&& f )
{
if( r )
{
r = std::forward<F>( f )();
}
return r;
}
} // namespace system
} // namespace boost

View File

@ -43,7 +43,7 @@ public:
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
error_code code() const noexcept
{
return code_;
}

View File

@ -13,5 +13,5 @@
"Error-handling",
"Programming"
],
"cxxstd": "03"
"cxxstd": "11"
}

View File

@ -15,6 +15,7 @@ macro(system_run s1)
boost_test(SOURCES ${s1} ${ARGN})
boost_test(SOURCES ${s1} ${ARGN} COMPILE_DEFINITIONS BOOST_NO_ANSI_APIS NAME ${n1}_no_ansi)
boost_test(SOURCES ${s1} ${ARGN} COMPILE_DEFINITIONS BOOST_SYSTEM_USE_UTF8 NAME ${n1}_utf8)
boost_test(SOURCES ${s1} ${ARGN} COMPILE_DEFINITIONS BOOST_SYSTEM_DISABLE_THREADS NAME ${n1}_nthr)
endmacro()
@ -83,7 +84,6 @@ boost_test(TYPE run SOURCES system_category_test2.cpp)
boost_test(TYPE run SOURCES system_category_test3.cpp)
boost_test(TYPE run SOURCES windows_error_test.cpp)
boost_test(TYPE run SOURCES cygwin_error_test.cpp)
boost_test(TYPE run SOURCES linux_error_test.cpp)
boost_test(TYPE link SOURCES errc_test3.cpp)
@ -124,9 +124,18 @@ 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
boost_test(TYPE compile SOURCES constexpr_test2.cpp)
set(BOOST_TEST_COMPILE_FEATURES cxx_std_11)
boost_test(TYPE run SOURCES error_code_test3.cpp)
boost_test(TYPE run SOURCES std_interop_test15.cpp)
boost_test(TYPE run SOURCES win32_generic_test.cpp)
boost_test(TYPE run SOURCES ec_hash_value_test.cpp)
boost_test(TYPE run SOURCES std_interop_test16.cpp)
# result
boost_test(TYPE run SOURCES result_default_construct.cpp)
boost_test(TYPE run SOURCES result_value_construct.cpp)
@ -142,4 +151,29 @@ boost_test(TYPE run SOURCES result_eq.cpp)
boost_test(TYPE run SOURCES result_range_for.cpp)
boost_test(TYPE run SOURCES result_value_construct2.cpp)
boost_test(TYPE run SOURCES result_error_construct2.cpp)
boost_test(TYPE run SOURCES result_errc_construct.cpp)
boost_test(TYPE run SOURCES result_convert_construct.cpp)
boost_test(TYPE run SOURCES result_typedefs.cpp)
boost_test(TYPE run SOURCES result_value_construct3.cpp)
boost_test(TYPE run SOURCES result_error_construct3.cpp)
boost_test(TYPE run SOURCES result_emplace.cpp)
boost_test(TYPE run SOURCES result_error_construct4.cpp)
boost_test(TYPE run SOURCES result_value_construct4.cpp)
boost_test(TYPE run SOURCES result_value_construct5.cpp)
boost_test(TYPE run SOURCES result_error_move.cpp)
boost_test(TYPE run SOURCES result_value_construct6.cpp)
boost_test(TYPE run SOURCES result_value_construct7.cpp)
boost_test(TYPE run SOURCES result_error_construct5.cpp)
boost_test(TYPE run SOURCES result_or_value.cpp)
boost_test(TYPE compile-fail SOURCES result_or_value_fail.cpp)
boost_test(TYPE compile-fail SOURCES result_or_value_fail2.cpp)
boost_test(TYPE run SOURCES result_or_fn0v.cpp)
boost_test(TYPE run SOURCES result_or_fn0r.cpp)
boost_test(TYPE run SOURCES result_and_fn1v.cpp)
boost_test(TYPE run SOURCES result_and_fn1r.cpp)
boost_test(TYPE run SOURCES result_and_eq_fn1v.cpp)
boost_test(TYPE run SOURCES result_and_eq_fn1r.cpp)
boost_test(TYPE run SOURCES result_in_place_use.cpp)
boost_test(TYPE run SOURCES result_or_eq_value.cpp)
boost_test(TYPE run SOURCES result_or_eq_fn0v.cpp)
boost_test(TYPE run SOURCES result_or_eq_fn0r.cpp)

View File

@ -33,6 +33,7 @@ rule system-run ( sources + )
result += [ run $(sources) : : : <library>/boost/system//boost_system <link>shared : $(sources[1]:B)_shared ] ;
result += [ run $(sources) : : : <define>BOOST_NO_ANSI_APIS : $(sources[1]:B)_no_ansi ] ;
result += [ run $(sources) : : : <define>BOOST_SYSTEM_USE_UTF8 : $(sources[1]:B)_utf8 ] ;
result += [ run $(sources) : : : <define>BOOST_SYSTEM_DISABLE_THREADS : $(sources[1]:B)_nthr ] ;
return $(result) ;
}
@ -74,7 +75,9 @@ system-run generic_category_test.cpp ;
system-run system_category_test.cpp ;
system-run after_main_test.cpp ;
system-run failed_test.cpp ;
system-run failed_constexpr_test.cpp ;
run failed_constexpr_test.cpp : : :
# GCC w/ UBSAN doesn't consider `cat_ != 0` a constant expression
<toolset>gcc,<undefined-sanitizer>norecover:<build>no ;
# Quick (CI) test
run quick.cpp ;
@ -105,7 +108,6 @@ run system_category_test2.cpp ;
run system_category_test3.cpp ;
run windows_error_test.cpp ;
run cygwin_error_test.cpp ;
run linux_error_test.cpp ;
link errc_test3.cpp ;
@ -152,25 +154,56 @@ run std_interop_test14.cpp ;
run ec_location_test3.cpp ;
run ec_location_test4.cpp ;
compile constexpr_test2.cpp ;
run error_code_test3.cpp ;
run std_interop_test15.cpp ;
run win32_generic_test.cpp ;
run ec_hash_value_test.cpp ;
run std_interop_test16.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) ;
run result_default_construct.cpp ;
run result_value_construct.cpp ;
run result_error_construct.cpp ;
run result_copy_construct.cpp ;
run result_move_construct.cpp ;
run result_copy_assign.cpp ;
run result_move_assign.cpp ;
run result_value_access.cpp ;
run result_error_access.cpp ;
run result_swap.cpp : : : <toolset>gcc-10:<cxxflags>"-Wno-maybe-uninitialized" ;
run result_eq.cpp ;
run result_range_for.cpp ;
run result_value_construct2.cpp ;
run result_error_construct2.cpp ;
run result_errc_construct.cpp ;
run result_convert_construct.cpp ;
run result_typedefs.cpp ;
run result_value_construct3.cpp ;
run result_error_construct3.cpp ;
run result_emplace.cpp ;
run result_error_construct4.cpp ;
run result_value_construct4.cpp ;
run result_value_construct5.cpp ;
run result_error_move.cpp ;
run result_value_construct6.cpp ;
run result_value_construct7.cpp ;
run result_error_construct5.cpp ;
run result_or_value.cpp ;
compile-fail result_or_value_fail.cpp ;
compile-fail result_or_value_fail2.cpp ;
run result_or_fn0v.cpp ;
run result_or_fn0r.cpp ;
run result_and_fn1v.cpp ;
run result_and_fn1r.cpp ;
run result_and_eq_fn1v.cpp ;
run result_and_eq_fn1r.cpp ;
run result_in_place_use.cpp ;
run result_or_eq_value.cpp ;
run result_or_eq_fn0v.cpp ;
run result_or_eq_fn0r.cpp ;

View File

@ -50,16 +50,6 @@ int main()
std::cout << "BOOST_NO_ANSI_APIS is defined" << std::endl;
#else
std::cout << "BOOST_NO_ANSI_APIS is not defined" << std::endl;
#endif
#ifdef BOOST_NO_CXX11_NOEXCEPT
std::cout << "BOOST_NO_CXX11_NOEXCEPT is defined" << std::endl;
#else
std::cout << "BOOST_NO_CXX11_NOEXCEPT is not defined" << std::endl;
#endif
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
std::cout << "BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS is defined" << std::endl;
#else
std::cout << "BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS is not defined" << std::endl;
#endif
return 0;
}

35
test/constexpr_test2.cpp Normal file
View File

@ -0,0 +1,35 @@
// Copyright 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_GCC) && BOOST_GCC >= 40700 && BOOST_GCC < 40800
BOOST_PRAGMA_MESSAGE("Skipping test, BOOST_GCC is 407xx")
#else
struct X
{
boost::system::error_code ec;
};
X const& f()
{
#if defined(BOOST_CLANG_VERSION) && BOOST_CLANG_VERSION < 30900
BOOST_STATIC_CONSTEXPR X x = {};
return x;
#else
BOOST_STATIC_CONSTEXPR X x;
return x;
#endif
}
#endif

View File

@ -1,29 +0,0 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/cygwin_error.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(__CYGWIN__)
BOOST_PRAGMA_MESSAGE( "Skipping test, __CYGWIN__ is not defined" )
int main() {}
#else
#include <boost/core/lightweight_test.hpp>
int main()
{
namespace sys = boost::system;
sys::error_code ec = sys::cygwin_error::no_package;
BOOST_TEST_EQ( ec, sys::cygwin_error::no_package );
BOOST_TEST_EQ( ec, sys::error_code( ENOPKG, sys::system_category() ) );
return boost::report_errors();
}
#endif

126
test/ec_hash_value_test.cpp Normal file
View File

@ -0,0 +1,126 @@
// 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/system/generic_category.hpp>
#include <boost/system/system_category.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
#include <system_error>
namespace sys = boost::system;
int main()
{
// normal against normal (equal, system)
{
sys::error_code e2( 0, sys::system_category() );
sys::error_code e3( e2.value(), e2.category() );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// normal against normal (equal, generic)
{
sys::error_code e2( EINVAL, sys::generic_category() );
sys::error_code e3( e2.value(), e2.category() );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// normal against normal (inequal, value, generic)
{
sys::error_code e2( 0, sys::generic_category() );
sys::error_code e3( EINVAL, sys::generic_category() );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// normal against normal (inequal, value, system)
{
sys::error_code e2( 1, sys::system_category() );
sys::error_code e3( 2, sys::system_category() );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// normal against normal (inequal, category)
{
sys::error_code e2( 0, sys::system_category() );
sys::error_code e3( 0, sys::generic_category() );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// empty against normal
{
sys::error_code e2;
sys::error_code e3( e2.value(), e2.category() );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// std:: wrapping against normal
{
std::error_code e1( EINVAL, std::generic_category() );
sys::error_code e2( e1 );
sys::error_code e3( e2.value(), e2.category() );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// empty against wrapping std:: empty
{
std::error_code e1;
sys::error_code e2( e1 );
sys::error_code e3;
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// empty against roundtrip via std
{
sys::error_code e2;
std::error_code e1( e2 );
sys::error_code e3( e1 );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// normal/generic against roundtrip via std
{
sys::error_code e2( EINVAL, boost::system::generic_category() );
std::error_code e1( e2 );
sys::error_code e3( e1 );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
// normal/system against roundtrip via std
{
sys::error_code e2( 0, boost::system::system_category() );
std::error_code e1( e2 );
sys::error_code e3( e1 );
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
}
return boost::report_errors();
}

View File

@ -85,8 +85,6 @@ int main()
BOOST_TEST_EQ( ec.location().line(), 75 );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
@ -107,10 +105,8 @@ int main()
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 100 );
BOOST_TEST_EQ( ec.location().line(), 98 );
}
#endif
return boost::report_errors();
}

View File

@ -32,8 +32,6 @@ 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
@ -57,8 +55,6 @@ std::error_code make_error_code( E2 e )
return std::error_code( e, std::generic_category() );
}
#endif
int main()
{
{
@ -84,7 +80,7 @@ int main()
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 77 );
BOOST_TEST_EQ( ec.location().line(), 73 );
}
{
@ -134,7 +130,7 @@ int main()
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 127 );
BOOST_TEST_EQ( ec.location().line(), 123 );
}
{
@ -182,7 +178,7 @@ int main()
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 175 );
BOOST_TEST_EQ( ec.location().line(), 171 );
}
{
@ -209,8 +205,6 @@ int main()
BOOST_TEST_EQ( ec.location().line(), 0 );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
sys::error_code ec( e2inval );
@ -281,7 +275,5 @@ int main()
BOOST_TEST_EQ( ec.location().line(), 0 );
}
#endif
return boost::report_errors();
}

View File

@ -57,8 +57,6 @@ int main()
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
@ -84,7 +82,5 @@ int main()
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
#endif
return boost::report_errors();
}

View File

@ -59,8 +59,6 @@ int main()
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
@ -87,7 +85,5 @@ int main()
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
#endif
return boost::report_errors();
}

View File

@ -62,8 +62,6 @@ int main()
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 );
@ -85,7 +83,5 @@ int main()
BOOST_TEST_EQ( ec2.what(), ec2.message() + " [std:system:5]" );
}
#endif
return boost::report_errors();
}

View File

@ -8,11 +8,9 @@
// See library home page at http://www.boost.org/libs/system
// Avoid spurious VC++ warnings
# define _CRT_SECURE_NO_WARNINGS
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/snprintf.hpp>
#include <cstdio>
//
@ -23,7 +21,7 @@ class user_category: public sys::error_category
{
public:
virtual const char * name() const BOOST_NOEXCEPT
virtual const char * name() const noexcept
{
return "user";
}
@ -31,7 +29,7 @@ public:
virtual std::string message( int ev ) const
{
char buffer[ 256 ];
std::sprintf( buffer, "user message %d", ev );
boost::core::snprintf( buffer, sizeof( buffer ), "user message %d", ev );
return buffer;
}

View File

@ -8,11 +8,9 @@
// See library home page at http://www.boost.org/libs/system
// Avoid spurious VC++ warnings
#define _CRT_SECURE_NO_WARNINGS
#include <boost/system/error_category.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/snprintf.hpp>
#include <cstdio>
//
@ -23,7 +21,7 @@ class user_category: public sys::error_category
{
public:
virtual const char * name() const BOOST_NOEXCEPT
virtual const char * name() const noexcept
{
return "user";
}
@ -31,7 +29,7 @@ public:
virtual std::string message( int ev ) const
{
char buffer[ 256 ];
std::sprintf( buffer, "user message %d", ev );
boost::core::snprintf( buffer, sizeof( buffer ), "user message %d", ev );
return buffer;
}

View File

@ -11,26 +11,53 @@ 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" ) );
char buffer[ 4096 ], buffer2[ 4096 ];
{
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(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( ec.message( buffer, sizeof( buffer ) ), ec.message().c_str() );
{
char const* msg = ec.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, ec.message().c_str() );
}
}
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec );
BOOST_TEST_EQ( ec.to_string(), std::string( "system:0" ) );
}
{
sys::error_code ec;
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_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.message().c_str() );
{
char const* msg = ec2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, ec2.message().c_str() );
}
}
BOOST_TEST( !ec2.failed() );
BOOST_TEST( !ec2 );
@ -41,12 +68,25 @@ int main()
}
{
sys::error_code ec;
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_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.message().c_str() );
{
char const* msg = ec2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, ec2.message().c_str() );
}
}
BOOST_TEST( !ec2.failed() );
BOOST_TEST( !ec2 );
@ -61,34 +101,124 @@ int main()
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_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.message().c_str() );
{
char const* msg = ec2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, ec2.message().c_str() );
}
}
BOOST_TEST( ec2.failed() );
BOOST_TEST( ec2 );
BOOST_TEST_NOT( !ec2 );
sys::error_code ec;
BOOST_TEST_NE( ec, ec2 );
BOOST_TEST_NOT( ec == ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "generic:5" ) );
}
{
sys::error_code ec2( -4, sys::generic_category() );
BOOST_TEST_EQ( ec2.value(), -4 );
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(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.message().c_str() );
{
char const* msg = ec2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, ec2.message().c_str() );
}
}
BOOST_TEST( ec2.failed() );
BOOST_TEST( ec2 );
BOOST_TEST_NOT( !ec2 );
sys::error_code ec;
BOOST_TEST_NE( ec, ec2 );
BOOST_TEST_NOT( ec == ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "generic:-4" ) );
}
{
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_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.category().message( ec2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.message().c_str() );
{
char const* msg = ec2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, ec2.message().c_str() );
}
}
BOOST_TEST( ec2.failed() );
BOOST_TEST( ec2 );
BOOST_TEST_NOT( !ec2 );
sys::error_code ec;
BOOST_TEST_NE( ec, ec2 );
BOOST_TEST_NOT( ec == ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "system:5" ) );
}
{
sys::error_code ec2( -4, sys::system_category() );
BOOST_TEST_EQ( ec2.value(), -4 );
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(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( ec2.message( buffer, sizeof( buffer ) ), ec2.message().c_str() );
{
char const* msg = ec2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, ec2.message().c_str() );
}
}
BOOST_TEST( ec2.failed() );
BOOST_TEST( ec2 );
BOOST_TEST_NOT( !ec2 );
sys::error_code ec;
BOOST_TEST_NE( ec, ec2 );
BOOST_TEST_NOT( ec == ec2 );
BOOST_TEST_EQ( ec2.to_string(), std::string( "system:-4" ) );
}
return boost::report_errors();
}

69
test/error_code_test3.cpp Normal file
View File

@ -0,0 +1,69 @@
// 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/system/error_condition.hpp>
#include <boost/system/generic_category.hpp>
#include <boost/core/lightweight_test.hpp>
namespace sys = boost::system;
enum my_errc
{
enomem_c = ENOMEM
};
enum my_errn
{
enomem_n = ENOMEM
};
namespace boost {
namespace system {
template<> struct is_error_code_enum<my_errc>
{
static const bool value = true;
};
template<> struct is_error_condition_enum<my_errn>
{
static const bool value = true;
};
} // namespace system
} // namespace boost
sys::error_code make_error_code( my_errc e )
{
return sys::error_code( e, sys::generic_category() );
}
sys::error_condition make_error_condition( my_errn e )
{
return sys::error_condition( e, sys::generic_category() );
}
int main()
{
sys::error_code ec = make_error_code( sys::errc::not_enough_memory );
sys::error_condition en( sys::errc::not_enough_memory );
BOOST_TEST_EQ( ec, en );
BOOST_TEST_EQ( en, ec );
BOOST_TEST_EQ( ec, enomem_c );
BOOST_TEST_EQ( enomem_c, ec );
BOOST_TEST_EQ( ec, enomem_n );
BOOST_TEST_EQ( enomem_n, ec );
BOOST_TEST_EQ( en, enomem_c );
BOOST_TEST_EQ( enomem_c, en );
BOOST_TEST_EQ( en, enomem_n );
BOOST_TEST_EQ( enomem_n, en );
return boost::report_errors();
}

View File

@ -11,26 +11,53 @@ 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" ) );
char buffer[ 4096 ], buffer2[ 4096 ];
{
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(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( en.message( buffer, sizeof( buffer ) ), en.message().c_str() );
{
char const* msg = en.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, en.message().c_str() );
}
}
BOOST_TEST( !en.failed() );
BOOST_TEST( !en );
BOOST_TEST_EQ( en.to_string(), std::string( "cond:generic:0" ) );
}
{
sys::error_condition en;
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_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.message().c_str() );
{
char const* msg = en2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, en2.message().c_str() );
}
}
BOOST_TEST( !en2.failed() );
BOOST_TEST( !en2 );
@ -41,12 +68,25 @@ int main()
}
{
sys::error_condition en;
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_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.message().c_str() );
{
char const* msg = en2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, en2.message().c_str() );
}
}
BOOST_TEST( !en2.failed() );
BOOST_TEST( !en2 );
@ -61,34 +101,124 @@ int main()
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_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.message().c_str() );
{
char const* msg = en2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, en2.message().c_str() );
}
}
BOOST_TEST( en2.failed() );
BOOST_TEST( en2 );
BOOST_TEST_NOT( !en2 );
sys::error_condition en;
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( -4, sys::generic_category() );
BOOST_TEST_EQ( en2.value(), -4 );
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(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.message().c_str() );
{
char const* msg = en2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, en2.message().c_str() );
}
}
BOOST_TEST( en2.failed() );
BOOST_TEST( en2 );
BOOST_TEST_NOT( !en2 );
sys::error_condition en;
BOOST_TEST_NE( en, en2 );
BOOST_TEST_NOT( en == en2 );
BOOST_TEST_EQ( en2.to_string(), std::string( "cond:generic:-4" ) );
}
{
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_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.category().message( en2.value(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.message().c_str() );
{
char const* msg = en2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, en2.message().c_str() );
}
}
BOOST_TEST( en2.failed() );
BOOST_TEST( en2 );
BOOST_TEST_NOT( !en2 );
sys::error_condition en;
BOOST_TEST_NE( en, en2 );
BOOST_TEST_NOT( en == en2 );
BOOST_TEST_EQ( en2.to_string(), std::string( "cond:system:5" ) );
}
{
sys::error_condition en2( -4, sys::system_category() );
BOOST_TEST_EQ( en2.value(), -4 );
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(), buffer2, sizeof( buffer2 ) ) );
BOOST_TEST_CSTR_EQ( en2.message( buffer, sizeof( buffer ) ), en2.message().c_str() );
{
char const* msg = en2.message( nullptr, 0 );
if( msg != nullptr )
{
BOOST_TEST_CSTR_EQ( msg, en2.message().c_str() );
}
}
BOOST_TEST( en2.failed() );
BOOST_TEST( en2 );
BOOST_TEST_NOT( !en2 );
sys::error_condition en;
BOOST_TEST_NE( en, en2 );
BOOST_TEST_NOT( en == en2 );
BOOST_TEST_EQ( en2.to_string(), std::string( "cond:system:-4" ) );
}
return boost::report_errors();
}

View File

@ -2,11 +2,9 @@
// Copyright 2018 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// Avoid spurious VC++ warnings
#define _CRT_SECURE_NO_WARNINGS
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/snprintf.hpp>
#include <cstdio>
using namespace boost::system;
@ -15,11 +13,11 @@ struct http_category_impl: public error_category
{
// clang++ 3.8 and below: initialization of const object
// requires a user-provided default constructor
BOOST_SYSTEM_CONSTEXPR http_category_impl() BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR http_category_impl() noexcept
{
}
char const * name() const BOOST_NOEXCEPT
char const * name() const noexcept
{
return "http";
}
@ -28,11 +26,11 @@ struct http_category_impl: public error_category
{
char buffer[ 32 ];
std::sprintf( buffer, "HTTP/1.0 %d", ev );
boost::core::snprintf( buffer, sizeof( buffer ), "HTTP/1.0 %d", ev );
return buffer;
}
bool failed( int ev ) const BOOST_NOEXCEPT
bool failed( int ev ) const noexcept
{
return !( ev >= 200 && ev < 300 );
}

149
test/result_and_eq_fn1r.cpp Normal file
View File

@ -0,0 +1,149 @@
// 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>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& r )
{
if( &r != this )
{
v_ = r.v_;
r.v_ = 0;
}
return *this;
}
};
struct E
{
};
struct E2
{
E2() {}
E2( E ) {}
};
result<int, E> fi( int x )
{
return 2 * x + 1;
}
result<int, E2> fi2( int )
{
return E2();
}
result<X, E> fy( Y y )
{
return X{ 2 * y.v_ + 1 };
}
result<Y, E2> fy2( Y )
{
return E2();
}
result<int&, E> fri( int& )
{
static int x = 2;
return x;
}
result<int&, E2> fri2( int& )
{
return E2();
}
result<void, E2> fv()
{
return {};
}
result<void, E2> fv2()
{
return E2();
}
int main()
{
{
result<int, E2> r( 1 );
r &= fi;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 3 );
r &= fi2;
BOOST_TEST( r.has_error() );
r &= fi;
BOOST_TEST( r.has_error() );
}
{
result<Y, E2> r( in_place_value, 1 );
r &= fy;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 3 );
r &= fy2;
BOOST_TEST( r.has_error() );
r &= fy;
BOOST_TEST( r.has_error() );
}
{
int x1 = 1;
result<int&, E2> r( x1 );
r &= fri;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &*fri( x1 ) );
r &= fri2;
BOOST_TEST( r.has_error() );
r &= fri;
BOOST_TEST( r.has_error() );
}
{
result<void, E2> r;
r &= fv;
BOOST_TEST( r.has_value() );
r &= fv2;
BOOST_TEST( r.has_error() );
r &= fv;
BOOST_TEST( r.has_error() );
}
return boost::report_errors();
}

141
test/result_and_eq_fn1v.cpp Normal file
View File

@ -0,0 +1,141 @@
// 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>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& r )
{
if( &r != this )
{
v_ = r.v_;
r.v_ = 0;
}
return *this;
}
};
struct E
{
};
int f( int x )
{
return x * 2 + 1;
}
X g( Y y )
{
return X{ y.v_ * 2 + 1 };
}
int& h( int& )
{
static int x = 2;
return x;
}
static int fv_called;
void fv()
{
++fv_called;
}
int main()
{
{
result<int> r( 1 );
r &= f;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 3 );
}
{
result<int, E> r( in_place_error );
r &= f;
BOOST_TEST( r.has_error() );
}
{
result<Y> r( in_place_value, 1 );
r &= g;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 3 );
}
{
result<Y, E> r( in_place_error );
r &= g;
BOOST_TEST( r.has_error() );
}
{
int x1 = 1;
result<int&> r( x1 );
r &= h;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &h( x1 ) );
}
{
result<int&, E> r( in_place_error );
r &= h;
BOOST_TEST( r.has_error() );
}
{
result<void> r;
fv_called = 0;
r &= fv;
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( fv_called, 1 );
}
{
result<void, E> r( in_place_error );
fv_called = 0;
r &= fv;
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( fv_called, 0 );
}
return boost::report_errors();
}

503
test/result_and_fn1r.cpp Normal file
View File

@ -0,0 +1,503 @@
// 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>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& ) = delete;
};
struct E
{
};
struct E2
{
E2() {}
E2( E ) {}
};
result<int, E2> fi( int x )
{
return 2 * x + 1;
}
result<int, E2> fi2( int )
{
return E2();
}
result<void, E2> fi3( int )
{
return {};
}
result<X, E2> fy( Y y )
{
return X{ 2 * y.v_ + 1 };
}
result<X, E2> fy2( Y )
{
return E2();
}
result<void, E2> fy3( Y )
{
return {};
}
result<int, E2> fri( int& x )
{
return x * 2 + 1;
}
result<int&, E2> fri2( int& )
{
return E2();
}
result<void, E2> fri3( int& )
{
return {};
}
result<int, E2> fk()
{
return 7;
}
result<int, E2> fk2()
{
return E2();
}
result<void, E2> fk3()
{
return {};
}
result<void, E2> fk4()
{
return E2();
}
int main()
{
{
result<int, E> r( 1 );
{
result<int, E2> r2 = r & fi;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int, E2> r2 = r & fi2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fi3;
BOOST_TEST( r2.has_value() );
}
}
{
result<int, E> const r( 1 );
{
result<int, E2> r2 = r & fi;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int, E2> r2 = r & fi2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fi3;
BOOST_TEST( r2.has_value() );
}
}
{
result<int, E2> r2 = result<int, E>( 1 ) & fi;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int, E2> r2 = result<int, E>( 1 ) & fi2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<int, E>( 1 ) & fi3;
BOOST_TEST( r2.has_value() );
}
{
result<int, E> r( in_place_error );
{
result<int, E2> r2 = r & fi;
BOOST_TEST( r2.has_error() );
}
{
result<int, E2> r2 = r & fi2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fi3;
BOOST_TEST( r2.has_error() );
}
}
{
result<int, E> const r( in_place_error );
{
result<int, E2> r2 = r & fi;
BOOST_TEST( r2.has_error() );
}
{
result<int, E2> r2 = r & fi2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fi3;
BOOST_TEST( r2.has_error() );
}
}
{
result<int, E2> r2 = result<int, E>( in_place_error ) & fi;
BOOST_TEST( r2.has_error() );
}
{
result<int, E2> r2 = result<int, E>( in_place_error ) & fi2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<int, E>( in_place_error ) & fi3;
BOOST_TEST( r2.has_error() );
}
{
result<X, E2> r2 = result<Y, E>( in_place_value, 1 ) & fy;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2->v_, 3 );
}
{
result<X, E2> r2 = result<Y, E>( in_place_value, 1 ) & fy2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<Y, E>( in_place_value, 1 ) & fy3;
BOOST_TEST( r2.has_value() );
}
{
result<X, E2> r2 = result<Y, E>( in_place_error ) & fy;
BOOST_TEST( r2.has_error() );
}
{
result<X, E2> r2 = result<Y, E>( in_place_error ) & fy2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<Y, E>( in_place_error ) & fy3;
BOOST_TEST( r2.has_error() );
}
{
int x1 = 1;
result<int&, E> r( x1 );
{
result<int, E2> r2 = r & fri;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int&, E2> r2 = r & fri2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fri3;
BOOST_TEST( r2.has_value() );
}
}
{
int x1 = 1;
result<int&, E> const r( x1 );
{
result<int, E2> r2 = r & fri;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int&, E2> r2 = r & fri2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fri3;
BOOST_TEST( r2.has_value() );
}
}
{
int x1 = 1;
result<int, E2> r2 = result<int&, E>( x1 ) & fri;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
int x1 = 1;
result<int&, E2> r2 = result<int&, E>( x1 ) & fri2;
BOOST_TEST( r2.has_error() );
}
{
int x1 = 1;
result<void, E2> r2 = result<int&, E>( x1 ) & fri3;
BOOST_TEST( r2.has_value() );
}
{
result<int&, E> r( in_place_error );
{
result<int, E2> r2 = r & fri;
BOOST_TEST( r2.has_error() );
}
{
result<int&, E2> r2 = r & fri2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fri3;
BOOST_TEST( r2.has_error() );
}
}
{
result<int&, E> const r( in_place_error );
{
result<int, E2> r2 = r & fri;
BOOST_TEST( r2.has_error() );
}
{
result<int&, E2> r2 = r & fri2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fri3;
BOOST_TEST( r2.has_error() );
}
}
{
result<int, E2> r2 = result<int&, E>( in_place_error ) & fri;
BOOST_TEST( r2.has_error() );
}
{
result<int&, E2> r2 = result<int&, E>( in_place_error ) & fri2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<int&, E>( in_place_error ) & fri3;
BOOST_TEST( r2.has_error() );
}
{
result<void, E> r;
{
result<int, E2> r2 = r & fk;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 7 );
}
{
result<int, E2> r2 = r & fk2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fk3;
BOOST_TEST( r2.has_value() );
}
{
result<void, E2> r2 = r & fk4;
BOOST_TEST( r2.has_error() );
}
}
{
result<void, E> const r;
{
result<int, E2> r2 = r & fk;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 7 );
}
{
result<int, E2> r2 = r & fk2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fk3;
BOOST_TEST( r2.has_value() );
}
{
result<void, E2> r2 = r & fk4;
BOOST_TEST( r2.has_error() );
}
}
{
result<int, E2> r2 = result<void, E>() & fk;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 7 );
}
{
result<int, E2> r2 = result<void, E>() & fk2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<void, E>() & fk3;
BOOST_TEST( r2.has_value() );
}
{
result<void, E2> r2 = result<void, E>() & fk4;
BOOST_TEST( r2.has_error() );
}
{
result<void, E> r( in_place_error );
{
result<int, E2> r2 = r & fk;
BOOST_TEST( r2.has_error() );
}
{
result<int, E2> r2 = r & fk2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fk3;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fk4;
BOOST_TEST( r2.has_error() );
}
}
{
result<void, E> const r( in_place_error );
{
result<int, E2> r2 = r & fk;
BOOST_TEST( r2.has_error() );
}
{
result<int, E2> r2 = r & fk2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fk3;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = r & fk4;
BOOST_TEST( r2.has_error() );
}
}
{
result<int, E2> r2 = result<void, E>( in_place_error ) & fk;
BOOST_TEST( r2.has_error() );
}
{
result<int, E2> r2 = result<void, E>( in_place_error ) & fk2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<void, E>( in_place_error ) & fk3;
BOOST_TEST( r2.has_error() );
}
{
result<void, E2> r2 = result<void, E>( in_place_error ) & fk4;
BOOST_TEST( r2.has_error() );
}
return boost::report_errors();
}

331
test/result_and_fn1v.cpp Normal file
View File

@ -0,0 +1,331 @@
// 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>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& ) = delete;
};
struct E
{
};
int f( int x )
{
return x * 2 + 1;
}
X g( Y y )
{
return X{ y.v_ * 2 + 1 };
}
int& h( int& )
{
static int x = 2;
return x;
}
int k()
{
return 7;
}
static int fv1_called_with;
void fv1( int x )
{
fv1_called_with = x;
}
static int fv2_called;
void fv2()
{
++fv2_called;
}
int main()
{
{
result<int> r( 1 );
result<int> r2 = r & f;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int> const r( 1 );
result<int> r2 = r & f;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int> r2 = result<int>( 1 ) & f;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
}
{
result<int, E> r( in_place_error );
result<int, E> r2 = r & f;
BOOST_TEST( r2.has_error() );
}
{
result<int, E> const r( in_place_error );
result<int, E> r2 = r & f;
BOOST_TEST( r2.has_error() );
}
{
result<int, E> r2 = result<int, E>( in_place_error ) & f;
BOOST_TEST( r2.has_error() );
}
{
result<X> r2 = result<Y>( in_place_value, 1 ) & g;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2->v_, 3 );
}
{
result<X, E> r2 = result<Y, E>( in_place_error ) & g;
BOOST_TEST( r2.has_error() );
}
{
int x1 = 1;
result<int&> r( x1 );
result<int&> r2 = r & h;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) );
}
{
int x1 = 1;
result<int&> const r( x1 );
result<int&> r2 = r & h;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) );
}
{
int x1 = 1;
result<int&> r2 = result<int&>( x1 ) & h;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) );
}
{
result<int&, E> r( in_place_error );
result<int&, E> r2 = r & h;
BOOST_TEST( r2.has_error() );
}
{
result<int&, E> const r( in_place_error );
result<int&, E> r2 = r & h;
BOOST_TEST( r2.has_error() );
}
{
result<int&, E> r2 = result<int&, E>( in_place_error ) & h;
BOOST_TEST( r2.has_error() );
}
{
result<void> r;
result<int> r2 = r & k;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 7 );
}
{
result<void> const r;
result<int> r2 = r & k;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 7 );
}
{
result<int> r2 = result<void>() & k;
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 7 );
}
{
result<void, E> r( in_place_error );
result<int, E> r2 = r & k;
BOOST_TEST( r2.has_error() );
}
{
result<void, E> const r( in_place_error );
result<int, E> r2 = r & k;
BOOST_TEST( r2.has_error() );
}
{
result<int, E> r2 = result<void, E>( in_place_error ) & k;
BOOST_TEST( r2.has_error() );
}
{
fv1_called_with = 0;
result<int> r( 1 );
result<void> r2 = r & fv1;
BOOST_TEST( r2.has_value() );
BOOST_TEST_EQ( fv1_called_with, 1 );
}
{
result<int> const r( 1 );
result<void> r2 = r & fv1;
BOOST_TEST( r2.has_value() );
BOOST_TEST_EQ( fv1_called_with, 1 );
}
{
fv1_called_with = 0;
result<void> r2 = result<int>( 1 ) & fv1;
BOOST_TEST( r2.has_value() );
BOOST_TEST_EQ( fv1_called_with, 1 );
}
{
fv1_called_with = 0;
result<int, E> r( in_place_error );
result<void, E> r2 = r & fv1;
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( fv1_called_with, 0 );
}
{
fv1_called_with = 0;
result<int, E> const r( in_place_error );
result<void, E> r2 = r & fv1;
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( fv1_called_with, 0 );
}
{
fv1_called_with = 0;
result<void, E> r2 = result<int, E>( in_place_error ) & fv1;
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( fv1_called_with, 0 );
}
{
result<void> r;
fv2_called = 0;
result<void> r2 = r & fv2;
BOOST_TEST( r2.has_value() );
BOOST_TEST_EQ( fv2_called, 1 );
}
{
result<void> const r;
fv2_called = 0;
result<void> r2 = r & fv2;
BOOST_TEST( r2.has_value() );
BOOST_TEST_EQ( fv2_called, 1 );
}
{
fv2_called = 0;
result<void> r2 = result<void>() & fv2;
BOOST_TEST( r2.has_value() );
BOOST_TEST_EQ( fv2_called, 1 );
}
{
result<void, E> r( in_place_error );
fv2_called = 0;
result<void, E> r2 = r & fv2;
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( fv2_called, 0 );
}
{
result<void, E> const r( in_place_error );
fv2_called = 0;
result<void, E> r2 = r & fv2;
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( fv2_called, 0 );
}
{
fv2_called = 0;
result<void, E> r2 = result<void, E>( in_place_error ) & fv2;
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( fv2_called, 0 );
}
return boost::report_errors();
}

View File

@ -181,6 +181,95 @@ int main()
BOOST_TEST_EQ( X::instances, 0 );
//
{
result<void, int> r;
result<void, X> r2 = r;
BOOST_TEST( r2 );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<void, int> const r;
result<void, X> r2 = r;
BOOST_TEST( r2 );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<void, X> r2 = result<void, int>();
BOOST_TEST( r2 );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<void, int> r( 5 );
result<void, 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<void, int> const r( 6 );
result<void, X> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(6) );
BOOST_TEST_EQ( X::instances, 1 );
}
{
result<void, X> r2 = result<void, int>( 7 );
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(7) );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
//
{
int x = 5;
result<int&> r( x );
result<int const&> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 5 );
}
{
int x = 6;
result<int&> const r( x );
result<int const&> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 6 );
}
{
int x = 7;
result<int const&> r2 = result<int&>( x );
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 7 );
}
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<long>, result<int>>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<result<int>, result<long>>));
@ -196,6 +285,21 @@ int main()
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*>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<void, void*>, result<void, int>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<void, int>, result<void, void*>>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int const&>, result<int&>>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<result<int&>, result<int const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&>, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<int>, result<int const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&>, result<long&>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<long&>, result<int const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&>, result<long const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<long const&>, result<int const&>>));
}
return boost::report_errors();

View File

@ -682,5 +682,151 @@ int main()
BOOST_TEST_EQ( r, r2 );
}
// reference
{
int x1 = 1;
int x2 = 2;
result<int&> r1( x1 );
result<int&> r2( x2 );
r2 = r1;
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST_EQ( x2, 2 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r1, &*r2 );
}
{
int const x1 = 1;
int const x2 = 2;
result<int const&> r1( x1 );
result<int const&> r2( x2 );
r2 = r1;
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST_EQ( x2, 2 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r1, &*r2 );
}
{
int x1 = 1;
result<int&> r1( x1 );
result<int&> r2( ENOENT, generic_category() );
r2 = r1;
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r1, &*r2 );
}
{
int x1 = 1;
int x2 = 2;
result<int&> const r1( x1 );
result<int&> r2( x2 );
r2 = r1;
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST_EQ( x2, 2 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r1, &*r2 );
}
{
int const x1 = 1;
int const x2 = 2;
result<int const &> const r1( x1 );
result<int const &> r2( x2 );
r2 = r1;
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST_EQ( x2, 2 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r1, &*r2 );
}
{
int x1 = 1;
result<int&> const r1( x1 );
result<int&> r2( ENOENT, generic_category() );
r2 = r1;
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r1, &*r2 );
}
{
int x2 = 2;
auto ec = make_error_code( errc::invalid_argument );
result<int&> r1( ec );
result<int&> r2( x2 );
r2 = r1;
BOOST_TEST_EQ( x2, 2 );
BOOST_TEST_EQ( r1, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int&> r1( ec );
result<int&> r2( ENOENT, generic_category() );
r2 = r1;
BOOST_TEST_EQ( r1, r2 );
}
{
int x2 = 2;
auto ec = make_error_code( errc::invalid_argument );
result<int&> const r1( ec );
result<int&> r2( x2 );
r2 = r1;
BOOST_TEST_EQ( x2, 2 );
BOOST_TEST_EQ( r1, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int&> const r1( ec );
result<int&> r2( ENOENT, generic_category() );
r2 = r1;
BOOST_TEST_EQ( r1, r2 );
}
return boost::report_errors();
}

View File

@ -145,6 +145,8 @@ int main()
BOOST_TEST_EQ( X::instances, 0 );
//
{
result<void> r;
result<void> r2( r );
@ -177,5 +179,121 @@ int main()
BOOST_TEST_EQ( r, r2 );
}
//
{
int x1 = 1;
result<int&> r1( x1 );
result<int&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
}
{
int x1 = 1;
result<int&> const r1( x1 );
result<int&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
}
{
int const x1 = 1;
result<int const&> r1( x1 );
result<int const&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
}
{
int const x1 = 1;
result<int const&> const r1( x1 );
result<int const&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X x1( 1 );
result<X&> r1( x1 );
result<X&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X x1( 1 );
result<X&> const r1( x1 );
result<X&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X const x1( 1 );
result<X const&> r1( x1 );
result<X const&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X const x1( 1 );
result<X const&> const r1( x1 );
result<X const&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<int&> r1( ec );
result<int&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int&> const r1( ec );
result<int&> r2( r1 );
BOOST_TEST_EQ( r1, r2 );
}
//
return boost::report_errors();
}

View File

@ -12,6 +12,11 @@ struct X
{
};
struct Y
{
Y( int );
};
int main()
{
{
@ -23,6 +28,24 @@ int main()
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<int> r{};
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<int> r = {};
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<X> r;
@ -30,6 +53,20 @@ int main()
BOOST_TEST( !r.has_error() );
}
{
result<X> r{};
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
result<X> r = {};
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
result<void> r;
@ -37,5 +74,34 @@ int main()
BOOST_TEST( !r.has_error() );
}
{
result<void> r{};
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
result<void> r = {};
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<int>>));
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<int, int>>));
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<X>>));
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<X, int>>));
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<void>>));
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<void, int>>));
BOOST_TEST_TRAIT_FALSE((std::is_default_constructible<result<Y>>));
BOOST_TEST_TRAIT_FALSE((std::is_default_constructible<result<Y, int>>));
BOOST_TEST_TRAIT_FALSE((std::is_default_constructible<result<int&>>));
BOOST_TEST_TRAIT_FALSE((std::is_default_constructible<result<int&, int>>));
}
return boost::report_errors();
}

218
test/result_emplace.cpp Normal file
View File

@ -0,0 +1,218 @@
// 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 <cerrno>
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;
struct Y
{
static int instances;
Y() noexcept { ++instances; }
Y( Y const& ) noexcept { ++instances; }
Y& operator=( Y const& ) = default;
~Y() { --instances; }
};
int Y::instances = 0;
int main()
{
{
result<int> r;
BOOST_TEST( r.has_value() );
r.emplace( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value(), 1 );
}
{
result<int> r( ENOENT, generic_category() );
BOOST_TEST( !r.has_value() );
r.emplace( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value(), 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 0 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value().v_, 0 );
BOOST_TEST_EQ( X::instances, 1 );
r.emplace( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
r.emplace( 1, 2 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value().v_, 1+2 );
BOOST_TEST_EQ( X::instances, 1 );
r.emplace( 1, 2, 3 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value().v_, 1+2+3 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( ENOENT, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST_EQ( X::instances, 0 );
r.emplace( 1, 2 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value().v_, 1+2 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<int, Y> r( Y{} );
BOOST_TEST( !r.has_value() );
BOOST_TEST_EQ( Y::instances, 1 );
r.emplace( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( *r, 1 );
BOOST_TEST_EQ( Y::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<X, Y> r( in_place_error );
BOOST_TEST( !r.has_value() );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 1 );
r.emplace( 1, 2, 3 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->v_, 1+2+3 );
BOOST_TEST_EQ( X::instances, 1 );
BOOST_TEST_EQ( Y::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<void> r;
BOOST_TEST( r.has_value() );
r.emplace();
BOOST_TEST( r.has_value() );
}
{
result<void> r( ENOENT, generic_category() );
BOOST_TEST( !r.has_value() );
r.emplace();
BOOST_TEST( r.has_value() );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<void, Y> r( in_place_error );
BOOST_TEST( !r.has_value() );
BOOST_TEST_EQ( Y::instances, 1 );
r.emplace();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( Y::instances, 0 );
}
{
int x1 = 1;
result<int&> r( x1 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value(), 1 );
int x2 = 2;
r.emplace( x2 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value(), 2 );
}
{
result<int&> r( ENOENT, generic_category() );
BOOST_TEST( !r.has_value() );
int x2 = 2;
r.emplace( x2 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r.value(), 2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<int&, Y> r( in_place_error );
BOOST_TEST( !r.has_value() );
BOOST_TEST_EQ( Y::instances, 1 );
int x2 = 2;
r.emplace( x2 );
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( *r, 2 );
BOOST_TEST_EQ( Y::instances, 0 );
}
return boost::report_errors();
}

View File

@ -149,5 +149,83 @@ int main()
BOOST_TEST_NE( r1, r2 );
}
{
int x1 = 1;
int x2 = 2;
result<int&> r1( x1 );
result<int&> r2( x2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
int x1 = 1;
int x2 = 1;
result<int&> r1( x1 );
result<int&> r2( x2 );
BOOST_TEST_EQ( r1, r2 );
}
{
result<int&> r1( 1, generic_category() );
result<int&> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
int x1 = 1;
result<int&> r1( x1 );
result<int&> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
X x1( 1 );
X x2( 2 );
result<X&, Y> r1( x1 );
result<X&, Y> r2( x2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
X x1( 1 );
X x2( 1 );
result<X&, Y> r1( x1 );
result<X&, Y> r2( x2 );
BOOST_TEST_EQ( 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 );
}
{
X x1( 1 );
result<X&, Y> r1( x1 );
result<X&, Y> r2( in_place_error, 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
return boost::report_errors();
}

View File

@ -19,5 +19,14 @@ int main()
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<bool>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, errc::errc_t>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<int const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&>, errc::errc_t>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<double const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<double const&>, errc::errc_t>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<bool const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const&>, errc::errc_t>));
return boost::report_errors();
}

View File

@ -152,6 +152,8 @@ int main()
BOOST_TEST_EQ( (result<std::string, X>( "s" ).error().v_), 0 );
}
//
{
result<void> r;
@ -208,5 +210,71 @@ int main()
BOOST_TEST_EQ( result<void>( ec ).error(), ec );
}
//
{
int x1 = 1;
result<int&> r( x1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
int x1 = 1;
result<int&> const r( x1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
int x1 = 1;
BOOST_TEST( result<int&>( x1 ).has_value() );
BOOST_TEST( !result<int&>( x1 ).has_error() );
BOOST_TEST_EQ( result<int&>( x1 ).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 );
}
//
return boost::report_errors();
}

View File

@ -146,8 +146,14 @@ int main()
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<std::string, X>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<std::string, X>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, X>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<int, X>>));
// We'd like this to be false due to the ambiguity caused by X having
// an explicit constructor taking an int, which should be viable in this
// context, but the implicit constructor is enabled, and there's no way to
// disallow it
//
// BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, X>, int>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<int, result<int, X>>));
}
{

View File

@ -0,0 +1,183 @@
// 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 <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 );
using R = result<int>;
R r( R::in_place_error, ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
using R = result<int>;
R r( 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() ) );
}
{
auto ec = make_error_code( errc::invalid_argument );
using R = result<error_code>;
R r( R::in_place_error, ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
using R = result<error_code>;
R r( 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 );
{
using R = result<std::string, X>;
R r( 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 );
{
using R = result<int, X>;
R r( R::in_place_error, 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 );
{
using R = result<int, X>;
R r( R::in_place_error, 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 );
{
using R = result<X, X>;
R r( 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 );
{
auto ec = make_error_code( errc::invalid_argument );
using R = result<void>;
R r( R::in_place_error, ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
using R = result<void>;
R r( 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() ) );
}
{
auto ec = make_error_code( errc::invalid_argument );
using R = result<int&>;
R r( R::in_place_error, ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
using R = result<int&>;
R r( 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() ) );
}
return boost::report_errors();
}

View File

@ -0,0 +1,45 @@
// Copyright 2023 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::system;
// Eigen::Matrix4d has an explicit templated constructor
// https://github.com/boostorg/system/issues/103
// https://github.com/boostorg/json/issues/843
struct X
{
X() {}
template<class T> explicit X( T const& ) {}
};
int main()
{
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r = ec;
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( std::errc::invalid_argument );
result<X> r = ec;
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
return boost::report_errors();
}

View File

@ -0,0 +1,160 @@
// 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_TRUE((std::is_constructible<result<int&, X>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<int&, X>>));
// There's an ambiguity here between int& and X, but since is_convertible
// is true, is_constructible can't be false.
// BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int&, X>, int&>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<int&, result<int&, X>>));
}
return boost::report_errors();
}

133
test/result_error_move.cpp Normal file
View File

@ -0,0 +1,133 @@
// Copyright 2023 Klemens Morgenstern
// 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 v_;
explicit X( int v = 0 ): v_( v ) {}
X( X const& ) = delete;
X& operator=( X const& ) = delete;
X( X && ) = default;
X& operator=( X && ) = default;
};
int main()
{
{
result<std::string, X> r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( std::move( 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( std::move( 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, X> r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( std::move( r ).error().v_, 1 );
}
{
BOOST_TEST(( !result<void, X>( 1 ).has_value() ));
BOOST_TEST(( result<void, X>( 1 ).has_error() ));
BOOST_TEST_EQ( (result<void, X>( 1 ).error().v_), 1 );
}
{
result<void, X> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( std::move( r ).error().v_, 0 );
}
{
BOOST_TEST(( result<void, X>().has_value() ));
BOOST_TEST(( !result<void, X>().has_error() ));
BOOST_TEST_EQ( (result<void, X>().error().v_), 0 );
}
//
{
result<double&, X> r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( std::move( r ).error().v_, 1 );
}
{
BOOST_TEST(( !result<double&, X>( 1 ).has_value() ));
BOOST_TEST(( result<double&, X>( 1 ).has_error() ));
BOOST_TEST_EQ( (result<double&, X>( 1 ).error().v_), 1 );
}
{
double x = 1.0;
result<double&, X> r( x );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( std::move( r ).error().v_, 0 );
}
{
double x = 1.0;
BOOST_TEST(( result<double&, X>( x ).has_value() ));
BOOST_TEST(( !result<double&, X>( x ).has_error() ));
BOOST_TEST_EQ( (result<double&, X>( x ).error().v_), 0 );
}
//
return boost::report_errors();
}

View File

@ -0,0 +1,22 @@
// Copyright 2023 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T, class U> void test( T const& t, U const& u )
{
BOOST_TEST_NE( static_cast<void const*>( &t ), static_cast<void const*>( &u ) );
}
int main()
{
using namespace boost::system;
test( result<int>::in_place_value, result<int>::in_place_error );
test( result<void>::in_place_value, result<void>::in_place_error );
test( result<int&>::in_place_value, result<int&>::in_place_error );
return boost::report_errors();
}

View File

@ -508,6 +508,8 @@ int main()
BOOST_TEST_EQ( Y::instances, 0 );
//
{
result<void> r;
result<void> r2;
@ -600,5 +602,110 @@ int main()
BOOST_TEST_EQ( r2.error(), ec );
}
//
{
int x1 = 1;
int x2 = 2;
result<int&> r1( x1 );
result<int&> r2( x2 );
r2 = std::move( r1 );
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST_EQ( x2, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r1, r2 );
BOOST_TEST_EQ( &*r1, &*r2 );
}
{
int x1 = 1;
result<int&> r1( x1 );
result<int&> r2( ENOENT, generic_category() );
r2 = std::move( r1 );
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r1, r2 );
}
{
int x1 = 1;
auto ec = make_error_code( errc::invalid_argument );
result<int&> r1( ec );
result<int&> r2( x1 );
r2 = std::move( r1 );
BOOST_TEST_EQ( x1, 1 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
int x1 = 1;
auto ec = make_error_code( errc::invalid_argument );
result<int&> r2( x1 );
r2 = result<int&>( ec );
BOOST_TEST_EQ( x1, 1 );
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&> r1( ec );
result<int&> r2( ENOENT, generic_category() );
r2 = std::move( r1 );
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 );
}
//
return boost::report_errors();
}

View File

@ -207,6 +207,8 @@ int main()
BOOST_TEST_EQ( X::instances, 0 );
//
{
result<void> r;
result<void> r2( std::move( r ) );
@ -245,5 +247,149 @@ int main()
BOOST_TEST_EQ( r2.error(), ec );
}
//
{
int x1 = 1;
result<int&> r1( x1 );
result<int&> r2( std::move( r1 ) );
BOOST_TEST( r1.has_value() );
BOOST_TEST( !r1.has_error() );
BOOST_TEST_EQ( r1.value(), 1 );
BOOST_TEST_EQ( &*r1, &x1 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( &*r2, &x1 );
}
{
int const x1 = 1;
result<int const&> r1( x1 );
result<int const&> r2( std::move( r1 ) );
BOOST_TEST( r1.has_value() );
BOOST_TEST( !r1.has_error() );
BOOST_TEST_EQ( r1.value(), 1 );
BOOST_TEST_EQ( &*r1, &x1 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( &*r2, &x1 );
}
{
int x1 = 1;
result<int&> r2(( result<int&>( x1 ) ));
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( &*r2, &x1 );
}
{
int const x1 = 1;
result<int const&> r2(( result<int const&>( x1 ) ));
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( &*r2, &x1 );
}
{
X x1( 1 );
result<X&> r1( x1 );
result<X&> r2( std::move( r1 ) );
BOOST_TEST( r1.has_value() );
BOOST_TEST( !r1.has_error() );
BOOST_TEST_EQ( r1.value().v_, 1 );
BOOST_TEST_EQ( &*r1, &x1 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X x1( 1 );
result<X&> r2(( result<X&>( x1 ) ));
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X const x1( 1 );
result<X const&> r1( x1 );
result<X const&> r2( std::move( r1 ) );
BOOST_TEST( r1.has_value() );
BOOST_TEST( !r1.has_error() );
BOOST_TEST_EQ( r1.value().v_, 1 );
BOOST_TEST_EQ( &*r1, &x1 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X const x1( 1 );
result<X const&> r2(( result<X const&>( x1 ) ));
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( &*r2, &x1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
//
return boost::report_errors();
}

160
test/result_or_eq_fn0r.cpp Normal file
View File

@ -0,0 +1,160 @@
// Copyright 2017, 2021-2024 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& r )
{
if( &r != this )
{
v_ = r.v_;
r.v_ = 0;
}
return *this;
}
};
struct E
{
};
struct E2
{
E2() {}
E2( E ) {}
};
result<int, E> fi()
{
return 2;
}
result<int, E2> fi2()
{
return E2();
}
result<X, E> fy()
{
return X{ 2 };
}
result<Y, E2> fy2()
{
return E2();
}
result<int&, E> fri()
{
static int x = 2;
return x;
}
result<int&, E2> fri2()
{
return E2();
}
int main()
{
{
result<int, E2> r( 1 );
r |= fi;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 1 );
r |= fi2;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 1 );
}
{
result<int, E2> r( in_place_error );
r |= fi2;
BOOST_TEST( r.has_error() );
r |= fi;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 2 );
}
{
result<Y, E2> r( in_place_value, 1 );
r |= fy;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 1 );
r |= fy2;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 1 );
}
{
result<Y, E2> r( in_place_error );
r |= fy2;
BOOST_TEST( r.has_error() );
r |= fy;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 2 );
}
{
int x1 = 1;
result<int&, E2> r( x1 );
r |= fri;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x1 );
r |= fri2;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x1 );
}
{
result<int&, E2> r( in_place_error );
r |= fri2;
BOOST_TEST( r.has_error() );
r |= fri;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &*fri() );
}
return boost::report_errors();
}

115
test/result_or_eq_fn0v.cpp Normal file
View File

@ -0,0 +1,115 @@
// Copyright 2017, 2021-2024 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& r )
{
if( &r != this )
{
v_ = r.v_;
r.v_ = 0;
}
return *this;
}
};
struct E
{
};
int f()
{
return 2;
}
X g()
{
return { 2 };
}
int& h()
{
static int x = 2;
return x;
}
int main()
{
{
result<int> r( 1 );
r |= f;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 1 );
}
{
result<int, E> r( in_place_error );
r |= f;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 2 );
}
{
result<Y> r( in_place_value, 1 );
r |= g;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 1 );
}
{
result<Y, E> r( in_place_error );
r |= g;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 2 );
}
{
int x1 = 1;
result<int&> r( x1 );
r |= h;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x1 );
}
{
result<int&, E> r( in_place_error );
r |= h;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &h() );
}
return boost::report_errors();
}

102
test/result_or_eq_value.cpp Normal file
View File

@ -0,0 +1,102 @@
// Copyright 2017, 2021-2024 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& r )
{
if( &r != this )
{
v_ = r.v_;
r.v_ = 0;
}
return *this;
}
};
struct E
{
};
int main()
{
{
result<int> r( 1 );
r |= 2;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 1 );
}
{
result<int, E> r( in_place_error );
r |= 2;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 2 );
}
{
result<Y> r( in_place_value, 1 );
r |= X{2};
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 1 );
}
{
result<Y, E> r( in_place_error );
r |= X{2};
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 2 );
}
{
int x1 = 1;
int x2 = 2;
result<int&> r( x1 );
r |= x2;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x1 );
}
{
int x2 = 2;
result<int&, E> r( in_place_error );
r |= x2;
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x2 );
}
return boost::report_errors();
}

359
test/result_or_fn0r.cpp Normal file
View File

@ -0,0 +1,359 @@
// 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>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& ) = delete;
};
struct E
{
};
result<int, E> fi()
{
return 2;
}
result<int, E> fi2()
{
return E();
}
result<Y, E> fy()
{
return Y{ 2 };
}
result<Y, E> fy2()
{
return E();
}
result<int&, E> fri()
{
static int x = 2;
return x;
}
result<int&, E> fri2()
{
return E();
}
result<void, E> fv()
{
return {};
}
result<void, E> fv2()
{
return E();
}
int main()
{
{
result<int> r( 1 );
int x = r | fi | 3;
BOOST_TEST_EQ( x, 1 );
}
{
result<int> const r( 1 );
int x = r | fi | 3;
BOOST_TEST_EQ( x, 1 );
}
{
int x = result<int>( 1 ) | fi | 3;
BOOST_TEST_EQ( x, 1 );
}
{
result<int> r( 1 );
int x = r | fi2 | 3;
BOOST_TEST_EQ( x, 1 );
}
{
result<int> const r( 1 );
int x = r | fi2 | 3;
BOOST_TEST_EQ( x, 1 );
}
{
int x = result<int>( 1 ) | fi2 | 3;
BOOST_TEST_EQ( x, 1 );
}
{
result<int> r( in_place_error );
int x = r | fi | 3;
BOOST_TEST_EQ( x, 2 );
}
{
result<int> const r( in_place_error );
int x = r | fi | 3;
BOOST_TEST_EQ( x, 2 );
}
{
int x = result<int>( in_place_error ) | fi | 3;
BOOST_TEST_EQ( x, 2 );
}
{
result<int> r( in_place_error );
int x = r | fi2 | 3;
BOOST_TEST_EQ( x, 3 );
}
{
result<int> const r( in_place_error );
int x = r | fi2 | 3;
BOOST_TEST_EQ( x, 3 );
}
{
int x = result<int>( in_place_error ) | fi2 | 3;
BOOST_TEST_EQ( x, 3 );
}
{
Y y = result<X>( X{1} ) | fy | X{3};
BOOST_TEST_EQ( y.v_, 1 );
}
{
Y y = result<X>( X{1} ) | fy2 | X{3};
BOOST_TEST_EQ( y.v_, 1 );
}
{
Y y = result<X, E>( in_place_error ) | fy | X{3};
BOOST_TEST_EQ( y.v_, 2 );
}
{
Y y = result<X, E>( in_place_error ) | fy2 | Y{3};
BOOST_TEST_EQ( y.v_, 3 );
}
{
int x1 = 1;
int x3 = 3;
result<int&> r( x1 );
int& x = r | fri | x3;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int x3 = 3;
result<int&> const r( x1 );
int& x = r | fri | x3;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int x3 = 3;
int& x = result<int&>( x1 ) | fri | x3;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int x3 = 3;
result<int&> r( x1 );
int& x = r | fri2 | x3;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int x3 = 3;
result<int&> const r( x1 );
int& x = r | fri2 | x3;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int x3 = 3;
int& x = result<int&>( x1 ) | fri2 | x3;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x3 = 3;
result<int&, E> r( in_place_error );
int& x = r | fri | x3;
BOOST_TEST_EQ( &x, &*fri() );
}
{
int x3 = 3;
result<int&, E> const r( in_place_error );
int& x = r | fri | x3;
BOOST_TEST_EQ( &x, &*fri() );
}
{
int x3 = 3;
int& x = result<int&, E>( in_place_error ) | fri | x3;
BOOST_TEST_EQ( &x, &*fri() );
}
{
int x3 = 3;
result<int&, E> r( in_place_error );
int& x = r | fri2 | x3;
BOOST_TEST_EQ( &x, &x3 );
}
{
int x3 = 3;
result<int&, E> const r( in_place_error );
int& x = r | fri2 | x3;
BOOST_TEST_EQ( &x, &x3 );
}
{
int x3 = 3;
int& x = result<int&, E>( in_place_error ) | fri2 | x3;
BOOST_TEST_EQ( &x, &x3 );
}
{
result<void> r;
result<void, E> r2 = r | fv;
BOOST_TEST( r2.has_value() );
}
{
result<void> r;
result<void, E> r2 = r | fv2;
BOOST_TEST( r2.has_value() );
}
{
result<void> r( in_place_error );
result<void, E> r2 = r | fv;
BOOST_TEST( r2.has_value() );
}
{
result<void> r( in_place_error );
result<void, E> r2 = r | fv2;
BOOST_TEST( r2.has_error() );
}
{
result<void, E> r2 = result<void>() | fv;
BOOST_TEST( r2.has_value() );
}
{
result<void, E> r2 = result<void>() | fv2;
BOOST_TEST( r2.has_value() );
}
{
result<void, E> r2 = result<void>( in_place_error ) | fv;
BOOST_TEST( r2.has_value() );
}
{
result<void, E> r2 = result<void>( in_place_error ) | fv2;
BOOST_TEST( r2.has_error() );
}
return boost::report_errors();
}

162
test/result_or_fn0v.cpp Normal file
View File

@ -0,0 +1,162 @@
// 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>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& ) = delete;
};
struct E
{
};
int f()
{
return 2;
}
X g()
{
return { 2 };
}
int& h()
{
static int x = 2;
return x;
}
int main()
{
{
result<int> r( 1 );
int x = r | f;
BOOST_TEST_EQ( x, 1 );
}
{
result<int> const r( 1 );
int x = r | f;
BOOST_TEST_EQ( x, 1 );
}
{
int x = result<int>( 1 ) | f;
BOOST_TEST_EQ( x, 1 );
}
{
result<int, E> r( in_place_error );
int x = r | f;
BOOST_TEST_EQ( x, 2 );
}
{
result<int, E> const r( in_place_error );
int x = r | f;
BOOST_TEST_EQ( x, 2 );
}
{
int x = result<int, E>( in_place_error ) | f;
BOOST_TEST_EQ( x, 2 );
}
{
Y y = result<Y>( in_place_value, 1 ) | g;
BOOST_TEST_EQ( y.v_, 1 );
}
{
Y y = result<Y, E>( in_place_error ) | g;
BOOST_TEST_EQ( y.v_, 2 );
}
{
int x1 = 1;
result<int&> r( x1 );
int& x = r | h;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
result<int&> const r( x1 );
int& x = r | h;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int& x = result<int&>( x1 ) | h;
BOOST_TEST_EQ( &x, &x1 );
}
{
result<int&, E> r( in_place_error );
int& x = r | h;
BOOST_TEST_EQ( &x, &h() );
}
{
result<int&, E> const r( in_place_error );
int& x = r | h;
BOOST_TEST_EQ( &x, &h() );
}
{
int& x = result<int&, E>( in_place_error ) | h;
BOOST_TEST_EQ( &x, &h() );
}
return boost::report_errors();
}

167
test/result_or_value.cpp Normal file
View File

@ -0,0 +1,167 @@
// 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>
using namespace boost::system;
struct X
{
int v_;
};
struct Y
{
int v_;
explicit Y( int v ): v_( v ) {}
Y( X x ): v_( x.v_) {}
Y( Y const& ) = delete;
Y& operator=( Y const& ) = delete;
Y( Y&& r ): v_( r.v_ )
{
r.v_ = 0;
}
Y& operator=( Y&& ) = delete;
};
struct E
{
};
int main()
{
{
result<int> r( 1 );
int x = r | 2;
BOOST_TEST_EQ( x, 1 );
}
{
result<int> const r( 1 );
int x = r | 2;
BOOST_TEST_EQ( x, 1 );
}
{
int x = result<int>( 1 ) | 2;
BOOST_TEST_EQ( x, 1 );
}
{
result<int, E> r( in_place_error );
int x = r | 2;
BOOST_TEST_EQ( x, 2 );
}
{
result<int, E> const r( in_place_error );
int x = r | 2;
BOOST_TEST_EQ( x, 2 );
}
{
int x = result<int, E>( in_place_error ) | 2;
BOOST_TEST_EQ( x, 2 );
}
{
Y y = result<Y>( in_place_value, 1 ) | Y{2};
BOOST_TEST_EQ( y.v_, 1 );
}
{
Y y = result<Y, E>( in_place_error ) | Y{2};
BOOST_TEST_EQ( y.v_, 2 );
}
{
Y y = result<Y>( in_place_value, 1 ) | X{2};
BOOST_TEST_EQ( y.v_, 1 );
}
{
Y y = result<Y, E>( in_place_error ) | X{2};
BOOST_TEST_EQ( y.v_, 2 );
}
{
int x1 = 1;
int x2 = 2;
result<int&> r( x1 );
int& x = r | x2;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int x2 = 2;
result<int&> const r( x1 );
int& x = r | x2;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x1 = 1;
int x2 = 2;
int& x = result<int&>( x1 ) | x2;
BOOST_TEST_EQ( &x, &x1 );
}
{
int x2 = 2;
result<int&, E> r( in_place_error );
int& x = r | x2;
BOOST_TEST_EQ( &x, &x2 );
}
{
int x2 = 2;
result<int&, E> const r( in_place_error );
int& x = r | x2;
BOOST_TEST_EQ( &x, &x2 );
}
{
int x2 = 2;
int& x = result<int&, E>( in_place_error ) | x2;
BOOST_TEST_EQ( &x, &x2 );
}
return boost::report_errors();
}

View File

@ -0,0 +1,14 @@
// 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>
using namespace boost::system;
int main()
{
int x = 1;
result<int const&> r( x );
r | 2;
}

View File

@ -0,0 +1,13 @@
// 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>
using namespace boost::system;
int main()
{
int x = 1;
result<int const&>( x ) | 2;
}

View File

@ -259,5 +259,55 @@ int main()
BOOST_TEST_EQ( r2, r2c );
}
{
int x1 = 1;
int x2 = 2;
result<int&> r1( x1 ), r1c( r1 );
result<int&> r2( x2 ), 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 );
}
{
int x1 = 1;
result<int&> r1( x1 ), 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 );
}
return boost::report_errors();
}

39
test/result_typedefs.cpp Normal file
View File

@ -0,0 +1,39 @@
// Copyright 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_trait.hpp>
using namespace boost::system;
struct X {};
int main()
{
BOOST_TEST_TRAIT_SAME( result<int>::value_type, int );
BOOST_TEST_TRAIT_SAME( result<int>::error_type, error_code );
BOOST_TEST_TRAIT_SAME( result<X>::value_type, X );
BOOST_TEST_TRAIT_SAME( result<X>::error_type, error_code );
BOOST_TEST_TRAIT_SAME( result<void>::value_type, void );
BOOST_TEST_TRAIT_SAME( result<void>::error_type, error_code );
BOOST_TEST_TRAIT_SAME( result<int&>::value_type, int& );
BOOST_TEST_TRAIT_SAME( result<int&>::error_type, error_code );
BOOST_TEST_TRAIT_SAME( result<int, X>::value_type, int );
BOOST_TEST_TRAIT_SAME( result<int, X>::error_type, X );
BOOST_TEST_TRAIT_SAME( result<X, X>::value_type, X );
BOOST_TEST_TRAIT_SAME( result<X, X>::error_type, X );
BOOST_TEST_TRAIT_SAME( result<void, X>::value_type, void );
BOOST_TEST_TRAIT_SAME( result<void, X>::error_type, X );
BOOST_TEST_TRAIT_SAME( result<int&, X>::value_type, int& );
BOOST_TEST_TRAIT_SAME( result<int&, X>::error_type, X );
return boost::report_errors();
}

View File

@ -5,6 +5,7 @@
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config.hpp>
#include <system_error>
using namespace boost::system;
@ -223,7 +224,10 @@ int main()
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
#if defined(BOOST_CLANG_VERSION) && BOOST_CLANG_VERSION < 30600
#else
BOOST_TEST_THROWS( r.value(), E2 );
#endif
BOOST_TEST_EQ( r.operator->(), static_cast<int*>(0) );
}
@ -332,6 +336,8 @@ int main()
BOOST_TEST_EQ( (result<X, Y>( ec ).operator->()), static_cast<X*>(0) );
}
//
{
result<void> r;
@ -471,7 +477,10 @@ int main()
BOOST_TEST_NOT( r );
BOOST_TEST( !r );
#if defined(BOOST_CLANG_VERSION) && BOOST_CLANG_VERSION < 30600
#else
BOOST_TEST_THROWS( r.value(), E2 );
#endif
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
@ -490,5 +499,179 @@ int main()
BOOST_TEST_EQ( r.operator->(), static_cast<void*>(0) );
}
//
{
int x1 = 1;
result<int&> r( x1 );
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 );
}
{
int x1 = 1;
result<int&> const r( x1 );
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 );
}
{
int x1 = 1;
BOOST_TEST( result<int&>( x1 ).has_value() );
BOOST_TEST( !result<int&>( x1 ).has_error() );
BOOST_TEST( result<int&>( x1 ) );
BOOST_TEST_NOT( !result<int&>( x1 ) );
BOOST_TEST_EQ( result<int&>( x1 ).value(), 1 );
BOOST_TEST_EQ( *result<int&>( x1 ), 1 );
BOOST_TEST_EQ( result<int&>( x1 ).operator->(), &x1 );
}
{
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 );
#if defined(BOOST_CLANG_VERSION) && BOOST_CLANG_VERSION < 30600
#else
BOOST_TEST_THROWS( r.value(), E2 );
#endif
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) );
}
//
return boost::report_errors();
}

View File

@ -69,6 +69,11 @@ result<std::vector<int>> fv2()
return {{ 1, 2 }};
}
result<void> fw0()
{
return {};
}
int main()
{
{
@ -148,5 +153,12 @@ int main()
BOOST_TEST_EQ( r->at(1), 2 );
}
{
result<void> r = fw0();
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
return boost::report_errors();
}

View File

@ -0,0 +1,142 @@
// 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>
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()
{
{
using R = result<int>;
R r( R::in_place_value, 0 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
using R = result<int, int>;
R r( 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 );
{
using R = result<X>;
R r( R::in_place_value, 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 );
{
using R = result<X>;
R r( R::in_place_value, 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 );
{
using R = result<X>;
R r( R::in_place_value, 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 );
{
using R = result<X, X>;
R r( 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 );
{
using R = result<void>;
R r( R::in_place_value );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
int x1 = 1;
using R = result<int&>;
R r( R::in_place_value, x1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 1 );
}
{
int x1 = 1;
using R = result<int&, int>;
R r( R::in_place_value, x1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( *r, 1 );
}
return boost::report_errors();
}

View File

@ -0,0 +1,59 @@
// Copyright 2023 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::system;
// Tricky mixed construction cases
// https://github.com/boostorg/system/issues/104
// https://brevzin.github.io//c++/2023/01/18/optional-construction/
int main()
{
{
result<int> r( make_error_code( errc::invalid_argument ) );
result<result<int>> r2( r );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
}
{
result<int> r( 5 );
result<result<int>> r2( r );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
}
{
result<int> const r( make_error_code( errc::invalid_argument ) );
result<result<int>> r2( r );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
}
{
result<int> const r( 5 );
result<result<int>> r2( r );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
}
{
result<int> r( make_error_code( errc::invalid_argument ) );
result<result<int>> r2( std::move( r ) );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
}
{
result<int> r( 5 );
result<result<int>> r2( std::move( r ) );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), r );
}
return boost::report_errors();
}

View File

@ -0,0 +1,86 @@
// Copyright 2023 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER) && _MSC_VER < 1910
# pragma warning( disable: 4800 ) // forcing value to bool 'true' or 'false'
#endif
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <utility>
#include <type_traits>
using namespace boost::system;
// Tricky mixed construction cases
// https://github.com/boostorg/system/issues/104
// https://brevzin.github.io//c++/2023/01/18/optional-construction/
template<class R1, class R2> void test()
{
{
R1 r1( make_error_code( errc::invalid_argument ) );
R2 r2( r1 );
BOOST_TEST( !r2.has_value() );
}
{
R1 r1( 0 );
R2 r2( r1 );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), false );
}
{
R1 r1( 1 );
R2 r2( r1 );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), true );
}
{
R1 r1( make_error_code( errc::invalid_argument ) );
R2 r2( std::move( r1 ) );
BOOST_TEST( !r2.has_value() );
}
{
R1 r1( 0 );
R2 r2( std::move( r1 ) );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), false );
}
{
R1 r1( 1 );
R2 r2( std::move( r1 ) );
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2.value(), true );
}
}
struct X
{
};
int main()
{
test< result<int>, result<bool> >();
test< result<int> const, result<bool> >();
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X> const&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X>&&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, result<X> const&&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X> const&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X>&&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool const>, result<X> const&&>));
return boost::report_errors();
}

View File

@ -0,0 +1,121 @@
// Copyright 2017, 2021, 2023 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#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( X const& ) = delete;
X& operator=( X const& ) = delete;
~X() { --instances; }
};
int X::instances = 0;
int main()
{
{
int x = 0;
result<int&> r( x );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
int x = 0;
result<int&> r = x;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
int x = 1;
result<int&, int> r( in_place_value, x );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( *r, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X x( 1 );
result<X&> r( x );
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 );
{
X x( 1 );
result<X&> r = x;
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 );
{
X x( 1 );
result<X&, X> r( in_place_value, x );
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 const&>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int const&, result<int&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int&>, int>));
BOOST_TEST_TRAIT_FALSE((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_FALSE((std::is_constructible<result<X&>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<X&>>));
}
return boost::report_errors();
}

View File

@ -0,0 +1,211 @@
// Copyright 2017, 2021, 2023 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#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( X const& ) = delete;
X& operator=( X const& ) = delete;
~X() { --instances; }
};
int X::instances = 0;
int main()
{
{
int x = 0;
result<int const&> r( x );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
int const x = 0;
result<int const&> r( x );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
int x = 0;
result<int const&> r = x;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
int const x = 0;
result<int const&> r = x;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
int x = 1;
result<int const&, int> r( in_place_value, x );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( *r, 1 );
}
{
int const x = 1;
result<int const&, int> r( in_place_value, x );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( *r, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
X x( 1 );
result<X const&> r( x );
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 );
{
X const x( 1 );
result<X const&> r( x );
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 );
{
X x( 1 );
result<X const&> r = x;
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 );
{
X const x( 1 );
result<X const&> r = x;
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 );
{
X x( 1 );
result<X const&, X> r( in_place_value, x );
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 );
{
X const x( 1 );
result<X const&, X> r( in_place_value, x );
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 const&>, int&>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<int&, result<int const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int const&>, int const&>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<int const&, result<int const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<int const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<double const&>, int&>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int&, result<double const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<double const&>, int const&>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int const&, result<double const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<double const&>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<double const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&, int>, int&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&, float>, int&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&, int>, int const&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&, float>, int const&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&, int>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int const&, float>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<X const&>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<X const&>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<X const&>, X const>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<X const, result<X const&>>));
}
return boost::report_errors();
}

View File

@ -2,6 +2,16 @@
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#if defined(__GNUC__) && __GNUC__ >= 7
# pragma GCC diagnostic ignored "-Wformat-truncation"
#endif
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wformat-truncation" )
# pragma clang diagnostic ignored "-Wformat-truncation"
# endif
#endif
#include <boost/system/detail/snprintf.hpp>
#include <boost/core/lightweight_test.hpp>

View File

@ -8,28 +8,9 @@
// See library home page at http://www.boost.org/libs/system
// Avoid spurious VC++ warnings
# define _CRT_SECURE_NO_WARNINGS
#include <boost/system/error_code.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#include <iostream>
#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" )
int main()
{
std::cout
<< "The version of the C++ standard library being used does not"
" support header <system_error> so interoperation will not be tested.\n";
}
#else
#include <boost/core/lightweight_test.hpp>
#include <boost/core/snprintf.hpp>
#include <system_error>
#include <cerrno>
#include <string>
@ -119,7 +100,7 @@ class user_category_impl: public boost::system::error_category
{
public:
virtual const char * name() const BOOST_NOEXCEPT
virtual const char * name() const noexcept
{
return "user";
}
@ -127,12 +108,12 @@ public:
virtual std::string message( int ev ) const
{
char buffer[ 256 ];
std::sprintf( buffer, "user message %d", ev );
boost::core::snprintf( buffer, sizeof( buffer ), "user message %d", ev );
return buffer;
}
virtual boost::system::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT
virtual boost::system::error_condition default_error_condition( int ev ) const noexcept
{
if( ev == 4 )
{
@ -148,7 +129,7 @@ public:
}
}
virtual bool equivalent( int code, const boost::system::error_condition & condition ) const BOOST_NOEXCEPT
virtual bool equivalent( int code, const boost::system::error_condition & condition ) const noexcept
{
if( code == 4 && condition == make_error_condition( boost::system::errc::too_many_files_open_in_system ) )
{
@ -163,7 +144,7 @@ public:
return default_error_condition( code ) == condition;
}
// virtual bool equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT;
// virtual bool equivalent( const error_code & code, int condition ) const noexcept;
};
boost::system::error_category const & user_category()
@ -259,7 +240,7 @@ class user2_category_impl: public boost::system::error_category
{
public:
virtual const char * name() const BOOST_NOEXCEPT
virtual const char * name() const noexcept
{
return "user2";
}
@ -267,22 +248,22 @@ public:
virtual std::string message( int ev ) const
{
char buffer[ 256 ];
std::sprintf( buffer, "user2 message %d", ev );
boost::core::snprintf( buffer, sizeof( buffer ), "user2 message %d", ev );
return buffer;
}
virtual boost::system::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT
virtual boost::system::error_condition default_error_condition( int ev ) const noexcept
{
return boost::system::error_condition( ev, *this );
}
virtual bool equivalent( int code, const boost::system::error_condition & condition ) const BOOST_NOEXCEPT
virtual bool equivalent( int code, const boost::system::error_condition & condition ) const noexcept
{
return default_error_condition( code ) == condition;
}
virtual bool equivalent( const boost::system::error_code & code, int condition ) const BOOST_NOEXCEPT
virtual bool equivalent( const boost::system::error_code & code, int condition ) const noexcept
{
if( code.category() == *this )
{
@ -339,9 +320,6 @@ static void test_user2_category()
int main()
{
std::cout
<< "The version of the C++ standard library being used"
" supports header <system_error> so interoperation will be tested.\n";
test_generic_category();
test_system_category();
test_user_category();
@ -349,5 +327,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -4,16 +4,7 @@
#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()
@ -62,5 +53,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -8,12 +8,7 @@
#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
#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 50000
BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_LIBSTDCXX_VERSION < 50000" )
int main() {}

View File

@ -6,17 +6,8 @@
#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
@ -28,12 +19,12 @@ class my_category: public boost::system::error_category
{
public:
char const* name() const BOOST_NOEXCEPT
char const* name() const noexcept
{
return "mycat";
}
boost::system::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT
boost::system::error_condition default_error_condition( int ev ) const noexcept
{
switch( ev )
{
@ -123,5 +114,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -5,24 +5,15 @@
#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
char const* name() const noexcept
{
return "mycat";
}
@ -73,5 +64,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -5,24 +5,15 @@
#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
char const* name() const noexcept
{
return "mycat";
}
@ -53,5 +44,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -0,0 +1,89 @@
// 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_condition.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY is defined" )
int main() {}
#else
#include <system_error>
namespace sys = boost::system;
enum my_errc
{
enomem_c = ENOMEM
};
enum my_errn
{
enomem_n = ENOMEM
};
namespace std {
template<> struct is_error_code_enum<my_errc>
{
static const bool value = true;
};
template<> struct is_error_condition_enum<my_errn>
{
static const bool value = true;
};
} // namespace std
std::error_code make_error_code( my_errc e )
{
return std::error_code( e, std::generic_category() );
}
std::error_condition make_error_condition( my_errn e )
{
return std::error_condition( e, std::generic_category() );
}
int main()
{
sys::error_code ec = make_error_code( sys::errc::not_enough_memory );
sys::error_condition en( sys::errc::not_enough_memory );
BOOST_TEST_EQ( ec, en );
BOOST_TEST_EQ( en, ec );
BOOST_TEST_EQ( ec, enomem_c );
BOOST_TEST_EQ( enomem_c, ec );
BOOST_TEST_EQ( ec, enomem_n );
BOOST_TEST_EQ( enomem_n, ec );
BOOST_TEST_EQ( en, enomem_c );
BOOST_TEST_EQ( enomem_c, en );
#if BOOST_WORKAROUND(BOOST_MSVC, == 1800)
// msvc-12.0 has op== as a member of std::error_condition
#else
BOOST_TEST_EQ( en, enomem_n );
#endif
BOOST_TEST_EQ( enomem_n, en );
return boost::report_errors();
}
#endif

View File

@ -0,0 +1,46 @@
// Copyright 2023 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_category.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/snprintf.hpp>
#include <system_error>
// get_user_category
class user_category: public boost::system::error_category
{
public:
virtual const char * name() const noexcept
{
return "user";
}
virtual std::string message( int ev ) const
{
char buffer[ 256 ];
boost::core::snprintf( buffer, sizeof( buffer ), "user message %d", ev );
return buffer;
}
};
boost::system::error_category const & get_user_category()
{
static user_category instance;
return instance;
}
//
bool init_lwt = (boost::core::lwt_init(), true);
std::error_category const & cat = get_user_category();
int main()
{
BOOST_TEST_CSTR_EQ( cat.name(), "user" );
return boost::report_errors();
}

View File

@ -6,16 +6,7 @@
#include <boost/system/system_category.hpp>
#include <boost/system/generic_category.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>
void f1( std::error_code ec, int value, std::error_category const& category )
@ -94,5 +85,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -4,16 +4,7 @@
#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()
@ -75,5 +66,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -4,16 +4,7 @@
#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>
void f( std::error_code& e1, std::error_code e2 )
@ -85,5 +76,3 @@ int main()
return boost::report_errors();
}
#endif

View File

@ -4,16 +4,7 @@
#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()
@ -104,5 +95,3 @@ int main()
return boost::report_errors();
}
#endif

Some files were not shown because too many files have changed in this diff Show More