Compare commits

...

361 Commits

Author SHA1 Message Date
Peter Dimov
707b24bfa1 Update reference 2023-03-18 05:30:43 +02:00
Peter Dimov
bb1caae0d5 Update test/result_error_move.cpp 2023-03-18 05:25:44 +02:00
Klemens
c5c49894e6 Made result::error movable.
Closes #108.
2023-03-17 12:53:14 +08:00
Peter Dimov
ee80491cab Add C++03 deprecation notice 2023-03-06 07:49:33 +02:00
Peter Dimov
a83319fde1 Update ci.yml 2023-03-06 06:22:31 +02:00
Peter Dimov
4b90524729 Disable the constexpr constructors on GCC 4.7 2023-03-01 05:18:23 +02:00
Peter Dimov
6ac5f23999 Make error_category constructors unconditionally constexpr 2023-03-01 03:36:07 +02:00
Peter Dimov
f332a52597 Disable C4800 under msvc-14.0 2023-01-22 04:54:46 +02:00
Peter Dimov
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
Peter Dimov
805b260a7a Add test/result_value_construct5.cpp. Refs #104. 2023-01-22 01:58:29 +02:00
Peter Dimov
f32ffcba48 Update result_value_construct4.cpp 2023-01-22 01:25:30 +02:00
Peter Dimov
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
Peter Dimov
6a58b03eab Add test/result_value_construct4.cpp. Refs #104. 2023-01-22 01:15:08 +02:00
Peter Dimov
f0b27c5826 Enable implicit construction when the alternative is explicitly constructible from the argument. Fixes #103. 2023-01-21 20:09:53 +02:00
Peter Dimov
456b3c2dad Add test/result_error_construct4.cpp. Refs #103. 2023-01-21 19:45:32 +02:00
Peter Dimov
eb3f3a8e41 Use boost::core::snprintf in std_interop_test16 as well 2023-01-20 04:39:08 +02:00
Peter Dimov
e6986a51d5 Merge branch 'develop' into feature/issue-102 2023-01-20 04:38:15 +02:00
Peter Dimov
fb648760b5 Change uses of std::sprintf in tests to boost::core::snprintf, to avoid deprecation warnings 2023-01-20 02:29:38 +02:00
Peter Dimov
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
Peter Dimov
8449c62162 Update detail/mutex.hpp to use std::shared_mutex under the MS STL 2023-01-19 18:05:21 +02:00
Peter Dimov
4bca94ffc4 Merge branch 'develop' into feature/issue-102 2023-01-19 16:35:05 +02:00
Peter Dimov
3e6af15652 Add system/detail/mutex.hpp, use it in error_category_impl.hpp 2023-01-19 12:04:06 +02:00
Peter Dimov
86ff47ff63 Update std_interop_test16.cpp to not use asio/error.hpp. 2023-01-19 11:13:40 +02:00
Peter Dimov
06ddfdb4a6 Add std_interop_test16.cpp. Refs #102. 2023-01-19 05:46:11 +02:00
Peter Dimov
bb60a27b18 Update appveyor.yml 2023-01-12 20:38:54 +02:00
Peter Dimov
e478ba1a2b Update appveyor.yml 2023-01-12 15:18:11 +02:00
Peter Dimov
50100b0e81 Update CMakeLists.txt 2023-01-12 10:37:55 +02:00
Peter Dimov
bb502f5d67 Merge branch 'develop' into feature/pr-90 2023-01-12 10:36:56 +02:00
Peter Dimov
fa2349eee7 Add CMake tests to Appveyor 2023-01-12 05:45:30 +02:00
Peter Dimov
3d9acaf082 Update CMakeLists.txt 2023-01-12 05:41:30 +02:00
Peter Dimov
c6795eb9d0 Merge branch 'natvis' of https://github.com/vinniefalco/boost-system into feature/pr-90 2023-01-12 05:39:37 +02:00
Peter Dimov
57c295bbf7 Work around Clang 3.5 failures in result_value_access 2023-01-10 05:46:57 +02:00
Peter Dimov
36e3b2c6ae Work around Clang 3.5..3.8 failure in constexpr_test2 2023-01-10 05:14:36 +02:00
Peter Dimov
583cd8dba2 Update .drone.jsonnet 2023-01-10 04:36:37 +02:00
Peter Dimov
0c2de4cb2a Update .drone.jsonnet 2023-01-10 04:19:25 +02:00
Peter Dimov
3d595a6e79 Update ci.yml 2023-01-10 04:06:30 +02:00
Peter Dimov
b3faedfe3e Extend Clang 6 workaround to Clang 7 under Android. Fixes #100. 2023-01-10 03:09:20 +02:00
Peter Dimov
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
Peter Dimov
5d15aa1267 Add ec_hash_value_test 2023-01-07 19:42:59 +02:00
Peter Dimov
36e1236a0f Remove _Addr assignment from the constructor of std_category. Fixes #98. 2022-12-10 22:17:51 +02:00
Peter Dimov
2c20b6e7e5 Work around ERROR_INVALID_NAME failure on msvc-14.0, msvc-14.1 2022-12-10 19:45:14 +02:00
Peter Dimov
103f3b4f00 Print original error code in win32_generic_test 2022-12-10 18:47:54 +02:00
Peter Dimov
14f779e234 Update Win32 translation table. Closes #97. 2022-12-10 18:38:19 +02:00
Peter Dimov
bfccd4b4d9 Add win32_generic_test. Refs #97. 2022-12-10 18:24:34 +02:00
Peter Dimov
7ae6b317f3 Only disable C4351 on msvc-12.0 and earlier (refs #96) 2022-10-26 15:52:18 +03:00
Peter Dimov
9a6d79b841 Update revision history 2022-10-18 04:17:17 +03:00
Peter Dimov
ece71199a9 Document result<>::emplace 2022-10-18 04:15:40 +03:00
Peter Dimov
1e4c050d6c Add result<>::emplace (refs #85) 2022-10-18 00:46:59 +03:00
Peter Dimov
21115121bb Update ci.yml 2022-10-15 04:17:12 +03:00
Peter Dimov
956fa92a53 Update revision history 2022-09-27 20:32:03 +03:00
Peter Dimov
ee318f937f Document result<>::value_type, error_type, in_place_value, in_place_error. Closes #93. 2022-09-27 20:23:28 +03:00
Peter Dimov
19f99264de Document BOOST_SYSTEM_DISABLE_THREADS 2022-09-27 20:20:36 +03:00
Peter Dimov
3261bae6de Update .drone.jsonnet 2022-09-27 18:58:14 +03:00
Peter Dimov
20ce51858b Add in_place_value, in_place_error to result<>. Refs #93. 2022-09-27 18:18:16 +03:00
Peter Dimov
52d7429473 Add value_type, error_type typedefs to result. Refs #93. 2022-09-26 21:20:40 +03:00
Peter Dimov
53c00841fc Add support for BOOST_SYSTEM_DISABLE_THREADS (refs #92) 2022-09-08 18:32:26 +03:00
Peter Dimov
19e27a73e9 Disable failing test for msvc-12.0 2022-08-25 17:38:59 +03:00
Peter Dimov
19020ce925 Disable std_interop_test15 on g++ 4.8/4.9 2022-08-24 23:37:03 +03:00
Peter Dimov
3faf415026 Resolve ambiguities when comparing error_condition with std enums (refs #91) 2022-08-24 22:56:15 +03:00
Peter Dimov
a2df4d09da Update error_code_test3.cpp 2022-08-24 21:41:38 +03:00
Peter Dimov
455c6a6332 Add std_interop_test15.cpp 2022-08-24 21:40:20 +03:00
Peter Dimov
efb7634666 Move code/condition comparisons back outside class error_code; fixes #91 2022-08-24 21:10:05 +03:00
Peter Dimov
2bba3fd5e2 Add error_code_test3.cpp 2022-08-24 20:54:20 +03:00
Peter Dimov
8c740705e6 Add missing include 2022-08-21 19:42:10 +03:00
Peter Dimov
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
Peter Dimov
867f6d06d0 Add constexpr_test2.cpp 2022-08-21 19:13:12 +03:00
Vinnie Falco
ac1ed1ecc1 error_code default ctor is constexpr in c++11 2022-08-21 08:17:54 -07:00
Vinnie Falco
fe48c3058d add boost_system.natvis and interface source files 2022-08-19 11:40:36 -07:00
Peter Dimov
cc7c2f7ee4 Return v_.index() == 1 from has_error() to avoid -Wmaybe-uninitialized in error() 2022-08-02 22:44:34 +03:00
Peter Dimov
f2e1db8021 Constrain explicit value and error constructors to not accept zero arguments. Fixes #86. 2022-07-26 21:49:13 +03:00
Peter Dimov
ede243c42f Add (negative) tests for default constructability (refs #86) 2022-07-26 21:35:33 +03:00
Peter Dimov
1558aaa789 Update ci.yml 2022-07-26 20:41:24 +03:00
Peter Dimov
96b876d91a Add README.md 2022-06-19 02:19:58 +03:00
Peter Dimov
eb9ae4ac69 Update revision history 2022-06-19 01:30:17 +03:00
Peter Dimov
8fd487d496 Update documentation 2022-06-19 01:28:36 +03:00
Peter Dimov
5223c94aa9 Disable throws_assign_fail.cpp for GCC/release, because gcc-12 fails it at compile time 2022-06-18 23:07:41 +03:00
Peter Dimov
a5ee3f291c Update ci.yml 2022-06-18 21:47:57 +03:00
Peter Dimov
4200b00973 Add converting constructor to result (refs #82) 2022-06-18 18:12:06 +03:00
Peter Dimov
533dfe1688 Update revision history 2022-05-05 21:17:09 +03:00
Peter Dimov
7dec756a6f Update documentation 2022-05-05 21:15:03 +03:00
Peter Dimov
648a35838b Remove unnecessary overloads 2022-05-05 05:12:08 +03:00
Peter Dimov
256fe92dbb Add error_code(error_code const& ec, source_location const* loc) and a corresponding assign 2022-05-05 05:02:37 +03:00
Peter Dimov
5debb8a041 Update revision history 2022-05-05 02:30:07 +03:00
Peter Dimov
a97e5a0546 Move BOOST_NOINLINE to operator std::error_category 2022-04-22 22:41:26 +03:00
Peter Dimov
dc17edfa07 Remove clang-win from appveyor.yml 2022-04-22 21:16:09 +03:00
Peter Dimov
65da7dfd56 Update result_error_construct tests to use sys::error_code instead of (erroneously) std::error_code 2022-04-22 19:52:19 +03:00
Peter Dimov
9279001b8c Check BOOST_NO_CXX11_HDR_MUTEX when enabling <system_error> integration 2022-04-22 16:49:03 +03:00
Peter Dimov
616e652bd7 Suppress strict-aliasing warning for gcc 4.8 to 6 2022-04-21 21:06:14 +03:00
Peter Dimov
98439855bd Use static_cast instead of reinterpret_cast 2022-04-21 20:52:02 +03:00
Peter Dimov
986efb1420 Rework conversion to std::error_category to not allocate (closes #78) 2022-04-21 20:32:25 +03:00
Peter Dimov
28a13571b9 Restore the original system::error_code from std::error_code (refs #79) 2022-03-18 18:24:01 +02:00
Peter Dimov
65ed1eef66 Add std_interop_test14.cpp (refs #79) 2022-03-18 08:12:05 +02:00
Peter Dimov
6de20eeebc Add std_interop_test13 2022-03-18 08:12:05 +02:00
Peter Dimov
0a9266ea7e Add a comment explaining the one-time allocation in error_category_impl.hpp. Fixes #78. 2022-03-18 08:11:16 +02:00
Peter Dimov
adb9fc54cb Remove msvc-14.1 from ci.yml 2022-03-18 07:51:38 +02:00
Peter Dimov
e197c5e803 Update documentation 2022-02-18 19:43:08 +02:00
Peter Dimov
6d7a57a970 Add throw_exception_from_error overload for std::exception_ptr 2022-02-18 02:55:34 +02:00
Peter Dimov
00c71cf388 Add throw_exception_from_error overloads for boost::system::errc, std::errc 2022-02-17 21:55:47 +02:00
Peter Dimov
d930cea481 Update documentation 2022-02-14 02:05:44 +02:00
Peter Dimov
4f09f4adde Use throw_with_location in throw_exception_from_error 2022-02-13 22:50:20 +02:00
Peter Dimov
abd62362ef Update documentation 2022-02-09 20:52:23 +02:00
Peter Dimov
8d8e6a90de Add an errc::make_error_code overload taking a source location 2022-02-09 20:41:34 +02:00
Peter Dimov
716c2ed8ef Disable result tests on GCC 4.7 2022-02-07 21:40:26 +02:00
Peter Dimov
46a5ecd490 Do not include boost/system/result.hpp on GCC 4.7 2022-02-07 21:38:14 +02:00
Peter Dimov
79f4ef0416 Remove .drone.star 2022-02-07 21:34:11 +02:00
Peter Dimov
d0a8f7fbb7 Squash-merge feature/drone-jsonnet into develop 2022-02-07 21:33:48 +02:00
Peter Dimov
bc07ab1e25 Update .drone.star 2022-02-07 05:09:49 +02:00
Peter Dimov
c6bff94709 Update std_interop_test12.cpp 2022-02-07 04:35:44 +02:00
Peter Dimov
ae079810be Add std_interop_test12.cpp 2022-02-07 04:30:50 +02:00
Peter Dimov
928de55563 Update .drone.star 2022-02-07 03:47:42 +02:00
Peter Dimov
442138de0a Update .drone.star 2022-02-07 03:41:35 +02:00
Peter Dimov
de610efd53 Move conditions to detail/config.hpp 2022-02-07 03:16:23 +02:00
Peter Dimov
4b143cdacc Use BOOST_LIBSTDCXX_VERSION instead of BOOST_GCC; update syscat condition 2022-02-07 03:02:57 +02:00
Peter Dimov
a1cb578f52 Update .drone.star 2022-02-07 02:55:54 +02:00
Peter Dimov
96b5073b79 Update .drone.star 2022-02-07 02:03:13 +02:00
Peter Dimov
2bff5c7071 Update .drone.star 2022-02-07 01:27:59 +02:00
Peter Dimov
137128176d Update .drone.star 2022-02-07 01:14:28 +02:00
Peter Dimov
e0e0f56eae Update .drone.star 2022-02-07 00:54:07 +02:00
Peter Dimov
58d55a67e5 Update .drone.star 2022-02-07 00:01:53 +02:00
Peter Dimov
34dcb59ee8 Update drone.bat 2022-02-06 23:30:19 +02:00
Peter Dimov
33f6ecba31 Update Drone files 2022-02-06 23:21:40 +02:00
Peter Dimov
23fbfb1ffa Update .drone.star 2022-02-06 22:55:48 +02:00
Peter Dimov
5366407135 Add Windows jobs to Drone 2022-02-06 22:42:19 +02:00
Peter Dimov
72a79b1dcb Disable -Wsign-compare for GCC 4.4 2022-02-06 22:29:28 +02:00
Peter Dimov
a5c1ab042e Update Drone files 2022-02-06 22:25:45 +02:00
Peter Dimov
c2beb75d66 Merge pull request #59 from sdarwin/drone
Drone config
2022-02-06 22:08:07 +02:00
Peter Dimov
54d9f4f38a Update documentation 2022-02-05 19:25:43 +02:00
Peter Dimov
b92be6417a Add a source_location parameter to throw_exception_from_error 2022-02-05 05:24:29 +02:00
Peter Dimov
245fff8af3 Update ci.yml 2022-02-05 03:11:09 +02:00
Peter Dimov
c359af3141 Update system_error constructors 2022-02-04 21:34:14 +02:00
Peter Dimov
50cad72fac Update system_error_test3.cpp 2022-02-04 21:22:35 +02:00
Peter Dimov
9554d8bbd3 Suppress incorrect warnings from GCC 7/8 2022-02-03 19:02:19 +02:00
Peter Dimov
cf9d986871 Update documentation 2022-02-03 18:47:53 +02:00
Peter Dimov
a5d68e52e6 Add throw_exception_from_error overload for std::error_code 2022-02-03 18:35:42 +02:00
Peter Dimov
9c6a09f41d Mark throw_exception_from_error as noinline 2022-02-03 09:37:59 +02:00
Peter Dimov
b9c26b9fa0 Add detail::system_error_category_message, use it in error_code::message 2022-02-03 05:47:43 +02:00
Peter Dimov
2e2430c4fa Add error_code::category_name helper, use it in to_string 2022-02-03 04:36:58 +02:00
Peter Dimov
4b1caad727 Avoid sign conversion warnings in error_code::value 2022-01-19 17:30:56 +02:00
Peter Dimov
5b96abbaa8 Undeprecate linux_error.hpp (closes #77) 2021-12-27 02:53:04 +02:00
Peter Dimov
2e1c800d82 Update appveyor.yml 2021-12-21 22:35:10 +02:00
Peter Dimov
04a79d710f Merge branch 'fix_error_code_wostream' of https://github.com/MarcelRaad/system into feature/pr-76 2021-12-21 19:51:50 +02:00
Peter Dimov
5700936367 Add ec_wstream_test (refs #76) 2021-12-21 19:51:08 +02:00
Marcel Raad
86b031cab9 Fix error_code's operator<< for arbitrary basic_ostream specializations
This fixes a regression from commit
a9b64a888a.
Calling `operator<<` with `std::string` only works for `std::ostream`.
Use `c_str()` to restore the previous behavior of using `const char*`,
which works for any `basic_ostream` specialization.
2021-12-21 13:17:26 +01:00
Peter Dimov
204e65f725 Add msvc-14.0 to GHA 2021-12-11 03:42:52 +02:00
Peter Dimov
01ce081470 Disable errc_t -> arithmetic conversions when initializing result (closes #74) 2021-12-11 01:22:08 +02:00
Peter Dimov
8c9ceba775 Add negative test for constructing result<int> from errc_t (refs #74) 2021-12-09 20:19:05 +02:00
Peter Dimov
91c0dd9a74 Merge pull request #73 from kpushkaryov/patch-1
Fix a typo
2021-11-17 06:24:18 +02:00
Kirill Pushkaryov
189fff42fe Fix a typo 2021-11-17 10:59:03 +07:00
Peter Dimov
3b4045c149 Minor doc update 2021-11-17 04:11:15 +02:00
Peter Dimov
3d877a1fca Update meta/libraries.json 2021-11-11 04:51:03 +02:00
Peter Dimov
128bdf9db2 Minor usage section changes 2021-11-11 04:33:06 +02:00
Peter Dimov
0e84860604 Add another usage subsection 2021-11-11 04:09:49 +02:00
Peter Dimov
83a306f3bf Update introduction 2021-11-10 20:36:57 +02:00
Peter Dimov
7dce2e3f42 Change 'wrapping' to 'adapting' 2021-11-10 18:52:41 +02:00
Peter Dimov
292c6825c6 Add another usage subsection 2021-11-09 22:05:45 +02:00
Peter Dimov
0d90d3d883 Add myimg_category implementation to usage example 2021-11-08 20:50:41 +02:00
Peter Dimov
81fec2b171 Add another usage subsection 2021-11-07 23:45:25 +02:00
Peter Dimov
4e15afe5be Add error handling and programming categories to libraries.json 2021-11-07 20:32:42 +02:00
Peter Dimov
8d1a866920 Add a usage subsection on wrapping zlib errors 2021-11-05 22:05:23 +02:00
Peter Dimov
09466c85b4 Add another usage subsection 2021-11-05 20:38:03 +02:00
Peter Dimov
baef8e50ea Rename 'Usage Examples' to 'Usage', add another subsection 2021-11-05 16:48:33 +02:00
Peter Dimov
5034f11a3a Add usage examples 2021-11-02 03:12:26 +02:00
Peter Dimov
f78b036665 Update #if condition 2021-10-29 21:13:10 +03:00
Ed Catmur
9b0d735040 Add __attribute__((__format__)) to snprintf
This attribute will check format string bugs and is required for clean compile if -Wformat-nonliteral is enabled.
2021-10-29 11:59:03 +01:00
Peter Dimov
bfebaf53d7 Add static_assert to cmake_subdir_test 2021-10-28 23:48:03 +03:00
Peter Dimov
8338e80295 Enable syntax hightlighting 2021-10-28 23:17:20 +03:00
Peter Dimov
2b23aaab16 Add msvc-14.3 to ci.yml 2021-10-28 23:16:53 +03:00
Peter Dimov
7933300b6f Disable test on g++ 4.x because no std::io_errc 2021-10-11 03:30:50 +03:00
Peter Dimov
4ec1e54099 Enable error_code construction from enums specializing std::is_error_code_enum. Fixes #70. 2021-10-11 02:02:22 +03:00
Peter Dimov
5217e58a7d Enable implicit construction for aggregates using {{ ... }} 2021-10-02 22:07:05 +03:00
Peter Dimov
ce37e23491 Protect against dangling references in op* and value() 2021-10-02 19:16:04 +03:00
Peter Dimov
420a262733 Fix warnings_test.cpp 2021-10-02 17:25:31 +03:00
Peter Dimov
e15bccc09b Fix cmake_install_test/main.cpp 2021-10-02 16:57:38 +03:00
Peter Dimov
bb775c071a Update system_error::what to use error_code::what 2021-10-02 15:00:40 +03:00
Peter Dimov
01676ae42f Update documentation 2021-10-02 14:47:07 +03:00
Peter Dimov
eefcc5dcf6 Add error_code::what 2021-10-02 14:41:27 +03:00
Peter Dimov
f2d3a0decf Update documentation 2021-10-02 01:39:06 +03:00
Peter Dimov
0ccf08509b Add a constructor taking ErrorCodeEnum and a source location 2021-10-01 23:04:04 +03:00
Peter Dimov
7a72aee355 Merge branch 'develop' into feature/std-category-2 2021-09-24 23:54:51 +03:00
Peter Dimov
a8df99e927 Use source_location::to_string in system_error::build_message 2021-09-24 20:40:19 +03:00
Peter Dimov
85c7d92302 Avoid instantiating the system category in error_code::operator std::error_code 2021-09-24 15:24:45 +03:00
Peter Dimov
4c201d26b2 Update std_interop_test10 2021-09-24 04:29:29 +03:00
Peter Dimov
1659dfbeba Avoid instantiating generic_category in error_condition::operator std::error_condition 2021-09-24 04:27:08 +03:00
Peter Dimov
d2b8b54356 Do not use std::system_category under MinGW and g++ 4.x 2021-09-21 16:35:40 +03:00
Peter Dimov
41f7ea49cb Do not use std::system_category under VS2013 2021-09-21 16:02:12 +03:00
Peter Dimov
0b22dc595f Merge branch 'develop' into feature/std-category-2 2021-09-21 15:57:56 +03:00
Peter Dimov
aab58b0d5b Add std_interop_test10 2021-09-21 15:57:39 +03:00
Peter Dimov
ad66ea43a3 Revert addition of get_generic_std_category, get_system_std_category (they need this); do not use std::system_category on Cygwin 2021-09-21 15:45:00 +03:00
Peter Dimov
811564f186 Disable failing comparisons in std_interop_test6; stdlibs are at fault 2021-09-21 15:11:19 +03:00
Peter Dimov
a7e4879e55 Fix message comparisons in std_interop_test 2021-09-21 15:06:28 +03:00
Peter Dimov
9b11d864be Add helper functions get_generic_std_category, get_system_std_category 2021-09-21 15:01:44 +03:00
Peter Dimov
cc6a61b6c5 Convert system_category to std::system_category 2021-09-21 05:34:05 +03:00
Peter Dimov
9151633c95 Merge branch 'develop' into feature/std-category 2021-09-20 17:41:47 +03:00
Peter Dimov
5e0db22075 Include errc.hpp in system_error.hpp 2021-09-20 17:41:34 +03:00
Peter Dimov
60a20eeeb9 Retain old generic_category conversion behavior on g++ 4.8/4.9 2021-09-19 18:44:45 +03:00
Peter Dimov
1c8128e4cb Merge branch 'develop' into feature/std-category 2021-09-19 18:12:59 +03:00
Peter Dimov
1879ba6d35 Minor test update 2021-09-19 18:12:46 +03:00
Peter Dimov
b1dec88674 Convert generic_category to std::generic_category 2021-09-19 17:08:46 +03:00
Peter Dimov
5fd2535d9f Excise generic_category() references from error_condition 2021-09-19 16:04:16 +03:00
Peter Dimov
b39f239b3d Update documentation 2021-09-19 15:53:13 +03:00
Peter Dimov
abb13e707d Minor test fixes 2021-09-19 15:46:03 +03:00
Peter Dimov
bf34091cfe Add error_code_test2 2021-09-19 15:41:20 +03:00
Peter Dimov
e3f198e52c Add error_condition::to_string 2021-09-19 15:37:49 +03:00
Peter Dimov
05581aba03 Add error_condition_test3 2021-09-19 15:26:19 +03:00
Peter Dimov
47137ad116 Change predefined error_category identifiers to be contiguous for better codegen 2021-09-19 15:04:51 +03:00
Peter Dimov
c02cd2b004 Add private error_code::equals, use it in error_category::equivalent 2021-09-19 05:24:08 +03:00
Peter Dimov
c8c5ad1ce5 Rework error_condition::op== to not require the generic_category() instance 2021-09-19 04:49:35 +03:00
Peter Dimov
361834e49c Minor documentation corrections 2021-09-18 16:57:21 +03:00
Peter Dimov
360effcf1d Remove static/shared tests, System is header-only 2021-09-18 02:23:21 +03:00
Peter Dimov
aaa893b5d6 Add mp11 to cmake_subdir_test/CMakeLists.txt 2021-09-18 00:08:30 +03:00
Peter Dimov
ff0bd3294f Add back predef, winapi needs it 2021-09-17 23:54:33 +03:00
Peter Dimov
aedadc27ce Update test/cmake_subdir_test/CMakeLists.txt 2021-09-17 21:31:13 +03:00
Peter Dimov
aad1212cfd Update tests/CMakeLists.txt 2021-09-17 21:15:13 +03:00
Peter Dimov
c15c2eeb74 Update dependencies in CMakeLists.txt 2021-09-17 21:10:53 +03:00
Peter Dimov
0ea47dd886 Add CMake jobs to ci.yml 2021-09-17 21:00:18 +03:00
Peter Dimov
08c12e8ad5 Document result<void, E> 2021-09-17 20:16:01 +03:00
Peter Dimov
7d3cfdd09a Update test/result_value_construct 2021-09-17 19:54:53 +03:00
Peter Dimov
15f94537a6 Update test/result_value_access 2021-09-17 19:53:11 +03:00
Peter Dimov
c0f38e2f3e Update test/result_swap 2021-09-17 19:46:56 +03:00
Peter Dimov
ac28a8cec9 Update test/result_move_assign 2021-09-17 19:44:58 +03:00
Peter Dimov
4169ef3ce6 Update test/result_error_construct 2021-09-17 19:36:58 +03:00
Peter Dimov
ce49a7d1be Update test/result_move_construct 2021-09-17 19:35:20 +03:00
Peter Dimov
1a4eb29719 Update test/result_error_access 2021-09-17 19:35:05 +03:00
Peter Dimov
465f6c57da Update test/result_eq 2021-09-17 19:34:44 +03:00
Peter Dimov
cb8db34d7b Update test/result_copy_assign 2021-09-17 19:34:26 +03:00
Peter Dimov
2b6a708070 Update test/result_copy_construct 2021-09-17 19:25:20 +03:00
Peter Dimov
50f84f16dc Add result<void, E> specialization 2021-09-17 19:22:15 +03:00
Peter Dimov
fd21395802 Minor indentation fixes 2021-09-17 18:50:30 +03:00
Peter Dimov
cebb011a58 Update indentation in reference 2021-09-17 18:43:30 +03:00
Peter Dimov
3f67d3def5 Rename throw_exception_from_error_code to throw_exception_from_error 2021-09-17 18:33:04 +03:00
Peter Dimov
f2b3ae7e2b Document throw_exception_from_error_code 2021-09-17 18:28:53 +03:00
Peter Dimov
48e56b9874 Update revision history 2021-09-17 18:19:24 +03:00
Peter Dimov
967b7cbc98 Add result to reference 2021-09-17 18:16:54 +03:00
Peter Dimov
c8492a705d Use unsafe_get instead of *get_if 2021-09-17 15:47:35 +03:00
Peter Dimov
a3187439e3 Disable warning in after_main_test 2021-09-16 19:49:17 +03:00
Peter Dimov
19f9d0c5b4 Fix unused parameter error 2021-09-16 19:43:32 +03:00
Peter Dimov
d17f7d7fe6 Fix unused variable warning 2021-09-16 19:32:22 +03:00
Peter Dimov
36843a4e2d Fix unused variable warnings 2021-09-16 19:30:28 +03:00
Peter Dimov
a6c988181e Include result.hpp in <boost/system.hpp> 2021-09-16 19:25:26 +03:00
Peter Dimov
10572b7a59 Trim includes in system_error.hpp 2021-09-16 19:21:27 +03:00
Peter Dimov
fe3d0e6c14 Update all references to <system_error> to refer to Boost.System 2021-09-16 19:16:30 +03:00
Peter Dimov
ae77563039 Define result in boost::system instead of in boost::result 2021-09-16 18:56:35 +03:00
Peter Dimov
fd852c675e Add <boost/system/result.hpp> 2021-09-16 18:47:05 +03:00
Peter Dimov
6156076dab Specify assign in terms of construction and assignment 2021-09-16 18:13:55 +03:00
Peter Dimov
984f8f1a92 Reorder constructor overloads 2021-09-16 18:04:27 +03:00
Peter Dimov
b507b2294e Unbreak the loc == 0 case, even though the specification disallows it 2021-09-16 03:12:20 +03:00
Peter Dimov
39ad22d660 Update reference 2021-09-16 03:07:32 +03:00
Peter Dimov
3b70265ced Rearrange error_code::failed to improve codegen 2021-09-15 16:42:47 +03:00
Peter Dimov
a65b91b3fb Merge branch 'develop' into feature/source-location 2021-09-15 16:06:55 +03:00
Peter Dimov
bed0d59d22 Disable failing tests under g++ 7 -std=c++17 2021-09-15 15:23:52 +03:00
Peter Dimov
5e642b1d43 Remove error_condition::failed_ in order to prioritise construction efficiency over failed() efficiency (latter is rare for conditions) 2021-09-15 14:54:26 +03:00
Peter Dimov
b35b47d8c2 Reformat what() message slightly 2021-09-15 13:42:54 +03:00
Peter Dimov
f21035f8af Move location to the end of what() 2021-09-15 07:58:24 +03:00
Peter Dimov
cd98f4edd7 Update system_error to incorporate the source location in what() 2021-09-15 07:42:57 +03:00
Peter Dimov
a9b64a888a Add support for source_location to error_code 2021-09-15 07:03:18 +03:00
Peter Dimov
bb4b500cfc Update Windows error mapping to match msvc-14.2 <system_error> 2021-09-08 00:48:55 +03:00
Peter Dimov
d44dab91dc Merge pull request #62 from rohitk5252/patch-2
Update index.html
2021-09-08 00:24:46 +03:00
Peter Dimov
2b6498ad80 Merge pull request #63 from rohitk5252/patch-3
Update system.adoc
2021-09-08 00:24:30 +03:00
Peter Dimov
22072bfbc9 Merge pull request #64 from rohitk5252/patch-5
Update Jamfile.v2
2021-09-08 00:24:08 +03:00
Peter Dimov
65f644d5de Switch ubuntu-16.04 jobs to ubuntu-18.04 2021-09-07 21:57:40 +03:00
Peter Dimov
f967081d7e Merge pull request #69 from marc-groundctl/map-broken-pipe
Map ERROR_BROKEN_PIPE to errc_t::broken_pipe
2021-09-07 21:34:22 +03:00
Marc Aldorasi
19e9f08666 Map ERROR_BROKEN_PIPE to errc_t::broken_pipe 2021-09-07 12:02:02 -04:00
Peter Dimov
b41139b28e Update documentation 2021-06-16 03:06:26 +03:00
Peter Dimov
39a19f3c90 Add constexpr to op== against error code enums 2021-06-16 03:06:11 +03:00
Peter Dimov
b4dd5e98c9 Update appveyor.yml 2021-06-15 20:53:48 +03:00
Peter Dimov
41e3a7c8af Update appveyor.yml 2021-06-15 06:02:49 +03:00
Peter Dimov
aee97e91ce Update .travis.yml 2021-06-15 05:34:04 +03:00
Peter Dimov
98533dedb3 Disable failing tests on g++ 4.8 and 4.9 2021-06-15 05:32:04 +03:00
Peter Dimov
fe811d1dd1 Update .travis.yml 2021-06-15 03:17:42 +03:00
Peter Dimov
137ecb4abf Add more tests to std_interop_test7 2021-06-15 03:06:07 +03:00
Peter Dimov
e5cd7bf852 Placate g++ 6 and earlier 2021-06-15 02:25:13 +03:00
Peter Dimov
96cd1c0163 Add error_code comparisons against standard error code enums (to resolve the ambiguity when an enum is both standard and ours) 2021-06-15 02:17:26 +03:00
Peter Dimov
a9da17f2e2 Add std_interop_test9 2021-06-15 01:59:51 +03:00
Peter Dimov
f26dfd3dd7 Add error_code comparisons against standard error condition enums (to resolve the ambiguity when an enum is both standard and ours) 2021-06-15 01:52:32 +03:00
Peter Dimov
d09c998eb2 Add std_interop_test8 2021-06-15 01:43:49 +03:00
Peter Dimov
2374e85dc7 Add std_interop_test7 2021-06-14 22:25:31 +03:00
Peter Dimov
9167bf8ee8 Update documentation 2021-06-14 21:23:01 +03:00
Peter Dimov
7f7a9da4d5 Update revision history 2021-06-14 20:07:18 +03:00
Peter Dimov
67ae4d3c47 Disable std_interop_test5 on g++ 4.8 and 4.9, rather. 2021-06-14 19:04:15 +03:00
Peter Dimov
ee028e2f9d Remove tabs 2021-06-14 18:28:29 +03:00
Peter Dimov
7657188802 Disable std_interop_test5 on g++ 4.7 and 4.8; these crash on Xenial, but the real g++ 4.8 on CentOS 7 and Trusty works 2021-06-14 18:07:06 +03:00
Peter Dimov
210c54b09a Update .travis.yml 2021-06-14 17:36:29 +03:00
Peter Dimov
87bb5616a8 Update .travis.yml 2021-06-14 17:10:56 +03:00
Peter Dimov
6de562c79d Update .travis.yml 2021-06-14 15:10:36 +03:00
Peter Dimov
8efb96350f Clang 6 needs more help with mixed comparisons 2021-06-14 14:44:07 +03:00
Peter Dimov
88a7be42b5 Update Clang version check 2021-06-14 14:38:26 +03:00
Peter Dimov
a3225e78e2 Update GCC version check 2021-06-14 14:35:50 +03:00
Peter Dimov
3c469fe710 Update std_interop_test5.cpp 2021-06-14 04:19:45 +03:00
Peter Dimov
c2d044f34e Add std_interop_test6 2021-06-14 04:09:24 +03:00
Peter Dimov
9fdfa6c645 Move code == condition comparisons into error_code, unwrap std::error_code when needed 2021-06-14 04:06:24 +03:00
Peter Dimov
42a257e17c Add operator<< for error_condition 2021-06-14 03:59:44 +03:00
Peter Dimov
26d0d32c54 Add std_interop_test5 2021-06-14 03:53:55 +03:00
Peter Dimov
70b5449e99 Resolve ambiguity for std::error_code == boost::system::error_code 2021-06-14 03:53:00 +03:00
Peter Dimov
8043ce0278 Resolve ambiguity for std::error_code == boost::system::error_condition 2021-06-14 03:42:50 +03:00
Peter Dimov
83a2933afa Disable failing test cases on clang-6 and earlier 2021-06-14 02:54:40 +03:00
Peter Dimov
2e707ca921 Disable -Wstrict-aliasing on g++ 6, really 2021-06-14 02:50:31 +03:00
Peter Dimov
a6c4b6329c Add a deleted T const& conversion for clang-6 and earlier 2021-06-14 02:35:48 +03:00
Peter Dimov
5b1909eba4 Disable -Wstrict-aliasing on g++ 6 and below 2021-06-14 02:15:37 +03:00
Peter Dimov
9dc13fd82a Change value() when holding std::error_code 2021-06-14 02:09:31 +03:00
Peter Dimov
e9cdb10409 Use std::hash<std::error_code> in hash_value 2021-06-14 01:51:33 +03:00
Peter Dimov
e625bd0eea Do not access d2_ when <system_error> isn't available; use std::error_code comparisons in op== and op< 2021-06-13 22:48:31 +03:00
Peter Dimov
66656f7044 Use copy-init instead of direct-init for older clangs 2021-06-13 20:45:50 +03:00
Peter Dimov
0d8511f571 Use reinterpret_cast to pointer instead of to reference 2021-06-13 20:40:27 +03:00
Peter Dimov
fbc49bbaa0 Add more tests to std_interop_test3 2021-06-13 19:51:02 +03:00
Peter Dimov
344eb1e1f8 Rework error_code for better std interop 2021-06-13 19:47:37 +03:00
Peter Dimov
20b8e90dff Add detail/snprintf.hpp 2021-06-13 18:58:50 +03:00
Peter Dimov
a0136e570d Update tests/CMakeLists 2021-06-13 18:45:15 +03:00
Peter Dimov
6586fcb01e Add errc_test3.cpp 2021-06-13 18:42:59 +03:00
Peter Dimov
b74b1e3c8c Merge branch 'develop' into feature/error-condition 2021-06-13 07:12:16 +03:00
Peter Dimov
1caaacff57 Split reference into headers 2021-06-13 06:58:48 +03:00
Peter Dimov
75d5287558 Update copyright 2021-06-13 05:59:04 +03:00
Peter Dimov
25eaf0fdae Document comparisons as inline friends; use value() and category() instead of val_ and cat_; add subheadings 2021-06-13 05:58:16 +03:00
Peter Dimov
f43293f451 Increase ToC levels 2021-06-13 05:24:30 +03:00
Peter Dimov
f8ab3df822 Initialize failed_ in the other two constructors 2021-06-13 05:05:31 +03:00
Peter Dimov
f6fb85d7d3 Revert "Update Travis to use undefined-sanitizer; disable failed_constexpr_test"
This reverts commit c069ae048f.
2021-06-13 04:59:49 +03:00
Peter Dimov
9cd9d8732f Revert "Update test/Jamfile"
This reverts commit 3d4c31c213.
2021-06-13 04:59:38 +03:00
Peter Dimov
1b7fd6854d Revert "Disable failing tests on g++-7/c++17"
This reverts commit b20191f8d7.
2021-06-13 04:58:53 +03:00
Peter Dimov
610d5f3f78 Revert "Mark error_condition::failed, error_condition::message as deprecated; revert op bool"
This reverts commit 329e72fb92.
2021-06-13 04:56:18 +03:00
Peter Dimov
88f7c2bf53 Revert "Update documentation"
This reverts commit 8962c9101a.
2021-06-13 04:47:19 +03:00
Peter Dimov
723daf5d57 Update changelog 2021-06-13 04:39:39 +03:00
Peter Dimov
3d4c31c213 Update test/Jamfile 2021-06-13 01:13:48 +03:00
Peter Dimov
c069ae048f Update Travis to use undefined-sanitizer; disable failed_constexpr_test 2021-06-13 01:08:54 +03:00
Peter Dimov
28e1b919ac Disable failing test 2021-06-12 22:36:12 +03:00
Peter Dimov
b20191f8d7 Disable failing tests on g++-7/c++17 2021-06-12 22:20:38 +03:00
Peter Dimov
d019c1cdae Remove detail/is_generic_value.hpp 2021-06-12 22:01:16 +03:00
Peter Dimov
ff77d4c094 Do not call generic_category() in system_error_category 2021-06-12 21:59:22 +03:00
Peter Dimov
a21a3050a5 Use nullptr for &generic_category() in error_condition 2021-06-12 21:51:51 +03:00
Peter Dimov
08d62ac444 Restore Sun workaround 2021-06-12 05:42:03 +03:00
Peter Dimov
45e9dfeba9 Declare operator std::error_category as BOOST_SYMBOL_VISIBLE 2021-06-12 05:12:58 +03:00
Peter Dimov
7d9eb384c6 Make error_category comparisons inline friends, to avoid clang 'member call on mutable' constexpr errors 2021-06-12 04:52:21 +03:00
Peter Dimov
04bfb05b19 Improve the implementation of the std::category conversion 2021-06-12 04:29:13 +03:00
Peter Dimov
a650f5d676 Remove cmake_install_test dependency on Boost::core 2021-06-12 00:18:26 +03:00
Peter Dimov
6ab5fd9dac Update ci.yml 2021-06-11 22:15:46 +03:00
Peter Dimov
ed14d74323 Update .travis.yml 2021-06-11 22:12:35 +03:00
Peter Dimov
ff9bca96e3 Add boost/system.hpp 2021-06-11 21:15:17 +03:00
Peter Dimov
8560290b71 Merge pull request #67 from Lastique/feature/add_win32_error_not_supported
Add support for Windows error code ERROR_NOT_SUPPORTED
2021-05-29 03:36:51 +03:00
Peter Dimov
8b41ff22a6 Update ci.yml 2021-05-29 02:41:45 +03:00
Peter Dimov
79f9a297cd Update ci.yml 2021-05-29 01:15:51 +03:00
Andrey Semashev
344ea58a77 Added support for Windows error code ERROR_NOT_SUPPORTED.
The error code description reads as "The request is not supported," which
is close to POSIX ENOTSUP "Not supported" and matches MSVC standard library
implementation.
2021-05-29 00:55:40 +03:00
Peter Dimov
5eae4824ab Update .github/workflows 2021-04-19 21:29:14 +03:00
Peter Dimov
f502e6cda4 Update .github/workflows 2021-04-19 20:30:50 +03:00
Peter Dimov
69bc20fb15 Merge pull request #66 from vahtis/vahtis-patch-1
Define BOOST_SYSTEM_DEPRECATED for Oracle Developer Studio
2021-03-22 17:23:49 +02:00
vahtis
fbf7f4a417 Define BOOST_SYSTEM_DEPRECATED for Oracle Developer Studio
Added Oracle Developer Studio specific define.
2021-03-22 15:38:27 +02:00
sdarwin
a688d7834a add drone config [ci skip] 2021-01-21 19:45:47 +00:00
Peter Dimov
689e09e86f Merge pull request #65 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-21 18:58:57 +02:00
Edward Diener
b92035d4d2 [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-21 11:11:01 -05:00
Rohit Kumar
1ba5c9efc4 Update Jamfile.v2 2021-01-20 16:35:23 +05:30
Rohit Kumar
23db4e8d69 Update system.adoc 2021-01-20 16:31:00 +05:30
Rohit Kumar
189cc0c185 Update index.html
Changed http:// to https://
2021-01-20 16:28:26 +05:30
Peter Dimov
63a32cea9a Remove deprecation message from windows_error.hpp (closes #57) 2021-01-02 22:16:39 +02:00
Peter Dimov
3e2cb8975f Update .travis.yml 2021-01-02 16:19:54 +02:00
Peter Dimov
4e7c88779b Merge branch 'patch-1' of https://github.com/tanzislam/system into feature/pr-56 2020-12-24 02:11:38 +02:00
Peter Dimov
3ee8200e75 Add .github/workflows 2020-12-24 02:10:50 +02:00
Tanzinul Islam
516484a821 Define BOOST_SYSTEM_DEPRECATED for other compilers
Currently compilation fails with Oracle Developer Studio 12.6, for example:

    $ ./b2 toolset=sun threading=multi variant=debug link=static cxxflags=-std=c++11 --with-system
    ...
    "./boost/system/detail/error_condition.hpp", line 96: Error: BOOST_SYSTEM_DEPRECATED is not defined.
    "./boost/system/detail/error_condition.hpp", line 96: Error: No direct declarator preceding ""this function is slated for removal"".
    "./boost/system/detail/error_condition.hpp", line 96: Error: No direct declarator preceding "(".
2020-12-23 23:57:18 +00:00
Peter Dimov
39bd8ba98f Use address-model=32 for msvc-9.0, 10.0, 11.0 2020-10-06 13:29:14 +03:00
Peter Dimov
f1c0a52426 Fix typo 2020-10-06 04:44:07 +03:00
Peter Dimov
8962c9101a Update documentation 2020-10-06 04:26:02 +03:00
Peter Dimov
329e72fb92 Mark error_condition::failed, error_condition::message as deprecated; revert op bool 2020-10-06 04:03:13 +03:00
Peter Dimov
6758690d2f Add BOOST_SYSTEM_DEPRECATED; mark deprecated categories 2020-10-06 03:42:00 +03:00
Peter Dimov
8f32183b63 Mark platform-specific error headers as deprecated; split tests 2020-10-06 03:21:38 +03:00
Peter Dimov
99db03ee96 Remove tab 2020-09-04 17:02:14 +03:00
123 changed files with 14184 additions and 1393 deletions

319
.drone.jsonnet Normal file
View File

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

23
.drone/drone.bat Normal file
View File

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

24
.drone/drone.sh Executable file
View File

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

578
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,578 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-4.8
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: gcc-10
cxxstd: "03,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
- toolset: gcc-12
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install: g++-12
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,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-latest
container: ubuntu:18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,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-20.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-20.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17"
os: ubuntu-20.04
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17"
os: ubuntu-20.04
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install: clang-15
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-11
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-12
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python git g++
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- 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%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Use library with add_subdirectory
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error
windows-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- 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@v3
- 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@v3
- 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

@@ -4,8 +4,6 @@
language: cpp
sudo: false
dist: xenial
branches:
@@ -26,7 +24,26 @@ matrix:
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
addons:
apt:
packages:
- g++-multilib
- os: linux
arch: arm64
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
- os: linux
arch: ppc64le
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
- os: linux
arch: s390x
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
- os: linux
compiler: g++-4.4
@@ -49,108 +66,20 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
dist: trusty
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,2a
compiler: g++-11
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-11 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-10
- g++-11
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: trusty
@@ -171,189 +100,75 @@ matrix:
- clang-3.4
- os: linux
dist: trusty
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
compiler: clang++-12
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-12 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-3.5
- clang-12
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-7
- os: linux
compiler: clang++-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- os: linux
compiler: clang++-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-9
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-12 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: xenial
compiler: clang++-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: xenial
compiler: clang++-10
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: trusty
dist: bionic
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- os: linux
dist: trusty
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
- os: osx
compiler: clang++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
- os: freebsd
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17,2a
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode7.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode8.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode9.4
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode10.1
- os: osx
osx_image: xcode11.3
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
- os: osx
osx_image: xcode12.2
compiler: clang++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
- os: linux
env: CMAKE=1
script:
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=system -DBUILD_TESTING=ON ..
- ctest --output-on-failure -R boost_system
- cmake -DBOOST_INCLUDE_LIBRARIES=system -DBUILD_TESTING=ON ..
- cmake --build . --target tests
- ctest --output-on-failure --no-tests=error
- os: linux
env: CMAKE=1 BUILD_SHARED_LIBS=ON
script:
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBUILD_SHARED_LIBS=ON -DBOOST_INCLUDE_LIBRARIES=system -DBUILD_TESTING=ON ..
- ctest --output-on-failure -R boost_system
- cmake -DBUILD_SHARED_LIBS=ON -DBOOST_INCLUDE_LIBRARIES=system -DBUILD_TESTING=ON ..
- cmake --build . --target tests
- ctest --output-on-failure --no-tests=error
- os: linux
env: CMAKE_SUBDIR_TEST=1
@@ -375,7 +190,7 @@ matrix:
script:
- pip install --user cmake
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES="system;core" -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake -DBOOST_INCLUDE_LIBRARIES=system -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build . --target install
- cd ../libs/system/test/cmake_install_test && mkdir __build__ && cd __build__
- cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
@@ -396,7 +211,7 @@ install:
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 -j3 libs/system/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
- ./b2 -j3 libs/system/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
notifications:
email:

View File

@@ -1,8 +1,8 @@
# Copyright 2018-2020 Peter Dimov
# Copyright 2018-2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_system VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
@@ -13,10 +13,22 @@ target_include_directories(boost_system INTERFACE include)
target_link_libraries(boost_system
INTERFACE
Boost::assert
Boost::config
Boost::throw_exception
Boost::variant2
Boost::winapi
)
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)
add_subdirectory(test)

25
README.md Normal file
View File

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

View File

@@ -16,20 +16,13 @@ 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
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
CXXSTD: 14,17
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14,17
CXXSTD: 14,17,latest
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
@@ -47,6 +40,12 @@ environment:
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_SUBDIR: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMAKE_INSTALL: 1
install:
- set BOOST_BRANCH=develop
@@ -66,4 +65,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
- 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

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

View File

@@ -4,19 +4,22 @@ Copyright 2018 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
https://www.boost.org/LICENSE_1_0.txt
////
# Boost.System: Extensible Error Reporting
Beman Dawes, Christopher Kohlhoff, Peter Dimov
:toc: left
:toclevels: 3
:toclevels: 4
:idprefix:
:docinfo: private-footer
:source-highlighter: rouge
:source-language: c++
:leveloffset: +1
include::system/introduction.adoc[]
include::system/usage.adoc[]
include::system/changes.adoc[]
include::system/rationale.adoc[]
include::system/reference.adoc[]

View File

@@ -1,16 +1,91 @@
////
Copyright 2018 Peter Dimov
Copyright 2018-2022 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
https://www.boost.org/LICENSE_1_0.txt
////
[#changes]
# Revision History
:idprefix:
## 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
to `error_code`, the original is now restored, if possible.
* Reworked the conversion from `error_category` to `std::error_category`
to avoid the one-time allocation that shows up on leak checkers.
* Added a constructor that allows replacing the source location of an
`error_code`, and a corresponding `assign`.
* Added a converting constructor to `result`.
## Changes in Boost 1.79
* Added a `boost::source_location` parameter to `throw_exception_from_error`.
* Added `throw_exception_from_error` overloads for `errc::errc_t`,
`std::error_code`, `std::errc`, `std::exception_ptr`.
* `result<T>::value` now automatically supplies `BOOST_CURRENT_LOCATION` to
`throw_exception_from_error` via a default argument.
* Added an `errc::make_error_code` overload taking a source location.
## Changes in Boost 1.78
* Added support for source locations to `error_code`.
* Added `error_code::to_string`, `error_condition::to_string`, `error_code::what`.
* `system_error::what()` now contains the source location, if present.
* Added `result<T, E = error_code>`, a class holding either a value or an
error, defined in `<boost/system/result.hpp>`.
## Changes in Boost 1.77
* The conversion operator from `error_category` to `std::error_category`
has been improved and no longer requires `<map>` or `<mutex>`.
* The comparison operators of `error_category` are now inline friends
instead of member functions (a side effect of the previous change.)
* `error_condition` now defers calling `generic_category()` to avoid
instantiating the object until it's actually needed.
* `error_condition::failed` and `error_condition::message` have been
undeprecated, and `operator bool()` now once again returns `failed()`.
* The system category now doesn't call `generic_category()`, to avoid
instantiating the object.
* The return value of `default_error_condition` changes in some cases into
an `error_condition` from the generic category, instead of from the system
category. This happens on POSIX when the input `error_code` is from
the system category and does not correspond to any `errc_t` value.
* The interoperability of `error_code` and `std::error_code` has been
improved substantially. It is now possible to construct
`boost::system::error_code` from `std::error_code`, and it's possible
to pass `boost::system::error_code` to functions taking `std::error_code&`.
* A stream insertion operator for `error_condition` has been added.
## Changes in Boost 1.76
* `windows_error.hpp` is no longer deprecated.
## Changes in Boost 1.75
* The platform-specific headers `windows_error.hpp`, `linux_error.hpp`,
and `cygwin_error.hpp` emit deprecation messages and are slated for
removal.
* The old names for `generic_category()` and `system_category()` emit
deprecation messages and are slated for removal.
* `error_condition::failed` is deprecated and is slated for removal.
`operator bool()` for `error_condition` has been reverted to its old
meaning of `value() != 0`. This is done for compatibility with
`std::error_condition` as the next release is expected to improve
interoperability with `<system_error>` even further. _Note that this
does not affect_ `error_code::failed`, which is still alive and well.
* The overload of `error_condition::message` that takes a buffer is
deprecated and is slated for removal, for the same reasons. _Note that
this does not affect_ `error_code::message`.
## Changes in Boost 1.74
* `operator bool()` now returns `failed()` instead of `value() != 0`.

View File

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

View File

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

File diff suppressed because it is too large Load Diff

1414
doc/system/usage.adoc Normal file

File diff suppressed because it is too large Load Diff

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>

18
include/boost/system.hpp Normal file
View File

@@ -0,0 +1,18 @@
#ifndef BOOST_SYSTEM_HPP_INCLUDED
#define BOOST_SYSTEM_HPP_INCLUDED
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/config.hpp>
#if (__cplusplus >= 201103L) && !(defined(BOOST_GCC) && BOOST_GCC < 40800) || (defined(_MSC_VER) && _MSC_VER >= 1900)
# include <boost/system/result.hpp>
#endif
#endif // #ifndef BOOST_SYSTEM_HPP_INCLUDED

View File

@@ -10,6 +10,13 @@
#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.

View File

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

View File

@@ -1,32 +1,29 @@
#ifndef BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED
// Copyright 2018 Peter Dimov
// Copyright 2018-2022 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/system for documentation.
#include <boost/system/detail/requires_cxx11.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
// BOOST_SYSTEM_HAS_SYSTEM_ERROR
//
// 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
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_CXX11_HDR_ATOMIC) && ( !defined(BOOST_NO_CXX11_HDR_MUTEX) || defined(BOOST_SYSTEM_DISABLE_THREADS) )
# define BOOST_SYSTEM_HAS_SYSTEM_ERROR
#endif
#if BOOST_WORKAROUND(BOOST_GCC, < 40600)
// g++ 4.4's <map> is not good enough
# undef BOOST_SYSTEM_HAS_SYSTEM_ERROR
#endif
#if defined(BOOST_NO_CXX11_HDR_MUTEX)
// Required for thread-safe map manipulation
# undef BOOST_SYSTEM_HAS_SYSTEM_ERROR
#endif
// BOOST_SYSTEM_NOEXCEPT
// Retained for backward compatibility
@@ -48,4 +45,46 @@
# define BOOST_SYSTEM_CONSTEXPR
#endif
// BOOST_SYSTEM_DEPRECATED
#if defined(__clang__)
# define BOOST_SYSTEM_DEPRECATED(msg) __attribute__((deprecated(msg)))
#elif defined(__GNUC__)
# if __GNUC__ * 100 + __GNUC_MINOR__ >= 405
# define BOOST_SYSTEM_DEPRECATED(msg) __attribute__((deprecated(msg)))
# else
# define BOOST_SYSTEM_DEPRECATED(msg) __attribute__((deprecated))
# endif
#elif defined(_MSC_VER)
# define BOOST_SYSTEM_DEPRECATED(msg) __declspec(deprecated(msg))
#elif defined(__sun)
# define BOOST_SYSTEM_DEPRECATED(msg) __attribute__((deprecated(msg)))
#else
# define BOOST_SYSTEM_DEPRECATED(msg)
#endif
// BOOST_SYSTEM_CLANG_6
// 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
//
#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 50000
# define BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY
#endif
#if defined(__CYGWIN__) || defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER == 1800) || (defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 90000)
// Under Cygwin (and MinGW!), std::system_category() is POSIX
// Under VS2013, std::system_category() isn't quite right
// Under libstdc++ before 7.4, before 8.3, before 9.1, default_error_condition
// for the system category returns a condition from the system category
# define BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY
#endif
#endif // BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED

View File

@@ -13,12 +13,14 @@
#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
namespace boost
@@ -38,11 +40,7 @@ namespace detail
BOOST_SYSTEM_CONSTEXPR bool failed_impl( int ev, error_category const & cat );
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
std::error_category const & to_std_category( error_category const & cat );
#endif
class std_category;
} // namespace detail
@@ -51,6 +49,11 @@ std::error_category const & to_std_category( error_category const & cat );
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
#pragma warning(push)
#pragma warning(disable: 4351) // new behavior: elements of array will be default initialized
#endif
class BOOST_SYMBOL_VISIBLE error_category
{
private:
@@ -58,9 +61,8 @@ private:
friend std::size_t hash_value( error_code const & ec );
friend BOOST_SYSTEM_CONSTEXPR bool detail::failed_impl( int ev, error_category const & cat );
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
friend std::error_category const & detail::to_std_category( error_category const & cat );
#endif
friend class error_code;
friend class error_condition;
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
public:
@@ -80,6 +82,24 @@ private:
boost::ulong_long_type id_;
static std::size_t const stdcat_size_ = 4 * sizeof( void const* );
union
{
mutable unsigned char stdcat_[ stdcat_size_ ];
void const* stdcat_align_;
};
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
mutable std::atomic< unsigned > sc_init_;
#else
unsigned sc_init_;
#endif
protected:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
@@ -97,11 +117,18 @@ protected:
#endif
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 )
#if !BOOST_WORKAROUND(BOOST_GCC, < 40800)
BOOST_CONSTEXPR
#endif
error_category() BOOST_NOEXCEPT: id_( 0 ), stdcat_(), sc_init_()
{
}
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id )
explicit
#if !BOOST_WORKAROUND(BOOST_GCC, < 40800)
BOOST_CONSTEXPR
#endif
error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id ), stdcat_(), sc_init_()
{
}
@@ -121,24 +148,24 @@ public:
return ev != 0;
}
BOOST_SYSTEM_CONSTEXPR bool operator==( const error_category & rhs ) const BOOST_NOEXCEPT
friend BOOST_SYSTEM_CONSTEXPR bool operator==( error_category const & lhs, error_category const & rhs ) BOOST_NOEXCEPT
{
return rhs.id_ == 0? this == &rhs: id_ == rhs.id_;
return rhs.id_ == 0? &lhs == &rhs: lhs.id_ == rhs.id_;
}
BOOST_SYSTEM_CONSTEXPR bool operator!=( const error_category & rhs ) const BOOST_NOEXCEPT
friend BOOST_SYSTEM_CONSTEXPR bool operator!=( error_category const & lhs, error_category const & rhs ) BOOST_NOEXCEPT
{
return !( *this == rhs );
return !( lhs == rhs );
}
BOOST_SYSTEM_CONSTEXPR bool operator<( const error_category & rhs ) const BOOST_NOEXCEPT
friend BOOST_SYSTEM_CONSTEXPR bool operator<( error_category const & lhs, error_category const & rhs ) BOOST_NOEXCEPT
{
if( id_ < rhs.id_ )
if( lhs.id_ < rhs.id_ )
{
return true;
}
if( id_ > rhs.id_ )
if( lhs.id_ > rhs.id_ )
{
return false;
}
@@ -148,16 +175,26 @@ public:
return false; // equal
}
return std::less<error_category const *>()( this, &rhs );
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
operator std::error_category const & () const;
# else
operator std::error_category const & () const BOOST_SYMBOL_VISIBLE;
# endif
#endif
};
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
#pragma warning(pop)
#endif
#if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
#pragma GCC diagnostic pop
#endif
@@ -165,8 +202,9 @@ public:
namespace detail
{
static const boost::ulong_long_type generic_category_id = ( boost::ulong_long_type( 0xB2AB117A ) << 32 ) + 0x257EDF0D;
static const boost::ulong_long_type system_category_id = ( boost::ulong_long_type( 0x8FAFD21E ) << 32 ) + 0x25C5E09B;
static const boost::ulong_long_type generic_category_id = ( boost::ulong_long_type( 0xB2AB117A ) << 32 ) + 0x257EDFD0;
static const boost::ulong_long_type system_category_id = generic_category_id + 1;
static const boost::ulong_long_type interop_category_id = generic_category_id + 2;
BOOST_SYSTEM_CONSTEXPR inline bool failed_impl( int ev, error_category const & cat )
{

View File

@@ -13,13 +13,14 @@
#include <boost/system/detail/error_category.hpp>
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/snprintf.hpp>
#include <boost/system/detail/config.hpp>
#include <boost/config.hpp>
#include <string>
#include <cstring>
namespace boost
{
namespace system
{
@@ -37,7 +38,7 @@ inline bool error_category::equivalent( int code, const error_condition & condit
inline bool error_category::equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT
{
return *this == code.category() && code.value() == condition;
return code.equals( condition, *this );
}
inline char const * error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
@@ -83,26 +84,107 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
#if !defined(BOOST_NO_EXCEPTIONS)
catch( ... )
{
return "Message text unavailable";
detail::snprintf( buffer, len, "No message text available for error %d", ev );
return buffer;
}
#endif
}
} // namespace system
} // namespace boost
// interoperability with std::error_code, std::error_condition
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#include <boost/system/detail/to_std_category.hpp>
#include <boost/system/detail/std_category_impl.hpp>
#include <boost/system/detail/mutex.hpp>
#include <new>
inline boost::system::error_category::operator std::error_category const & () const
namespace boost
{
return boost::system::detail::to_std_category( *this );
namespace system
{
inline void error_category::init_stdcat() const
{
static_assert( sizeof( stdcat_ ) >= sizeof( boost::system::detail::std_category ), "sizeof(stdcat_) is not enough for std_category" );
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
// no alignof
#else
static_assert( alignof( decltype(stdcat_align_) ) >= alignof( boost::system::detail::std_category ), "alignof(stdcat_) is not enough for std_category" );
#endif
// 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, system::detail::id_wrapper<0>() );
sc_init_.store( 1, std::memory_order_release );
}
}
#if defined( BOOST_GCC ) && BOOST_GCC >= 40800 && BOOST_GCC < 70000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
inline BOOST_NOINLINE error_category::operator std::error_category const & () const
{
if( id_ == detail::generic_category_id )
{
// This condition must be the same as the one in error_condition.hpp
#if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
static const boost::system::detail::std_category generic_instance( this, system::detail::id_wrapper<0x1F4D3>() );
return generic_instance;
#else
return std::generic_category();
#endif
}
if( id_ == detail::system_category_id )
{
// This condition must be the same as the one in error_code.hpp
#if defined(BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY)
static const boost::system::detail::std_category system_instance( this, system::detail::id_wrapper<0x1F4D7>() );
return system_instance;
#else
return std::system_category();
#endif
}
if( sc_init_.load( std::memory_order_acquire ) == 0 )
{
init_stdcat();
}
return *static_cast<boost::system::detail::std_category const*>( static_cast<void const*>( stdcat_ ) );
}
#if defined( BOOST_GCC ) && BOOST_GCC >= 40800 && BOOST_GCC < 70000
#pragma GCC diagnostic pop
#endif
} // namespace system
} // namespace boost
#endif // #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CATEGORY_IMPL_HPP_INCLUDED

View File

@@ -3,22 +3,45 @@
// Copyright Beman Dawes 2006, 2007
// Copyright Christoper Kohlhoff 2007
// Copyright Peter Dimov 2017, 2018
// Copyright Peter Dimov 2017-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/is_error_code_enum.hpp>
#include <boost/system/detail/error_category.hpp>
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/detail/system_category.hpp>
#include <boost/system/detail/system_category_impl.hpp>
#include <boost/system/detail/interop_category.hpp>
#include <boost/system/detail/enable_if.hpp>
#include <boost/system/is_error_code_enum.hpp>
#include <boost/system/detail/is_same.hpp>
#include <boost/system/detail/append_int.hpp>
#include <boost/system/detail/snprintf.hpp>
#include <boost/system/detail/config.hpp>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <boost/system/detail/std_category.hpp>
#endif
#include <boost/assert/source_location.hpp>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <ostream>
#include <new>
#include <cstdio>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <system_error>
#endif
#if defined(BOOST_GCC) && BOOST_GCC >= 40600 && BOOST_GCC < 70000
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
namespace boost
{
@@ -35,41 +58,146 @@ 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 ) BOOST_NOEXCEPT;
std::size_t hash_value( error_code const & ec );
class error_code
{
private:
int val_;
bool failed_;
const error_category * cat_;
friend bool operator==( const error_code & code, const error_condition & condition ) BOOST_NOEXCEPT;
friend std::size_t hash_value( error_code const & ec );
private:
struct data
{
int val_;
const error_category * cat_;
};
union
{
data d1_;
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
unsigned char d2_[ sizeof(std::error_code) ];
#endif
};
// 0: default constructed, d1_ value initialized
// 1: holds std::error_code in d2_
// 2: holds error code in d1_, failed == false
// 3: holds error code in d1_, failed == true
// >3: pointer to source_location, failed_ in lsb
boost::uintptr_t lc_flags_;
private:
char const* category_name() const BOOST_NOEXCEPT
{
// return category().name();
if( lc_flags_ == 0 )
{
// must match detail::system_error_category::name()
return "system";
}
else if( lc_flags_ == 1 )
{
// must match detail::interop_error_category::name()
return "std:unknown";
}
else
{
return d1_.cat_->name();
}
}
public:
// constructors:
BOOST_SYSTEM_CONSTEXPR error_code() BOOST_NOEXCEPT:
val_( 0 ), failed_( false ), cat_( &system_category() )
#if !BOOST_WORKAROUND(BOOST_GCC, < 40800)
BOOST_CONSTEXPR
#endif
error_code() BOOST_NOEXCEPT:
d1_(), lc_flags_( 0 )
{
}
BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_NOEXCEPT:
val_( val ), failed_( detail::failed_impl( val, cat ) ), cat_( &cat )
d1_(), lc_flags_( 2 + detail::failed_impl( val, cat ) )
{
d1_.val_ = val;
d1_.cat_ = &cat;
}
error_code( int val, const error_category & cat, source_location const * loc ) BOOST_NOEXCEPT:
d1_(), lc_flags_( ( loc? reinterpret_cast<boost::uintptr_t>( loc ): 2 ) | +detail::failed_impl( val, cat ) )
{
d1_.val_ = val;
d1_.cat_ = &cat;
}
template<class ErrorCodeEnum> BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e,
typename detail::enable_if<is_error_code_enum<ErrorCodeEnum>::value>::type* = 0 ) BOOST_NOEXCEPT
typename detail::enable_if<
is_error_code_enum<ErrorCodeEnum>::value
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|| std::is_error_code_enum<ErrorCodeEnum>::value
#endif
>::type* = 0 ) BOOST_NOEXCEPT: d1_(), lc_flags_( 0 )
{
*this = make_error_code( e );
}
error_code( error_code const& ec, source_location const * loc ) BOOST_NOEXCEPT:
d1_(), lc_flags_( 0 )
{
*this = ec;
if( ec.lc_flags_ != 0 && ec.lc_flags_ != 1 )
{
lc_flags_ = ( loc? reinterpret_cast<boost::uintptr_t>( loc ): 2 ) | ( ec.lc_flags_ & 1 );
}
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
error_code( std::error_code const& ec ) BOOST_NOEXCEPT:
d1_(), lc_flags_( 0 )
{
#ifndef BOOST_NO_RTTI
if( detail::std_category const* pc2 = dynamic_cast< detail::std_category const* >( &ec.category() ) )
{
*this = boost::system::error_code( ec.value(), pc2->original_category() );
}
else
#endif
{
::new( d2_ ) std::error_code( ec );
lc_flags_ = 1;
}
}
#endif
// modifiers:
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT
{
val_ = val;
failed_ = detail::failed_impl( val, cat );
cat_ = &cat;
*this = error_code( val, cat );
}
void assign( int val, const error_category & cat, source_location const * loc ) BOOST_NOEXCEPT
{
*this = error_code( val, cat, loc );
}
void assign( error_code const& ec, source_location const * loc ) BOOST_NOEXCEPT
{
*this = error_code( ec, loc );
}
template<typename ErrorCodeEnum>
@@ -82,48 +210,136 @@ public:
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
{
val_ = 0;
failed_ = false;
cat_ = &system_category();
*this = error_code();
}
// observers:
BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT
{
return val_;
if( lc_flags_ != 1 )
{
return d1_.val_;
}
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
{
return *cat_;
if( lc_flags_ == 0 )
{
return system_category();
}
else if( lc_flags_ == 1 )
{
return detail::interop_category();
}
else
{
return *d1_.cat_;
}
}
// deprecated?
error_condition default_error_condition() const BOOST_NOEXCEPT
{
return cat_->default_error_condition( value() );
return category().default_error_condition( value() );
}
std::string message() const
{
return cat_->message( value() );
#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 )
{
return detail::system_error_category_message( value() );
}
else
{
return category().message( value() );
}
}
char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
return cat_->message( value(), buffer, len );
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( lc_flags_ == 1 )
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
#if !defined(BOOST_NO_EXCEPTIONS)
try
#endif
{
detail::snprintf( buffer, len, "%s", ec.message().c_str() );
return buffer;
}
#if !defined(BOOST_NO_EXCEPTIONS)
catch( ... )
{
detail::snprintf( buffer, len, "No message text available for error std:%s:%d", ec.category().name(), ec.value() );
return buffer;
}
#endif
}
#endif
if( lc_flags_ == 0 )
{
return detail::system_error_category_message( value(), buffer, len );
}
else
{
return category().message( value(), buffer, len );
}
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
{
return failed_;
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
{
return false;
}
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error
{
return failed_;
return failed();
}
#else
@@ -133,56 +349,353 @@ public:
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{
return failed_? unspecified_bool_true: 0;
return failed()? unspecified_bool_true: 0;
}
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{
return !failed_;
return !failed();
}
#endif
bool has_location() const BOOST_NOEXCEPT
{
return lc_flags_ >= 4;
}
source_location const & location() const BOOST_NOEXCEPT
{
BOOST_STATIC_CONSTEXPR source_location loc;
return lc_flags_ >= 4? *reinterpret_cast<source_location const*>( lc_flags_ &~ static_cast<boost::uintptr_t>( 1 ) ): loc;
}
// relationals:
private:
// private equality for use in error_category::equivalent
friend class error_category;
BOOST_SYSTEM_CONSTEXPR bool equals( int val, error_category const& cat ) const BOOST_NOEXCEPT
{
if( lc_flags_ == 0 )
{
return val == 0 && cat.id_ == detail::system_category_id;
}
else if( lc_flags_ == 1 )
{
return cat.id_ == detail::interop_category_id && val == value();
}
else
{
return val == d1_.val_ && cat == *d1_.cat_;
}
}
public:
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT
{
return lhs.val_ == rhs.val_ && *lhs.cat_ == *rhs.cat_;
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
bool s1 = lhs.lc_flags_ == 1;
bool s2 = 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_ );
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
{
return *lhs.cat_ < *rhs.cat_ || ( *lhs.cat_ == *rhs.cat_ && lhs.val_ < rhs.val_ );
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
bool s1 = lhs.lc_flags_ == 1;
bool s2 = 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_ );
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
{
return !( lhs == rhs );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
operator std::error_code () const
inline friend bool operator==( std::error_code const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
{
return std::error_code( value(), category() );
return lhs == static_cast< std::error_code >( rhs );
}
inline friend bool operator==( error_code const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
{
return static_cast< std::error_code >( lhs ) == rhs;
}
inline friend bool operator!=( std::error_code const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
inline friend bool operator!=( error_code const & lhs, std::error_code const & rhs ) BOOST_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==( error_code const & lhs, E rhs ) BOOST_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
{
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
{
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
{
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==( error_code const & lhs, E rhs ) BOOST_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
{
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
{
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
{
return !( lhs == rhs );
}
#if defined(BOOST_SYSTEM_CLANG_6)
inline friend bool operator==( error_code const & lhs, std::error_condition const & rhs ) BOOST_NOEXCEPT
{
return static_cast< std::error_code >( lhs ) == rhs;
}
inline friend bool operator==( std::error_condition const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
{
return lhs == static_cast< std::error_code >( rhs );
}
inline friend bool operator!=( error_code const & lhs, std::error_condition const & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
inline friend bool operator!=( std::error_condition const & lhs, error_code const & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
#endif
// conversions
operator std::error_code () const
{
if( lc_flags_ == 1 )
{
return *reinterpret_cast<std::error_code const*>( d2_ );
}
else if( lc_flags_ == 0 )
{
// This condition must be the same as the one in error_category_impl.hpp
#if defined(BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY)
return std::error_code( 0, boost::system::system_category() );
#else
return std::error_code();
#endif
}
else
{
return std::error_code( d1_.val_, *d1_.cat_ );
}
}
operator std::error_code ()
{
return const_cast<error_code const&>( *this );
}
template<class T,
class E = typename detail::enable_if<detail::is_same<T, std::error_code>::value>::type>
operator T& ()
{
if( lc_flags_ != 1 )
{
std::error_code e2( *this );
::new( d2_ ) std::error_code( e2 );
lc_flags_ = 1;
}
return *reinterpret_cast<std::error_code*>( d2_ );
}
#if defined(BOOST_SYSTEM_CLANG_6)
template<class T,
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_ );
std::string r( "std:" );
r += e2.category().name();
detail::append_int( r, e2.value() );
return r;
}
else
#endif
{
std::string r = category_name();
detail::append_int( r, value() );
return r;
}
}
template<class Ch, class Tr>
inline friend std::basic_ostream<Ch, Tr>&
operator<< (std::basic_ostream<Ch, Tr>& os, error_code const & ec)
{
return os << ec.to_string().c_str();
}
std::string what() const
{
std::string r = message();
r += " [";
r += to_string();
if( has_location() )
{
r += " at ";
r += location().to_string();
}
r += "]";
return r;
}
};
BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT
inline 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 bool operator==( const error_condition & condition, const error_code & code ) BOOST_NOEXCEPT
{
return code == condition;
}
inline bool operator!=( const error_code & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
template<class Ch, class Tr>
inline std::basic_ostream<Ch, Tr>&
operator<< (std::basic_ostream<Ch, Tr>& os, error_code const & ec)
inline bool operator!=( const error_condition & lhs, const error_code & rhs ) BOOST_NOEXCEPT
{
os << ec.category().name() << ':' << ec.value();
return os;
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_;
@@ -212,4 +725,8 @@ inline std::size_t hash_value( error_code const & ec )
} // namespace boost
#if defined(BOOST_GCC) && BOOST_GCC >= 40600 && BOOST_GCC < 70000
# pragma GCC diagnostic pop
#endif
#endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CODE_HPP_INCLUDED

View File

@@ -3,7 +3,7 @@
// Copyright Beman Dawes 2006, 2007
// Copyright Christoper Kohlhoff 2007
// Copyright Peter Dimov 2017, 2018
// Copyright Peter Dimov 2017-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -13,6 +13,9 @@
#include <boost/system/detail/error_category.hpp>
#include <boost/system/detail/generic_category.hpp>
#include <boost/system/detail/enable_if.hpp>
#include <boost/system/detail/is_same.hpp>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/append_int.hpp>
#include <boost/system/is_error_condition_enum.hpp>
#include <boost/system/detail/config.hpp>
#include <boost/config.hpp>
@@ -27,40 +30,69 @@ namespace system
// error_conditions are portable, error_codes are system or library specific
namespace detail
{
struct generic_value_tag
{
int value;
BOOST_SYSTEM_CONSTEXPR explicit generic_value_tag( int v ): value( v ) {}
};
} // namespace detail
class error_condition
{
private:
int val_;
bool failed_;
error_category const * cat_;
private:
boost::ulong_long_type cat_id() const BOOST_NOEXCEPT
{
return cat_? cat_->id_: detail::generic_category_id;
}
public:
// constructors:
BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT:
val_( 0 ), failed_( false ), cat_( &generic_category() )
val_( 0 ), cat_( 0 )
{
}
BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT:
val_( val ), failed_( detail::failed_impl( val, cat ) ), cat_( &cat )
val_( val ), cat_( &cat )
{
}
BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) BOOST_NOEXCEPT:
val_( vt.value ), cat_( 0 )
{
}
template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e,
typename detail::enable_if<is_error_condition_enum<ErrorConditionEnum>::value>::type* = 0) BOOST_NOEXCEPT
typename detail::enable_if<
is_error_condition_enum<ErrorConditionEnum>::value && !boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value
>::type* = 0) BOOST_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:
val_( e ), cat_( 0 )
{
}
// modifiers:
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT
{
val_ = val;
failed_ = detail::failed_impl( val, cat );
cat_ = &cat;
}
@@ -68,15 +100,14 @@ public:
BOOST_SYSTEM_CONSTEXPR typename detail::enable_if<is_error_condition_enum<ErrorConditionEnum>::value, error_condition>::type &
operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT
{
*this = make_error_condition( val );
*this = error_condition( val );
return *this;
}
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
{
val_ = 0;
failed_ = false;
cat_ = &generic_category();
cat_ = 0;
}
// observers:
@@ -88,29 +119,50 @@ public:
BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT
{
return *cat_;
return cat_? *cat_: generic_category();
}
std::string message() const
{
return cat_->message( value() );
if( cat_ )
{
return cat_->message( value() );
}
else
{
return detail::generic_error_category_message( value() );
}
}
char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
return cat_->message( value(), buffer, len );
if( cat_ )
{
return cat_->message( value(), buffer, len );
}
else
{
return detail::generic_error_category_message( value(), buffer, len );
}
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
{
return failed_;
if( cat_ )
{
return detail::failed_impl( val_, *cat_ );
}
else
{
return val_ != 0;
}
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error
{
return failed_;
return failed();
}
#else
@@ -120,12 +172,12 @@ public:
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{
return failed_? unspecified_bool_true: 0;
return failed()? unspecified_bool_true: 0;
}
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{
return !failed_;
return !failed();
}
#endif
@@ -136,28 +188,159 @@ public:
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return lhs.val_ == rhs.val_ && *lhs.cat_ == *rhs.cat_;
if( lhs.val_ != rhs.val_ )
{
return false;
}
else if( lhs.cat_ == 0 )
{
return rhs.cat_id() == detail::generic_category_id;
}
else if( rhs.cat_ == 0 )
{
return lhs.cat_id() == detail::generic_category_id;
}
else
{
return *lhs.cat_ == *rhs.cat_;
}
}
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return *lhs.cat_ < *rhs.cat_ || ( *lhs.cat_ == *rhs.cat_ && lhs.val_ < rhs.val_ );
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
{
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
#if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
return std::error_condition( value(), category() );
#else
if( cat_ )
{
return std::error_condition( val_, *cat_ );
}
else
{
return std::error_condition( val_, std::generic_category() );
}
#endif
}
inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT
{
return lhs == static_cast< std::error_condition >( rhs );
}
inline friend bool operator==( error_condition const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
{
return static_cast< std::error_condition >( lhs ) == rhs;
}
inline friend bool operator!=( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
inline friend bool operator!=( error_condition const & lhs, std::error_code const & rhs ) BOOST_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==( error_condition const & lhs, E rhs ) BOOST_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 ) BOOST_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 ) BOOST_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 ) BOOST_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 ) BOOST_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 ) BOOST_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 ) BOOST_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 ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
#endif
};
BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
std::string to_string() const
{
std::string r( "cond:" );
if( cat_ )
{
r += cat_->name();
}
else
{
r += "generic";
}
detail::append_int( r, value() );
return r;
}
template<class Ch, class Tr>
inline friend std::basic_ostream<Ch, Tr>&
operator<< (std::basic_ostream<Ch, Tr>& os, error_condition const & en)
{
os << en.to_string();
return os;
}
};
} // namespace system

View File

@@ -109,10 +109,10 @@ inline error_category const & generic_category() BOOST_NOEXCEPT
#ifdef BOOST_SYSTEM_ENABLE_DEPRECATED
inline const error_category & get_generic_category() { return generic_category(); }
inline const error_category & get_posix_category() { return generic_category(); }
static const error_category & posix_category BOOST_ATTRIBUTE_UNUSED = generic_category();
static const error_category & errno_ecat BOOST_ATTRIBUTE_UNUSED = generic_category();
BOOST_SYSTEM_DEPRECATED("please use generic_category()") inline const error_category & get_generic_category() { return generic_category(); }
BOOST_SYSTEM_DEPRECATED("please use generic_category()") inline const error_category & get_posix_category() { return generic_category(); }
BOOST_SYSTEM_DEPRECATED("please use generic_category()") static const error_category & posix_category BOOST_ATTRIBUTE_UNUSED = generic_category();
BOOST_SYSTEM_DEPRECATED("please use generic_category()") static const error_category & errno_ecat BOOST_ATTRIBUTE_UNUSED = generic_category();
#endif

View File

@@ -0,0 +1,107 @@
#ifndef BOOST_SYSTEM_DETAIL_INTEROP_CATEGORY_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_INTEROP_CATEGORY_HPP_INCLUDED
// Copyright Beman Dawes 2006, 2007
// Copyright Christoper Kohlhoff 2007
// Copyright Peter Dimov 2017, 2018, 2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/error_category.hpp>
#include <boost/system/detail/snprintf.hpp>
#include <boost/system/detail/config.hpp>
#include <boost/config.hpp>
namespace boost
{
namespace system
{
namespace detail
{
// interop_error_category, used for std::error_code
#if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
class BOOST_SYMBOL_VISIBLE interop_error_category: public error_category
{
public:
BOOST_SYSTEM_CONSTEXPR interop_error_category() BOOST_NOEXCEPT:
error_category( detail::interop_category_id )
{
}
const char * name() const BOOST_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;
};
#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
{
detail::snprintf( buffer, len, "Unknown interop error %d", ev );
return buffer;
}
inline std::string interop_error_category::message( int ev ) const
{
char buffer[ 48 ];
return message( ev, buffer, sizeof( buffer ) );
}
// interop_category()
#if defined(BOOST_SYSTEM_HAS_CONSTEXPR)
template<class T> struct BOOST_SYMBOL_VISIBLE interop_cat_holder
{
static constexpr interop_error_category instance{};
};
// Before C++17 it was mandatory to redeclare all static constexpr
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
template<class T> constexpr interop_error_category interop_cat_holder<T>::instance;
#endif
constexpr error_category const & interop_category() BOOST_NOEXCEPT
{
return interop_cat_holder<void>::instance;
}
#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;
#endif
inline error_category const & interop_category() BOOST_NOEXCEPT
{
static const detail::interop_error_category instance;
return instance;
}
#endif // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR)
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_INTEROP_CATEGORY_HPP_INCLUDED

View File

@@ -1,125 +0,0 @@
#ifndef BOOST_SYSTEM_DETAIL_IS_GENERIC_VALUE_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_IS_GENERIC_VALUE_HPP_INCLUDED
// Copyright 2018 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/errc.hpp>
namespace boost
{
namespace system
{
namespace detail
{
inline bool is_generic_value( int ev ) BOOST_NOEXCEPT
{
using namespace errc;
static int const gen[] =
{
success,
address_family_not_supported,
address_in_use,
address_not_available,
already_connected,
argument_list_too_long,
argument_out_of_domain,
bad_address,
bad_file_descriptor,
bad_message,
broken_pipe,
connection_aborted,
connection_already_in_progress,
connection_refused,
connection_reset,
cross_device_link,
destination_address_required,
device_or_resource_busy,
directory_not_empty,
executable_format_error,
file_exists,
file_too_large,
filename_too_long,
function_not_supported,
host_unreachable,
identifier_removed,
illegal_byte_sequence,
inappropriate_io_control_operation,
interrupted,
invalid_argument,
invalid_seek,
io_error,
is_a_directory,
message_size,
network_down,
network_reset,
network_unreachable,
no_buffer_space,
no_child_process,
no_link,
no_lock_available,
no_message_available,
no_message,
no_protocol_option,
no_space_on_device,
no_stream_resources,
no_such_device_or_address,
no_such_device,
no_such_file_or_directory,
no_such_process,
not_a_directory,
not_a_socket,
not_a_stream,
not_connected,
not_enough_memory,
not_supported,
operation_canceled,
operation_in_progress,
operation_not_permitted,
operation_not_supported,
operation_would_block,
owner_dead,
permission_denied,
protocol_error,
protocol_not_supported,
read_only_file_system,
resource_deadlock_would_occur,
resource_unavailable_try_again,
result_out_of_range,
state_not_recoverable,
stream_timeout,
text_file_busy,
timed_out,
too_many_files_open_in_system,
too_many_files_open,
too_many_links,
too_many_symbolic_link_levels,
value_too_large,
wrong_protocol_type
};
int const n = sizeof( gen ) / sizeof( gen[0] );
for( int i = 0; i < n; ++i )
{
if( ev == gen[ i ] ) return true;
}
return false;
}
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_IS_GENERIC_VALUE_HPP_INCLUDED

View File

@@ -0,0 +1,33 @@
#ifndef BOOST_SYSTEM_DETAIL_IS_SAME_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_IS_SAME_HPP_INCLUDED
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// http://www.boost.org/LICENSE_1_0.txt
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 };
};
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_IS_SAME_HPP_INCLUDED

View File

@@ -0,0 +1,110 @@
#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
#elif 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 <shared_mutex>
namespace boost
{
namespace system
{
namespace detail
{
typedef std::shared_mutex mutex;
} // namespace detail
} // namespace system
} // namespace boost
#else
#include <mutex>
namespace boost
{
namespace system
{
namespace detail
{
using std::mutex;
} // namespace detail
} // namespace system
} // namespace boost
#endif
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

@@ -0,0 +1,21 @@
#ifndef BOOST_SYSTEM_DETAIL_REQUIRES_CXX11_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_REQUIRES_CXX11_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>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX11_CONSTEXPR) || \
defined(BOOST_NO_CXX11_NOEXCEPT) || \
defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) || \
defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \
defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.System 1.82 and will be removed in Boost.System 1.84.")
#endif
#endif // #ifndef BOOST_SYSTEM_DETAIL_REQUIRES_CXX11_HPP_INCLUDED

View File

@@ -0,0 +1,73 @@
#ifndef BOOST_SYSTEM_DETAIL_SNPRINTF_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_SNPRINTF_HPP_INCLUDED
// Copyright 2018, 2020, 2021 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/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
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_SNPRINTF_HPP_INCLUDED

View File

@@ -0,0 +1,88 @@
#ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_STD_CATEGORY_HPP_INCLUDED
// Support for interoperability between Boost.System and <system_error>
//
// Copyright 2018, 2021 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/error_category.hpp>
#include <boost/config.hpp>
#include <system_error>
//
namespace boost
{
namespace system
{
namespace detail
{
template<unsigned Id> struct id_wrapper {};
class BOOST_SYMBOL_VISIBLE std_category: public std::error_category
{
private:
boost::system::error_category const * pc_;
public:
boost::system::error_category const & original_category() const BOOST_NOEXCEPT
{
return *pc_;
}
public:
template<unsigned Id>
explicit std_category( boost::system::error_category const * pc, id_wrapper<Id> ): pc_( pc )
{
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
// 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
#if !defined(BOOST_NO_CXX11_STATIC_ASSERT)
static_assert( Id == 0, "This constructor should only be called with Id == 0 under MS STL 14.0+" );
#endif
#endif
}
const char * name() const BOOST_NOEXCEPT BOOST_OVERRIDE
{
return pc_->name();
}
std::string message( int ev ) const BOOST_OVERRIDE
{
return pc_->message( ev );
}
std::error_condition default_error_condition( int ev ) const BOOST_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;
};
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_HPP_INCLUDED

View File

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

View File

@@ -98,8 +98,8 @@ inline error_category const & system_category() BOOST_NOEXCEPT
#ifdef BOOST_SYSTEM_ENABLE_DEPRECATED
inline const error_category & get_system_category() { return system_category(); }
static const error_category & native_ecat BOOST_ATTRIBUTE_UNUSED = system_category();
BOOST_SYSTEM_DEPRECATED("please use system_category()") inline const error_category & get_system_category() { return system_category(); }
BOOST_SYSTEM_DEPRECATED("please use system_category()") static const error_category & native_ecat BOOST_ATTRIBUTE_UNUSED = system_category();
#endif

View File

@@ -58,7 +58,10 @@ 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;
case ERROR_BUSY_: return device_or_resource_busy;
case ERROR_BUSY_DRIVE_: return device_or_resource_busy;
@@ -73,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;
@@ -80,7 +84,8 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_INVALID_DRIVE_: return no_such_device;
case ERROR_INVALID_FUNCTION_: return function_not_supported;
case ERROR_INVALID_HANDLE_: return invalid_argument;
case ERROR_INVALID_NAME_: return invalid_argument;
case ERROR_INVALID_NAME_: return no_such_file_or_directory;
case ERROR_INVALID_PARAMETER_: return invalid_argument;
case ERROR_LOCK_VIOLATION_: return no_lock_available;
case ERROR_LOCKED_: return no_lock_available;
case ERROR_NEGATIVE_SEEK_: return invalid_argument;
@@ -94,14 +99,20 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_OUTOFMEMORY_: return not_enough_memory;
case ERROR_PATH_NOT_FOUND_: return no_such_file_or_directory;
case ERROR_READ_FAULT_: return io_error;
case ERROR_REPARSE_TAG_INVALID_: return invalid_argument;
case ERROR_RETRY_: return resource_unavailable_try_again;
case ERROR_SEEK_: return io_error;
case ERROR_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 WSAEACCES_: 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;
case WSAEAFNOSUPPORT_: return address_family_not_supported;

View File

@@ -11,10 +11,9 @@
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/system_category.hpp>
#include <boost/system/detail/system_category_message.hpp>
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/detail/generic_category.hpp>
#include <boost/system/api_config.hpp>
#include <boost/config.hpp>
#if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API)
# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined
@@ -24,7 +23,6 @@
#if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/system_category_message_win32.hpp>
#include <boost/system/detail/system_category_condition_win32.hpp>
inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT
@@ -37,47 +35,27 @@ inline boost::system::error_condition boost::system::detail::system_error_catego
}
else
{
return error_condition( e2, generic_category() );
return error_condition( boost::system::detail::generic_value_tag( e2 ) );
}
}
inline std::string boost::system::detail::system_error_category::message( int ev ) const
{
return system_category_message_win32( ev );
}
inline char const * boost::system::detail::system_error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
return system_category_message_win32( ev, buffer, len );
}
#else // #if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/generic_category_message.hpp>
#include <boost/system/detail/is_generic_value.hpp>
inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT
{
if( is_generic_value( ev ) )
{
return error_condition( ev, generic_category() );
}
else
{
return error_condition( ev, *this );
}
}
inline std::string boost::system::detail::system_error_category::message( int ev ) const
{
return generic_error_category_message( ev );
}
inline char const * boost::system::detail::system_error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
return generic_error_category_message( ev, buffer, len );
return error_condition( boost::system::detail::generic_value_tag( ev ) );
}
#endif // #if defined(BOOST_WINDOWS_API)
inline std::string boost::system::detail::system_error_category::message( int ev ) const
{
return system_error_category_message( ev );
}
inline char const * boost::system::detail::system_error_category::message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{
return system_error_category_message( ev, buffer, len );
}
#endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_IMPL_HPP_INCLUDED

View File

@@ -0,0 +1,71 @@
#ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_HPP_INCLUDED
// Implementation of system_error_category_message
//
// Copyright 2018, 2022 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/api_config.hpp>
#if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API)
# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined
#endif
#if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/system_category_message_win32.hpp>
namespace boost
{
namespace system
{
namespace detail
{
inline std::string system_error_category_message( int ev )
{
return system_category_message_win32( ev );
}
inline char const * system_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
{
return system_category_message_win32( ev, buffer, len );
}
} // namespace detail
} // namespace system
} // namespace boost
#else // #if defined(BOOST_WINDOWS_API)
#include <boost/system/detail/generic_category_message.hpp>
namespace boost
{
namespace system
{
namespace detail
{
inline std::string system_error_category_message( int ev )
{
return generic_error_category_message( ev );
}
inline char const * system_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
{
return generic_error_category_message( ev, buffer, len );
}
} // namespace detail
} // namespace system
} // namespace boost
#endif // #if defined(BOOST_WINDOWS_API)
#endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_HPP_INCLUDED

View File

@@ -10,6 +10,7 @@
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/snprintf.hpp>
#include <boost/winapi/error_handling.hpp>
#include <boost/winapi/character_code_conversion.hpp>
#include <boost/winapi/local_memory.hpp>
@@ -27,35 +28,12 @@ namespace system
namespace detail
{
#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
{
# if defined( BOOST_MSVC )
# pragma warning( push )
# pragma warning( disable: 4996 )
# endif
_snprintf( buffer, len - 1, "Unknown error (%d)", ev );
buffer[ len - 1 ] = 0;
return buffer;
# if defined( BOOST_MSVC )
# pragma warning( pop )
# endif
}
#else
inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
{
std::snprintf( buffer, len, "Unknown error (%d)", ev );
detail::snprintf( buffer, len, "Unknown error (%d)", ev );
return buffer;
}
#endif
inline boost::winapi::UINT_ message_cp_win32()
{
#if defined(BOOST_SYSTEM_USE_UTF8)

View File

@@ -1,191 +0,0 @@
#ifndef BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
// Support for interoperability between Boost.System and <system_error>
//
// Copyright 2018 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See library home page at http://www.boost.org/libs/system
#include <boost/system/detail/error_category.hpp>
#include <boost/system/detail/error_condition.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/generic_category.hpp>
#include <system_error>
#include <map>
#include <memory>
#include <mutex>
//
namespace boost
{
namespace system
{
namespace detail
{
class BOOST_SYMBOL_VISIBLE std_category: public std::error_category
{
private:
boost::system::error_category const * pc_;
public:
explicit std_category( boost::system::error_category const * pc, unsigned 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
_Addr = id;
#endif
}
}
const char * name() const BOOST_NOEXCEPT BOOST_OVERRIDE
{
return pc_->name();
}
std::string message( int ev ) const BOOST_OVERRIDE
{
return pc_->message( ev );
}
std::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT BOOST_OVERRIDE
{
return pc_->default_error_condition( ev );
}
bool equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
bool equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
};
#if !defined(__SUNPRO_CC) // trailing __global is not supported
inline std::error_category const & to_std_category( boost::system::error_category const & cat ) BOOST_SYMBOL_VISIBLE;
#endif
struct cat_ptr_less
{
bool operator()( boost::system::error_category const * p1, boost::system::error_category const * p2 ) const BOOST_NOEXCEPT
{
return *p1 < *p2;
}
};
inline std::error_category const & to_std_category( boost::system::error_category const & cat )
{
if( cat.id_ == boost::system::detail::system_category_id )
{
static const std_category system_instance( &cat, 0x1F4D7 );
return system_instance;
}
else if( cat.id_ == boost::system::detail::generic_category_id )
{
static const std_category generic_instance( &cat, 0x1F4D3 );
return generic_instance;
}
else
{
typedef std::map< boost::system::error_category const *, std::unique_ptr<std_category>, cat_ptr_less > map_type;
static map_type map_;
static std::mutex map_mx_;
std::lock_guard<std::mutex> guard( map_mx_ );
map_type::iterator i = map_.find( &cat );
if( i == map_.end() )
{
std::unique_ptr<std_category> p( new std_category( &cat, 0 ) );
std::pair<map_type::iterator, bool> r = map_.insert( map_type::value_type( &cat, std::move( p ) ) );
i = r.first;
}
return *i->second;
}
}
inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT
{
if( condition.category() == *this )
{
boost::system::error_condition bn( condition.value(), *pc_ );
return pc_->equivalent( code, bn );
}
else if( condition.category() == std::generic_category() || condition.category() == boost::system::generic_category() )
{
boost::system::error_condition bn( condition.value(), boost::system::generic_category() );
return pc_->equivalent( code, bn );
}
#ifndef BOOST_NO_RTTI
else if( std_category const* pc2 = dynamic_cast< std_category const* >( &condition.category() ) )
{
boost::system::error_condition bn( condition.value(), *pc2->pc_ );
return pc_->equivalent( code, bn );
}
#endif
else
{
return default_error_condition( code ) == condition;
}
}
inline bool std_category::equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT
{
if( code.category() == *this )
{
boost::system::error_code bc( code.value(), *pc_ );
return pc_->equivalent( bc, condition );
}
else if( code.category() == std::generic_category() || code.category() == boost::system::generic_category() )
{
boost::system::error_code bc( code.value(), boost::system::generic_category() );
return pc_->equivalent( bc, condition );
}
#ifndef BOOST_NO_RTTI
else if( std_category const* pc2 = dynamic_cast< std_category const* >( &code.category() ) )
{
boost::system::error_code bc( code.value(), *pc2->pc_ );
return pc_->equivalent( bc, condition );
}
#endif
else if( *pc_ == boost::system::generic_category() )
{
return std::generic_category().equivalent( code, condition );
}
else
{
return false;
}
}
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED

View File

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

View File

@@ -17,38 +17,5 @@
#include <boost/system/generic_category.hpp>
#include <boost/system/system_category.hpp>
#include <boost/system/detail/throws.hpp>
#include <boost/config.hpp>
namespace boost
{
namespace system
{
// non-member functions of error_code and error_condition
inline bool operator==( const error_code & code, const error_condition & condition ) BOOST_NOEXCEPT
{
return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
}
inline bool operator!=( const error_code & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
inline bool operator==( const error_condition & condition, const error_code & code ) BOOST_NOEXCEPT
{
return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
}
inline bool operator!=( const error_condition & lhs, const error_code & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
} // namespace system
} // namespace boost
#endif // BOOST_SYSTEM_ERROR_CODE_HPP_INCLUDED

View File

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

View File

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

View File

@@ -18,16 +18,6 @@
#ifdef BOOST_WINDOWS_API
#include <boost/system/error_code.hpp>
//// Neither MinGW or Cygwin versions of winerror.h work if used alone, so on
//// either of those platforms include the full windows.h
//
//#if defined(__MINGW32__) || defined(__CYGWIN__)
//#include <windows.h>
//#else
//#include <winerror.h>
//#endif
#include <boost/winapi/error_codes.hpp>
namespace boost
@@ -82,7 +72,8 @@ namespace boost
wrong_disk = boost::winapi::ERROR_WRONG_DISK_,
sharing_buffer_exceeded = boost::winapi::ERROR_SHARING_BUFFER_EXCEEDED_,
handle_eof = boost::winapi::ERROR_HANDLE_EOF_,
handle_disk_full= boost::winapi::ERROR_HANDLE_DISK_FULL_,
handle_disk_full = boost::winapi::ERROR_HANDLE_DISK_FULL_,
not_supported = boost::winapi::ERROR_NOT_SUPPORTED_,
rem_not_list = boost::winapi::ERROR_REM_NOT_LIST_,
dup_name = boost::winapi::ERROR_DUP_NAME_,
bad_net_path = boost::winapi::ERROR_BAD_NETPATH_,
@@ -94,7 +85,7 @@ namespace boost
broken_pipe = boost::winapi::ERROR_BROKEN_PIPE_,
open_failed = boost::winapi::ERROR_OPEN_FAILED_,
buffer_overflow = boost::winapi::ERROR_BUFFER_OVERFLOW_,
disk_full= boost::winapi::ERROR_DISK_FULL_,
disk_full = boost::winapi::ERROR_DISK_FULL_,
// ...
lock_failed = boost::winapi::ERROR_LOCK_FAILED_,
busy = boost::winapi::ERROR_BUSY_,

View File

@@ -8,8 +8,8 @@ Automatic redirection failed, please go to
</body>
</html>
<!--
<EFBFBD> Copyright Beman Dawes, 2001
© Copyright Beman Dawes, 2001
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
https://www.boost.org/LICENSE_1_0.txt
-->

View File

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

View File

@@ -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()
@@ -69,3 +70,97 @@ lib(boost_system_std_single_instance_lib2 STD_SINGLE_INSTANCE_DYN_LINK std_singl
system_run(std_single_instance_test.cpp std_single_instance_1.cpp std_single_instance_2.cpp)
boost_test(SOURCES std_single_instance_test.cpp NAME std_single_instance_test_lib LINK_LIBRARIES boost_system_std_single_instance_lib1 boost_system_std_single_instance_lib2)
boost_test(TYPE run SOURCES is_error_code_enum_test.cpp)
boost_test(TYPE run SOURCES is_error_condition_enum_test.cpp)
boost_test(TYPE run SOURCES errc_test.cpp)
boost_test(TYPE run SOURCES errc_test2.cpp)
boost_test(TYPE run SOURCES error_category_test2.cpp)
boost_test(TYPE run SOURCES error_condition_test.cpp)
boost_test(TYPE run SOURCES error_condition_test2.cpp)
boost_test(TYPE run SOURCES generic_category_test2.cpp)
boost_test(TYPE run SOURCES generic_category_test3.cpp)
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)
boost_test(TYPE run SOURCES snprintf_test.cpp)
boost_test(TYPE run SOURCES std_interop_test2.cpp)
boost_test(TYPE run SOURCES std_interop_test3.cpp)
boost_test(TYPE run SOURCES std_interop_test4.cpp)
boost_test(TYPE run SOURCES std_interop_test5.cpp)
boost_test(TYPE run SOURCES std_interop_test6.cpp)
boost_test(TYPE run SOURCES std_interop_test7.cpp)
boost_test(TYPE run SOURCES std_interop_test8.cpp)
boost_test(TYPE run SOURCES std_interop_test9.cpp)
boost_test(TYPE run SOURCES ec_location_test.cpp)
boost_test(TYPE run SOURCES error_condition_test3.cpp)
boost_test(TYPE run SOURCES error_code_test2.cpp)
boost_test(TYPE run SOURCES system_error_test2.cpp)
boost_test(TYPE run SOURCES std_interop_test10.cpp)
boost_test(TYPE run SOURCES ec_location_test2.cpp)
boost_test(TYPE run SOURCES ec_what_test.cpp)
boost_test(TYPE run SOURCES system_error_test3.cpp)
boost_test(TYPE run SOURCES std_interop_test11.cpp)
boost_test(TYPE run SOURCES ec_wstream_test.cpp)
boost_test(TYPE run SOURCES std_interop_test12.cpp)
boost_test(TYPE run SOURCES errc_test4.cpp)
boost_test(TYPE run SOURCES std_interop_test13.cpp)
boost_test(TYPE run SOURCES std_interop_test14.cpp)
boost_test(TYPE run SOURCES ec_location_test3.cpp)
boost_test(TYPE run SOURCES ec_location_test4.cpp)
boost_test(TYPE compile SOURCES constexpr_test2.cpp)
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
set(BOOST_TEST_COMPILE_FEATURES cxx_std_11)
boost_test(TYPE run SOURCES result_default_construct.cpp)
boost_test(TYPE run SOURCES result_value_construct.cpp)
boost_test(TYPE run SOURCES result_error_construct.cpp)
boost_test(TYPE run SOURCES result_copy_construct.cpp)
boost_test(TYPE run SOURCES result_move_construct.cpp)
boost_test(TYPE run SOURCES result_copy_assign.cpp)
boost_test(TYPE run SOURCES result_move_assign.cpp)
boost_test(TYPE run SOURCES result_value_access.cpp)
boost_test(TYPE run SOURCES result_error_access.cpp)
boost_test(TYPE run SOURCES result_swap.cpp)
boost_test(TYPE run SOURCES result_eq.cpp)
boost_test(TYPE run SOURCES result_range_for.cpp)
boost_test(TYPE run SOURCES result_value_construct2.cpp)
boost_test(TYPE run SOURCES result_error_construct2.cpp)
boost_test(TYPE run SOURCES result_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)

View File

@@ -1,7 +1,7 @@
# Boost System Library test Jamfile
# Copyright Beman Dawes 2003, 2006
# Copyright 2017-2019 Peter Dimov
# Copyright 2017-2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
@@ -10,6 +10,20 @@
import testing ;
project
: default-build
<warnings>extra
: requirements
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
<toolset>gcc-4.4:<cxxflags>-Wno-sign-compare
;
rule system-run ( sources + )
{
local result ;
@@ -19,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) ;
}
@@ -47,7 +62,11 @@ run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : <li
run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : <link>shared : single_instance_lib_shared ;
system-run before_main_test.cpp ;
run-fail throws_assign_fail.cpp ;
run-fail throws_assign_fail.cpp : : :
# GCC 12 catches this at compile time with a warning
<toolset>gcc,<variant>release:<build>no ;
system-run constexpr_test.cpp ;
system-run win32_hresult_test.cpp ;
@@ -61,8 +80,8 @@ system-run failed_constexpr_test.cpp ;
# Quick (CI) test
run quick.cpp ;
compile warnings_test.cpp
: <warnings>pedantic
run warnings_test.cpp
: : : <warnings>pedantic
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
@@ -85,3 +104,93 @@ run generic_category_test2.cpp ;
run generic_category_test3.cpp ;
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 ;
run snprintf_test.cpp ;
run std_interop_test2.cpp ;
run std_interop_test3.cpp ;
run std_interop_test4.cpp ;
run std_interop_test5.cpp
: : :
# crash on xenial, but the real g++ 4.8 on both centos 7 and trusty works
<toolset>gcc-4.8:<build>no
<toolset>gcc-4.9:<build>no
;
run std_interop_test6.cpp ;
run std_interop_test7.cpp ;
run std_interop_test8.cpp ;
run std_interop_test9.cpp ;
run ec_location_test.cpp ;
run error_condition_test3.cpp ;
run error_code_test2.cpp ;
run system_error_test2.cpp ;
run std_interop_test10.cpp ;
run ec_location_test2.cpp ;
run ec_what_test.cpp ;
run system_error_test3.cpp ;
run std_interop_test11.cpp ;
run ec_wstream_test.cpp ;
run std_interop_test12.cpp ;
run errc_test4.cpp ;
run std_interop_test13.cpp ;
run std_interop_test14.cpp ;
run ec_location_test3.cpp ;
run ec_location_test4.cpp ;
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_typedefs.cpp : : : $(CPP11) ;
run result_value_construct3.cpp : : : $(CPP11) ;
run result_error_construct3.cpp : : : $(CPP11) ;
run result_emplace.cpp : : : $(CPP11) ;
run result_error_construct4.cpp : : : $(CPP11) ;
run result_value_construct4.cpp : : : $(CPP11) ;
run result_value_construct5.cpp : : : $(CPP11) ;
run result_error_move.cpp : : : $(CPP11) ;

View File

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

View File

@@ -7,12 +7,11 @@ cmake_minimum_required(VERSION 3.5...3.16)
project(cmake_install_test LANGUAGES CXX)
find_package(boost_system REQUIRED)
find_package(boost_core REQUIRED)
add_executable(quick ../quick.cpp)
target_link_libraries(quick Boost::system Boost::core)
add_executable(main main.cpp)
target_link_libraries(main Boost::system)
enable_testing()
add_test(quick quick)
add_test(main main)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)

View File

@@ -0,0 +1,44 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
// See library home page at http://www.boost.org/libs/system
#include <boost/system.hpp>
#include <cassert>
#include <cerrno>
#define BOOST_TEST(expr) assert(expr)
#define BOOST_TEST_EQ(x1, x2) assert((x1)==(x2))
int main()
{
boost::system::error_category const & bt = boost::system::generic_category();
int ev = ENOENT;
boost::system::error_code bc( ev, bt );
BOOST_TEST_EQ( bc.value(), ev );
BOOST_TEST_EQ( &bc.category(), &bt );
boost::system::error_condition bn = bt.default_error_condition( ev );
BOOST_TEST_EQ( bn.value(), ev );
BOOST_TEST_EQ( &bn.category(), &bt );
BOOST_TEST( bt.equivalent( ev, bn ) );
BOOST_TEST( bc == bn );
boost::system::error_code bc2 = make_error_code( boost::system::errc::no_such_file_or_directory );
BOOST_TEST_EQ( bc2, bc );
BOOST_TEST_EQ( bc2.value(), ev );
BOOST_TEST_EQ( &bc.category(), &bt );
boost::system::system_error x( bc, "prefix" );
BOOST_TEST_EQ( x.code(), bc );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.what() );
}

View File

@@ -1,8 +1,8 @@
# Copyright 2018, 2019 Peter Dimov
# Copyright 2018-2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.5...3.20)
project(cmake_subdir_test LANGUAGES CXX)
@@ -10,7 +10,11 @@ add_subdirectory(../.. boostorg/system)
add_subdirectory(../../../assert boostorg/assert)
add_subdirectory(../../../config boostorg/config)
add_subdirectory(../../../core boostorg/core)
add_subdirectory(../../../mp11 boostorg/mp11)
add_subdirectory(../../../predef boostorg/predef)
add_subdirectory(../../../static_assert boostorg/static_assert)
add_subdirectory(../../../throw_exception boostorg/throw_exception)
add_subdirectory(../../../variant2 boostorg/variant2)
add_subdirectory(../../../winapi boostorg/winapi)
add_executable(quick ../quick.cpp)
@@ -19,4 +23,4 @@ target_link_libraries(quick Boost::system Boost::core)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --no-tests=error -C $<CONFIG>)

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

@@ -0,0 +1,29 @@
// 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

132
test/ec_hash_value_test.cpp Normal file
View File

@@ -0,0 +1,132 @@
// 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>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#include <system_error>
#endif
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 ) );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
// 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 ) );
}
#endif
return boost::report_errors();
}

116
test/ec_location_test.cpp Normal file
View File

@@ -0,0 +1,116 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
int main()
{
int const val = ENOENT;
boost::system::error_category const & cat = boost::system::generic_category();
{
boost::system::error_code ec( val, cat );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
}
{
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
boost::system::error_code ec( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 27 );
}
{
boost::system::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &boost::system::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec = boost::system::error_code( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 51 );
}
{
boost::system::error_code ec;
BOOST_TEST_EQ( ec.value(), 0 );
BOOST_TEST_EQ( &ec.category(), &boost::system::system_category() );
BOOST_TEST( !ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 75 );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
boost::system::error_code ec( e2 );
BOOST_TEST( ec.failed() );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 0 );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( val, cat, &loc );
BOOST_TEST_EQ( ec.value(), val );
BOOST_TEST_EQ( &ec.category(), &cat );
BOOST_TEST( ec.failed() );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location().line(), 100 );
}
#endif
return boost::report_errors();
}

287
test/ec_location_test2.cpp Normal file
View File

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

View File

@@ -0,0 +1,90 @@
// Copyright 2021, 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
int main()
{
int const val = ENOENT;
boost::system::error_category const & cat = boost::system::generic_category();
{
boost::system::error_code ec;
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
boost::system::error_code ec2( ec, &loc );
BOOST_TEST_EQ( ec2, ec );
BOOST_TEST( !ec2.has_location() );
BOOST_TEST_EQ( ec2.location(), boost::source_location() );
boost::system::error_code ec3( ec2, 0 );
BOOST_TEST_EQ( ec3, ec2 );
BOOST_TEST( !ec3.has_location() );
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
{
boost::system::error_code ec( val, cat );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
boost::system::error_code ec2( ec, &loc );
BOOST_TEST_EQ( ec2, ec );
BOOST_TEST( ec2.has_location() );
BOOST_TEST_EQ( ec2.location(), loc );
boost::system::error_code ec3( ec2, 0 );
BOOST_TEST_EQ( ec3, ec2 );
BOOST_TEST( !ec3.has_location() );
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
boost::system::error_code ec( e2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
boost::system::error_code ec2( ec, &loc );
BOOST_TEST_EQ( ec2, ec );
BOOST_TEST( !ec2.has_location() );
BOOST_TEST_EQ( ec2.location(), boost::source_location() );
boost::system::error_code ec3( ec2, 0 );
BOOST_TEST_EQ( ec3, ec2 );
BOOST_TEST( !ec3.has_location() );
BOOST_TEST_EQ( ec3.location(), boost::source_location() );
}
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,93 @@
// Copyright 2021, 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
int main()
{
int const val = ENOENT;
boost::system::error_category const & cat = boost::system::generic_category();
{
boost::system::error_code ec;
boost::system::error_code ec2( ec );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( ec, &loc );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
ec.assign( ec, 0 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
{
boost::system::error_code ec( val, cat );
boost::system::error_code ec2( ec );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( ec, &loc );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( ec.has_location() );
BOOST_TEST_EQ( ec.location(), loc );
ec.assign( ec, 0 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
{
std::error_code e2( val, std::generic_category() );
boost::system::error_code ec( e2 );
boost::system::error_code ec2( ec );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
ec.assign( ec, &loc );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
ec.assign( ec, 0 );
BOOST_TEST_EQ( ec, ec2 );
BOOST_TEST( !ec.has_location() );
BOOST_TEST_EQ( ec.location(), boost::source_location() );
}
#endif
return boost::report_errors();
}

91
test/ec_what_test.cpp Normal file
View File

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

21
test/ec_wstream_test.cpp Normal file
View File

@@ -0,0 +1,21 @@
// Copyright 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <sstream>
namespace sys = boost::system;
int main()
{
{
std::wostringstream os;
os << sys::error_code();
BOOST_TEST( os.str() == L"system:0" );
}
return boost::report_errors();
}

34
test/errc_test3.cpp Normal file
View File

@@ -0,0 +1,34 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/errc.hpp>
int main()
{
make_error_code( boost::system::errc::success ).value();
make_error_code( boost::system::errc::success ).category();
make_error_code( boost::system::errc::success ).default_error_condition();
make_error_code( boost::system::errc::success ).message();
make_error_code( boost::system::errc::success ).failed();
make_error_code( boost::system::errc::success ).clear();
make_error_condition( boost::system::errc::success ).value();
make_error_condition( boost::system::errc::success ).category();
make_error_condition( boost::system::errc::success ).message();
make_error_condition( boost::system::errc::success ).failed();
make_error_condition( boost::system::errc::success ).clear();
make_error_code( boost::system::errc::no_such_file_or_directory ).value();
make_error_code( boost::system::errc::no_such_file_or_directory ).category();
make_error_code( boost::system::errc::no_such_file_or_directory ).default_error_condition();
make_error_code( boost::system::errc::no_such_file_or_directory ).message();
make_error_code( boost::system::errc::no_such_file_or_directory ).failed();
make_error_code( boost::system::errc::no_such_file_or_directory ).clear();
make_error_condition( boost::system::errc::no_such_file_or_directory ).value();
make_error_condition( boost::system::errc::no_such_file_or_directory ).category();
make_error_condition( boost::system::errc::no_such_file_or_directory ).message();
make_error_condition( boost::system::errc::no_such_file_or_directory ).failed();
make_error_condition( boost::system::errc::no_such_file_or_directory ).clear();
}

17
test/errc_test4.cpp Normal file
View File

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

View File

@@ -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>
//
@@ -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>
//
@@ -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,11 +11,8 @@
#include <boost/config/warning_disable.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/cygwin_error.hpp>
#include <boost/system/linux_error.hpp>
#include <boost/system/windows_error.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iostream>
#include <sstream>
#include <string>
@@ -111,6 +108,7 @@ int main( int, char ** )
std::cout << "Conversion use cases...\n";
error_condition x1( errc::file_exists );
(void)x1;
//error_code x2( errc::file_exists ); // should fail to compile
make_error_code(errc::file_exists);
make_error_condition(errc::file_exists);
@@ -294,29 +292,7 @@ int main( int, char ** )
BOOST_TEST( ec.default_error_condition().value() == errc::permission_denied );
BOOST_TEST( ec.default_error_condition().category() == generic_category() );
# ifdef __CYGWIN__
std::cout << "Cygwin tests...\n";
ec = cygwin_error::no_package;
BOOST_TEST( ec == cygwin_error::no_package );
BOOST_TEST( ec == error_code( ENOPKG, system_category() ) );
BOOST_TEST( ec == error_code( cygwin_error::no_package, system_category() ) );
BOOST_TEST( ec.default_error_condition().category() == system_category() );
# elif defined(linux) || defined(__linux) || defined(__linux__)
std::cout << "Linux tests...\n";
ec = linux_error::dot_dot_error;
BOOST_TEST( ec == linux_error::dot_dot_error );
BOOST_TEST( ec == error_code( EDOTDOT, system_category() ) );
BOOST_TEST( ec == error_code( linux_error::dot_dot_error, system_category() ) );
BOOST_TEST( ec.default_error_condition().category() == system_category() );
# endif
#endif
return ::boost::report_errors();
}

94
test/error_code_test2.cpp Normal file
View File

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

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

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

View File

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

View File

@@ -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;
@@ -28,7 +26,7 @@ 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;
}

View File

@@ -16,8 +16,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <boost/system/error_code.hpp>
int main( int, char*[] )
int main()
{
boost::system::error_code ec( 0, boost::system::system_category() );
return ::boost::report_errors();
boost::system::error_code ec( 0, boost::system::system_category() );
(void)ec;
return ::boost::report_errors();
}

29
test/linux_error_test.cpp Normal file
View File

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

View File

@@ -1,15 +1,10 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 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
// See library home page at http://www.boost.org/libs/system
#include <boost/system/system_error.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cerrno>
@@ -33,10 +28,16 @@ int main()
BOOST_TEST( bc == bn );
boost::system::error_code bc2 = make_error_code( boost::system::errc::no_such_file_or_directory );
BOOST_TEST_EQ( bc2, bc );
BOOST_TEST_EQ( bc2.value(), ev );
BOOST_TEST_EQ( &bc.category(), &bt );
boost::system::system_error x( bc, "prefix" );
BOOST_TEST_EQ( x.code(), bc );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.message() );
BOOST_TEST_EQ( std::string( x.what() ), "prefix: " + bc.what() );
return boost::report_errors();
}

View File

@@ -0,0 +1,202 @@
// Copyright 2017, 2021, 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
X( int v ): v_( v ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
int main()
{
{
result<int> r( 5 );
result<long> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 5 );
}
{
result<int> const r( 6 );
result<long> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 6 );
}
{
result<long> r2 = result<int>( 7 );
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 7 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> r( 5 );
result<X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 5 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> const r( 6 );
result<X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 6 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r2 = result<int>( 7 );
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, 7 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<long> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<long> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<long> r2 = result<int>( ec );
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> r( "test" );
result<std::string, X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, std::string( "test" ) );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> const r( "test" );
result<std::string, X> r2 = r;
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, std::string( "test" ) );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r2 = result<char const*, int>( "test" );
BOOST_TEST( r2 ) && BOOST_TEST_EQ( *r2, std::string( "test" ) );
BOOST_TEST_EQ( X::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> r( 5 );
result<std::string, X> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(5) );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<char const*, int> const r( 6 );
result<std::string, X> r2 = r;
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(6) );
BOOST_TEST_EQ( X::instances, 1 );
}
{
result<std::string, X> r2 = result<char const*, int>( 7 );
BOOST_TEST( !r2 );
BOOST_TEST_EQ( r2.error(), X(7) );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<long>, result<int>>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<result<int>, result<long>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int>, result<void*>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<void*>, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int>, result<void>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<void>, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<void>, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<int>, result<void>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, void*>, result<int, int>>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<int, int>, result<int, void*>>));
}
return boost::report_errors();
}

686
test/result_copy_assign.cpp Normal file
View File

@@ -0,0 +1,686 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v = 0 ): v_( v ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = default;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y& operator=( Y const& ) = default;
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
// default-initialized lhs
{
result<int> r;
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r;
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r;
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r;
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r;
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r;
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
// value lhs
{
result<int> r( 0 );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 0 );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 0 );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 0 );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 0 );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 0 );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( 2 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2( 2 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
// error lhs
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2( 1 );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2;
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 0 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> const r( ec );
result<X> r2;
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> const r( ec );
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 1 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> const r( ec );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 0 );
r2 = r;
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
//
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( "str" );
BOOST_TEST_EQ( Y::instances, 1 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> const r( 1 );
result<std::string, Y> r2( 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> const r( 1 );
result<std::string, Y> r2( "str" );
BOOST_TEST_EQ( Y::instances, 1 );
r2 = r;
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( Y::instances, 0 );
// void
{
result<void> r;
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<void> r;
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<void> const r;
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
result<void> const r;
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
result<void> r2;
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
result<void> r2( ENOENT, generic_category() );
r2 = r;
BOOST_TEST_EQ( r, r2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,181 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
int main()
{
{
result<int> r;
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r;
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> r( 1 );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> const r( 1 );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> const r( 1 );
result<X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
result<int> r2( r );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r( 1 );
result<std::string, X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> const r( 1 );
result<std::string, X> r2( r );
BOOST_TEST_EQ( r, r2 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<void> r;
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
result<void> const r;
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
result<void> r2( r );
BOOST_TEST_EQ( r, r2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,58 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
};
struct Y
{
Y( int );
};
int main()
{
{
result<int> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<X> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
result<void> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
{
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>>));
}
return boost::report_errors();
}

176
test/result_emplace.cpp Normal file
View File

@@ -0,0 +1,176 @@
// 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 );
}
return boost::report_errors();
}

153
test/result_eq.cpp Normal file
View File

@@ -0,0 +1,153 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v ): v_( v ) { ++instances; }
X( X const& r ) = delete;
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
X& operator=( X&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y( Y&& r ) noexcept: v_( r.v_ ) { r.v_ = 0; ++instances; }
Y& operator=( Y const& ) = default;
Y& operator=( Y&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
{
result<int> r1( 1 );
result<int> r2( 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<int> r1( 1, generic_category() );
result<int> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<int> r1( 1 );
result<int> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<X, Y> r1( in_place_value, 1 );
result<X, Y> r2( in_place_value, 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<X, Y> r1( in_place_error, 1 );
result<X, Y> r2( in_place_error, 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<X, Y> r1( in_place_value, 1 );
result<X, Y> r2( in_place_error, 2 );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
{
result<void> r1;
result<void> r2;
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_EQ( r1, r2 );
}
{
result<void> r1( 1, generic_category() );
result<void> r2( 2, generic_category() );
BOOST_TEST_EQ( r1, r1 );
BOOST_TEST_NE( r1, r2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,23 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
using namespace boost::system;
int main()
{
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int>, errc::errc_t>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<double>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<double>, errc::errc_t>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<errc::errc_t, result<bool>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<bool>, errc::errc_t>));
return boost::report_errors();
}

View File

@@ -0,0 +1,212 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <string>
using namespace boost::system;
struct X
{
int v_;
explicit X( int v = 0 ): v_( v ) {}
X( X const& ) = default;
X& operator=( X const& ) = delete;
};
int main()
{
{
result<int> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
result<int> const r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
BOOST_TEST( result<int>().has_value() );
BOOST_TEST( !result<int>().has_error() );
BOOST_TEST_EQ( result<int>().error(), error_code() );
}
{
result<int> r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
result<int> const r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
BOOST_TEST( result<int>( 1 ).has_value() );
BOOST_TEST( !result<int>( 1 ).has_error() );
BOOST_TEST_EQ( result<int>( 1 ).error(), error_code() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
BOOST_TEST( !result<int>( ec ).has_value() );
BOOST_TEST( result<int>( ec ).has_error() );
BOOST_TEST_EQ( result<int>( ec ).error(), ec );
}
{
result<std::string, X> r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1 );
}
{
result<std::string, X> const r( 1 );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 1 );
}
{
BOOST_TEST(( !result<std::string, X>( 1 ).has_value() ));
BOOST_TEST(( result<std::string, X>( 1 ).has_error() ));
BOOST_TEST_EQ( (result<std::string, X>( 1 ).error().v_), 1 );
}
{
result<std::string, X> r( "s" );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error().v_, 0 );
}
{
result<std::string, X> const r( "s" );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error().v_, 0 );
}
{
BOOST_TEST(( result<std::string, X>( "s" ).has_value() ));
BOOST_TEST(( !result<std::string, X>( "s" ).has_error() ));
BOOST_TEST_EQ( (result<std::string, X>( "s" ).error().v_), 0 );
}
{
result<void> r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
result<void> const r;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.error(), error_code() );
}
{
BOOST_TEST( result<void>().has_value() );
BOOST_TEST( !result<void>().has_error() );
BOOST_TEST_EQ( result<void>().error(), error_code() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> const r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
BOOST_TEST( !result<void>( ec ).has_value() );
BOOST_TEST( result<void>( ec ).has_error() );
BOOST_TEST_EQ( result<void>( ec ).error(), ec );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,191 @@
// 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>>));
// 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>>));
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r = ec;
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
result<void> r( EINVAL, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,57 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <string>
using namespace boost::system;
struct X
{
int a, b;
};
result<X> fx1()
{
return {{ EINVAL, generic_category() }};
}
struct Y
{
std::string v;
};
struct E
{
int v;
};
result<Y, E> fy1()
{
return {{ 42 }};
}
int main()
{
{
result<X> r = fx1();
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), error_code( EINVAL, generic_category() ) );
}
{
result<Y, E> r = fy1();
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v, 42 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,161 @@
// 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() ) );
}
return boost::report_errors();
}

View File

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

View File

@@ -0,0 +1,91 @@
// 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 );
}
return boost::report_errors();
}

604
test/result_move_assign.cpp Normal file
View File

@@ -0,0 +1,604 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v = 0 ): v_( v ) { ++instances; }
X( X const& r ) = delete;
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
X& operator=( X&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y( Y&& r ) noexcept: v_( r.v_ ) { r.v_ = 0; ++instances; }
Y& operator=( Y const& ) = default;
Y& operator=( Y&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
// default-initialized lhs
{
result<int> r;
result<int> r2;
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2;
r2 = result<int>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r;
result<int> r2( 1 );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2( 1 );
r2 = result<int>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r;
result<int> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2( ENOENT, generic_category() );
r2 = result<int>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
}
BOOST_TEST_EQ( X::instances, 0 );
// value lhs
{
result<int> r( 1 );
result<int> r2;
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 1 );
result<int> r2( 2 );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r, r2 );
}
{
result<int> r( 1 );
result<int> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
BOOST_TEST_EQ( r, r2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2;
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( r.value().v_, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( 2 );
BOOST_TEST_EQ( X::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( r.value().v_, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( r.value().v_, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
// error lhs
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2;
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2;
r2 = result<int>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( 1 );
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2( 1 );
r2 = result<int>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2( ENOENT, generic_category() );
r2 = result<int>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2;
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( 1 );
BOOST_TEST_EQ( X::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<X> r( ec );
result<X> r2( ENOENT, generic_category() );
BOOST_TEST_EQ( X::instances, 0 );
r2 = std::move( r );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
//
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r2 = std::move( r );
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( r.error().v_, 0 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<std::string, Y> r( 1 );
result<std::string, Y> r2( "str" );
BOOST_TEST_EQ( Y::instances, 1 );
r2 = std::move( r );
BOOST_TEST_EQ( Y::instances, 2 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( r.error().v_, 0 );
}
BOOST_TEST_EQ( Y::instances, 0 );
{
result<void> r;
result<void> r2;
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r2;
r2 = result<void>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r;
result<void> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r2( ENOENT, generic_category() );
r2 = result<void>();
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2;
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r2;
r2 = result<void>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( ENOENT, generic_category() );
r2 = std::move( r );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r2( ENOENT, generic_category() );
r2 = result<void>( ec );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,249 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
int main()
{
{
result<int> r;
result<int> r2( std::move( r ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
{
result<int> r2( result<int>{} );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r;
result<X> r2( std::move( r ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r2( result<X>{} );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), X() );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<int> r( 1 );
result<int> r2( std::move( r ) );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 1 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
}
{
result<int> r2( result<int>( 1 ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value(), 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
result<X> r2( std::move( r ) );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 0 );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r2( result<X>( 1 ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
BOOST_TEST_EQ( r2.value().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
result<int> r2( std::move( r ) );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r2( result<int>{ ec } );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r( 1 );
result<std::string, X> r2( std::move( r ) );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error().v_, 0 );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( X::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<std::string, X> r2( result<std::string, X>( 1 ) );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<void> r;
result<void> r2( std::move( r ) );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
result<void> r2( result<void>{} );
BOOST_TEST( r2.has_value() );
BOOST_TEST( !r2.has_error() );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
result<void> r2( std::move( r ) );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r2( result<void>{ ec } );
BOOST_TEST( !r2.has_value() );
BOOST_TEST( r2.has_error() );
BOOST_TEST_EQ( r2.error(), ec );
}
return boost::report_errors();
}

30
test/result_range_for.cpp Normal file
View File

@@ -0,0 +1,30 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <vector>
using namespace boost::system;
result<std::vector<int>> f()
{
return std::vector<int>{ 1, 2, 3 };
}
int main()
{
{
int s = 0;
for( int x: f().value() )
{
s += x;
}
BOOST_TEST_EQ( s, 6 );
}
return boost::report_errors();
}

263
test/result_swap.cpp Normal file
View File

@@ -0,0 +1,263 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iosfwd>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v ): v_( v ) { ++instances; }
X( X const& r ) = delete;
X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
X& operator=( X const& ) = delete;
X& operator=( X&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~X() { --instances; }
};
bool operator==( X const & x1, X const & x2 )
{
return x1.v_ == x2.v_;
}
std::ostream& operator<<( std::ostream& os, X const & x )
{
os << "X:" << x.v_;
return os;
}
int X::instances = 0;
struct Y
{
static int instances;
int v_;
explicit Y( int v = 0 ): v_( v ) { ++instances; }
Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
Y( Y&& r ) noexcept: v_( r.v_ ) { r.v_ = 0; ++instances; }
Y& operator=( Y const& ) = default;
Y& operator=( Y&& r )
{
v_ = r.v_;
r.v_ = 0;
return *this;
}
~Y() { --instances; }
};
bool operator==( Y const & y1, Y const & y2 )
{
return y1.v_ == y2.v_;
}
std::ostream& operator<<( std::ostream& os, Y const & y )
{
os << "Y:" << y.v_;
return os;
}
int Y::instances = 0;
int main()
{
{
result<int> r1( 1 ), r1c( r1 );
result<int> r2( 2 ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<int> r1( 1, generic_category() ), r1c( r1 );
result<int> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<int> r1( 1 ), r1c( r1 );
result<int> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<X, Y> r1( in_place_value, 1 ), r1c( in_place_value, 1 );
result<X, Y> r2( in_place_value, 2 ), r2c( in_place_value, 2 );
BOOST_TEST_EQ( X::instances, 4 );
BOOST_TEST_EQ( Y::instances, 0 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
BOOST_TEST_EQ( X::instances, 4 );
BOOST_TEST_EQ( Y::instances, 0 );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
BOOST_TEST_EQ( X::instances, 4 );
BOOST_TEST_EQ( Y::instances, 0 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<X, Y> r1( in_place_error, 1 ), r1c( in_place_error, 1 );
result<X, Y> r2( in_place_error, 2 ), r2c( in_place_error, 2 );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 4 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 4 );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 4 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<X, Y> r1( in_place_value, 1 ), r1c( in_place_value, 1 );
result<X, Y> r2( in_place_error, 2 ), r2c( in_place_error, 2 );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( Y::instances, 2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( Y::instances, 2 );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
BOOST_TEST_EQ( X::instances, 2 );
BOOST_TEST_EQ( Y::instances, 2 );
}
BOOST_TEST_EQ( X::instances, 0 );
BOOST_TEST_EQ( Y::instances, 0 );
{
result<void> r1, r1c( r1 );
result<void> r2, r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<void> r1( 1, generic_category() ), r1c( r1 );
result<void> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
{
result<void> r1, r1c( r1 );
result<void> r2( 2, generic_category() ), r2c( r2 );
r1.swap( r2 );
BOOST_TEST_EQ( r1, r2c );
BOOST_TEST_EQ( r2, r1c );
swap( r1, r2 );
BOOST_TEST_EQ( r1, r1c );
BOOST_TEST_EQ( r2, r2c );
}
return boost::report_errors();
}

22
test/result_typedefs.cpp Normal file
View File

@@ -0,0 +1,22 @@
// 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<X>::value_type, X );
BOOST_TEST_TRAIT_SAME( result<void>::value_type, void );
BOOST_TEST_TRAIT_SAME( result<int>::error_type, error_code );
BOOST_TEST_TRAIT_SAME( result<int, X>::error_type, X );
return boost::report_errors();
}

View File

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

View File

@@ -0,0 +1,132 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
static int instances;
int v_;
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& ) = delete;
X& operator=( X const& ) = delete;
~X() { --instances; }
};
int X::instances = 0;
int main()
{
{
result<int> r( 0 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<int> r = 0;
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value(), 0 );
}
{
result<int, int> r( in_place_value, 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( *r, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1, 2 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 1+2 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X> r( 1, 2, 3 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r.value().v_, 1+2+3 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
result<X, X> r( in_place_value, 1 );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
BOOST_TEST_EQ( r->v_, 1 );
BOOST_TEST_EQ( X::instances, 1 );
}
BOOST_TEST_EQ( X::instances, 0 );
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int>, int>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<int, result<int>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, int>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, float>, int>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<X>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<X>>));
}
{
result<void> r( in_place_value );
BOOST_TEST( r.has_value() );
BOOST_TEST( !r.has_error() );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,152 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <vector>
#include <string>
using namespace boost::system;
struct X
{
int a;
};
struct Y
{
int a, b;
};
struct E
{
std::string v;
};
result<X> fx0()
{
return {};
}
result<X> fx1()
{
return {{ 1 }};
}
result<Y> fy0()
{
return {};
}
result<Y> fy2()
{
return {{ 1, 2 }};
}
result<X, E> fxe0()
{
return {};
}
result<X, E> fxe1()
{
return {{ 1 }};
}
result<std::vector<int>> fv0()
{
return {};
}
result<std::vector<int>> fv1()
{
return {{ 1 }};
}
result<std::vector<int>> fv2()
{
return {{ 1, 2 }};
}
int main()
{
{
result<X> r = fx0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 0 );
}
{
result<X> r = fx1();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 1 );
}
{
result<Y> r = fy0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 0 );
BOOST_TEST_EQ( r->b, 0 );
}
{
result<Y> r = fy2();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 1 );
BOOST_TEST_EQ( r->b, 2 );
}
{
result<X, E> r = fxe0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 0 );
}
{
result<X, E> r = fxe1();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->a, 1 );
}
{
result<std::vector<int>> r = fv0();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->size(), 0 );
}
{
result<std::vector<int>> r = fv1();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->size(), 1 );
BOOST_TEST_EQ( r->at(0), 1 );
}
{
result<std::vector<int>> r = fv2();
BOOST_TEST( r.has_value() );
BOOST_TEST_EQ( r->size(), 2 );
BOOST_TEST_EQ( r->at(0), 1 );
BOOST_TEST_EQ( r->at(1), 2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,118 @@
// 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() );
}
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();
}

60
test/snprintf_test.cpp Normal file
View File

@@ -0,0 +1,60 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/detail/snprintf.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
{
char buffer[ 64 ];
boost::system::detail::snprintf( buffer, sizeof(buffer), "...%s...%d...", "xy", 151 );
BOOST_TEST_CSTR_EQ( buffer, "...xy...151..." );
}
{
char buffer[ 64 ];
boost::system::detail::snprintf( buffer, sizeof(buffer), "...%s...%d...", "xy", 151 );
BOOST_TEST_CSTR_EQ( buffer, "...xy...151..." );
}
{
char buffer[ 15 ];
boost::system::detail::snprintf( buffer, sizeof(buffer), "...%s...%d...", "xy", 151 );
BOOST_TEST_CSTR_EQ( buffer, "...xy...151..." );
}
{
char buffer[ 14 ];
boost::system::detail::snprintf( buffer, sizeof(buffer), "...%s...%d...", "xy", 151 );
BOOST_TEST_CSTR_EQ( buffer, "...xy...151.." );
}
{
char buffer[ 5 ];
boost::system::detail::snprintf( buffer, sizeof(buffer), "...%s...%d...", "xy", 151 );
BOOST_TEST_CSTR_EQ( buffer, "...x" );
}
{
char buffer[ 1 ];
boost::system::detail::snprintf( buffer, sizeof(buffer), "...%s...%d...", "xy", 151 );
BOOST_TEST_CSTR_EQ( buffer, "" );
}
{
char buffer[ 1 ] = { 'Q' };
boost::system::detail::snprintf( buffer, 0, "...%s...%d...", "xy", 151 );
BOOST_TEST_EQ( buffer[0], 'Q' );
}
return boost::report_errors();
}

View File

@@ -8,9 +8,6 @@
// 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>
@@ -30,6 +27,7 @@ int main()
#else
#include <boost/core/lightweight_test.hpp>
#include <boost/core/snprintf.hpp>
#include <system_error>
#include <cerrno>
#include <string>
@@ -44,7 +42,8 @@ static void test_generic_category()
int ev = ENOENT;
BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
// Under MSVC, it's "no such file or directory" instead of "No such file or directory"
BOOST_TEST_EQ( bt.message( ev ).substr( 1 ), st.message( ev ).substr( 1 ) );
{
boost::system::error_code bc( ev, bt );
@@ -82,34 +81,13 @@ static void test_system_category()
BOOST_TEST_CSTR_EQ( bt.name(), st.name() );
for( int ev = 1; ev < 6; ++ev )
{
int ev = 5;
BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
std::string bm = bt.message( ev );
std::string sm = st.message( ev );
{
boost::system::error_code bc( ev, bt );
BOOST_TEST_EQ( bc.value(), ev );
BOOST_TEST_EQ( &bc.category(), &bt );
std::error_code sc( bc );
BOOST_TEST_EQ( sc.value(), ev );
BOOST_TEST_EQ( &sc.category(), &st );
}
{
boost::system::error_condition bn = bt.default_error_condition( ev );
BOOST_TEST( bt.equivalent( ev, bn ) );
std::error_condition sn( bn );
BOOST_TEST( st.equivalent( ev, sn ) );
}
}
{
int ev = 4;
BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
// We strip whitespace and the trailing dot, MSVC not so much
BOOST_TEST_EQ( bm, sm.substr( 0, bm.size() ) );
{
boost::system::error_code bc( ev, bt );
@@ -147,7 +125,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;
}
@@ -287,7 +265,7 @@ 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;
}

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