Compare commits

...

50 Commits

Author SHA1 Message Date
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
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
Rene Rivera
5c34125b14 Make the library modular usable. 2024-03-11 08:38:17 -05:00
22 changed files with 846 additions and 174 deletions

View File

@@ -32,6 +32,8 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
commands:
[
'set -e',
'uname -a',
'echo $DRONE_STAGE_MACHINE',
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
@@ -99,7 +101,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
linux_pipeline(
"Linux 16.04 GCC 4.8 32/64",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11', ADDRMD: '32,64' },
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '11', ADDRMD: '32,64' },
"g++-4.8-multilib",
),
@@ -177,44 +179,37 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
),
linux_pipeline(
"Linux 23.04 GCC 13 32 ASAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + asan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 64 ASAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + asan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 64 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 32",
"Linux 24.04 GCC 13 32/64",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' },
{ 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",
"Linux 24.04 GCC 14 64 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' },
{ 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",
),
@@ -263,7 +258,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
linux_pipeline(
"Linux 18.04 Clang 5.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '11,14,1z' },
{ TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '11,14' },
"clang-5.0",
),
@@ -338,22 +333,22 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
),
linux_pipeline(
"Linux 23.04 Clang 16",
"cppalliance/droneubuntu2304:1",
"Linux 24.04 Clang 16",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' },
"clang-16",
),
linux_pipeline(
"Linux 23.10 Clang 17 UBSAN",
"cppalliance/droneubuntu2310:1",
"Linux 24.04 Clang 17 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + ubsan,
"clang-17",
),
linux_pipeline(
"Linux 23.10 Clang 17 ASAN",
"cppalliance/droneubuntu2310:1",
"Linux 24.04 Clang 17 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + asan,
"clang-17",
),
@@ -372,6 +367,13 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
"clang-18",
),
linux_pipeline(
"Linux 24.10 Clang 19",
"cppalliance/droneubuntu2410:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '11,14,17,20,2b' } + asan,
"clang-19",
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan,

View File

@@ -43,26 +43,31 @@ jobs:
os: ubuntu-latest
- toolset: gcc-8
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: g++-8
- toolset: gcc-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
- toolset: gcc-10
cxxstd: "11,14,17,2a"
os: ubuntu-22.04
container: ubuntu:22.04
os: ubuntu-latest
install: g++-10
- toolset: gcc-11
cxxstd: "11,14,17,2a"
os: ubuntu-22.04
container: ubuntu:22.04
os: ubuntu-latest
install: g++-11
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
container: ubuntu:22.04
os: ubuntu-latest
install: g++-12
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:23.04
container: ubuntu:24.04
os: ubuntu-latest
install: g++-13
- toolset: gcc-14
@@ -70,6 +75,11 @@ jobs:
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: "11,14"
@@ -84,44 +94,51 @@ jobs:
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14,1z"
cxxstd: "11,14"
container: ubuntu:18.04
os: ubuntu-latest
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-12
- toolset: clang
compiler: clang++-13
@@ -144,13 +161,13 @@ jobs:
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
container: ubuntu:23.04
container: ubuntu:24.04
os: ubuntu-latest
install: clang-16
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,2b"
container: ubuntu:23.10
container: ubuntu:24.04
os: ubuntu-latest
install: clang-17
- toolset: clang
@@ -160,33 +177,54 @@ jobs:
os: ubuntu-latest
install: clang-18
- toolset: clang
cxxstd: "11,14,17,2a"
os: macos-11
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,2b"
os: macos-12
container: ubuntu:24.04
os: ubuntu-latest
install: clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:25.04
os: ubuntu-latest
install: clang-20
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-15
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
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@v3
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++
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
@@ -231,14 +269,6 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
@@ -250,7 +280,7 @@ jobs:
- toolset: gcc
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2019
os: windows-2022
runs-on: ${{matrix.os}}
@@ -283,18 +313,18 @@ 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 embed-manifest-via=linker
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-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
@@ -338,11 +368,11 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
@@ -396,11 +426,11 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
@@ -452,8 +482,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-latest
runs-on: ${{matrix.os}}
@@ -501,8 +530,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-latest
runs-on: ${{matrix.os}}
@@ -568,8 +596,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-latest
runs-on: ${{matrix.os}}

View File

@@ -59,7 +59,7 @@ test_script:
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- if not "%CXXFLAGS%" == "" set CXXFLAGS=cxxflags=%CXXFLAGS%
- if "%CMAKE%%CMAKE_SUBDIR%%CMAKE_INSTALL%" == "" b2 -j3 libs/variant2/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %CXXFLAGS% variant=debug,release embed-manifest-via=linker
- 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 ..

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-2022 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,10 @@ https://www.boost.org/LICENSE_1_0.txt
# Revision History
:idprefix: changelog_
## Changes in 1.88.0
* Use the smallest appropriate unsigned type for the index.
## Changes in 1.83.0
* Added `uses_double_storage()`.

View File

@@ -26,6 +26,16 @@
#include <iosfwd>
#include <cstdint>
#include <cerrno>
#include <limits>
//
// constexpr destructors
#if defined(__cpp_constexpr_dynamic_alloc) && __cpp_constexpr_dynamic_alloc >= 201907L
# define BOOST_VARIANT2_CXX20_CONSTEXPR constexpr
#else
# define BOOST_VARIANT2_CXX20_CONSTEXPR
#endif
//
@@ -83,7 +93,7 @@ struct monostate
{
};
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1940)
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1950)
constexpr bool operator<(monostate, monostate) noexcept { return false; }
constexpr bool operator>(monostate, monostate) noexcept { return false; }
@@ -556,16 +566,16 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_false, T1, T.
{
}
~variant_storage_impl()
BOOST_VARIANT2_CXX20_CONSTEXPR ~variant_storage_impl()
{
}
template<class... A> void emplace( mp11::mp_size_t<0>, A&&... a )
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<0>, A&&... a )
{
::new( &first_ ) T1( std::forward<A>(a)... );
}
template<std::size_t I, class... A> void emplace( mp11::mp_size_t<I>, A&&... a )
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<I>, A&&... a )
{
rest_.emplace( mp11::mp_size_t<I-1>(), std::forward<A>(a)... );
}
@@ -605,22 +615,22 @@ template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, c
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
~variant_storage_impl()
BOOST_VARIANT2_CXX20_CONSTEXPR ~variant_storage_impl()
{
}
template<class... A> void emplace( mp11::mp_size_t<0>, A&&... a ) { ::new( &t0_ ) T0( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<1>, A&&... a ) { ::new( &t1_ ) T1( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<2>, A&&... a ) { ::new( &t2_ ) T2( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<3>, A&&... a ) { ::new( &t3_ ) T3( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<4>, A&&... a ) { ::new( &t4_ ) T4( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<5>, A&&... a ) { ::new( &t5_ ) T5( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<6>, A&&... a ) { ::new( &t6_ ) T6( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<7>, A&&... a ) { ::new( &t7_ ) T7( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<8>, A&&... a ) { ::new( &t8_ ) T8( std::forward<A>(a)... ); }
template<class... A> void emplace( mp11::mp_size_t<9>, A&&... a ) { ::new( &t9_ ) T9( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<0>, A&&... a ) { ::new( &t0_ ) T0( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<1>, A&&... a ) { ::new( &t1_ ) T1( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<2>, A&&... a ) { ::new( &t2_ ) T2( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<3>, A&&... a ) { ::new( &t3_ ) T3( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<4>, A&&... a ) { ::new( &t4_ ) T4( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<5>, A&&... a ) { ::new( &t5_ ) T5( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<6>, A&&... a ) { ::new( &t6_ ) T6( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<7>, A&&... a ) { ::new( &t7_ ) T7( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<8>, A&&... a ) { ::new( &t8_ ) T8( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<9>, A&&... a ) { ::new( &t9_ ) T9( std::forward<A>(a)... ); }
template<std::size_t I, class... A> void emplace( mp11::mp_size_t<I>, A&&... a )
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( mp11::mp_size_t<I>, A&&... a )
{
rest_.emplace( mp11::mp_size_t<I-10>(), std::forward<A>(a)... );
}
@@ -673,7 +683,7 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_true, T1, T..
{
}
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<0>, A&&... a )
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<0>, A&&... a )
{
::new( &first_ ) T1( std::forward<A>(a)... );
}
@@ -741,16 +751,16 @@ template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, c
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<0>, A&&... a ) { ::new( &t0_ ) T0( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<1>, A&&... a ) { ::new( &t1_ ) T1( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<2>, A&&... a ) { ::new( &t2_ ) T2( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<3>, A&&... a ) { ::new( &t3_ ) T3( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<4>, A&&... a ) { ::new( &t4_ ) T4( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<5>, A&&... a ) { ::new( &t5_ ) T5( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<6>, A&&... a ) { ::new( &t6_ ) T6( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<7>, A&&... a ) { ::new( &t7_ ) T7( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<8>, A&&... a ) { ::new( &t8_ ) T8( std::forward<A>(a)... ); }
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<9>, A&&... a ) { ::new( &t9_ ) T9( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<0>, A&&... a ) { ::new( &t0_ ) T0( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<1>, A&&... a ) { ::new( &t1_ ) T1( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<2>, A&&... a ) { ::new( &t2_ ) T2( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<3>, A&&... a ) { ::new( &t3_ ) T3( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<4>, A&&... a ) { ::new( &t4_ ) T4( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<5>, A&&... a ) { ::new( &t5_ ) T5( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<6>, A&&... a ) { ::new( &t6_ ) T6( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<7>, A&&... a ) { ::new( &t7_ ) T7( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<8>, A&&... a ) { ::new( &t8_ ) T8( std::forward<A>(a)... ); }
template<class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<9>, A&&... a ) { ::new( &t9_ ) T9( std::forward<A>(a)... ); }
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_size_t<I>, A&&... a )
{
@@ -845,6 +855,26 @@ template<class U, class... T> using resolve_overload_type = typename decltype( o
template<class U, class... T> using resolve_overload_index = mp11::mp_find<mp11::mp_list<T...>, resolve_overload_type<U, T...>>;
// index_type
template<std::size_t N> using get_smallest_unsigned_type = mp11::mp_cond<
mp11::mp_bool< N <= (std::numeric_limits<unsigned char>::max)() >, unsigned char,
mp11::mp_bool< N <= (std::numeric_limits<unsigned short>::max)() >, unsigned short,
mp11::mp_true, unsigned
>;
#if BOOST_WORKAROUND( BOOST_CLANG_VERSION, < 30800 )
template<bool Double, class... T> using get_index_type = unsigned short;
#else
template<bool Double, class... T> using get_index_type = get_smallest_unsigned_type< (Double + 1) * sizeof...(T) >;
#endif
// variant_base
template<bool is_trivially_destructible, bool is_single_buffered, class... T> struct variant_base_impl;
@@ -855,8 +885,10 @@ struct none {};
// trivially destructible, single buffered
template<class... T> struct variant_base_impl<true, true, T...>
{
using index_type = get_index_type<false, T...>;
variant_storage<none, T...> st_;
unsigned ix_;
index_type ix_;
constexpr variant_base_impl(): st_( mp11::mp_size_t<0>() ), ix_( 0 )
{
@@ -867,9 +899,11 @@ template<class... T> struct variant_base_impl<true, true, T...>
}
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
template<class I, class... A> BOOST_CXX14_CONSTEXPR void _replace( I, A&&... a )
{
::new( &st_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
static_assert( I::value + 1 <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = I::value + 1;
}
@@ -880,7 +914,7 @@ template<class... T> struct variant_base_impl<true, true, T...>
template<std::size_t I> BOOST_CXX14_CONSTEXPR mp11::mp_at_c<variant<T...>, I>& _get_impl( mp11::mp_size_t<I> ) noexcept
{
size_t const J = I+1;
std::size_t const J = I+1;
BOOST_ASSERT( ix_ == J );
@@ -889,7 +923,7 @@ template<class... T> struct variant_base_impl<true, true, T...>
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
{
// size_t const J = I+1;
// std::size_t const J = I+1;
BOOST_VARIANT2_CX14_ASSERT( ix_ == I+1 )
@@ -901,6 +935,8 @@ template<class... T> struct variant_base_impl<true, true, T...>
static_assert( std::is_nothrow_constructible<U, A&&...>::value, "Logic error: U must be nothrow constructible from A&&..." );
st_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
static_assert( J <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = J;
}
@@ -911,6 +947,8 @@ template<class... T> struct variant_base_impl<true, true, T...>
U tmp( std::forward<A>(a)... );
st_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
static_assert( J <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = J;
}
@@ -931,8 +969,10 @@ template<class... T> struct variant_base_impl<true, true, T...>
// trivially destructible, double buffered
template<class... T> struct variant_base_impl<true, false, T...>
{
using index_type = get_index_type<true, T...>;
variant_storage<none, T...> st_[ 2 ];
unsigned ix_;
index_type ix_;
constexpr variant_base_impl(): st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }, ix_( 0 )
{
@@ -943,9 +983,11 @@ template<class... T> struct variant_base_impl<true, false, T...>
}
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
template<class I, class... A> BOOST_CXX14_CONSTEXPR void _replace( I, A&&... a )
{
::new( &st_[ 0 ] ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
static_assert( ( I::value + 1 ) * 2 <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = ( I::value + 1 ) * 2;
}
@@ -958,7 +1000,7 @@ template<class... T> struct variant_base_impl<true, false, T...>
{
BOOST_ASSERT( index() == I );
size_t const J = I+1;
std::size_t const J = I+1;
constexpr mp11::mp_size_t<J> j{};
return st_[ ix_ & 1 ].get( j );
@@ -968,7 +1010,7 @@ template<class... T> struct variant_base_impl<true, false, T...>
{
BOOST_VARIANT2_CX14_ASSERT( index() == I )
// size_t const J = I+1;
// std::size_t const J = I+1;
// constexpr mp_size_t<J> j{};
return st_[ ix_ & 1 ].get( mp11::mp_size_t<I+1>() );
@@ -976,13 +1018,14 @@ template<class... T> struct variant_base_impl<true, false, T...>
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( A&&... a )
{
size_t const J = I+1;
std::size_t const J = I+1;
unsigned i2 = 1 - ( ix_ & 1 );
st_[ i2 ].emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
ix_ = J * 2 + i2;
static_assert( J * 2 + 1 <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = static_cast<index_type>( J * 2 + i2 );
}
static constexpr bool uses_double_storage() noexcept
@@ -994,8 +1037,10 @@ template<class... T> struct variant_base_impl<true, false, T...>
// not trivially destructible, single buffered
template<class... T> struct variant_base_impl<false, true, T...>
{
using index_type = get_index_type<false, T...>;
variant_storage<none, T...> st_;
unsigned ix_;
index_type ix_;
constexpr variant_base_impl(): st_( mp11::mp_size_t<0>() ), ix_( 0 )
{
@@ -1006,9 +1051,11 @@ template<class... T> struct variant_base_impl<false, true, T...>
}
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
template<class I, class... A> BOOST_CXX14_CONSTEXPR void _replace( I, A&&... a )
{
::new( &st_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
static_assert( I::value + 1 <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = I::value + 1;
}
@@ -1021,14 +1068,14 @@ template<class... T> struct variant_base_impl<false, true, T...>
{
variant_base_impl * this_;
template<class I> void operator()( I ) const noexcept
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I ) const noexcept
{
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
this_->st_.get( I() ).~U();
}
};
void _destroy() noexcept
BOOST_CXX14_CONSTEXPR void _destroy() noexcept
{
if( ix_ > 0 )
{
@@ -1036,7 +1083,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
}
}
~variant_base_impl() noexcept
BOOST_VARIANT2_CXX20_CONSTEXPR ~variant_base_impl() noexcept
{
_destroy();
}
@@ -1048,7 +1095,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
template<std::size_t I> BOOST_CXX14_CONSTEXPR mp11::mp_at_c<variant<T...>, I>& _get_impl( mp11::mp_size_t<I> ) noexcept
{
size_t const J = I+1;
std::size_t const J = I+1;
BOOST_ASSERT( ix_ == J );
@@ -1057,16 +1104,16 @@ template<class... T> struct variant_base_impl<false, true, T...>
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
{
// size_t const J = I+1;
// std::size_t const J = I+1;
BOOST_VARIANT2_CX14_ASSERT( ix_ == I+1 )
return st_.get( mp11::mp_size_t<I+1>() );
}
template<std::size_t I, class... A> void emplace( A&&... a )
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( A&&... a )
{
size_t const J = I+1;
std::size_t const J = I+1;
using U = mp11::mp_at_c<variant<T...>, I>;
@@ -1077,6 +1124,8 @@ template<class... T> struct variant_base_impl<false, true, T...>
_destroy();
st_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
static_assert( J <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = J;
}
@@ -1089,12 +1138,14 @@ template<class... T> struct variant_base_impl<false, true, T...>
// not trivially destructible, double buffered
template<class... T> struct variant_base_impl<false, false, T...>
{
using index_type = get_index_type<true, T...>;
#if defined(__GNUC__) && __GNUC__ < 11 && !defined(__clang__) && !defined(__INTEL_COMPILER)
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63707 :-(
variant_storage<none, T...> st1_, st2_;
unsigned ix_;
index_type ix_;
constexpr variant_base_impl(): st1_( mp11::mp_size_t<0>() ), st2_( mp11::mp_size_t<0>() ), ix_( 0 )
{
@@ -1117,7 +1168,7 @@ template<class... T> struct variant_base_impl<false, false, T...>
#else
variant_storage<none, T...> st_[ 2 ];
unsigned ix_;
index_type ix_;
constexpr variant_base_impl(): st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }, ix_( 0 )
{
@@ -1140,9 +1191,11 @@ template<class... T> struct variant_base_impl<false, false, T...>
#endif
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
template<class I, class... A> BOOST_CXX14_CONSTEXPR void _replace( I, A&&... a )
{
::new( &storage( 0 ) ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
static_assert( ( I::value + 1 ) * 2 <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = ( I::value + 1 ) * 2;
}
@@ -1156,19 +1209,19 @@ template<class... T> struct variant_base_impl<false, false, T...>
variant_base_impl * this_;
unsigned i2_;
template<class I> void operator()( I ) const noexcept
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I ) const noexcept
{
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
this_->storage( i2_ ).get( I() ).~U();
}
};
void _destroy() noexcept
BOOST_CXX14_CONSTEXPR void _destroy() noexcept
{
mp11::mp_with_index<1 + sizeof...(T)>( ix_ / 2, _destroy_L1{ this, ix_ & 1 } );
mp11::mp_with_index<1 + sizeof...(T)>( ix_ / 2, _destroy_L1{ this, static_cast<unsigned>( ix_ & 1 ) } );
}
~variant_base_impl() noexcept
BOOST_VARIANT2_CXX20_CONSTEXPR ~variant_base_impl() noexcept
{
_destroy();
}
@@ -1182,7 +1235,7 @@ template<class... T> struct variant_base_impl<false, false, T...>
{
BOOST_ASSERT( index() == I );
size_t const J = I+1;
std::size_t const J = I+1;
constexpr mp11::mp_size_t<J> j{};
return storage( ix_ & 1 ).get( j );
@@ -1192,22 +1245,23 @@ template<class... T> struct variant_base_impl<false, false, T...>
{
BOOST_VARIANT2_CX14_ASSERT( index() == I )
// size_t const J = I+1;
// std::size_t const J = I+1;
// constexpr mp_size_t<J> j{};
return storage( ix_ & 1 ).get( mp11::mp_size_t<I+1>() );
}
template<std::size_t I, class... A> void emplace( A&&... a )
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( A&&... a )
{
size_t const J = I+1;
std::size_t const J = I+1;
unsigned i2 = 1 - ( ix_ & 1 );
storage( i2 ).emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
_destroy();
ix_ = J * 2 + i2;
static_assert( J * 2 + 1 <= (std::numeric_limits<index_type>::max)(), "" );
ix_ = static_cast<index_type>( J * 2 + i2 );
}
static constexpr bool uses_double_storage() noexcept
@@ -1358,7 +1412,7 @@ private:
variant_base * this_;
variant_base const & r;
template<class I> void operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I i ) const
{
this_->_replace( i, r._get_impl( i ) );
}
@@ -1366,7 +1420,7 @@ private:
public:
variant_cc_base_impl( variant_cc_base_impl const& r )
BOOST_CXX14_CONSTEXPR variant_cc_base_impl( variant_cc_base_impl const& r )
noexcept( mp11::mp_all<std::is_nothrow_copy_constructible<T>...>::value )
: variant_base()
{
@@ -1438,7 +1492,7 @@ private:
variant_base * this_;
variant_base const & r;
template<class I> void operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I i ) const
{
this_->template emplace<I::value>( r._get_impl( i ) );
}
@@ -1512,7 +1566,7 @@ private:
variant_base * this_;
variant_base & r;
template<class I> void operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I i ) const
{
this_->_replace( i, std::move( r._get_impl( i ) ) );
}
@@ -1520,7 +1574,7 @@ private:
public:
variant_mc_base_impl( variant_mc_base_impl && r )
BOOST_CXX14_CONSTEXPR variant_mc_base_impl( variant_mc_base_impl && r )
noexcept( mp11::mp_all<std::is_nothrow_move_constructible<T>...>::value )
{
mp11::mp_with_index<sizeof...(T)>( r.index(), L2{ this, r } );
@@ -1591,7 +1645,7 @@ private:
variant_base * this_;
variant_base & r;
template<class I> void operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I i ) const
{
this_->template emplace<I::value>( std::move( r._get_impl( i ) ) );
}
@@ -1599,7 +1653,7 @@ private:
public:
variant_ma_base_impl& operator=( variant_ma_base_impl && r )
BOOST_CXX14_CONSTEXPR variant_ma_base_impl& operator=( variant_ma_base_impl && r )
noexcept( mp11::mp_all<std::is_nothrow_move_constructible<T>...>::value )
{
mp11::mp_with_index<sizeof...(T)>( r.index(), L4{ this, r } );
@@ -1745,7 +1799,7 @@ private:
variant * this_;
variant & r;
template<class I> void operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I i ) const
{
using std::swap;
swap( this_->_get_impl( i ), r._get_impl( i ) );
@@ -1754,7 +1808,7 @@ private:
public:
void swap( variant& r ) noexcept( mp11::mp_all<std::is_nothrow_move_constructible<T>..., detail::is_nothrow_swappable<T>...>::value )
BOOST_CXX14_CONSTEXPR void swap( variant& r ) noexcept( mp11::mp_all<std::is_nothrow_move_constructible<T>..., detail::is_nothrow_swappable<T>...>::value )
{
if( index() == r.index() )
{
@@ -1781,7 +1835,7 @@ private:
variant_base * this_;
variant<U...> const & r;
template<class I> void operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<T...>, mp11::mp_at<mp11::mp_list<U...>, I>>;
this_->_replace( J{}, r._get_impl( i ) );
@@ -1792,7 +1846,7 @@ public:
template<class... U,
class E2 = mp11::mp_if<mp11::mp_all<std::is_copy_constructible<U>..., mp11::mp_contains<mp11::mp_list<T...>, U>...>, void> >
variant( variant<U...> const& r )
BOOST_CXX14_CONSTEXPR variant( variant<U...> const& r )
noexcept( mp11::mp_all<std::is_nothrow_copy_constructible<U>...>::value )
{
mp11::mp_with_index<sizeof...(U)>( r.index(), L6<U...>{ this, r } );
@@ -1805,7 +1859,7 @@ private:
variant_base * this_;
variant<U...> & r;
template<class I> void operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR void operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<T...>, mp11::mp_at<mp11::mp_list<U...>, I>>;
this_->_replace( J{}, std::move( r._get_impl( i ) ) );
@@ -1816,7 +1870,7 @@ public:
template<class... U,
class E2 = mp11::mp_if<mp11::mp_all<std::is_move_constructible<U>..., mp11::mp_contains<mp11::mp_list<T...>, U>...>, void> >
variant( variant<U...> && r )
BOOST_CXX14_CONSTEXPR variant( variant<U...> && r )
noexcept( mp11::mp_all<std::is_nothrow_move_constructible<U>...>::value )
{
mp11::mp_with_index<sizeof...(U)>( r.index(), L7<U...>{ this, r } );
@@ -1842,7 +1896,7 @@ private:
{
variant * this_;
template<class I> variant<U...> operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR variant<U...> operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<U...>, mp11::mp_at<mp11::mp_list<T...>, I>>;
return this_->_subset_impl<U...>( J{}, this_->_get_impl( i ) );
@@ -1864,7 +1918,7 @@ private:
{
variant const * this_;
template<class I> variant<U...> operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR variant<U...> operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<U...>, mp11::mp_at<mp11::mp_list<T...>, I>>;
return this_->_subset_impl<U...>( J{}, this_->_get_impl( i ) );
@@ -1886,7 +1940,7 @@ private:
{
variant * this_;
template<class I> variant<U...> operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR variant<U...> operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<U...>, mp11::mp_at<mp11::mp_list<T...>, I>>;
return this_->_subset_impl<U...>( J{}, std::move( this_->_get_impl( i ) ) );
@@ -1912,7 +1966,7 @@ private:
{
variant const * this_;
template<class I> variant<U...> operator()( I i ) const
template<class I> BOOST_CXX14_CONSTEXPR variant<U...> operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<U...>, mp11::mp_at<mp11::mp_list<T...>, I>>;
return this_->_subset_impl<U...>( J{}, std::move( this_->_get_impl( i ) ) );
@@ -2125,7 +2179,7 @@ template<class R, class F, class V1> struct visit_L1
F&& f;
V1&& v1;
template<class I> auto operator()( I ) const -> Vret<R, F, V1>
template<class I> constexpr auto operator()( I ) const -> Vret<R, F, V1>
{
return std::forward<F>(f)( unsafe_get<I::value>( std::forward<V1>(v1) ) );
}
@@ -2248,7 +2302,7 @@ template<class R = detail::deduced, class F, class V1, class V2, class... V> con
// specialized algorithms
template<class... T,
class E = typename std::enable_if<mp11::mp_all<std::is_move_constructible<T>..., detail::is_swappable<T>...>::value>::type>
void swap( variant<T...> & v, variant<T...> & w )
BOOST_CXX14_CONSTEXPR void swap( variant<T...> & v, variant<T...> & w )
noexcept( noexcept(v.swap(w)) )
{
v.swap( w );

View File

@@ -7,7 +7,8 @@
# http://www.boost.org/LICENSE_1_0.txt
import testing ;
import ../../config/checks/config : requires ;
import-search /boost/config/checks ;
import config : requires ;
project
: default-build
@@ -16,9 +17,14 @@ project
: requirements
<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 ;
@@ -54,10 +60,10 @@ run variant_in_place_type_construct.cpp ;
compile variant_in_place_type_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
run variant_copy_assign.cpp ;
compile variant_copy_assign_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_copy_assign_cx.cpp : [ requires cxx14_constexpr ] <toolset>gcc-5:<build>no <toolset>gcc-6:<build>no ;
run variant_move_assign.cpp ;
compile variant_move_assign_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_move_assign_cx.cpp : [ requires cxx14_constexpr ] <toolset>gcc-5:<build>no <toolset>gcc-6:<build>no ;
run variant_value_assign.cpp ;
compile variant_value_assign_cx.cpp : [ requires cxx14_constexpr ] ;
@@ -125,7 +131,7 @@ run variant_visit_by_index.cpp ;
run variant_ostream_insert.cpp ;
run is_output_streamable.cpp ;
local JSON = <library>/boost//json/<warnings>off "<toolset>msvc-14.0:<build>no" "<toolset>msvc-14.2:<cxxflags>-wd5104" "<undefined-sanitizer>norecover:<link>static" ;
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" ;
run variant_json_value_from.cpp : : : $(JSON) ;
run variant_json_value_to.cpp : : : $(JSON) ;
@@ -133,3 +139,30 @@ run variant_json_value_to.cpp : : : $(JSON) ;
compile variant_uses_double_storage.cpp ;
run variant_derived_construct2.cpp ;
compile variant_visit_cx.cpp : [ requires cxx14_constexpr ] ;
compile variant_visit_cx_2.cpp : [ requires cxx14_constexpr ] ;
compile variant_visit_r_cx.cpp : [ requires cxx14_constexpr ] ;
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 ;

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

@@ -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 < 1950
BOOST_PRAGMA_MESSAGE("Skipping constexpr destructor test because BOOST_MSVC < 1950")
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,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();
}

View File

@@ -2,6 +2,12 @@
// 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>

View File

@@ -2,6 +2,12 @@
// 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>

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 < 1950
BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_MSVC < 1950")
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

51
test/variant_visit_cx.cpp Normal file
View File

@@ -0,0 +1,51 @@
// 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>
using namespace boost::variant2;
#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Skipping constexpr visit test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
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

@@ -0,0 +1,52 @@
// 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>
using namespace boost::variant2;
#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Skipping constexpr visit test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
int main() {}
#else
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