Compare commits

...

148 Commits

Author SHA1 Message Date
5fd2535d9f Excise generic_category() references from error_condition 2021-09-19 16:04:16 +03:00
b39f239b3d Update documentation 2021-09-19 15:53:13 +03:00
abb13e707d Minor test fixes 2021-09-19 15:46:03 +03:00
bf34091cfe Add error_code_test2 2021-09-19 15:41:20 +03:00
e3f198e52c Add error_condition::to_string 2021-09-19 15:37:49 +03:00
05581aba03 Add error_condition_test3 2021-09-19 15:26:19 +03:00
47137ad116 Change predefined error_category identifiers to be contiguous for better codegen 2021-09-19 15:04:51 +03:00
c02cd2b004 Add private error_code::equals, use it in error_category::equivalent 2021-09-19 05:24:08 +03:00
c8c5ad1ce5 Rework error_condition::op== to not require the generic_category() instance 2021-09-19 04:49:35 +03:00
361834e49c Minor documentation corrections 2021-09-18 16:57:21 +03:00
360effcf1d Remove static/shared tests, System is header-only 2021-09-18 02:23:21 +03:00
aaa893b5d6 Add mp11 to cmake_subdir_test/CMakeLists.txt 2021-09-18 00:08:30 +03:00
ff0bd3294f Add back predef, winapi needs it 2021-09-17 23:54:33 +03:00
aedadc27ce Update test/cmake_subdir_test/CMakeLists.txt 2021-09-17 21:31:13 +03:00
aad1212cfd Update tests/CMakeLists.txt 2021-09-17 21:15:13 +03:00
c15c2eeb74 Update dependencies in CMakeLists.txt 2021-09-17 21:10:53 +03:00
0ea47dd886 Add CMake jobs to ci.yml 2021-09-17 21:00:18 +03:00
08c12e8ad5 Document result<void, E> 2021-09-17 20:16:01 +03:00
7d3cfdd09a Update test/result_value_construct 2021-09-17 19:54:53 +03:00
15f94537a6 Update test/result_value_access 2021-09-17 19:53:11 +03:00
c0f38e2f3e Update test/result_swap 2021-09-17 19:46:56 +03:00
ac28a8cec9 Update test/result_move_assign 2021-09-17 19:44:58 +03:00
4169ef3ce6 Update test/result_error_construct 2021-09-17 19:36:58 +03:00
ce49a7d1be Update test/result_move_construct 2021-09-17 19:35:20 +03:00
1a4eb29719 Update test/result_error_access 2021-09-17 19:35:05 +03:00
465f6c57da Update test/result_eq 2021-09-17 19:34:44 +03:00
cb8db34d7b Update test/result_copy_assign 2021-09-17 19:34:26 +03:00
2b6a708070 Update test/result_copy_construct 2021-09-17 19:25:20 +03:00
50f84f16dc Add result<void, E> specialization 2021-09-17 19:22:15 +03:00
fd21395802 Minor indentation fixes 2021-09-17 18:50:30 +03:00
cebb011a58 Update indentation in reference 2021-09-17 18:43:30 +03:00
3f67d3def5 Rename throw_exception_from_error_code to throw_exception_from_error 2021-09-17 18:33:04 +03:00
f2b3ae7e2b Document throw_exception_from_error_code 2021-09-17 18:28:53 +03:00
48e56b9874 Update revision history 2021-09-17 18:19:24 +03:00
967b7cbc98 Add result to reference 2021-09-17 18:16:54 +03:00
c8492a705d Use unsafe_get instead of *get_if 2021-09-17 15:47:35 +03:00
a3187439e3 Disable warning in after_main_test 2021-09-16 19:49:17 +03:00
19f9d0c5b4 Fix unused parameter error 2021-09-16 19:43:32 +03:00
d17f7d7fe6 Fix unused variable warning 2021-09-16 19:32:22 +03:00
36843a4e2d Fix unused variable warnings 2021-09-16 19:30:28 +03:00
a6c988181e Include result.hpp in <boost/system.hpp> 2021-09-16 19:25:26 +03:00
10572b7a59 Trim includes in system_error.hpp 2021-09-16 19:21:27 +03:00
fe3d0e6c14 Update all references to <system_error> to refer to Boost.System 2021-09-16 19:16:30 +03:00
ae77563039 Define result in boost::system instead of in boost::result 2021-09-16 18:56:35 +03:00
fd852c675e Add <boost/system/result.hpp> 2021-09-16 18:47:05 +03:00
6156076dab Specify assign in terms of construction and assignment 2021-09-16 18:13:55 +03:00
984f8f1a92 Reorder constructor overloads 2021-09-16 18:04:27 +03:00
b507b2294e Unbreak the loc == 0 case, even though the specification disallows it 2021-09-16 03:12:20 +03:00
39ad22d660 Update reference 2021-09-16 03:07:32 +03:00
3b70265ced Rearrange error_code::failed to improve codegen 2021-09-15 16:42:47 +03:00
a65b91b3fb Merge branch 'develop' into feature/source-location 2021-09-15 16:06:55 +03:00
bed0d59d22 Disable failing tests under g++ 7 -std=c++17 2021-09-15 15:23:52 +03:00
5e642b1d43 Remove error_condition::failed_ in order to prioritise construction efficiency over failed() efficiency (latter is rare for conditions) 2021-09-15 14:54:26 +03:00
b35b47d8c2 Reformat what() message slightly 2021-09-15 13:42:54 +03:00
f21035f8af Move location to the end of what() 2021-09-15 07:58:24 +03:00
cd98f4edd7 Update system_error to incorporate the source location in what() 2021-09-15 07:42:57 +03:00
a9b64a888a Add support for source_location to error_code 2021-09-15 07:03:18 +03:00
bb4b500cfc Update Windows error mapping to match msvc-14.2 <system_error> 2021-09-08 00:48:55 +03:00
d44dab91dc Merge pull request #62 from rohitk5252/patch-2
Update index.html
2021-09-08 00:24:46 +03:00
2b6498ad80 Merge pull request #63 from rohitk5252/patch-3
Update system.adoc
2021-09-08 00:24:30 +03:00
22072bfbc9 Merge pull request #64 from rohitk5252/patch-5
Update Jamfile.v2
2021-09-08 00:24:08 +03:00
65f644d5de Switch ubuntu-16.04 jobs to ubuntu-18.04 2021-09-07 21:57:40 +03:00
f967081d7e Merge pull request #69 from marc-groundctl/map-broken-pipe
Map ERROR_BROKEN_PIPE to errc_t::broken_pipe
2021-09-07 21:34:22 +03:00
19e9f08666 Map ERROR_BROKEN_PIPE to errc_t::broken_pipe 2021-09-07 12:02:02 -04:00
b41139b28e Update documentation 2021-06-16 03:06:26 +03:00
39a19f3c90 Add constexpr to op== against error code enums 2021-06-16 03:06:11 +03:00
b4dd5e98c9 Update appveyor.yml 2021-06-15 20:53:48 +03:00
41e3a7c8af Update appveyor.yml 2021-06-15 06:02:49 +03:00
aee97e91ce Update .travis.yml 2021-06-15 05:34:04 +03:00
98533dedb3 Disable failing tests on g++ 4.8 and 4.9 2021-06-15 05:32:04 +03:00
fe811d1dd1 Update .travis.yml 2021-06-15 03:17:42 +03:00
137ecb4abf Add more tests to std_interop_test7 2021-06-15 03:06:07 +03:00
e5cd7bf852 Placate g++ 6 and earlier 2021-06-15 02:25:13 +03:00
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
a9da17f2e2 Add std_interop_test9 2021-06-15 01:59:51 +03:00
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
d09c998eb2 Add std_interop_test8 2021-06-15 01:43:49 +03:00
2374e85dc7 Add std_interop_test7 2021-06-14 22:25:31 +03:00
9167bf8ee8 Update documentation 2021-06-14 21:23:01 +03:00
7f7a9da4d5 Update revision history 2021-06-14 20:07:18 +03:00
67ae4d3c47 Disable std_interop_test5 on g++ 4.8 and 4.9, rather. 2021-06-14 19:04:15 +03:00
ee028e2f9d Remove tabs 2021-06-14 18:28:29 +03:00
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
210c54b09a Update .travis.yml 2021-06-14 17:36:29 +03:00
87bb5616a8 Update .travis.yml 2021-06-14 17:10:56 +03:00
6de562c79d Update .travis.yml 2021-06-14 15:10:36 +03:00
8efb96350f Clang 6 needs more help with mixed comparisons 2021-06-14 14:44:07 +03:00
88a7be42b5 Update Clang version check 2021-06-14 14:38:26 +03:00
a3225e78e2 Update GCC version check 2021-06-14 14:35:50 +03:00
3c469fe710 Update std_interop_test5.cpp 2021-06-14 04:19:45 +03:00
c2d044f34e Add std_interop_test6 2021-06-14 04:09:24 +03:00
9fdfa6c645 Move code == condition comparisons into error_code, unwrap std::error_code when needed 2021-06-14 04:06:24 +03:00
42a257e17c Add operator<< for error_condition 2021-06-14 03:59:44 +03:00
26d0d32c54 Add std_interop_test5 2021-06-14 03:53:55 +03:00
70b5449e99 Resolve ambiguity for std::error_code == boost::system::error_code 2021-06-14 03:53:00 +03:00
8043ce0278 Resolve ambiguity for std::error_code == boost::system::error_condition 2021-06-14 03:42:50 +03:00
83a2933afa Disable failing test cases on clang-6 and earlier 2021-06-14 02:54:40 +03:00
2e707ca921 Disable -Wstrict-aliasing on g++ 6, really 2021-06-14 02:50:31 +03:00
a6c4b6329c Add a deleted T const& conversion for clang-6 and earlier 2021-06-14 02:35:48 +03:00
5b1909eba4 Disable -Wstrict-aliasing on g++ 6 and below 2021-06-14 02:15:37 +03:00
9dc13fd82a Change value() when holding std::error_code 2021-06-14 02:09:31 +03:00
e9cdb10409 Use std::hash<std::error_code> in hash_value 2021-06-14 01:51:33 +03:00
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
66656f7044 Use copy-init instead of direct-init for older clangs 2021-06-13 20:45:50 +03:00
0d8511f571 Use reinterpret_cast to pointer instead of to reference 2021-06-13 20:40:27 +03:00
fbc49bbaa0 Add more tests to std_interop_test3 2021-06-13 19:51:02 +03:00
344eb1e1f8 Rework error_code for better std interop 2021-06-13 19:47:37 +03:00
20b8e90dff Add detail/snprintf.hpp 2021-06-13 18:58:50 +03:00
a0136e570d Update tests/CMakeLists 2021-06-13 18:45:15 +03:00
6586fcb01e Add errc_test3.cpp 2021-06-13 18:42:59 +03:00
b74b1e3c8c Merge branch 'develop' into feature/error-condition 2021-06-13 07:12:16 +03:00
1caaacff57 Split reference into headers 2021-06-13 06:58:48 +03:00
75d5287558 Update copyright 2021-06-13 05:59:04 +03:00
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
f43293f451 Increase ToC levels 2021-06-13 05:24:30 +03:00
f8ab3df822 Initialize failed_ in the other two constructors 2021-06-13 05:05:31 +03:00
f6fb85d7d3 Revert "Update Travis to use undefined-sanitizer; disable failed_constexpr_test"
This reverts commit c069ae048f.
2021-06-13 04:59:49 +03:00
9cd9d8732f Revert "Update test/Jamfile"
This reverts commit 3d4c31c213.
2021-06-13 04:59:38 +03:00
1b7fd6854d Revert "Disable failing tests on g++-7/c++17"
This reverts commit b20191f8d7.
2021-06-13 04:58:53 +03:00
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
88f7c2bf53 Revert "Update documentation"
This reverts commit 8962c9101a.
2021-06-13 04:47:19 +03:00
723daf5d57 Update changelog 2021-06-13 04:39:39 +03:00
3d4c31c213 Update test/Jamfile 2021-06-13 01:13:48 +03:00
c069ae048f Update Travis to use undefined-sanitizer; disable failed_constexpr_test 2021-06-13 01:08:54 +03:00
28e1b919ac Disable failing test 2021-06-12 22:36:12 +03:00
b20191f8d7 Disable failing tests on g++-7/c++17 2021-06-12 22:20:38 +03:00
d019c1cdae Remove detail/is_generic_value.hpp 2021-06-12 22:01:16 +03:00
ff77d4c094 Do not call generic_category() in system_error_category 2021-06-12 21:59:22 +03:00
a21a3050a5 Use nullptr for &generic_category() in error_condition 2021-06-12 21:51:51 +03:00
08d62ac444 Restore Sun workaround 2021-06-12 05:42:03 +03:00
45e9dfeba9 Declare operator std::error_category as BOOST_SYMBOL_VISIBLE 2021-06-12 05:12:58 +03:00
7d9eb384c6 Make error_category comparisons inline friends, to avoid clang 'member call on mutable' constexpr errors 2021-06-12 04:52:21 +03:00
04bfb05b19 Improve the implementation of the std::category conversion 2021-06-12 04:29:13 +03:00
a650f5d676 Remove cmake_install_test dependency on Boost::core 2021-06-12 00:18:26 +03:00
6ab5fd9dac Update ci.yml 2021-06-11 22:15:46 +03:00
ed14d74323 Update .travis.yml 2021-06-11 22:12:35 +03:00
ff9bca96e3 Add boost/system.hpp 2021-06-11 21:15:17 +03:00
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
8b41ff22a6 Update ci.yml 2021-05-29 02:41:45 +03:00
79f9a297cd Update ci.yml 2021-05-29 01:15:51 +03:00
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
5eae4824ab Update .github/workflows 2021-04-19 21:29:14 +03:00
f502e6cda4 Update .github/workflows 2021-04-19 20:30:50 +03:00
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
fbf7f4a417 Define BOOST_SYSTEM_DEPRECATED for Oracle Developer Studio
Added Oracle Developer Studio specific define.
2021-03-22 15:38:27 +02:00
1ba5c9efc4 Update Jamfile.v2 2021-01-20 16:35:23 +05:30
23db4e8d69 Update system.adoc 2021-01-20 16:31:00 +05:30
189cc0c185 Update index.html
Changed http:// to https://
2021-01-20 16:28:26 +05:30
67 changed files with 7532 additions and 916 deletions

View File

@ -17,24 +17,17 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-16.04
os: ubuntu-18.04
install: g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
os: ubuntu-18.04
install: g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
os: ubuntu-18.04
install: g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
@ -42,51 +35,38 @@ jobs:
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install: g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-20.04
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.8
os: ubuntu-20.04
install: g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: g++-11
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-16.04
os: ubuntu-18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-16.04
os: ubuntu-18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
os: ubuntu-18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
@ -94,14 +74,24 @@ jobs:
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17,2a"
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++-10
compiler: clang++-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
@ -199,3 +189,159 @@ jobs:
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Use library with add_subdirectory
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error

View File

@ -65,14 +65,19 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
dist: bionic
compiler: g++-10
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
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:
- sourceline: "ppa:ubuntu-toolchain-r/test"
@ -95,15 +100,15 @@ matrix:
- clang-3.4
- os: linux
compiler: clang++-11
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-11 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1
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-11
- clang-12
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-11 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
@ -153,15 +158,17 @@ matrix:
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
@ -183,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 ..

View File

@ -1,4 +1,4 @@
# 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
@ -13,7 +13,10 @@ target_include_directories(boost_system INTERFACE include)
target_link_libraries(boost_system
INTERFACE
Boost::assert
Boost::config
Boost::throw_exception
Boost::variant2
Boost::winapi
)

View File

@ -30,8 +30,12 @@ environment:
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 2019
TOOLSET: clang-win
CXXSTD: 14,17,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
@ -67,4 +71,4 @@ 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
- b2 -j3 libs/system/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

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,13 +4,13 @@ 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

View File

@ -1,16 +1,47 @@
////
Copyright 2018 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
https://www.boost.org/LICENSE_1_0.txt
////
[#changes]
# Revision History
:idprefix:
## Changes in Boost 1.78
* Added support for source locations to `error_code`.
* Added `error_code::to_string`, `error_condition::to_string`.
* `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`,

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-2021 Peter Dimov
and is distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,17 @@
#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>
#if (__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1900)
# include <boost/system/result.hpp>
#endif
#endif // #ifndef BOOST_SYSTEM_HPP_INCLUDED

View File

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

View File

@ -13,20 +13,10 @@
// BOOST_SYSTEM_HAS_SYSTEM_ERROR
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_CXX11_HDR_ATOMIC)
# 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
@ -60,8 +50,16 @@
# 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
#if defined(__clang__) && (__clang_major__ < 7 || (defined(__APPLE__) && __clang_major__ < 11))
# define BOOST_SYSTEM_CLANG_6
#endif
#endif // BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED

View File

@ -19,6 +19,7 @@
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <system_error>
# include <atomic>
#endif
namespace boost
@ -38,11 +39,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
@ -58,9 +55,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 +76,16 @@ private:
boost::ulong_long_type id_;
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
mutable std::atomic< boost::system::detail::std_category* > ps_;
#else
boost::system::detail::std_category* ps_;
#endif
protected:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
@ -97,11 +103,11 @@ protected:
#endif
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 )
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 ), ps_()
{
}
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id )
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id ), ps_()
{
}
@ -121,24 +127,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,13 +154,15 @@ 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)
# 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
};
@ -165,8 +173,9 @@ public:
namespace detail
{
static const boost::ulong_long_type generic_category_id = ( boost::ulong_long_type( 0xB2AB117A ) << 32 ) + 0x257EDF0D;
static const boost::ulong_long_type system_category_id = ( boost::ulong_long_type( 0x8FAFD21E ) << 32 ) + 0x25C5E09B;
static const boost::ulong_long_type 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,6 +13,7 @@
#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/config.hpp>
#include <string>
#include <cstring>
@ -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,7 +84,8 @@ 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
}
@ -96,11 +98,40 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
#include <boost/system/detail/to_std_category.hpp>
#include <boost/system/detail/std_category.hpp>
inline boost::system::error_category::operator std::error_category const & () const
{
return boost::system::detail::to_std_category( *this );
if( id_ == boost::system::detail::system_category_id )
{
static const boost::system::detail::std_category system_instance( this, 0x1F4D7 );
return system_instance;
}
if( id_ == boost::system::detail::generic_category_id )
{
static const boost::system::detail::std_category generic_instance( this, 0x1F4D3 );
return generic_instance;
}
boost::system::detail::std_category* p = ps_.load( std::memory_order_acquire );
if( p != 0 )
{
return *p;
}
boost::system::detail::std_category* q = new detail::std_category( this, 0 );
if( ps_.compare_exchange_strong( p, q, std::memory_order_release, std::memory_order_acquire ) )
{
return *q;
}
else
{
delete q;
return *p;
}
}
#endif // #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)

View File

@ -3,22 +3,39 @@
// 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>
#include <boost/assert/source_location.hpp>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#include <ostream>
#include <new>
#include <cstdio>
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
# include <system_error>
#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 +52,87 @@ namespace system
// and error_code containing a pointer to an object of a type derived
// from error_category.
std::size_t hash_value( error_code const & ec );
class error_code
{
private:
int val_;
bool failed_;
const error_category * cat_;
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_;
public:
// constructors:
BOOST_SYSTEM_CONSTEXPR error_code() BOOST_NOEXCEPT:
val_( 0 ), failed_( false ), cat_( &system_category() )
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>::type* = 0 ) BOOST_NOEXCEPT:
d1_(), lc_flags_( 0 )
{
*this = make_error_code( e );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
error_code( std::error_code const& ec ) BOOST_NOEXCEPT:
lc_flags_( 1 )
{
::new( d2_ ) std::error_code( ec );
}
#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 );
}
template<typename ErrorCodeEnum>
@ -82,48 +145,115 @@ 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_ );
return ec.value() + 1000 * static_cast<unsigned>( reinterpret_cast<boost::uintptr_t>( &ec.category() ) % 2097143 ); // 2^21-9, prime
#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
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 )
{
#if !defined(BOOST_NO_EXCEPTIONS)
try
#endif
{
std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
detail::snprintf( buffer, len, "%s", ec.message().c_str() );
return buffer;
}
#if !defined(BOOST_NO_EXCEPTIONS)
catch( ... )
{
}
#endif
}
#endif
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 +263,328 @@ 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)
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
{
std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
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)
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
{
std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
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 );
}
inline friend bool operator==( const error_code & code, const error_condition & condition ) BOOST_NOEXCEPT
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( code.lc_flags_ == 1 )
{
return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
}
else
#endif
{
return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
}
}
inline friend bool operator==( const error_condition & condition, const error_code & code ) BOOST_NOEXCEPT
{
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
if( code.lc_flags_ == 1 )
{
return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
}
else
#endif
{
return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
}
}
inline friend bool operator!=( const error_code & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
inline friend bool operator!=( const error_condition & lhs, const error_code & rhs ) BOOST_NOEXCEPT
{
return !( lhs == rhs );
}
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
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 )
{
//return std::error_code();
return std::error_code( 0, boost::system::system_category() );
}
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();
}
};
BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_code & lhs, const error_code & 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)
{
os << ec.category().name() << ':' << ec.value();
return os;
}
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 +614,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,6 +30,17 @@ 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:
@ -34,12 +48,19 @@ private:
int val_;
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 ), cat_( &generic_category() )
val_( 0 ), cat_( 0 )
{
}
@ -48,12 +69,25 @@ public:
{
}
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
@ -66,14 +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;
cat_ = &generic_category();
cat_ = 0;
}
// observers:
@ -85,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() );
}
}
BOOST_SYSTEM_DEPRECATED("this function is slated for removal") char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
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_DEPRECATED("this function is slated for removal") BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
{
return detail::failed_impl( val_, *cat_ );
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 val_ != 0;
return failed();
}
#else
@ -117,12 +172,12 @@ public:
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{
return val_ != 0? unspecified_bool_true: 0;
return failed()? unspecified_bool_true: 0;
}
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{
return val_ == 0;
return !failed();
}
#endif
@ -133,12 +188,34 @@ 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)
@ -148,13 +225,54 @@ public:
return std::error_condition( value(), 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 );
}
BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{
return !( lhs == 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 );
}
#endif
std::string to_string() const
{
std::string r( "cond:" );
if( cat_ )
{
r += cat_->name();
}
else
{
r += "generic";
}
detail::append_int( r, value() );
return r;
}
template<class Ch, class Tr>
inline friend std::basic_ostream<Ch, Tr>&
operator<< (std::basic_ostream<Ch, Tr>& os, error_condition const & en)
{
os << en.to_string();
return os;
}
};
} // namespace system

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,70 @@
#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
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

@ -1,9 +1,9 @@
#ifndef BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
#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 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)
@ -15,9 +15,6 @@
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/generic_category.hpp>
#include <system_error>
#include <map>
#include <memory>
#include <mutex>
//
@ -73,54 +70,6 @@ public:
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 )
@ -170,6 +119,7 @@ inline bool std_category::equivalent( const std::error_code & code, int conditio
boost::system::error_code bc( code.value(), *pc2->pc_ );
return pc_->equivalent( bc, condition );
}
#endif
else if( *pc_ == boost::system::generic_category() )
@ -188,4 +138,4 @@ inline bool std_category::equivalent( const std::error_code & code, int conditio
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
#endif // #ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_HPP_INCLUDED

View File

@ -58,7 +58,9 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_ACCESS_DENIED_: return permission_denied;
case ERROR_ALREADY_EXISTS_: return file_exists;
case ERROR_BAD_NETPATH_: return no_such_file_or_directory;
case ERROR_BAD_UNIT_: return no_such_device;
case ERROR_BROKEN_PIPE_: return broken_pipe;
case ERROR_BUFFER_OVERFLOW_: return filename_too_long;
case ERROR_BUSY_: return device_or_resource_busy;
case ERROR_BUSY_DRIVE_: return device_or_resource_busy;
@ -80,7 +82,8 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_INVALID_DRIVE_: return no_such_device;
case ERROR_INVALID_FUNCTION_: return function_not_supported;
case ERROR_INVALID_HANDLE_: return invalid_argument;
case ERROR_INVALID_NAME_: return invalid_argument;
case ERROR_INVALID_NAME_: return no_such_file_or_directory;
case ERROR_INVALID_PARAMETER_: return invalid_argument;
case ERROR_LOCK_VIOLATION_: return no_lock_available;
case ERROR_LOCKED_: return no_lock_available;
case ERROR_NEGATIVE_SEEK_: return invalid_argument;
@ -94,9 +97,11 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
case ERROR_OUTOFMEMORY_: return not_enough_memory;
case ERROR_PATH_NOT_FOUND_: return no_such_file_or_directory;
case ERROR_READ_FAULT_: return io_error;
case ERROR_REPARSE_TAG_INVALID_: return invalid_argument;
case ERROR_RETRY_: return resource_unavailable_try_again;
case ERROR_SEEK_: return io_error;
case ERROR_SHARING_VIOLATION_: return permission_denied;
case ERROR_NOT_SUPPORTED_: return not_supported; // WinError.h: "The request is not supported."
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;

View File

@ -12,9 +12,7 @@
#include <boost/system/detail/system_category.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
@ -37,7 +35,7 @@ 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 ) );
}
}
@ -54,18 +52,10 @@ inline char const * boost::system::detail::system_error_category::message( int e
#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 );
}
return error_condition( boost::system::detail::generic_value_tag( ev ) );
}
inline std::string boost::system::detail::system_error_category::message( int ev ) const

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

@ -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,507 @@
#ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED
#define BOOST_SYSTEM_RESULT_HPP_INCLUDED
// 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/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.hpp>
#include <boost/config.hpp>
#include <type_traits>
#include <utility>
#include <iosfwd>
//
namespace boost
{
namespace system
{
// throw_exception_from_error
BOOST_NORETURN inline void throw_exception_from_error( error_code const & e )
{
boost::throw_exception( system_error( e ) );
}
// 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{};
// result
template<class T, class E = error_code> class result
{
private:
variant2::variant<T, E> v_;
public:
// constructors
// default
template<class En2 = void, class En = typename std::enable_if<
std::is_void<En2>::value &&
std::is_default_constructible<T>::value
>::type>
constexpr result()
noexcept( std::is_nothrow_default_constructible<T>::value )
: v_( in_place_value )
{
}
// explicit, value
template<class A, class En = typename std::enable_if<
std::is_constructible<T, A>::value &&
!std::is_convertible<A, T>::value &&
!std::is_constructible<E, A>::value
>::type>
explicit constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<T, A>::value )
: v_( in_place_value, std::forward<A>(a) )
{
}
// explicit, error
template<class A, class En2 = void, class En = typename std::enable_if<
std::is_constructible<E, A>::value &&
!std::is_convertible<A, E>::value &&
!std::is_constructible<T, A>::value
>::type>
explicit constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// implicit, value
template<class A, class En2 = void, class En3 = void, class En = typename std::enable_if<
std::is_convertible<A, T>::value &&
!std::is_constructible<E, A>::value
>::type>
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, class En2 = void, class En3 = void, class En4 = void, class En = typename std::enable_if<
std::is_convertible<A, E>::value &&
!std::is_constructible<T, A>::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, value
template<class... A, class En = typename std::enable_if<
std::is_constructible<T, A...>::value &&
!std::is_constructible<E, A...>::value &&
sizeof...(A) >= 2
>::type>
constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<T, A...>::value )
: v_( in_place_value, std::forward<A>(a)... )
{
}
// more than one arg, error
template<class... A, class En2 = void, class En = typename std::enable_if<
!std::is_constructible<T, A...>::value &&
std::is_constructible<E, A...>::value &&
sizeof...(A) >= 2
>::type>
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)... )
{
}
// queries
constexpr bool has_value() const noexcept
{
return v_.index() == 0;
}
constexpr bool has_error() const noexcept
{
return v_.index() != 0;
}
constexpr explicit operator bool() const noexcept
{
return v_.index() == 0;
}
// checked value access
#if defined( BOOST_NO_CXX11_REF_QUALIFIERS )
BOOST_CXX14_CONSTEXPR T value() const
{
if( has_value() )
{
return variant2::unsafe_get<0>( v_ );
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ) );
}
}
#else
BOOST_CXX14_CONSTEXPR T& value() &
{
if( has_value() )
{
return variant2::unsafe_get<0>( v_ );
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ) );
}
}
BOOST_CXX14_CONSTEXPR T const& value() const&
{
if( has_value() )
{
return variant2::unsafe_get<0>( v_ );
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ) );
}
}
BOOST_CXX14_CONSTEXPR T&& value() &&
{
return std::move( value() );
}
BOOST_CXX14_CONSTEXPR T const&& value() const&&
{
return std::move( value() );
}
#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;
}
BOOST_CXX14_CONSTEXPR T&& operator*() && noexcept
{
return std::move(**this);
}
BOOST_CXX14_CONSTEXPR T const&& operator*() const && noexcept
{
return std::move(**this);
}
#endif
// error access
constexpr E error() const
noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value )
{
return has_error()? variant2::unsafe_get<1>( v_ ): E();
}
// swap
BOOST_CXX14_CONSTEXPR void swap( result& r )
noexcept( noexcept( v_.swap( r.v_ ) ) )
{
v_.swap( r.v_ );
}
friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 )
noexcept( noexcept( r1.swap( r2 ) ) )
{
r1.swap( r2 );
}
// equality
friend constexpr bool operator==( result const & r1, result const & r2 )
noexcept( noexcept( r1.v_ == r2.v_ ) )
{
return r1.v_ == r2.v_;
}
friend constexpr bool operator!=( result const & r1, result const & r2 )
noexcept( noexcept( !( r1 == r2 ) ) )
{
return !( r1 == r2 );
}
};
template<class Ch, class Tr, class T, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<T, E> const & r )
{
if( r.has_value() )
{
os << "value:" << *r;
}
else
{
os << "error:" << r.error();
}
return os;
}
// result<void>
template<class E> class result<void, E>
{
private:
variant2::variant<variant2::monostate, E> v_;
public:
// constructors
// default
constexpr result() noexcept
: v_( in_place_value )
{
}
// explicit, error
template<class A, class En = typename std::enable_if<
std::is_constructible<E, A>::value &&
!std::is_convertible<A, E>::value
>::type>
explicit constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// implicit, error
template<class A, class En2 = void, class En = typename std::enable_if<
std::is_convertible<A, E>::value
>::type>
constexpr result( A&& a )
noexcept( std::is_nothrow_constructible<E, A>::value )
: v_( in_place_error, std::forward<A>(a) )
{
}
// more than one arg, error
template<class... A, class En2 = void, class En3 = void, class En = typename std::enable_if<
std::is_constructible<E, A...>::value &&
sizeof...(A) >= 2
>::type>
constexpr result( A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
: v_( in_place_error, std::forward<A>(a)... )
{
}
// tagged, value
constexpr result( in_place_value_t ) noexcept
: v_( in_place_value )
{
}
// tagged, error
template<class... A, class En = typename std::enable_if<
std::is_constructible<E, A...>::value
>::type>
constexpr result( in_place_error_t, A&&... a )
noexcept( std::is_nothrow_constructible<E, A...>::value )
: v_( in_place_error, std::forward<A>(a)... )
{
}
// queries
constexpr bool has_value() const noexcept
{
return v_.index() == 0;
}
constexpr bool has_error() const noexcept
{
return v_.index() != 0;
}
constexpr explicit operator bool() const noexcept
{
return v_.index() == 0;
}
// checked value access
BOOST_CXX14_CONSTEXPR void value() const
{
if( has_value() )
{
}
else
{
throw_exception_from_error( variant2::unsafe_get<1>( v_ ) );
}
}
// unchecked value access
BOOST_CXX14_CONSTEXPR void* operator->() noexcept
{
return variant2::get_if<0>( &v_ );
}
BOOST_CXX14_CONSTEXPR void const* operator->() const noexcept
{
return variant2::get_if<0>( &v_ );
}
BOOST_CXX14_CONSTEXPR void operator*() const noexcept
{
BOOST_ASSERT( has_value() );
}
// error access
constexpr E error() const
noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value )
{
return has_error()? variant2::unsafe_get<1>( v_ ): E();
}
// swap
BOOST_CXX14_CONSTEXPR void swap( result& r )
noexcept( noexcept( v_.swap( r.v_ ) ) )
{
v_.swap( r.v_ );
}
friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 )
noexcept( noexcept( r1.swap( r2 ) ) )
{
r1.swap( r2 );
}
// equality
friend constexpr bool operator==( result const & r1, result const & r2 )
noexcept( noexcept( r1.v_ == r2.v_ ) )
{
return r1.v_ == r2.v_;
}
friend constexpr bool operator!=( result const & r1, result const & r2 )
noexcept( noexcept( !( r1 == r2 ) ) )
{
return !( r1 == r2 );
}
};
template<class Ch, class Tr, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<void, E> const & r )
{
if( r.has_value() )
{
os << "value:void";
}
else
{
os << "error:" << r.error();
}
return os;
}
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED

View File

@ -1,84 +1,110 @@
// 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/detail/error_code.hpp>
#include <boost/system/detail/error_category_impl.hpp>
#include <boost/system/detail/snprintf.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_;
private:
static std::string to_string( int v )
{
public:
explicit system_error( error_code ec )
: std::runtime_error(""), m_error_code(ec) {}
char buffer[ 32 ];
detail::snprintf( buffer, sizeof( buffer ), "%d", v );
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 buffer;
}
} // namespace system
static std::string build_message( char const * prefix, error_code const & ec )
{
std::string r;
if( prefix )
{
r += prefix;
r += ": ";
}
r += ec.message();
if( ec.has_location() )
{
r += " [";
r += ec.to_string();
r += " at ";
boost::source_location loc = ec.location();
r += loc.file_name();
r += ':';
r += to_string( loc.line() );
if( loc.column() != 0 )
{
r += ':';
r += to_string( loc.column() );
}
r += " in function '";
r += loc.function_name();
r += "\']";
}
return r;
}
static std::string build_message( char const * prefix, int ev, error_category const & cat )
{
return build_message( prefix, error_code( ev, cat ) );
}
public:
explicit system_error( error_code const & ec )
: std::runtime_error( build_message( 0, ec ) ), code_( ec ) {}
system_error( error_code const & ec, std::string const & prefix )
: std::runtime_error( build_message( prefix.c_str(), ec ) ), code_( ec ) {}
system_error( error_code const & ec, char const * prefix )
: std::runtime_error( build_message( prefix, ec ) ), code_( ec ) {}
system_error( int ev, error_category const & ecat )
: std::runtime_error( build_message( 0, ev, ecat ) ), code_( ev, ecat ) {}
system_error( int ev, error_category const & ecat, std::string const & prefix )
: std::runtime_error( build_message( prefix.c_str(), ev, ecat ) ), code_( ev, ecat ) {}
system_error( int ev, error_category const & ecat, char const * prefix )
: std::runtime_error( build_message( prefix, ev, ecat ) ), code_( ev, ecat ) {}
error_code code() const BOOST_NOEXCEPT
{
return code_;
}
};
} // namespace system
} // namespace boost
#endif // BOOST_SYSTEM_SYSTEM_ERROR_HPP

View File

@ -72,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_,
@ -84,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

@ -69,3 +69,53 @@ 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)
# 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)

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,18 @@
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
;
rule system-run ( sources + )
{
local result ;
@ -89,3 +101,45 @@ 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 ;
# result
import ../../config/checks/config : requires ;
CPP11 = [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr cxx11_noexcept ] ;
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) ;

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

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,10 @@ 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(../../../throw_exception boostorg/throw_exception)
add_subdirectory(../../../variant2 boostorg/variant2)
add_subdirectory(../../../winapi boostorg/winapi)
add_executable(quick ../quick.cpp)
@ -19,4 +22,4 @@ target_link_libraries(quick Boost::system Boost::core)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --no-tests=error -C $<CONFIG>)

116
test/ec_location_test.cpp Normal file
View File

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

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

View File

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

94
test/error_code_test2.cpp Normal file
View File

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

View File

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

View File

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

View File

@ -120,30 +120,18 @@ template<class Ec> void test()
ec.assign( 0, generic_category() );
TEST_NOT_FAILED( ec );
}
}
template<class Ec> void test2()
{
Ec ec( 0, http_category() );
TEST_FAILED( ec );
{
Ec ec( 0, http_category() );
TEST_FAILED( ec );
ec.assign( 200, http_category() );
TEST_NOT_FAILED( ec );
ec.assign( 200, http_category() );
TEST_NOT_FAILED( ec );
ec = Ec( 404, http_category() );
TEST_FAILED( ec );
}
ec = Ec( 404, http_category() );
TEST_FAILED( ec );
}
template<class Ec> void test3()
{
Ec ec( 0, http_category() );
BOOST_TEST( ec.failed() );
ec.assign( 200, http_category() );
BOOST_TEST( !ec.failed() );
ec = Ec( 404, http_category() );
BOOST_TEST( ec.failed() );
}
int main()
@ -159,9 +147,7 @@ int main()
BOOST_TEST( http_category().failed( 404 ) );
test<error_code>();
test2<error_code>();
test<error_condition>();
test3<error_condition>();
{
error_condition ec( errc::success );

View File

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

View File

@ -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,6 +28,12 @@ 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 );

686
test/result_copy_assign.cpp Normal file
View File

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

View File

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

View File

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

153
test/result_eq.cpp Normal file
View File

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

View File

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

View File

@ -0,0 +1,185 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <string>
#include <cerrno>
using namespace boost::system;
struct X
{
static int instances;
int v_;
X(): v_() { ++instances; }
explicit X( int v ): v_( v ) { ++instances; }
X( int v1, int v2 ): v_( v1+v2 ) { ++instances; }
X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; }
X( X const& r ): v_( r.v_ ) { ++instances; }
X& operator=( X const& ) = delete;
~X() { --instances; }
};
int X::instances = 0;
int main()
{
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<int> r = ec;
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
result<int> r( EINVAL, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), std::error_code( EINVAL, generic_category() ) );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<std::error_code> r( in_place_error, ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
result<std::error_code> r( in_place_error, EINVAL, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), std::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>, std::error_code>));
BOOST_TEST_TRAIT_TRUE((std::is_convertible<std::error_code, result<int>>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<std::string, X>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<std::string, X>>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, X>, int>));
BOOST_TEST_TRAIT_FALSE((std::is_convertible<int, result<int, X>>));
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r( ec );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
auto ec = make_error_code( errc::invalid_argument );
result<void> r = ec;
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), ec );
}
{
result<void> r( EINVAL, generic_category() );
BOOST_TEST( !r.has_value() );
BOOST_TEST( r.has_error() );
BOOST_TEST_EQ( r.error(), std::error_code( EINVAL, generic_category() ) );
}
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();
}

263
test/result_swap.cpp Normal file
View File

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

View File

@ -0,0 +1,345 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
using namespace boost::system;
struct X
{
int 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 & )
{
throw E();
}
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) );
}
{
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) );
}
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();
}

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

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

View File

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

View File

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

108
test/std_interop_test5.cpp Normal file
View File

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

129
test/std_interop_test6.cpp Normal file
View File

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

View File

@ -0,0 +1,52 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.hpp>
#include <cerrno>
#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" )
int main() {}
#else
#include <system_error>
int main()
{
{
boost::system::error_code e1 = make_error_code( boost::system::errc::bad_address );
BOOST_TEST( e1 == boost::system::errc::bad_address );
BOOST_TEST_NOT( e1 != boost::system::errc::bad_address );
BOOST_TEST( e1 == std::errc::bad_address );
BOOST_TEST_NOT( e1 != std::errc::bad_address );
}
{
boost::system::error_code e1 = make_error_code( std::errc::bad_address );
BOOST_TEST( e1 == boost::system::errc::bad_address );
BOOST_TEST_NOT( e1 != boost::system::errc::bad_address );
#if defined(BOOST_GCC) && BOOST_GCC >= 40800 && BOOST_GCC < 50000
// fails on g++ 4.8.5 and g++ 4.9.4 from ubuntu-toolchain-r-test for unknown reasons
// works on the system g++ 4.8.4 on Trusty and the system g++ 4.8.5 on CentOS 7
#else
BOOST_TEST( e1 == std::errc::bad_address );
BOOST_TEST_NOT( e1 != std::errc::bad_address );
#endif
}
return boost::report_errors();
}
#endif

View File

@ -0,0 +1,82 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.hpp>
#include <cerrno>
#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" )
int main() {}
#else
#include <system_error>
enum my_errc
{
my_enoent = ENOENT
};
#if defined(BOOST_GCC) && BOOST_GCC < 70000
// g++ 6 and earlier do not allow specializations outside the namespace
namespace boost
{
namespace system
{
template<> struct is_error_condition_enum<my_errc>: std::true_type {};
} // namespace system
} // namespace boost
namespace std
{
template<> struct is_error_condition_enum<my_errc>: std::true_type {};
} // namespace std
#else
template<> struct boost::system::is_error_condition_enum<my_errc>: std::true_type {};
template<> struct std::is_error_condition_enum<my_errc>: std::true_type {};
#endif
boost::system::error_condition make_error_condition( my_errc e )
{
return boost::system::error_condition( e, boost::system::generic_category() );
}
boost::system::error_code make_error_code( my_errc e )
{
return boost::system::error_code( e, boost::system::generic_category() );
}
int main()
{
{
boost::system::error_code e1 = make_error_code( my_enoent );
BOOST_TEST( e1 == my_enoent );
BOOST_TEST_NOT( e1 != my_enoent );
}
{
std::error_code e1 = make_error_code( my_enoent );
BOOST_TEST( e1 == my_enoent );
BOOST_TEST_NOT( e1 != my_enoent );
}
return boost::report_errors();
}
#endif

View File

@ -0,0 +1,77 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.hpp>
#include <cerrno>
#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" )
int main() {}
#else
#include <system_error>
enum my_errc
{
my_enoent = ENOENT
};
#if defined(BOOST_GCC) && BOOST_GCC < 70000
// g++ 6 and earlier do not allow specializations outside the namespace
namespace boost
{
namespace system
{
template<> struct is_error_code_enum<my_errc>: std::true_type {};
} // namespace system
} // namespace boost
namespace std
{
template<> struct is_error_code_enum<my_errc>: std::true_type {};
} // namespace std
#else
template<> struct boost::system::is_error_code_enum<my_errc>: std::true_type {};
template<> struct std::is_error_code_enum<my_errc>: std::true_type {};
#endif
boost::system::error_code make_error_code( my_errc e )
{
return boost::system::error_code( e, boost::system::generic_category() );
}
int main()
{
{
boost::system::error_code e1 = my_enoent;
BOOST_TEST( e1 == my_enoent );
BOOST_TEST_NOT( e1 != my_enoent );
}
{
std::error_code e1 = my_enoent;
BOOST_TEST( e1 == my_enoent );
BOOST_TEST_NOT( e1 != my_enoent );
}
return boost::report_errors();
}
#endif

View File

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

View File

@ -18,7 +18,9 @@ int main()
// default_error_condition
BOOST_TEST( cat.default_error_condition( 0 ) == sys::error_condition() );
BOOST_TEST( cat.default_error_condition( -1 ) == sys::error_condition( -1, cat ) );
// No longer holds; returns a generic condition
// BOOST_TEST( cat.default_error_condition( -1 ) == sys::error_condition( -1, cat ) );
#if defined(BOOST_WINDOWS_API)

View File

@ -51,6 +51,7 @@ namespace
<< ex.what() << "\"\n";
}
# endif
(void)str;
}
const boost::uint_least32_t uvalue = 2u;