Compare commits

...

116 Commits

Author SHA1 Message Date
Peter Dimov
b137164c0d Update documentation 2026-01-22 02:39:43 +02:00
Peter Dimov
6e8f4e955d Relax get<T> constraint to permit duplicate alternatives. Refs #33. 2026-01-21 21:21:46 +02:00
Peter Dimov
3b731db14d Relax holds_alternative constraint to permit duplicate alternatives. Refs #33. 2026-01-21 16:28:21 +02:00
Peter Dimov
25a8596890 Move cxx14_constexpr conditions from test/Jamfile into test sources 2026-01-21 14:58:47 +02:00
Peter Dimov
8237d94f93 Move msvc-14.0 conditions from test/Jamfile into test sources 2026-01-21 14:42:31 +02:00
Peter Dimov
155ed414ab Disable variant_issue_55.cpp on clang-cl 32 bit 2026-01-02 12:29:11 +02:00
Peter Dimov
e6b336ec68 Call boost::core::lwt_init() in variant_issue_55.cpp, because it doesn't invoke any BOOST_TEST macros and clang-win 32 bit hangs w/ assertion 2026-01-02 02:51:46 +02:00
Peter Dimov
799a69eccc Disable -Wmaybe-uninitialized false positive. Refs #55. 2026-01-02 02:21:29 +02:00
Peter Dimov
74f6f0cd96 Fix issue link; fix __cplusplus check 2026-01-01 22:28:25 +02:00
Peter Dimov
fc786d39b3 Rename variant_gcc_false_positive.cpp 2026-01-01 22:21:34 +02:00
Vinnie Falco
382cf33824 Add test for GCC 12+ -Wmaybe-uninitialized false positive
Add variant_gcc_false_positive.cpp to reproduce GCC 12+ spurious
-Wmaybe-uninitialized warnings when copying/moving variant containing
non-trivially-copyable types like std::exception_ptr and std::string.

Tests use boost::system::result which internally uses variant2, and
include coroutine-based tests when C++20 coroutine support is available.

The test uses -O3 optimization to trigger the aggressive inlining that
exposes the false positive where GCC's dataflow analysis cannot prove
the discriminator ensures only initialized alternatives are accessed.

See https://github.com/boostorg/variant2/issues/33
2026-01-01 22:16:48 +02:00
Peter Dimov
4632862a4b msvc-14.5 still needs two more workarounds 2026-01-01 20:04:58 +02:00
Peter Dimov
48ed0a243f Update .drone.jsonnet 2026-01-01 18:45:22 +02:00
Peter Dimov
936a1a95b5 msvc-14.5 still needs the workarounds. sad! 2026-01-01 18:15:20 +02:00
Peter Dimov
fcdaadb0f5 Update .drone.jsonnet 2026-01-01 18:05:28 +02:00
Peter Dimov
540354878c Disable Boost.JSON tests on gcc-4.9 2026-01-01 17:28:41 +02:00
Peter Dimov
2a5aa1c7ad Update ci.yml 2026-01-01 15:52:54 +02:00
Peter Dimov
f267609ad6 Update revision history 2025-10-22 21:03:21 +03:00
Peter Dimov
edf1c7925b Correct CMake version check; VERSION_GREATER 3.18 is true for 3.18.1 2025-10-19 21:07:20 +03:00
Peter Dimov
b9d0499a8f BOOST_TEST_THROWS requires a semicolon after https://github.com/boostorg/core/pull/205 2025-10-18 20:23:49 +03:00
Peter Dimov
a63b03286e Add test/variant_value_construct_cx_2, 3, 4. Refs #53. 2025-10-18 08:24:39 +03:00
Peter Dimov
5661f2ba15 Disable variant_default_construct_cx_4, _5 on Clang < 18 as well 2025-10-18 03:12:52 +03:00
Peter Dimov
9d913eb1a0 Disable variant_default_construct_cx_3 on Clang < 18; earlier versions complain that the type isn't literal. 2025-10-18 03:01:19 +03:00
Peter Dimov
43377dcada Add test/variant_default_construct_cx_5. Refs #53. 2025-10-18 02:49:29 +03:00
Peter Dimov
2af2d02fce Add test/variant_default_construct_cx_4. Refs #53. 2025-10-18 02:41:28 +03:00
Peter Dimov
b2109dee2a Add test/variant_default_construct_cx_3. Refs #53. 2025-10-18 02:37:21 +03:00
Peter Dimov
df001efb54 Add test/variant_default_construct_cx_2. Refs #53. 2025-10-18 02:29:52 +03:00
Peter Dimov
e708866c65 Add more constexpr. Refs #53. 2025-10-17 22:24:26 +03:00
Peter Dimov
28d23c14f6 Update ci.yml 2025-10-17 21:21:02 +03:00
Peter Dimov
8caa1a3484 Update revision history 2025-01-15 19:44:18 +02:00
Peter Dimov
6669e07071 Work around GCC 5, 6 failures 2024-12-22 20:12:08 +02:00
Peter Dimov
df84f1f146 Work around Clang 3.x failures 2024-12-22 20:10:16 +02:00
Peter Dimov
2630b3e572 Use the smallest appropriate unsigned type for the index. Closes #50. 2024-12-22 19:09:05 +02:00
Peter Dimov
010c78598e Split variant_index_type into separate runs for each variant size 2024-12-22 06:03:10 +02:00
Peter Dimov
d77d61c8ec Avoid use of mp_back in variant_index_type.cpp 2024-12-22 04:52:07 +02:00
Peter Dimov
8f6918554e Use -j2 on GHA and Appveyor to avoid MSVC out of heap errors 2024-12-22 04:31:47 +02:00
Peter Dimov
183aea23a9 Only use -ftemplate-depth for Clang on Linux, because clang-cl doesn't like it (and Mac doesn't need it) 2024-12-22 03:20:39 +02:00
Peter Dimov
7c64abd41c Remove clang-5.0/cxxstd=1z from Drone as well 2024-12-22 03:16:12 +02:00
Peter Dimov
7b8e8c33bb Disable variant_index_type.cpp for msvc-14.0, because GHA fails with 'out of heap space' 2024-12-22 03:09:28 +02:00
Peter Dimov
2f5dbc19b5 Remove cxxstd=1z for Clang 5.0 2024-12-22 03:03:57 +02:00
Peter Dimov
639bd0232b Add -ftemplate-depth=1024 for Clang (3.x needs it) 2024-12-22 03:03:35 +02:00
Peter Dimov
94749d088d Disable variant_index_type.cpp for MSVC 32 bit 2024-12-22 02:44:02 +02:00
Peter Dimov
e2fc107ac7 Add test/variant_index_type.cpp. Refs #50. 2024-12-21 20:15:45 +02:00
Peter Dimov
306a602d19 Compute the index type with a metafunction. Refs #50. 2024-12-21 19:01:18 +02:00
Peter Dimov
509ce1dc77 Merge pull request #49 from Lastique/patch-1
Add missing std namespace qualifiers
2024-12-18 06:55:12 +02:00
Andrey Semashev
47e544959f Added missing std namespace qualifiers. 2024-12-18 02:57:01 +03:00
Peter Dimov
8333e9af93 Apply Node20 workaround 2024-12-12 19:50:00 +02:00
Peter Dimov
19b75fffe4 Add test/variant_visit_cx_2.cpp. Refs #47. 2024-11-23 04:11:30 +02:00
Peter Dimov
bdc1098c80 Add test/variant_visit_r_cx.cpp. Refs #47. 2024-11-23 03:38:27 +02:00
Peter Dimov
9061e427c2 Add test/variant_visit_cx.cpp. Refs #47. 2024-11-23 03:13:28 +02:00
Peter Dimov
1202390861 Update .drone.jsonnet 2024-11-22 23:06:34 +02:00
Peter Dimov
79061e470f Update ci.yml 2024-11-22 22:53:17 +02:00
Peter Dimov
a4b167b723 Add VERBATIM to add_custom_target 2024-08-28 20:45:54 +03:00
Peter Dimov
c7c5eb2510 Update .drone.jsonnet 2024-08-28 20:45:27 +03:00
Peter Dimov
acf24454d8 Update build.jam, test/Jamfile 2024-08-28 20:28:59 +03:00
Rene Rivera
f78343e18d Sync from upstream. 2024-07-25 17:19:46 -05:00
Rene Rivera
ea4394914c Move inter-lib dependencies to a project variable and into the build targets. 2024-07-23 22:34:24 -05:00
Peter Dimov
f5cd36af3d Update MSVC workaround 2024-07-21 22:55:40 +03:00
Peter Dimov
0e325dcf8d Update ci.yml 2024-07-21 22:38:06 +03:00
Peter Dimov
e3cf721a23 Define BOOST_ALLOW_DEPRECATED in JSON tests for g++ 4.x 2024-07-21 22:20:27 +03:00
Peter Dimov
d4f0e57b36 Update .drone.jsonnet 2024-07-21 21:54:28 +03:00
Rene Rivera
f874a2cb1b Update copyright dates. 2024-07-20 22:52:05 -05:00
Rene Rivera
fc088e7273 Change all <source> references to <library>. 2024-07-20 21:27:52 -05:00
Rene Rivera
4f207d7363 Bump B2 require to 5.2 2024-06-14 11:33:56 -05:00
Rene Rivera
429a82a52e Sync from upstream. 2024-05-19 23:15:27 -05:00
Peter Dimov
f9bdafd3ca Remove C++11 requirements from test/Jamfile 2024-05-18 03:18:56 +03:00
Peter Dimov
38293da18e Update .drone.jsonnet 2024-05-18 02:43:52 +03:00
Peter Dimov
65ab0f8cef Update ci.yml 2024-05-17 22:04:55 +03:00
Peter Dimov
78796d0e7d Increase workaround to < 1950, because VS2022 has reached _MSC_VER=1940. Refs #43. 2024-05-17 21:44:21 +03:00
Rene Rivera
bb13b5be08 Add requires-b2 check to top-level build file. 2024-05-05 09:00:01 -05:00
Rene Rivera
1324e32b33 Add missing import-search for cconfig/predef checks. 2024-05-04 23:33:36 -05:00
Rene Rivera
02303d662e Sync from upstream. 2024-04-10 07:58:16 -05:00
Rene Rivera
09f3802347 Switch to library requirements instead of source. As source puts extra source in install targets. 2024-03-29 21:16:00 -05:00
Peter Dimov
ff36c3aa1f Merge pull request #42 from K-ballo/more-natvis
Improve natvis
2024-03-25 02:22:20 +02:00
Peter Dimov
f0acc9326e Work around MSVC failures in variant_derived_construct2. Refs #43. 2024-03-24 19:16:09 +02:00
Peter Dimov
a936eae01b Add test/variant_derived_construct2. Refs #43. 2024-03-24 18:41:49 +02:00
Agustin Berge
77234b514c Improve natvis:
- extend support from 10 to 40 alternatives,
- split single-buffer vs double-buffer definitions,
- adjust display string to follow MS definition for std::variant
2024-03-23 16:04:54 -03:00
Rene Rivera
5c34125b14 Make the library modular usable. 2024-03-11 08:38:17 -05:00
Peter Dimov
c125b32938 Add msvc-14.3 /permissive- to Drone 2024-02-08 20:58:45 +02:00
Peter Dimov
3298078c8b Update .drone.jsonnet 2024-01-11 22:05:28 +02:00
Peter Dimov
a38839febc Update ci.yml 2024-01-11 21:20:40 +02:00
Peter Dimov
c3071b7d0b Merge pull request #40 from Lastique/patch-1
Add missing dots in visit_by_index docs
2024-01-11 21:03:37 +02:00
Andrey Semashev
9cf32980a9 Add missing dots in visit_by_index docs 2024-01-11 20:18:06 +03:00
Peter Dimov
9e4234bfd5 Merge pull request #39 from 13steinj/develop
Suppress -Wuninitialized in emplace_impl
2023-10-24 12:42:10 +03:00
Jonathan Stein
55f1332ce0 Suppress -Wuninitialized in emplace_impl
Closes #38
2023-10-23 15:46:15 -05:00
Peter Dimov
db12c36b89 Remove unnecessary includes 2023-10-11 18:28:11 +03:00
Peter Dimov
a5cb0582d5 Make tag_invoke_L2 more msvc-14.0-friendly 2023-09-03 18:28:49 +03:00
Peter Dimov
e2546b70ca Document uses_double_storage(). Refs #37. 2023-06-29 18:32:58 +03:00
Peter Dimov
362224a009 Update ci.yml 2023-06-29 16:44:47 +03:00
Peter Dimov
2c590716ab Use the exact 3.125f in variant_visit_r.cpp 2023-06-29 12:05:55 +03:00
Peter Dimov
82b98fb757 Cast 3.14f to float because FLT_EVAL_METHOD (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108742) for discussion 2023-06-29 10:46:54 +03:00
Peter Dimov
30afb9e183 Update test/Jamfile to fix Drone issues 2023-06-29 09:54:49 +03:00
Peter Dimov
129e27ce09 Update Drone files 2023-06-29 09:33:44 +03:00
Peter Dimov
26595285d3 Add variant<>::uses_double_storage(). Refs #37. 2023-06-28 22:14:56 +03:00
Peter Dimov
95a8c5ffec Update .drone.jsonnet 2023-01-23 03:53:25 +02:00
Peter Dimov
ec2819a05e Update CMakeLists.txt 2023-01-13 00:56:45 +02:00
Peter Dimov
fcf9746a2d Merge branch 'develop' of https://github.com/vinniefalco/boost-variant2 into feature/pr-36 2023-01-13 00:55:17 +02:00
Peter Dimov
a74ebd34dc Update appveyor.yml 2023-01-12 21:12:17 +02:00
Peter Dimov
1b34c20685 Update appveyor.yml 2023-01-12 18:38:10 +02:00
Peter Dimov
604d3700ad Add CMake tests to Appveyor 2023-01-12 10:49:41 +02:00
Peter Dimov
4d1fd43d72 Update supported compilers in documentation and README 2022-10-27 21:25:57 +03:00
Peter Dimov
376925a209 Work around msvc-14.1 /permissive- failure 2022-10-24 15:47:09 +03:00
Peter Dimov
bcb8796225 Add /permissive- jobs to Drone and Appveyor 2022-10-24 15:27:05 +03:00
Peter Dimov
a948b85c74 Update revision history 2022-10-18 17:38:59 +03:00
Peter Dimov
32862d6db7 Add missing std::move 2022-10-18 16:02:33 +03:00
Peter Dimov
423d350ff1 Remove unneeded forward declarations 2022-10-18 16:01:31 +03:00
Peter Dimov
aad1f86fae Reflect the change in is_null_like 2022-10-18 16:00:14 +03:00
Peter Dimov
1f8c4a1900 Replace polymorphic lambdas with function objects for C++11 2022-10-18 06:29:57 +03:00
Peter Dimov
67a12199e6 Add JSON support (refs #28) 2022-10-18 06:08:18 +03:00
Peter Dimov
457147d1b0 Suppress -Wmaybe-uninitialized in emplace_impl 2022-10-18 03:20:36 +03:00
Peter Dimov
4a5f3dc498 Add variant<monostate, T>::emplace tests to fish out -Wmaybe-uninitialized warnings 2022-10-18 02:56:15 +03:00
Peter Dimov
6fe1c69bc8 Add Drone support 2022-10-18 02:16:59 +03:00
Peter Dimov
78a974429a Update ci.yml 2022-10-15 19:39:32 +03:00
Vinnie Falco
4c5f254b9c add boost_variant2.natvis and interface source files 2022-08-19 12:13:08 -07:00
Peter Dimov
c633a953de Change macos-10.15 to macos-11 in ci.yml 2022-08-15 19:26:35 +03:00
Peter Dimov
8ee7c5aad0 Update ci.yml 2022-07-14 14:47:06 +03:00
55 changed files with 3021 additions and 457 deletions

465
.drone.jsonnet Normal file
View File

@@ -0,0 +1,465 @@
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
local library = "variant2";
local triggers =
{
branch: [ "master", "develop", "feature/*" ]
};
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
local asan = { ASAN: '1' };
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "linux",
arch: arch
},
steps:
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'set -e',
'uname -a',
'echo $DRONE_STAGE_MACHINE',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "exec",
trigger: triggers,
platform: {
"os": "darwin",
"arch": arch
},
node: {
"os": osx_version
},
steps: [
{
name: "everything",
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
commands:
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local windows_pipeline(name, image, environment, arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "windows",
arch: arch
},
"steps":
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'cmd /C .drone\\\\drone.bat ' + library,
]
}
]
};
[
linux_pipeline(
"Linux 16.04 GCC 4.8 32/64",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '11', ADDRMD: '32,64' },
"g++-4.8-multilib",
),
linux_pipeline(
"Linux 16.04 GCC 4.9 32/64",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11', ADDRMD: '32,64' },
"g++-4.9-multilib",
),
linux_pipeline(
"Linux 16.04 GCC 5* 32/64",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 18.04 GCC 6 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '11,14', ADDRMD: '32,64' },
"g++-6-multilib",
),
linux_pipeline(
"Linux 18.04 GCC 7* 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 18.04 GCC 8 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '11,14,17', ADDRMD: '32,64' },
"g++-8-multilib",
),
linux_pipeline(
"Linux 20.04 GCC 9* 32/64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 20.04 GCC 9* ARM64",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="arm64",
),
linux_pipeline(
"Linux 20.04 GCC 9* S390x",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="s390x",
),
linux_pipeline(
"Linux 20.04 GCC 10 32/64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '32,64' },
"g++-10-multilib",
),
linux_pipeline(
"Linux 22.04 GCC 11* 32/64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 22.04 GCC 12 32/64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' },
"g++-12-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 13 32/64",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' },
"g++-13-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 32 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 64 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 32 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 64 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 25.04 GCC 15 32/64",
"cppalliance/droneubuntu2504:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-15', CXXSTD: '11,14,17,20,23,2c', ADDRMD: '32,64' },
"g++-15-multilib",
),
linux_pipeline(
"Linux 16.04 Clang 3.5",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '11' },
"clang-3.5",
),
linux_pipeline(
"Linux 16.04 Clang 3.6",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' },
"clang-3.6",
),
linux_pipeline(
"Linux 16.04 Clang 3.7",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '11,14' },
"clang-3.7",
),
linux_pipeline(
"Linux 16.04 Clang 3.8",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '11,14' },
"clang-3.8",
),
linux_pipeline(
"Linux 18.04 Clang 3.9",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '11,14' },
"clang-3.9",
),
linux_pipeline(
"Linux 18.04 Clang 4.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '11,14' },
"clang-4.0",
),
linux_pipeline(
"Linux 18.04 Clang 5.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '11,14' },
"clang-5.0",
),
linux_pipeline(
"Linux 18.04 Clang 6.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '11,14,17' },
"clang-6.0",
),
linux_pipeline(
"Linux 20.04 Clang 7",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '11,14,17' },
"clang-7",
),
linux_pipeline(
"Linux 20.04 Clang 8",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '11,14,17' },
"clang-8",
),
linux_pipeline(
"Linux 20.04 Clang 9",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '11,14,17,2a' },
"clang-9",
),
linux_pipeline(
"Linux 20.04 Clang 10",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '11,14,17,2a' },
"clang-10",
),
linux_pipeline(
"Linux 20.04 Clang 11",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '11,14,17,2a' },
"clang-11",
),
linux_pipeline(
"Linux 20.04 Clang 12",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '11,14,17,2a' },
"clang-12",
),
linux_pipeline(
"Linux 22.04 Clang 13",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '11,14,17,20,2b' },
"clang-13",
),
linux_pipeline(
"Linux 22.04 Clang 14",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14,17,20,2b' },
"clang-14",
),
linux_pipeline(
"Linux 22.04 Clang 15",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '11,14,17,20,2b' },
"clang-15",
),
linux_pipeline(
"Linux 24.04 Clang 16",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' },
"clang-16",
),
linux_pipeline(
"Linux 24.04 Clang 17",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' },
"clang-17",
),
linux_pipeline(
"Linux 24.04 Clang 18",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' },
"clang-18",
),
linux_pipeline(
"Linux 24.04 Clang 19",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '11,14,17,20,2b' },
"clang-19",
),
linux_pipeline(
"Linux 24.04 Clang 20 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '11,14,17,20,23,2c' } + ubsan,
"clang-20",
),
linux_pipeline(
"Linux 24.04 Clang 20 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '11,14,17,20,23,2c' } + asan,
"clang-20",
),
linux_pipeline(
"Linux 25.10 Clang 21",
"cppalliance/droneubuntu2510:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-21', CXXSTD: '11,14,17,20,23,2c' },
"clang-21",
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan,
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + ubsan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + asan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
windows_pipeline(
"Windows VS2015 msvc-14.0",
"cppalliance/dronevs2015",
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' },
),
windows_pipeline(
"Windows VS2017 msvc-14.1",
"cppalliance/dronevs2017",
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
),
windows_pipeline(
"Windows VS2017 msvc-14.1 permissive-",
"cppalliance/dronevs2017",
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
),
windows_pipeline(
"Windows VS2019 msvc-14.2",
"cppalliance/dronevs2019",
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
),
windows_pipeline(
"Windows VS2019 msvc-14.2 permissive-",
"cppalliance/dronevs2019",
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
),
windows_pipeline(
"Windows VS2022 msvc-14.3",
"cppalliance/dronevs2022:1",
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
),
windows_pipeline(
"Windows VS2022 msvc-14.3 permissive-",
"cppalliance/dronevs2022:1",
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
),
windows_pipeline(
"Windows VS2026 msvc-14.5",
"cppalliance/dronevs2026:1",
{ TOOLSET: 'msvc-14.5', CXXSTD: '14,17,20,latest' },
),
windows_pipeline(
"Windows VS2026 msvc-14.5 permissive-",
"cppalliance/dronevs2026:1",
{ TOOLSET: 'msvc-14.5', CXXSTD: '14,17', CXXFLAGS: '/permissive-' },
),
]

24
.drone/drone.bat Normal file
View File

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

25
.drone/drone.sh Executable file
View File

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

View File

@@ -18,97 +18,225 @@ jobs:
matrix:
include:
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-18.04
cxxstd: "11"
container: ubuntu:16.04
os: ubuntu-latest
install: g++-4.8
- toolset: gcc-4.9
cxxstd: "11"
container: ubuntu:16.04
os: ubuntu-latest
install: g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14,1z"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14,1z"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
container: ubuntu:18.04
os: ubuntu-latest
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
container: ubuntu:22.04
os: ubuntu-latest
install: g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
container: ubuntu:22.04
os: ubuntu-latest
install: g++-11
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: g++-12
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: g++-13
- toolset: gcc-14
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: g++-14
- toolset: gcc-15
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:25.04
os: ubuntu-latest
install: g++-15
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
cxxstd: "11,14"
container: ubuntu:18.04
os: ubuntu-latest
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
cxxstd: "11,14"
container: ubuntu:18.04
os: ubuntu-latest
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14"
container: ubuntu:18.04
os: ubuntu-latest
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17"
os: ubuntu-20.04
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-12
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-16
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-17
- toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-18
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-20
- toolset: clang
compiler: clang++-21
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:25.10
os: ubuntu-latest
install: clang-21
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,23,2c"
os: macos-15
- toolset: clang
cxxstd: "11,14,17,20,23,2c"
os: macos-26
runs-on: ${{matrix.os}}
container:
image: ${{matrix.container}}
volumes:
- /node20217:/node20217:rw,rshared
- ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++ curl xz-utils
- name: Install nodejs20glibc2.17
if: ${{ startsWith( matrix.container, 'ubuntu:1' ) }}
run: |
curl -LO https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz
tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
ldd /__e/node20/bin/node
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: |
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@@ -128,7 +256,7 @@ jobs:
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
python3 tools/boostdep/depinst/depinst.py $LIBRARY
./bootstrap.sh
./b2 -d0 headers
@@ -147,31 +275,23 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.1
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2019
os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
@@ -199,25 +319,27 @@ jobs:
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
b2 -j2 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: macos-10.15
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@@ -252,18 +374,20 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: macos-10.15
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@@ -308,18 +432,20 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: macos-10.15
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@@ -356,3 +482,180 @@ jobs:
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error
windows-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Use library with add_subdirectory (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use library with add_subdirectory (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- name: Install (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Debug
- name: Install (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Release
- name: Use the installed library (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use the installed library (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON ..
- name: Build tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Debug
- name: Run tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Debug
- name: Build tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Release
- name: Run tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Release

View File

@@ -19,6 +19,15 @@ target_link_libraries(boost_variant2
Boost::mp11
)
if(NOT CMAKE_VERSION VERSION_LESS 3.19 AND CMAKE_GENERATOR MATCHES "Visual Studio")
file(GLOB_RECURSE boost_variant2_IDEFILES CONFIGURE_DEPENDS include/*.hpp)
source_group(TREE ${PROJECT_SOURCE_DIR}/include FILES ${boost_variant2_IDEFILES} PREFIX "Header Files")
list(APPEND boost_variant2_IDEFILES extra/boost_variant2.natvis)
target_sources(boost_variant2 PRIVATE ${boost_variant2_IDEFILES})
endif()
target_compile_features(boost_variant2 INTERFACE cxx_std_11)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")

View File

@@ -12,7 +12,7 @@ Supported compilers:
* g++ 4.8 or later with `-std=c++11` or above
* clang++ 3.9 or later with `-std=c++11` or above
* Visual Studio 2015, 2017, 2019
* Visual Studio 2015 or later
Tested on [Github Actions](https://github.com/boostorg/variant2/actions) and
[Appveyor](https://ci.appveyor.com/project/pdimov/variant2-fkab9).

View File

@@ -22,17 +22,24 @@ environment:
ADDRMD: 32,64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
TOOLSET: msvc-14.1
ADDRMD: 32,64
CXXSTD: 14,17,latest
CXXFLAGS: /permissive-
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_SUBDIR: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMAKE_INSTALL: 1
install:
- set BOOST_BRANCH=develop
@@ -51,4 +58,28 @@ build: off
test_script:
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 libs/variant2/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
- if not "%CXXFLAGS%" == "" set CXXFLAGS=cxxflags=%CXXFLAGS%
- if "%CMAKE%%CMAKE_SUBDIR%%CMAKE_INSTALL%" == "" b2 -j2 libs/variant2/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %CXXFLAGS% variant=debug,release embed-manifest-via=linker
- if not "%CMAKE%" == "" mkdir __build__ && cd __build__
- if not "%CMAKE%" == "" cmake -DBUILD_TESTING=ON -DBOOST_INCLUDE_LIBRARIES=variant2 -DBoost_VERBOSE=ON ..
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config Debug & ctest --output-on-failure --no-tests=error -j 3 -C Debug
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config Release & ctest --output-on-failure --no-tests=error -j 3 -C Release
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config MinSizeRel & ctest --output-on-failure --no-tests=error -j 3 -C MinSizeRel
- if not "%CMAKE%" == "" cmake --build . --target tests -j 3 --config RelWithDebInfo & ctest --output-on-failure --no-tests=error -j 3 -C RelWithDebInfo
- if not "%CMAKE_SUBDIR%" == "" cd libs/variant2/test/cmake_subdir_test && mkdir __build__ && cd __build__
- if not "%CMAKE_SUBDIR%" == "" cmake ..
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Release && cmake --build . --target check --config Release
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config MinSizeRel && cmake --build . --target check --config MinSizeRel
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config RelWithDebInfo && cmake --build . --target check --config RelWithDebInfo
- if not "%CMAKE_INSTALL%" == "" mkdir __build__ && cd __build__
- if not "%CMAKE_INSTALL%" == "" cmake -DBOOST_INCLUDE_LIBRARIES=variant2 -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Debug
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Release
- if not "%CMAKE_INSTALL%" == "" cd ../libs/variant2/test/cmake_install_test && mkdir __build__ && cd __build__
- if not "%CMAKE_INSTALL%" == "" cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Release && cmake --build . --target check --config Release

22
build.jam Normal file
View File

@@ -0,0 +1,22 @@
# Copyright 2023-2024 René Ferdinand Rivera Morell
# Copyright 2024 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/config//boost_config
/boost/mp11//boost_mp11
;
project /boost/variant2 ;
explicit
[ alias boost_variant2 : : : : <include>include <library>$(boost_dependencies) ]
[ alias all : boost_variant2 test ]
;
call-if : boost-library variant2
;

View File

@@ -1,5 +1,5 @@
////
Copyright 2019-2021 Peter Dimov
Copyright 2019-2025 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
@@ -8,6 +8,27 @@ https://www.boost.org/LICENSE_1_0.txt
# Revision History
:idprefix: changelog_
## Changes in 1.91.0
* `holds_alternative<T>` and `get<T>` have been relaxed to no longer require `T` to occur exactly once in the list of alternatives. It now must occur at least once.
## Changes in 1.90.0
* More functions have been marked as `constexpr`, including `~variant`.
This didn't matter before {cpp}20, but does now.
## Changes in 1.88.0
* Use the smallest appropriate unsigned type for the index.
## Changes in 1.83.0
* Added `uses_double_storage()`.
## Changes in 1.81.0
* Added support for `boost::json::value_from` and `boost::json::value_to`.
## Changes in 1.79.0
* Added `operator<<` for `monostate`.

View File

@@ -16,7 +16,7 @@ This implementation only depends on Boost.Config, Boost.Assert, and Boost.Mp11.
* GCC 4.8 or later with `-std=c++11` or above
* Clang 3.9 or later with `-std=c++11` or above
* Visual Studio 2015, 2017, 2019
* Visual Studio 2015 or later
Tested on https://github.com/boostorg/variant2/actions[Github Actions] and
https://ci.appveyor.com/project/pdimov/variant2-fkab9[Appveyor].

View File

@@ -157,7 +157,7 @@ template<class R = /*unspecified*/, class F, class... V>
// visit_by_index (extension)
template<class R = /*unspecified*/, class V, class... F>
constexpr /*see below*/ visit_by_index(V&& v, F&&.. f);
constexpr /*see below*/ visit_by_index(V&& v, F&&... f);
// monostate
@@ -250,6 +250,8 @@ public:
constexpr bool valueless_by_exception() const noexcept;
constexpr size_t index() const noexcept;
static constexpr bool uses_double_storage() noexcept;
// swap
void swap( variant& r ) noexcept( /*see below*/ );
@@ -570,6 +572,18 @@ constexpr size_t index() const noexcept;
Returns: ::
The zero-based index of the active alternative.
```
static constexpr bool uses_double_storage() noexcept;
```
[none]
* {blank}
+
Returns: ::
`true` if the variant uses double storage to meet the never valueless
guarantee because one of the alternatives is not nothrow move constructible,
and `false` otherwise.
#### Swap
```
@@ -705,10 +719,8 @@ template<class U, class... T>
[none]
* {blank}
+
Requires: :: The type `U` occurs exactly once in `T...`. Otherwise, the
program is ill-formed.
Returns: :: `true` if `index()` is equal to the zero-based index of `U`
in `T...`.
Requires: :: The type `U` must be present in `T...`. Otherwise, the program is ill-formed.
Returns: :: `true` if `v` holds a value of type `U`, otherwise `false`.
### get
@@ -759,10 +771,8 @@ template<class U, class... T>
[none]
* {blank}
+
Requires: :: The type `U` occurs exactly once in `T...`. Otherwise, the
program is ill-formed.
Effects: :: If `v` holds a value of type `U`, returns a reference to that value.
Otherwise, throws `bad_variant_access`.
Requires: :: The type `U` must be present in `T...`. Otherwise, the program is ill-formed.
Effects: :: If `v` holds a value of type `U`, returns a reference to that value. Otherwise, throws `bad_variant_access`.
### get_if
@@ -779,10 +789,8 @@ template<size_t I, class... T>
[none]
* {blank}
+
Effects: :: A pointer to the value stored in the variant, if
`v != nullptr && v\->index() == I`. Otherwise, `nullptr`.
Remarks: :: These functions do not participate in overload resolution
unless `I` < `sizeof...(T)`.
Returns: :: A pointer to the value stored in `*v`, if `v != nullptr && v\->index() == I`. Otherwise, `nullptr`.
Remarks: :: These functions do not participate in overload resolution unless `I` < `sizeof...(T)`.
```
template<class U, class... T>
@@ -797,10 +805,8 @@ template<class U, class... T>
[none]
* {blank}
+
Requires: :: The type `U` occurs exactly once in `T...`. Otherwise, the
program is ill-formed.
Effects: :: Equivalent to: `return get_if<I>(v);` with `I` being
the zero-based index of `U` in `T...`.
Requires: :: The type `U` must be present in `T...`. Otherwise, the program is ill-formed.
Returns: :: If `v != nullptr` and `*v` holds a value of type `U`, a pointer to that value. Otherwise, `nullptr`.
### unsafe_get (extension)
@@ -922,7 +928,7 @@ Remarks: :: If `R` is given explicitly, as in `visit<int>`, the return
```
template<class R = /*unspecified*/, class V, class... F>
constexpr /*see below*/ visit_by_index(V&& v, F&&.. f);
constexpr /*see below*/ visit_by_index(V&& v, F&&... f);
```
[none]
* {blank}

178
extra/boost_variant2.natvis Normal file
View File

@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="boost::variant2::detail::variant_base_impl&lt;*,1,*&gt;">
<Intrinsic Name="index" Expression="(int)ix_ - 1"/>
<DisplayString Condition="index() == 0" Optional="true">{{ index=0, value={*($T2*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 1" Optional="true">{{ index=1, value={*($T3*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 2" Optional="true">{{ index=2, value={*($T4*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 3" Optional="true">{{ index=3, value={*($T5*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 4" Optional="true">{{ index=4, value={*($T6*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 5" Optional="true">{{ index=5, value={*($T7*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 6" Optional="true">{{ index=6, value={*($T8*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 7" Optional="true">{{ index=7, value={*($T9*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 8" Optional="true">{{ index=8, value={*($T10*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 9" Optional="true">{{ index=9, value={*($T11*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 10" Optional="true">{{ index=10, value={*($T12*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 11" Optional="true">{{ index=11, value={*($T13*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 12" Optional="true">{{ index=12, value={*($T14*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 13" Optional="true">{{ index=13, value={*($T15*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 14" Optional="true">{{ index=14, value={*($T16*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 15" Optional="true">{{ index=15, value={*($T17*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 16" Optional="true">{{ index=16, value={*($T18*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 17" Optional="true">{{ index=17, value={*($T19*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 18" Optional="true">{{ index=18, value={*($T20*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 19" Optional="true">{{ index=19, value={*($T21*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 20" Optional="true">{{ index=10, value={*($T22*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 21" Optional="true">{{ index=21, value={*($T23*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 22" Optional="true">{{ index=22, value={*($T24*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 23" Optional="true">{{ index=23, value={*($T25*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 24" Optional="true">{{ index=24, value={*($T26*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 25" Optional="true">{{ index=25, value={*($T27*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 26" Optional="true">{{ index=26, value={*($T28*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 27" Optional="true">{{ index=27, value={*($T29*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 28" Optional="true">{{ index=28, value={*($T30*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 29" Optional="true">{{ index=29, value={*($T31*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 30" Optional="true">{{ index=30, value={*($T32*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 31" Optional="true">{{ index=31, value={*($T33*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 32" Optional="true">{{ index=32, value={*($T34*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 33" Optional="true">{{ index=33, value={*($T35*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 34" Optional="true">{{ index=34, value={*($T36*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 35" Optional="true">{{ index=35, value={*($T37*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 36" Optional="true">{{ index=36, value={*($T38*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 37" Optional="true">{{ index=37, value={*($T39*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 38" Optional="true">{{ index=38, value={*($T40*)&amp;st_} }}</DisplayString>
<DisplayString Condition="index() == 39" Optional="true">{{ index=39, value={*($T41*)&amp;st_} }}</DisplayString>
<Expand>
<Item Name="index">index()</Item>
<Item Name="[value]" Condition="index() == 0" Optional="true">*($T2*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 1" Optional="true">*($T3*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 2" Optional="true">*($T4*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 3" Optional="true">*($T5*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 4" Optional="true">*($T6*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 5" Optional="true">*($T7*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 6" Optional="true">*($T8*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 7" Optional="true">*($T9*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 8" Optional="true">*($T10*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 9" Optional="true">*($T11*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 10" Optional="true">*($T12*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 11" Optional="true">*($T13*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 12" Optional="true">*($T14*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 13" Optional="true">*($T15*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 14" Optional="true">*($T16*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 15" Optional="true">*($T17*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 16" Optional="true">*($T18*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 17" Optional="true">*($T19*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 18" Optional="true">*($T20*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 19" Optional="true">*($T21*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 20" Optional="true">*($T22*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 21" Optional="true">*($T23*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 22" Optional="true">*($T24*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 23" Optional="true">*($T25*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 24" Optional="true">*($T26*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 25" Optional="true">*($T27*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 26" Optional="true">*($T28*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 27" Optional="true">*($T29*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 28" Optional="true">*($T30*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 29" Optional="true">*($T31*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 30" Optional="true">*($T32*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 31" Optional="true">*($T33*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 32" Optional="true">*($T34*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 33" Optional="true">*($T35*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 34" Optional="true">*($T36*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 35" Optional="true">*($T37*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 36" Optional="true">*($T38*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 37" Optional="true">*($T39*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 38" Optional="true">*($T40*)&amp;st_</Item>
<Item Name="[value]" Condition="index() == 39" Optional="true">*($T41*)&amp;st_</Item>
</Expand>
</Type>
<Type Name="boost::variant2::detail::variant_base_impl&lt;*,0,*&gt;">
<Intrinsic Name="index" Expression="(int)((ix_-2)/2)"/>
<DisplayString Condition="index() == 0" Optional="true">{{ index=0, value={*($T2*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 1" Optional="true">{{ index=1, value={*($T3*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 2" Optional="true">{{ index=2, value={*($T4*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 3" Optional="true">{{ index=3, value={*($T5*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 4" Optional="true">{{ index=4, value={*($T6*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 5" Optional="true">{{ index=5, value={*($T7*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 6" Optional="true">{{ index=6, value={*($T8*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 7" Optional="true">{{ index=7, value={*($T9*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 8" Optional="true">{{ index=8, value={*($T10*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 9" Optional="true">{{ index=9, value={*($T11*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 10" Optional="true">{{ index=10, value={*($T12*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 11" Optional="true">{{ index=11, value={*($T13*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 12" Optional="true">{{ index=12, value={*($T14*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 13" Optional="true">{{ index=13, value={*($T15*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 14" Optional="true">{{ index=14, value={*($T16*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 15" Optional="true">{{ index=15, value={*($T17*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 16" Optional="true">{{ index=16, value={*($T18*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 17" Optional="true">{{ index=17, value={*($T19*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 18" Optional="true">{{ index=18, value={*($T20*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 19" Optional="true">{{ index=19, value={*($T21*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 20" Optional="true">{{ index=20, value={*($T22*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 21" Optional="true">{{ index=21, value={*($T23*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 22" Optional="true">{{ index=22, value={*($T24*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 23" Optional="true">{{ index=23, value={*($T25*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 24" Optional="true">{{ index=24, value={*($T26*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 25" Optional="true">{{ index=25, value={*($T27*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 26" Optional="true">{{ index=26, value={*($T28*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 27" Optional="true">{{ index=27, value={*($T29*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 28" Optional="true">{{ index=28, value={*($T30*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 29" Optional="true">{{ index=29, value={*($T31*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 30" Optional="true">{{ index=30, value={*($T32*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 31" Optional="true">{{ index=31, value={*($T33*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 32" Optional="true">{{ index=32, value={*($T34*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 33" Optional="true">{{ index=33, value={*($T35*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 34" Optional="true">{{ index=34, value={*($T36*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 35" Optional="true">{{ index=35, value={*($T37*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 36" Optional="true">{{ index=36, value={*($T38*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 37" Optional="true">{{ index=37, value={*($T39*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 38" Optional="true">{{ index=38, value={*($T40*)&amp;st_[ix_%2]} }}</DisplayString>
<DisplayString Condition="index() == 39" Optional="true">{{ index=39, value={*($T41*)&amp;st_[ix_%2]} }}</DisplayString>
<Expand>
<Item Name="index">index()</Item>
<Item Name="[value]" Condition="index() == 0" Optional="true">*($T2*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 1" Optional="true">*($T3*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 2" Optional="true">*($T4*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 3" Optional="true">*($T5*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 4" Optional="true">*($T6*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 5" Optional="true">*($T7*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 6" Optional="true">*($T8*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 7" Optional="true">*($T9*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 8" Optional="true">*($T10*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 9" Optional="true">*($T11*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 10" Optional="true">*($T12*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 11" Optional="true">*($T13*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 12" Optional="true">*($T14*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 13" Optional="true">*($T15*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 14" Optional="true">*($T16*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 15" Optional="true">*($T17*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 16" Optional="true">*($T18*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 17" Optional="true">*($T19*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 18" Optional="true">*($T20*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 19" Optional="true">*($T21*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 20" Optional="true">*($T22*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 21" Optional="true">*($T23*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 22" Optional="true">*($T24*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 23" Optional="true">*($T25*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 24" Optional="true">*($T26*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 25" Optional="true">*($T27*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 26" Optional="true">*($T28*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 27" Optional="true">*($T29*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 28" Optional="true">*($T30*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 29" Optional="true">*($T31*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 30" Optional="true">*($T32*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 31" Optional="true">*($T33*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 32" Optional="true">*($T34*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 33" Optional="true">*($T35*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 34" Optional="true">*($T36*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 35" Optional="true">*($T37*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 36" Optional="true">*($T38*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 37" Optional="true">*($T39*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 38" Optional="true">*($T40*)&amp;st_[ix_%2]</Item>
<Item Name="[value]" Condition="index() == 39" Optional="true">*($T41*)&amp;st_[ix_%2]</Item>
</Expand>
</Type>
</AutoVisualizer>

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,6 @@ include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
if(HAVE_BOOST_TEST)
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::variant2 Boost::core Boost::container_hash)
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::variant2 Boost::core Boost::container_hash Boost::system)
endif()

View File

@@ -1,13 +1,8 @@
# Boost.Variant2 Library Test Jamfile
#
# Copyright 2015-2019 Peter Dimov
#
# Copyright 2015-2026 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
import testing ;
import ../../config/checks/config : requires ;
project
: default-build
@@ -16,11 +11,14 @@ project
: requirements
[ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr ]
<library>/boost/variant2//boost_variant2
<library>/boost/core//boost_core
<library>/boost/container_hash//boost_container_hash
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
;
run quick.cpp ;
@@ -29,54 +27,54 @@ run variant_size.cpp ;
run variant_alternative.cpp ;
run variant_holds_alternative.cpp ;
compile variant_holds_alternative_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_holds_alternative_cx.cpp ;
run variant_get_by_index.cpp ;
compile variant_get_by_index_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_get_by_index_cx.cpp ;
run variant_get_by_type.cpp ;
compile variant_get_by_type_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_get_by_type_cx.cpp ;
run variant_default_construct.cpp ;
compile variant_default_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_default_construct_cx.cpp ;
run variant_copy_construct.cpp ;
compile variant_copy_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_copy_construct_cx.cpp ;
run variant_move_construct.cpp ;
compile variant_move_construct_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_move_construct_cx.cpp ;
run variant_value_construct.cpp ;
compile variant_value_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_value_construct_cx.cpp ;
run variant_in_place_index_construct.cpp ;
compile variant_in_place_index_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_in_place_index_construct_cx.cpp ;
run variant_in_place_type_construct.cpp ;
compile variant_in_place_type_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
compile variant_in_place_type_construct_cx.cpp ;
run variant_copy_assign.cpp ;
compile variant_copy_assign_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_copy_assign_cx.cpp ;
run variant_move_assign.cpp ;
compile variant_move_assign_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_move_assign_cx.cpp ;
run variant_value_assign.cpp ;
compile variant_value_assign_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_value_assign_cx.cpp ;
run variant_emplace_index.cpp ;
compile variant_emplace_index_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_emplace_index_cx.cpp ;
run variant_emplace_type.cpp ;
compile variant_emplace_type_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_emplace_type_cx.cpp ;
run variant_swap.cpp ;
run variant_eq_ne.cpp ;
compile variant_eq_ne_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_eq_ne_cx.cpp ;
run variant_lt_gt.cpp ;
compile variant_lt_gt_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_lt_gt_cx.cpp ;
run variant_destroy.cpp ;
run variant_visit.cpp ;
@@ -99,10 +97,10 @@ local NX =
;
run variant_get_by_index.cpp throw_exception.cpp : : : $(NX) : variant_get_by_index_nx ;
compile variant_get_by_index_cx.cpp : $(NX) <toolset>msvc-14.0:<build>no : variant_get_by_index_cx_nx ;
compile variant_get_by_index_cx.cpp : $(NX) : variant_get_by_index_cx_nx ;
run variant_get_by_type.cpp throw_exception.cpp : : : $(NX) : variant_get_by_type_nx ;
compile variant_get_by_type_cx.cpp : $(NX) <toolset>msvc-14.0:<build>no : variant_get_by_type_cx_nx ;
compile variant_get_by_type_cx.cpp : $(NX) : variant_get_by_type_cx_nx ;
run variant_subset.cpp throw_exception.cpp : : : $(NX) : variant_subset_nx ;
@@ -113,7 +111,12 @@ run variant_special.cpp ;
run variant_visit_derived.cpp ;
run variant_many_types.cpp ;
# These two tests require /bigobj under GCC/Windows and CMake/VS2022 (for some reason)
run variant_many_types.cpp : : :
<toolset>gcc,<target-os>windows:<variant>release
<toolset>gcc,<target-os>cygwin:<variant>release
;
run variant_visit_r.cpp : : :
<toolset>gcc,<target-os>windows:<variant>release
@@ -126,3 +129,54 @@ run variant_visit_by_index.cpp ;
run variant_ostream_insert.cpp ;
run is_output_streamable.cpp ;
local JSON =
<library>/boost/json//boost_json/<warnings>off
"<toolset>msvc-14.0:<build>no"
"<toolset>msvc-14.2:<cxxflags>-wd5104"
"<undefined-sanitizer>norecover:<link>static"
"<toolset>gcc-4.9:<build>no"
;
run variant_json_value_from.cpp : : : $(JSON) ;
run variant_json_value_to.cpp : : : $(JSON) ;
compile variant_uses_double_storage.cpp ;
run variant_derived_construct2.cpp ;
compile variant_visit_cx.cpp ;
compile variant_visit_cx_2.cpp ;
compile variant_visit_r_cx.cpp ;
local index-type-reqs =
<variant>release
<toolset>msvc,<address-model>32:<build>no
<toolset>clang,<target-os>linux:<cxxflags>-ftemplate-depth=1024 # for Clang 3.x
;
local list-sizes = 126 127 128 129 254 255 256 257 ;
for local list-size in $(list-sizes)
{
run variant_index_type.cpp : : : $(index-type-reqs) <define>LIST_SIZE=$(list-size) : variant_index_type_$(list-size) ;
}
compile variant_default_construct_cx_2.cpp ;
compile variant_default_construct_cx_3.cpp ;
compile variant_default_construct_cx_4.cpp ;
compile variant_default_construct_cx_5.cpp ;
compile variant_value_construct_cx_2.cpp ;
compile variant_value_construct_cx_3.cpp ;
compile variant_value_construct_cx_4.cpp ;
# GCC 12+ false positive -Wmaybe-uninitialized with non-trivially-copyable types
run variant_issue_55.cpp
: : :
<library>/boost/system//boost_system
# clang-cl 32 bit fails with an assertion in mp_with_index, likely due to a codegen bug
"<toolset>clang-win,<address-model>32:<build>no"
;

View File

@@ -14,4 +14,4 @@ target_link_libraries(quick Boost::variant2)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)

View File

@@ -18,4 +18,4 @@ target_link_libraries(quick Boost::variant2)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)

View File

@@ -1,12 +1,22 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#elif defined(BOOST_GCC) && BOOST_GCC < 70000
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_GCC < 70000" )
int main() {}
#else
using namespace boost::variant2;
@@ -33,26 +43,26 @@ enum E
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template<class V, class T, class A> constexpr T test( A const& a )
template<class V, std::size_t I, class A> constexpr variant_alternative_t<I, V> test( A const& a )
{
V v;
v = a;
return get<T>(v);
return get<I>(v);
}
int main()
{
{
constexpr variant<int> v( 1 );
constexpr auto w = test<variant<int>, int>( v );
constexpr auto w = test<variant<int>, 0>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<X> v( 1 );
constexpr auto w = test<variant<X>, X>( v );
constexpr auto w = test<variant<X>, 0>( v );
STATIC_ASSERT( w == 1 );
}
@@ -61,7 +71,7 @@ int main()
{
constexpr variant<Y> v( 1 );
constexpr auto w = test<variant<Y>, Y>( v );
constexpr auto w = test<variant<Y>, 0>( v );
STATIC_ASSERT( w == 1 );
}
@@ -69,31 +79,31 @@ int main()
{
constexpr variant<int, float> v( 1 );
constexpr auto w = test<variant<int, float>, int>( v );
constexpr auto w = test<variant<int, float>, 0>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<int, float> v( 3.0f );
constexpr auto w = test<variant<int, float>, float>( v );
constexpr auto w = test<variant<int, float>, 1>( v );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr variant<int, int, float> v( 3.0f );
constexpr auto w = test<variant<int, int, float>, float>( v );
constexpr auto w = test<variant<int, int, float>, 2>( v );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr variant<E, E, X> v( 1 );
constexpr auto w = test<variant<E, E, X>, X>( v );
constexpr auto w = test<variant<E, E, X>, 2>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<int, int, float, float, X> v( X(1) );
constexpr auto w = test<variant<int, int, float, float, X>, X>( v );
constexpr auto w = test<variant<int, int, float, float, X>, 4>( v );
STATIC_ASSERT( w == 1 );
}
@@ -102,15 +112,17 @@ int main()
{
constexpr variant<E, E, Y> v( 1 );
constexpr auto w = test<variant<E, E, Y>, Y>( v );
constexpr auto w = test<variant<E, E, Y>, 2>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<int, int, float, float, Y> v( Y(1) );
constexpr auto w = test<variant<int, int, float, float, Y>, Y>( v );
constexpr auto w = test<variant<int, int, float, float, Y>, 4>( v );
STATIC_ASSERT( w == 1 );
}
#endif
}
#endif

View File

@@ -45,7 +45,7 @@ void test()
variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
BOOST_TEST_THROWS( v1 = v2, std::runtime_error )
BOOST_TEST_THROWS( v1 = v2, std::runtime_error );
}
int main()

View File

@@ -1,12 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
int main() {}
#else
using namespace boost::variant2;
@@ -33,22 +38,22 @@ enum E
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template<class T, class V> constexpr T test( V const v )
template<std::size_t I, class V> constexpr variant_alternative_t<I, V> test( V const v )
{
return get<T>( v );
return get<I>( v );
}
int main()
{
{
constexpr variant<int> v( 1 );
constexpr auto w = test<int>( v );
constexpr auto w = test<0>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<X> v( 1 );
constexpr auto w = test<X>( v );
constexpr auto w = test<0>( v );
STATIC_ASSERT( w == 1 );
}
@@ -57,7 +62,7 @@ int main()
{
constexpr variant<Y> v( 1 );
constexpr auto w = test<Y>( v );
constexpr auto w = test<0>( v );
STATIC_ASSERT( w == 1 );
}
@@ -65,31 +70,31 @@ int main()
{
constexpr variant<int, float> v( 1 );
constexpr auto w = test<int>( v );
constexpr auto w = test<0>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<int, float> v( 3.0f );
constexpr auto w = test<float>( v );
constexpr auto w = test<1>( v );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr variant<int, int, float> v( 3.0f );
constexpr auto w = test<float>( v );
constexpr auto w = test<2>( v );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr variant<E, E, X> v( 1 );
constexpr auto w = test<X>( v );
constexpr auto w = test<2>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<int, int, float, float, X> v( X(1) );
constexpr auto w = test<X>( v );
constexpr auto w = test<4>( v );
STATIC_ASSERT( w == 1 );
}
@@ -98,15 +103,17 @@ int main()
{
constexpr variant<E, E, Y> v( 1 );
constexpr auto w = test<Y>( v );
constexpr auto w = test<2>( v );
STATIC_ASSERT( w == 1 );
}
{
constexpr variant<int, int, float, float, Y> v( Y(1) );
constexpr auto w = test<Y>( v );
constexpr auto w = test<4>( v );
STATIC_ASSERT( w == 1 );
}
#endif
}
#endif

View File

@@ -1,12 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
int main() {}
#else
using namespace boost::variant2;
@@ -49,3 +54,5 @@ int main()
STATIC_ASSERT( get<0>(v) == 0 );
}
}
#endif

View File

@@ -0,0 +1,32 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(__cpp_constexpr_dynamic_alloc) || __cpp_constexpr_dynamic_alloc < 201907L
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because __cpp_constexpr_dynamic_alloc < 201907L")
int main() {}
#else
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
struct X
{
constexpr ~X() {}
};
int main()
{
constexpr variant<int, X> v;
STATIC_ASSERT( v.index() == 0 );
STATIC_ASSERT( get<0>(v) == 0 );
}
#endif

View File

@@ -0,0 +1,37 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(__cpp_constexpr_dynamic_alloc) || __cpp_constexpr_dynamic_alloc < 201907L
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because __cpp_constexpr_dynamic_alloc < 201907L")
int main() {}
#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION < 180000
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because BOOST_CLANG_VERSION < 180000")
int main() {}
#else
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
struct X
{
~X() {}
};
int main()
{
constexpr variant<int, X> v;
STATIC_ASSERT( v.index() == 0 );
STATIC_ASSERT( get<0>(v) == 0 );
}
#endif

View File

@@ -0,0 +1,33 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#include <string>
#if !defined(__cpp_constexpr_dynamic_alloc) || __cpp_constexpr_dynamic_alloc < 201907L
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because __cpp_constexpr_dynamic_alloc < 201907L")
int main() {}
#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION < 180000
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because BOOST_CLANG_VERSION < 180000")
int main() {}
#else
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
int main()
{
constexpr variant<int, std::string> v;
STATIC_ASSERT( v.index() == 0 );
STATIC_ASSERT( get<0>(v) == 0 );
}
#endif

View File

@@ -0,0 +1,49 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(__cpp_constexpr_dynamic_alloc) || __cpp_constexpr_dynamic_alloc < 201907L
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because __cpp_constexpr_dynamic_alloc < 201907L")
int main() {}
#elif defined(BOOST_MSVC) && BOOST_MSVC < 1960
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because BOOST_MSVC < 1960")
int main() {}
#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION < 180000
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because BOOST_CLANG_VERSION < 180000")
int main() {}
#else
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
struct X
{
};
struct Y
{
constexpr ~Y() {}
};
struct Z
{
~Z() {}
};
int main()
{
constexpr variant<X, Y, Z> v;
STATIC_ASSERT( v.index() == 0 );
}
#endif

View File

@@ -0,0 +1,60 @@
// Copyright 2024 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/core/lightweight_test.hpp>
struct expr: boost::variant2::variant<bool, int, double>
{
using variant::variant;
};
int main()
{
using boost::variant2::get;
{
expr v{ true };
BOOST_TEST_EQ( v.index(), 0 );
BOOST_TEST_EQ( get<0>(v), true );
}
{
expr v{ 2 };
BOOST_TEST_EQ( v.index(), 1 );
BOOST_TEST_EQ( get<1>(v), 2 );
}
{
expr v{ 3.0 };
BOOST_TEST_EQ( v.index(), 2 );
BOOST_TEST_EQ( get<2>(v), 3.0 );
}
{
expr v( true );
BOOST_TEST_EQ( v.index(), 0 );
BOOST_TEST_EQ( get<0>(v), true );
}
{
expr v( 2 );
BOOST_TEST_EQ( v.index(), 1 );
BOOST_TEST_EQ( get<1>(v), 2 );
}
{
expr v( 3.0 );
BOOST_TEST_EQ( v.index(), 2 );
BOOST_TEST_EQ( get<2>(v), 3.0 );
}
return boost::report_errors();
}

View File

@@ -288,5 +288,39 @@ int main()
BOOST_TEST_EQ( Z1::instances, 0 );
BOOST_TEST_EQ( Z2::instances, 0 );
{
variant<monostate, monostate> v;
BOOST_TEST_EQ( v.index(), 0 );
v.emplace<0>();
BOOST_TEST_EQ( v.index(), 0 );
v.emplace<1>();
BOOST_TEST_EQ( v.index(), 1 );
v.emplace<1>();
BOOST_TEST_EQ( v.index(), 1 );
v.emplace<0>();
BOOST_TEST_EQ( v.index(), 0 );
}
{
variant<monostate, int> v;
BOOST_TEST_EQ( v.index(), 0 );
v.emplace<0>();
BOOST_TEST_EQ( v.index(), 0 );
v.emplace<1>();
BOOST_TEST_EQ( v.index(), 1 );
v.emplace<1>();
BOOST_TEST_EQ( v.index(), 1 );
v.emplace<0>();
BOOST_TEST_EQ( v.index(), 0 );
}
return boost::report_errors();
}

View File

@@ -1,12 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#else
using namespace boost::variant2;
@@ -134,3 +139,5 @@ int main()
#endif
}
#endif

View File

@@ -1,12 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#else
using namespace boost::variant2;
@@ -28,24 +33,24 @@ struct Y
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template<class V, class T, class A> constexpr A test( A const& a )
template<class V, std::size_t I, class A, class T = variant_alternative_t<I, V>> constexpr T test( A const& a )
{
V v;
v.template emplace<T>( a );
return get<T>(v);
return get<I>(v);
}
int main()
{
{
constexpr auto w = test<variant<int>, int>( 1 );
constexpr auto w = test<variant<int>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<X>, X>( 1 );
constexpr auto w = test<variant<X>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
@@ -53,29 +58,29 @@ int main()
#else
{
constexpr auto w = test<variant<Y>, Y>( 1 );
constexpr auto w = test<variant<Y>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
#endif
{
constexpr auto w = test<variant<int, float>, int>( 1 );
constexpr auto w = test<variant<int, float>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<int, float>, float>( 3.0f );
constexpr auto w = test<variant<int, float>, 1>( 3.0f );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<variant<int, int, float>, float>( 3.0f );
constexpr auto w = test<variant<int, int, float>, 2>( 3.0f );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<variant<int, int, float, float, X>, X>( 1 );
constexpr auto w = test<variant<int, int, float, float, X>, 4>( 1 );
STATIC_ASSERT( w == 1 );
}
@@ -83,9 +88,11 @@ int main()
#else
{
constexpr auto w = test<variant<int, int, float, float, Y>, Y>( 1 );
constexpr auto w = test<variant<int, int, float, float, Y>, 4>( 1 );
STATIC_ASSERT( w == 1 );
}
#endif
}
#endif

View File

@@ -1,24 +1,26 @@
// Copyright 2017, 2019 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
#include <boost/variant2/variant.hpp>
using namespace boost::variant2;
#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
#include <boost/mp11.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Skipping constexpr op==, op!= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#elif !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE("Skipping constexpr op==, op!= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
using namespace boost::variant2;
struct X
{
};

View File

@@ -1,13 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
int main() {}
#else
using namespace boost::variant2;
@@ -58,7 +62,7 @@ int main()
{
constexpr variant<int, float> v( 3.14f );
STATIC_ASSERT( get<1>(v) == 3.14f );
STATIC_ASSERT( get<1>(v) == (float)3.14f ); // see FLT_EVAL_METHOD
STATIC_ASSERT_IF( get_if<0>(&v) == nullptr );
STATIC_ASSERT_IF( get_if<1>(&v) == &get<1>(v) );
@@ -87,10 +91,12 @@ int main()
{
constexpr variant<int, int, float> v( 3.14f );
STATIC_ASSERT( get<2>(v) == 3.14f );
STATIC_ASSERT( get<2>(v) == (float)3.14f );
STATIC_ASSERT_IF( get_if<0>(&v) == nullptr );
STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
STATIC_ASSERT_IF( get_if<2>(&v) == &get<2>(v) );
}
}
#endif

View File

@@ -1,10 +1,6 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#if defined( __clang__ ) && defined( __has_warning )
# if __has_warning( "-Wdeprecated-volatile" )
@@ -217,6 +213,9 @@ int main()
BOOST_TEST_EQ( get<int>(v), 0 );
BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
BOOST_TEST_EQ( get_if<float>(&v), nullptr );
BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
}
@@ -226,6 +225,9 @@ int main()
BOOST_TEST_EQ( get<int>(v), 0 );
BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
BOOST_TEST_EQ( get_if<float>(&v), nullptr );
BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
}
@@ -235,6 +237,9 @@ int main()
BOOST_TEST_EQ( get<int>(v), 1 );
BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
BOOST_TEST_EQ( get_if<float>(&v), nullptr );
BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
}
@@ -244,12 +249,18 @@ int main()
BOOST_TEST_EQ( get<int>(v), 1 );
BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
BOOST_TEST_EQ( get_if<float>(&v), nullptr );
BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
}
{
variant<int, int, float> v( 3.14f );
BOOST_TEST_THROWS( get<int>(v), bad_variant_access );
BOOST_TEST_EQ( get_if<int>(&v), nullptr );
BOOST_TEST_EQ( get<float>(v), 3.14f );
BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
@@ -259,6 +270,9 @@ int main()
{
variant<int, int, float> const v( 3.14f );
BOOST_TEST_THROWS( get<int>(v), bad_variant_access );
BOOST_TEST_EQ( get_if<int>(&v), nullptr );
BOOST_TEST_EQ( get<float>(v), 3.14f );
BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
@@ -301,11 +315,13 @@ int main()
{
variant<int, int, float> * p = 0;
BOOST_TEST_EQ( get_if<int>(p), nullptr );
BOOST_TEST_EQ( get_if<float>(p), nullptr );
}
{
variant<int, int, float> const * p = 0;
BOOST_TEST_EQ( get_if<int>(p), nullptr );
BOOST_TEST_EQ( get_if<float>(p), nullptr );
}

View File

@@ -1,13 +1,18 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/mp11.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
using namespace boost::variant2;
@@ -58,7 +63,7 @@ int main()
{
constexpr variant<int, float> v( 3.14f );
STATIC_ASSERT( get<float>(v) == 3.14f );
STATIC_ASSERT( get<float>(v) == (float)3.14f ); // see FLT_EVAL_METHOD
STATIC_ASSERT_IF( get_if<int>(&v) == nullptr );
STATIC_ASSERT_IF( get_if<float>(&v) == &get<float>(v) );
@@ -70,6 +75,7 @@ int main()
STATIC_ASSERT( get<int>(v) == 0 );
STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
STATIC_ASSERT_IF( get_if<float>(&v) == nullptr );
}
{
@@ -78,13 +84,17 @@ int main()
STATIC_ASSERT( get<int>(v) == 1 );
STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
STATIC_ASSERT_IF( get_if<float>(&v) == nullptr );
}
{
constexpr variant<int, int, float> v( 3.14f );
STATIC_ASSERT( get<float>(v) == 3.14f );
STATIC_ASSERT( get<float>(v) == (float)3.14f );
STATIC_ASSERT_IF( get_if<int>(&v) == nullptr );
STATIC_ASSERT_IF( get_if<float>(&v) == &get<float>(v) );
}
}
#endif

View File

@@ -1,10 +1,6 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/core/lightweight_test.hpp>
@@ -34,13 +30,27 @@ int main()
{
variant<int, float, float> v;
BOOST_TEST( holds_alternative<int>( v ) );
BOOST_TEST( !holds_alternative<float>( v ) );
}
{
variant<int, int, float> v( 3.14f );
BOOST_TEST( !holds_alternative<int>( v ) );
BOOST_TEST( holds_alternative<float>( v ) );
}
{
variant<int, int, float> v( in_place_index_t<0>{} );
BOOST_TEST( holds_alternative<int>( v ) );
BOOST_TEST( !holds_alternative<float>( v ) );
}
{
variant<int, int, float> v( in_place_index_t<1>{} );
BOOST_TEST( holds_alternative<int>( v ) );
BOOST_TEST( !holds_alternative<float>( v ) );
}
{
variant<int, float, std::string> v;
BOOST_TEST( holds_alternative<int>( v ) );
@@ -64,15 +74,31 @@ int main()
{
variant<int, int, float, std::string> v( 3.14f );
BOOST_TEST( !holds_alternative<int>( v ) );
BOOST_TEST( holds_alternative<float>( v ) );
BOOST_TEST( !holds_alternative<std::string>( v ) );
}
{
variant<int, int, float, std::string> v( "text" );
BOOST_TEST( !holds_alternative<int>( v ) );
BOOST_TEST( !holds_alternative<float>( v ) );
BOOST_TEST( holds_alternative<std::string>( v ) );
}
{
variant<int, int, float, std::string> v( in_place_index_t<0>{} );
BOOST_TEST( holds_alternative<int>( v ) );
BOOST_TEST( !holds_alternative<float>( v ) );
BOOST_TEST( !holds_alternative<std::string>( v ) );
}
{
variant<int, int, float, std::string> v( in_place_index_t<1>{} );
BOOST_TEST( holds_alternative<int>( v ) );
BOOST_TEST( !holds_alternative<float>( v ) );
BOOST_TEST( !holds_alternative<std::string>( v ) );
}
return boost::report_errors();
}

View File

@@ -1,12 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
int main() {}
#else
using namespace boost::variant2;
@@ -34,10 +39,20 @@ int main()
{
constexpr variant<int, float, float> v;
STATIC_ASSERT( holds_alternative<int>( v ) );
STATIC_ASSERT( !holds_alternative<float>( v ) );
}
{
constexpr variant<int, int, float> v( 3.14f );
STATIC_ASSERT( !holds_alternative<int>( v ) );
STATIC_ASSERT( holds_alternative<float>( v ) );
}
{
constexpr variant<int, int, float> v;
STATIC_ASSERT( holds_alternative<int>( v ) );
STATIC_ASSERT( !holds_alternative<float>( v ) );
}
}
#endif

View File

@@ -1,14 +1,18 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
int main() {}
#else
using namespace boost::variant2;
@@ -68,7 +72,7 @@ int main()
constexpr variant<int, float> v( in_place_index_t<1>{}, 3.14f );
STATIC_ASSERT( v.index() == 1 );
STATIC_ASSERT( get<1>(v) == 3.14f );
STATIC_ASSERT( get<1>(v) == (float)3.14f ); // see FLT_EVAL_METHOD
}
{
@@ -89,14 +93,14 @@ int main()
constexpr variant<int, int, float, float, X, X> v( in_place_index_t<2>{}, 3.14f );
STATIC_ASSERT( v.index() == 2 );
STATIC_ASSERT( get<2>(v) == 3.14f );
STATIC_ASSERT( get<2>(v) == (float)3.14f );
}
{
constexpr variant<int, int, float, float, X, X> v( in_place_index_t<3>{}, 3.14f );
STATIC_ASSERT( v.index() == 3 );
STATIC_ASSERT( get<3>(v) == 3.14f );
STATIC_ASSERT( get<3>(v) == (float)3.14f );
}
{
@@ -119,3 +123,5 @@ int main()
#endif
}
#endif

View File

@@ -1,14 +1,18 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
int main() {}
#else
using namespace boost::variant2;
@@ -80,7 +84,7 @@ int main()
constexpr variant<int, float> v( in_place_type_t<float>{}, 3.14f );
STATIC_ASSERT( v.index() == 1 );
STATIC_ASSERT( get<1>(v) == 3.14f );
STATIC_ASSERT( get<1>(v) == (float)3.14f ); // see FLT_EVAL_METHOD
STATIC_ASSERT( holds_alternative<float>(v) );
}
@@ -89,7 +93,7 @@ int main()
constexpr variant<int, int, float, X> v( in_place_type_t<float>{}, 3.14f );
STATIC_ASSERT( v.index() == 2 );
STATIC_ASSERT( get<2>(v) == 3.14f );
STATIC_ASSERT( get<2>(v) == (float)3.14f );
STATIC_ASSERT( holds_alternative<float>(v) );
}
@@ -118,3 +122,5 @@ int main()
#endif
}
#endif

View File

@@ -0,0 +1,86 @@
// Copyright 2024 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning( disable: 4503 ) // decorated name length exceeded
#endif
#include <boost/variant2/variant.hpp>
#include <boost/mp11.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::mp11;
template<std::size_t I> struct X
{
};
template<class N> using Xf = X< N::value >;
template<std::size_t I> struct Y
{
Y() = default;
Y( Y&& ) {}
};
template<class N> using Yf = Y< N::value >;
template<std::size_t I> struct Z
{
~Z() {}
};
template<class N> using Zf = Z< N::value >;
template<std::size_t I> struct W
{
~W() {}
W() = default;
W( W&& ) {}
};
template<class N> using Wf = W< N::value >;
template<class L, template<class...> class F> void test()
{
using V = mp_rename< mp_transform<F, L>, boost::variant2::variant >;
constexpr std::size_t N = mp_size<L>::value;
using last_type = F<mp_size_t<N-1>>;
{
V v( last_type{} );
BOOST_TEST_EQ( v.index(), N-1 );
}
{
V v;
BOOST_TEST_EQ( v.index(), 0 );
v.template emplace<last_type>();
BOOST_TEST_EQ( v.index(), N-1 );
}
}
int main()
{
constexpr std::size_t N = LIST_SIZE;
using L = mp_iota_c<N>;
static_assert( !boost::variant2::variant< X<0>, X<1> >::uses_double_storage(), "" );
test<L, Xf>();
static_assert( boost::variant2::variant< Y<0>, Y<1> >::uses_double_storage(), "" );
test<L, Yf>();
static_assert( !boost::variant2::variant< Z<0>, Z<1> >::uses_double_storage(), "" );
test<L, Zf>();
static_assert( boost::variant2::variant< W<0>, W<1> >::uses_double_storage(), "" );
test<L, Wf>();
return boost::report_errors();
}

194
test/variant_issue_55.cpp Normal file
View File

@@ -0,0 +1,194 @@
// Copyright 2025 Peter Dimov
// Copyright 2025 Vinnie Falco
//
// 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
// GCC 12+ -Wmaybe-uninitialized false positive tests
// https://github.com/boostorg/variant2/issues/55
//
// GCC 12+'s improved dataflow analysis sees code paths for all alternatives
// in mp_with_index and warns that members may be uninitialized, even though
// the variant's discriminator guarantees only initialized alternatives are
// accessed.
#include <boost/system/result.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <exception>
#include <string>
// Check for C++17 std::optional support
#if BOOST_CXX_VERSION >= 201703L
# include <optional>
# define BOOST_VARIANT2_TEST_HAS_OPTIONAL 1
#endif
// Check for C++20 coroutine support
#if defined(__cpp_impl_coroutine) && __cpp_impl_coroutine >= 201902L
# include <coroutine>
# define BOOST_VARIANT2_TEST_HAS_CORO 1
#endif
using result_void = boost::system::result<void, std::exception_ptr>;
using result_string = boost::system::result<std::string, std::exception_ptr>;
void testGccUninitialized()
{
// Test 1: Simple copy construction
{
result_void r1;
result_void r2(r1);
(void)r2;
}
// Test 2: Copy assignment
{
result_void r1;
result_void r2;
r2 = r1;
(void)r2;
}
#ifdef BOOST_VARIANT2_TEST_HAS_OPTIONAL
// Test 3: std::optional assignment (matches spawn pattern)
{
std::optional<result_void> opt;
opt = result_void{};
(void)opt;
}
#endif
// Test 4: Pass to function via copy
{
auto fn = [](result_void r) { (void)r; };
fn(result_void{});
}
#ifdef BOOST_VARIANT2_TEST_HAS_OPTIONAL
// Test 5: Lambda capture + optional (closest to spawn)
{
auto fn = [](result_void r) {
std::optional<result_void> opt;
opt = r;
return opt.has_value();
};
(void)fn(result_void{});
}
#endif
// Test 6: Non-void result with string (triggers string warning)
{
result_string r1;
result_string r2(r1);
(void)r2;
}
// Test 7: Assign exception to result holding value
{
result_string r1{"hello"};
r1 = std::make_exception_ptr(std::runtime_error("test"));
(void)r1;
}
#ifdef BOOST_VARIANT2_TEST_HAS_OPTIONAL
// Test 8: Optional with string result
{
std::optional<result_string> opt;
opt = result_string{};
(void)opt;
}
#endif
#ifdef BOOST_VARIANT2_TEST_HAS_CORO
// Minimal fire-and-forget coroutine for testing
struct fire_and_forget
{
struct promise_type
{
fire_and_forget get_return_object() { return {}; }
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
};
};
// Test 9: Coroutine returning result (mimics spawn)
{
auto coro = []() -> fire_and_forget {
result_void r{};
(void)r;
co_return;
};
coro();
}
// Test 10: Coroutine with handler call (closest to actual spawn)
{
std::optional<result_void> received;
auto handler = [&](result_void r) {
received = r;
};
auto coro = [&]() -> fire_and_forget {
handler(result_void{});
co_return;
};
coro();
(void)received;
}
// Test 11: Coroutine with try/catch like spawn
{
std::optional<result_void> received;
auto handler = [&](result_void r) {
received = r;
};
auto coro = [&]() -> fire_and_forget {
try
{
handler(result_void{});
}
catch (...)
{
handler(result_void{std::current_exception()});
}
co_return;
};
coro();
(void)received;
}
// Test 12: Coroutine with string result
{
std::optional<result_string> received;
auto handler = [&](result_string r) {
received = r;
};
auto coro = [&]() -> fire_and_forget {
try
{
handler(result_string{"test"});
}
catch (...)
{
handler(result_string{std::current_exception()});
}
co_return;
};
coro();
(void)received;
}
#endif
}
int main()
{
boost::core::lwt_init();
testGccUninitialized();
return boost::report_errors();
}

View File

@@ -0,0 +1,47 @@
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#if defined(BOOST_GCC) && BOOST_GCC < 50000
# define BOOST_ALLOW_DEPRECATED
#endif
#include <boost/variant2/variant.hpp>
#include <boost/json/value_from.hpp>
#include <boost/json/serialize.hpp>
#include <boost/core/lightweight_test.hpp>
#include <string>
using namespace boost::variant2;
namespace json = boost::json;
int main()
{
{
monostate m;
json::value w = json::value_from( m );
BOOST_TEST_EQ( w, json::value( nullptr ) );
}
{
variant<monostate, int, std::string> v;
json::value w = json::value_from( v );
BOOST_TEST_EQ( w, json::value( nullptr ) );
}
{
variant<monostate, int, std::string> v( 17 );
json::value w = json::value_from( v );
BOOST_TEST_EQ( w, json::value( 17 ) );
}
{
variant<monostate, int, std::string> v( "test" );
json::value w = json::value_from( v );
BOOST_TEST_EQ( w, json::value( "test" ) );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,48 @@
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#if defined(BOOST_GCC) && BOOST_GCC < 50000
# define BOOST_ALLOW_DEPRECATED
#endif
#include <boost/variant2/variant.hpp>
#include <boost/json/value_to.hpp>
#include <boost/json/serialize.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::variant2;
namespace json = boost::json;
int main()
{
{
json::value v;
auto r = json::try_value_to<monostate>( v );
BOOST_TEST( r.has_value() );
}
using V = variant<monostate, int, std::string>;
{
json::value v;
auto r = json::try_value_to<V>( v );
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, V() );
}
{
json::value v( 12 );
auto r = json::try_value_to<V>( v );
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, V(12) );
}
{
json::value v( "test" );
auto r = json::try_value_to<V>( v );
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, V("test") );
}
return boost::report_errors();
}

View File

@@ -1,24 +1,26 @@
// Copyright 2017, 2019 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
#include <boost/variant2/variant.hpp>
using namespace boost::variant2;
#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
#include <boost/mp11.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Skipping constexpr op<, op<= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#elif !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE("Skipping constexpr op<, op<= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
using namespace boost::variant2;
struct X
{
};

View File

@@ -1,14 +1,24 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#include <utility>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#elif defined(BOOST_GCC) && BOOST_GCC < 70000
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_GCC < 70000" )
int main() {}
#else
using namespace boost::variant2;
struct X
@@ -34,24 +44,24 @@ enum E
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template<class V, class T, class A> constexpr T test( A&& a )
template<class V, std::size_t I, class A> constexpr variant_alternative_t<I, V> test( A&& a )
{
V v;
v = std::forward<A>(a);
return get<T>(v);
return get<I>(v);
}
int main()
{
{
constexpr auto w = test<variant<int>, int>( variant<int>( 1 ) );
constexpr auto w = test<variant<int>, 0>( variant<int>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<X>, X>( variant<X>( 1 ) );
constexpr auto w = test<variant<X>, 0>( variant<X>( 1 ) );
STATIC_ASSERT( w == 1 );
}
@@ -59,34 +69,34 @@ int main()
#else
{
constexpr auto w = test<variant<Y>, Y>( variant<Y>( 1 ) );
constexpr auto w = test<variant<Y>, 0>( variant<Y>( 1 ) );
STATIC_ASSERT( w == 1 );
}
#endif
{
constexpr auto w = test<variant<int, float>, int>( variant<int, float>( 1 ) );
constexpr auto w = test<variant<int, float>, 0>( variant<int, float>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<int, float>, float>( variant<int, float>( 3.0f ) );
constexpr auto w = test<variant<int, float>, 1>( variant<int, float>( 3.0f ) );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<variant<int, int, float>, float>( variant<int, int, float>( 3.0f ) );
constexpr auto w = test<variant<int, int, float>, 2>( variant<int, int, float>( 3.0f ) );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<variant<E, E, X>, X>( variant<E, E, X>( 1 ) );
constexpr auto w = test<variant<E, E, X>, 2>( variant<E, E, X>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<int, int, float, float, X>, X>( variant<int, int, float, float, X>( X(1) ) );
constexpr auto w = test<variant<int, int, float, float, X>, 4>( variant<int, int, float, float, X>( X(1) ) );
STATIC_ASSERT( w == 1 );
}
@@ -94,14 +104,16 @@ int main()
#else
{
constexpr auto w = test<variant<E, E, Y>, Y>( variant<E, E, Y>( 1 ) );
constexpr auto w = test<variant<E, E, Y>, 2>( variant<E, E, Y>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<int, int, float, float, Y>, Y>( variant<int, int, float, float, Y>( Y(1) ) );
constexpr auto w = test<variant<int, int, float, float, Y>, 4>( variant<int, int, float, float, Y>( Y(1) ) );
STATIC_ASSERT( w == 1 );
}
#endif
}
#endif

View File

@@ -45,7 +45,7 @@ void test()
variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
BOOST_TEST_THROWS( v1 = std::move( v2 ), std::runtime_error )
BOOST_TEST_THROWS( v1 = std::move( v2 ), std::runtime_error );
}
int main()

View File

@@ -1,14 +1,19 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#include <utility>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#else
using namespace boost::variant2;
struct X
@@ -34,21 +39,21 @@ enum E
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template<class T, class V> constexpr T test( V&& v )
template<std::size_t I, class V> constexpr variant_alternative_t<I, V> test( V&& v )
{
V v2( std::forward<V>(v) );
return get<T>( v2 );
return get<I>( v2 );
}
int main()
{
{
constexpr auto w = test<int>( variant<int>( 1 ) );
constexpr auto w = test<0>( variant<int>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<X>( variant<X>( 1 ) );
constexpr auto w = test<0>( variant<X>( 1 ) );
STATIC_ASSERT( w == 1 );
}
@@ -56,34 +61,34 @@ int main()
#else
{
constexpr auto w = test<Y>( variant<Y>( 1 ) );
constexpr auto w = test<0>( variant<Y>( 1 ) );
STATIC_ASSERT( w == 1 );
}
#endif
{
constexpr auto w = test<int>( variant<int, float>( 1 ) );
constexpr auto w = test<0>( variant<int, float>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<float>( variant<int, float>( 3.0f ) );
constexpr auto w = test<1>( variant<int, float>( 3.0f ) );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<float>( variant<int, int, float>( 3.0f ) );
constexpr auto w = test<2>( variant<int, int, float>( 3.0f ) );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<X>( variant<E, E, X>( 1 ) );
constexpr auto w = test<2>( variant<E, E, X>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<X>( variant<int, int, float, float, X>( X(1) ) );
constexpr auto w = test<4>( variant<int, int, float, float, X>( X(1) ) );
STATIC_ASSERT( w == 1 );
}
@@ -91,14 +96,16 @@ int main()
#else
{
constexpr auto w = test<Y>( variant<E, E, Y>( 1 ) );
constexpr auto w = test<2>( variant<E, E, Y>( 1 ) );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<Y>( variant<int, int, float, float, Y>( Y(1) ) );
constexpr auto w = test<4>( variant<int, int, float, float, Y>( Y(1) ) );
STATIC_ASSERT( w == 1 );
}
#endif
}
#endif

View File

@@ -0,0 +1,50 @@
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <type_traits>
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
struct X1
{
};
STATIC_ASSERT( std::is_nothrow_move_constructible<X1>::value );
STATIC_ASSERT( std::is_trivially_destructible<X1>::value );
struct X2
{
~X2() {}
};
STATIC_ASSERT( std::is_nothrow_move_constructible<X2>::value );
STATIC_ASSERT( !std::is_trivially_destructible<X2>::value );
struct X3
{
X3( X3&& ) {}
};
STATIC_ASSERT( !std::is_nothrow_move_constructible<X3>::value );
STATIC_ASSERT( std::is_trivially_destructible<X3>::value );
struct X4
{
~X4() {}
X4( X4&& ) {}
};
STATIC_ASSERT( !std::is_nothrow_move_constructible<X4>::value );
STATIC_ASSERT( !std::is_trivially_destructible<X4>::value );
//
STATIC_ASSERT( !variant<int, float>::uses_double_storage() );
STATIC_ASSERT( !variant<int, float, X1>::uses_double_storage() );
STATIC_ASSERT( !variant<int, float, X2>::uses_double_storage() );
STATIC_ASSERT( variant<int, float, X3>::uses_double_storage() );
STATIC_ASSERT( variant<int, float, X4>::uses_double_storage() );

View File

@@ -1,12 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#else
using namespace boost::variant2;
@@ -33,24 +38,24 @@ enum E
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template<class V, class T, class A> constexpr A test( A const& a )
template<class V, std::size_t I, class A> constexpr variant_alternative_t<I, V> test( A const& a )
{
V v;
v = a;
return get<T>(v);
return get<I>(v);
}
int main()
{
{
constexpr auto w = test<variant<int>, int>( 1 );
constexpr auto w = test<variant<int>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<X>, X>( 1 );
constexpr auto w = test<variant<X>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
@@ -58,34 +63,34 @@ int main()
#else
{
constexpr auto w = test<variant<Y>, Y>( 1 );
constexpr auto w = test<variant<Y>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
#endif
{
constexpr auto w = test<variant<int, float>, int>( 1 );
constexpr auto w = test<variant<int, float>, 0>( 1 );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<int, float>, float>( 3.0f );
constexpr auto w = test<variant<int, float>, 1>( 3.0f );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<variant<int, int, float>, float>( 3.0f );
constexpr auto w = test<variant<int, int, float>, 2>( 3.0f );
STATIC_ASSERT( w == 3.0f );
}
{
constexpr auto w = test<variant<E, E, X>, X>( 1 );
constexpr auto w = test<variant<E, E, X>, 2>( 1 );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<int, int, float, float, X>, X>( X(1) );
constexpr auto w = test<variant<int, int, float, float, X>, 4>( X(1) );
STATIC_ASSERT( w == 1 );
}
@@ -93,14 +98,16 @@ int main()
#else
{
constexpr auto w = test<variant<E, E, Y>, Y>( 1 );
constexpr auto w = test<variant<E, E, Y>, 2>( 1 );
STATIC_ASSERT( w == 1 );
}
{
constexpr auto w = test<variant<int, int, float, float, Y>, Y>( Y(1) );
constexpr auto w = test<variant<int, int, float, float, Y>, 4>( Y(1) );
STATIC_ASSERT( w == 1 );
}
#endif
}
#endif

View File

@@ -1,12 +1,17 @@
// Copyright 2017 Peter Dimov.
//
// Copyright 2017, 2026 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
#include <boost/variant2/variant.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
int main() {}
#else
using namespace boost::variant2;
@@ -82,7 +87,7 @@ int main()
STATIC_ASSERT( v.index() == 1 );
STATIC_ASSERT( holds_alternative<float>(v) );
STATIC_ASSERT( get<1>(v) == 3.14f );
STATIC_ASSERT( get<1>(v) == (float)3.14f ); // see FLT_EVAL_METHOD
}
{
@@ -97,7 +102,7 @@ int main()
STATIC_ASSERT( v.index() == 2 );
STATIC_ASSERT( holds_alternative<float>(v) );
STATIC_ASSERT( get<2>(v) == 3.14f );
STATIC_ASSERT( get<2>(v) == (float)3.14f );
}
{
@@ -107,3 +112,5 @@ int main()
STATIC_ASSERT( holds_alternative<X>(v) );
}
}
#endif

View File

@@ -0,0 +1,32 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(__cpp_constexpr_dynamic_alloc) || __cpp_constexpr_dynamic_alloc < 201907L
BOOST_PRAGMA_MESSAGE("Skipping test because __cpp_constexpr_dynamic_alloc < 201907L")
int main() {}
#else
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
struct X
{
constexpr ~X() {}
};
int main()
{
constexpr variant<X, int> v( 5 );
STATIC_ASSERT( v.index() == 1 );
STATIC_ASSERT( get<1>(v) == 5 );
}
#endif

View File

@@ -0,0 +1,37 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(__cpp_constexpr_dynamic_alloc) || __cpp_constexpr_dynamic_alloc < 201907L
BOOST_PRAGMA_MESSAGE("Skipping test because __cpp_constexpr_dynamic_alloc < 201907L")
int main() {}
#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION < 180000
BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_CLANG_VERSION < 180000")
int main() {}
#else
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
struct X
{
~X() {}
};
int main()
{
constexpr variant<X, int> v( 5 );
STATIC_ASSERT( v.index() == 1 );
STATIC_ASSERT( get<1>(v) == 5 );
}
#endif

View File

@@ -0,0 +1,56 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#if !defined(__cpp_constexpr_dynamic_alloc) || __cpp_constexpr_dynamic_alloc < 201907L
BOOST_PRAGMA_MESSAGE("Skipping test because __cpp_constexpr_dynamic_alloc < 201907L")
int main() {}
#elif defined(BOOST_MSVC) && BOOST_MSVC < 1960
BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_MSVC < 1960")
int main() {}
#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION < 180000
BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_CLANG_VERSION < 180000")
int main() {}
#else
using namespace boost::variant2;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
struct X
{
};
struct Y
{
constexpr ~Y() {}
};
struct Z
{
~Z() {}
};
int main()
{
{
constexpr variant<X, Y, Z> v( X{} );
STATIC_ASSERT( v.index() == 0 );
}
{
constexpr variant<X, Y, Z> v( Y{} );
STATIC_ASSERT( v.index() == 1 );
}
}
#endif

57
test/variant_visit_cx.cpp Normal file
View File

@@ -0,0 +1,57 @@
// Copyright 2017, 2024, 2026 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/mp11.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#elif !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE("Skipping constexpr visit test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
using namespace boost::variant2;
struct X
{
constexpr operator int() const { return 2; }
};
struct F
{
constexpr int operator()( int x ) const
{
return x;
}
};
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
int main()
{
{
constexpr variant<int> v( 1 );
STATIC_ASSERT( visit( F(), v ) == 1 );
}
{
constexpr variant<char, int> v( 'a' );
STATIC_ASSERT( visit( F(), v ) == 'a' );
}
{
constexpr variant<char, int, X> v( X{} );
STATIC_ASSERT( visit( F(), v ) == 2 );
}
}
#endif

View File

@@ -0,0 +1,53 @@
// Copyright 2017, 2024 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/config/pragma_message.hpp>
#if !( defined(__cpp_constexpr) && __cpp_constexpr >= 201603L )
BOOST_PRAGMA_MESSAGE("Skipping constexpr visit test because __cpp_constexpr < 201603L")
int main() {}
#elif !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE("Skipping constexpr visit test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
using namespace boost::variant2;
struct F
{
constexpr int operator()( int x1, int x2 ) const
{
return x1 + x2;
}
constexpr int operator()( int x1, int x2, int x3 ) const
{
return x1 + x2 + x3;
}
};
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
int main()
{
{
constexpr variant<char, int> v1( 1 );
constexpr variant<char, int> v2( '2' );
STATIC_ASSERT( visit( F(), v1, v2 ) == 1 + '2' );
}
{
constexpr variant<char, int> v1( 1 );
constexpr variant<char, int> v2( 2 );
constexpr variant<char, int> v3( '3' );
STATIC_ASSERT( visit( F(), v1, v2, v3 ) == 1 + 2 + '3' );
}
}
#endif

View File

@@ -61,18 +61,18 @@ int main()
}
{
variant<int, float> const v( 3.14f );
variant<int, float> const v( 3.125f );
BOOST_TEST_EQ( visit<int>( F1(), v ), 3 );
BOOST_TEST_EQ( visit<float>( F1(), v ), 3.14f );
BOOST_TEST_EQ( visit<float>( F1(), v ), 3.125f );
}
{
variant<int, float> v1( 1 );
variant<int, float> const v2( 3.14f );
variant<int, float> const v2( 3.125f );
BOOST_TEST_EQ( visit<int>( F2(), v1, v2 ), 4 );
BOOST_TEST_EQ( visit<float>( F2(), v1, v2 ), 1 + 3.14f );
BOOST_TEST_EQ( visit<float>( F2(), v1, v2 ), 1 + 3.125f );
}
{

View File

@@ -0,0 +1,58 @@
// Copyright 2017, 2024, 2026 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/mp11.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
int main() {}
#elif !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE("Skipping constexpr visit test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
using namespace boost::variant2;
struct X
{
int v;
constexpr operator int() const { return v; }
};
struct F
{
template<class T> constexpr T operator()( T x ) const
{
return x;
}
};
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
int main()
{
{
constexpr variant<int> v( 1 );
STATIC_ASSERT( visit<int>( F(), v ) == 1 );
}
{
constexpr variant<char, int> v( 'a' );
STATIC_ASSERT( visit<int>( F(), v ) == 'a' );
}
{
constexpr variant<char, int, X> v( X{2} );
STATIC_ASSERT( visit<int>( F(), v ) == 2 );
}
}
#endif