forked from boostorg/variant2
Compare commits
26 Commits
feature/gc
...
boost-1.77
Author | SHA1 | Date | |
---|---|---|---|
4153a535a0 | |||
f374ad68a3 | |||
3bc9a57c9b | |||
3ca95a65df | |||
ae1f72671e | |||
a2dab8c7d3 | |||
f39a71ed2f | |||
06dde96400 | |||
8be0a4a5fe | |||
90cda5339f | |||
afb0aafd64 | |||
f586dc8848 | |||
20b9175932 | |||
fb3ce863ff | |||
8ec0bf448a | |||
6d19e6be68 | |||
d8552b23ae | |||
f44aba09a2 | |||
99cc1db385 | |||
6d848c5af6 | |||
3c9f4e56bf | |||
3015e56bcb | |||
7c37053950 | |||
60995edb41 | |||
6de876954a | |||
453b00dec8 |
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@ -17,10 +17,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.7
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-16.04
|
||||
install: g++-4.7
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-16.04
|
||||
@ -42,6 +38,7 @@ jobs:
|
||||
- toolset: gcc-8
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
install: g++-8
|
||||
- toolset: gcc-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
@ -87,6 +84,7 @@ jobs:
|
||||
compiler: clang++-6.0
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-6.0
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
cxxstd: "03,11,14,17"
|
||||
@ -96,6 +94,7 @@ jobs:
|
||||
compiler: clang++-8
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-8
|
||||
- toolset: clang
|
||||
compiler: clang++-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
@ -104,6 +103,10 @@ jobs:
|
||||
compiler: clang++-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
compiler: clang++-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-10.15
|
||||
|
68
.travis.yml
68
.travis.yml
@ -1,4 +1,4 @@
|
||||
# Copyright 2016-2019 Peter Dimov
|
||||
# Copyright 2016-2021 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -95,7 +95,7 @@ matrix:
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: g++-10
|
||||
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=11,14,17,2a
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-10 CXXSTD=11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
@ -103,21 +103,6 @@ matrix:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-8
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-8 CXXSTD=11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: clang++
|
||||
env: DIST=trusty TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.5
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=11,14,1z
|
||||
@ -180,6 +165,7 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-5.0
|
||||
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=11,14,1z
|
||||
addons:
|
||||
@ -190,6 +176,7 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-6.0
|
||||
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=11,14,17
|
||||
addons:
|
||||
@ -200,6 +187,7 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-7
|
||||
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
@ -208,9 +196,10 @@ matrix:
|
||||
- clang-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-xenial-7
|
||||
- llvm-toolchain-bionic-7
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-8
|
||||
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
@ -219,10 +208,10 @@ matrix:
|
||||
- clang-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-xenial-8
|
||||
- llvm-toolchain-bionic-8
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
dist: bionic
|
||||
compiler: clang++-9
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
@ -231,11 +220,11 @@ matrix:
|
||||
- clang-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
dist: bionic
|
||||
compiler: clang++-10
|
||||
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
@ -244,19 +233,34 @@ matrix:
|
||||
- clang-10
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-8
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXSTD=11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
dist: bionic
|
||||
compiler: clang++-11
|
||||
env: TOOLSET=clang COMPILER=clang++-11 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
- clang-11
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-xenial-8
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-12
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-12 CXXSTD=11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-12
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-12 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
@ -268,18 +272,14 @@ matrix:
|
||||
- libc++-dev
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
dist: bionic
|
||||
compiler: clang++-libc++
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=11,14,1z UBSAN_OPTIONS=print_stacktrace=1
|
||||
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z UBSAN_OPTIONS=print_stacktrace=1
|
||||
@ -288,7 +288,7 @@ matrix:
|
||||
env: CMAKE_TEST=1
|
||||
script:
|
||||
- mkdir __build__ && cd __build__
|
||||
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=variant2 ..
|
||||
- cmake -DBOOST_ENABLE_CMAKE=1 -DBUILD_TESTING=ON -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=variant2 ..
|
||||
- ctest --output-on-failure -R boost_variant2
|
||||
|
||||
- os: linux
|
||||
|
@ -20,15 +20,15 @@ environment:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
CXXSTD: 14,17,latest
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: clang-win
|
||||
ADDRMD: 64
|
||||
CXXSTD: 14,17
|
||||
CXXSTD: 14,17,latest
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
TOOLSET: msvc-14.2
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
CXXSTD: 14,17,latest
|
||||
|
||||
install:
|
||||
- set BOOST_BRANCH=develop
|
||||
|
@ -1,5 +1,5 @@
|
||||
////
|
||||
Copyright 2019, 2020 Peter Dimov
|
||||
Copyright 2019-2021 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
@ -11,6 +11,10 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
# Revision History
|
||||
:idprefix: changelog_
|
||||
|
||||
## Changes in 1.76.0
|
||||
|
||||
* Improved generated code for the double buffered case.
|
||||
|
||||
## Changes in 1.74.0
|
||||
|
||||
* Added support for derived types in `visit`
|
||||
|
@ -490,8 +490,8 @@ template<size_t I, class... A>
|
||||
+
|
||||
Requires: :: `I < sizeof...(T)`.
|
||||
Effects: ::
|
||||
Destroys the currently contained value, then initializes a new contained
|
||||
value as if using the expression `Ti(std::forward<A>(a)...)`.
|
||||
Initializes a new contained value as if using the expression
|
||||
`Ti(std::forward<A>(a)...)`, then destroys the currently contained value.
|
||||
Ensures: :: `index() == I`.
|
||||
Returns: :: A reference to the new contained value.
|
||||
Throws: ::
|
||||
@ -511,8 +511,8 @@ template<size_t I, class V, class... A>
|
||||
+
|
||||
Requires: :: `I < sizeof...(T)`.
|
||||
Effects: ::
|
||||
Destroys the currently contained value, then initializes a new contained
|
||||
value as if using the expression `Ti(il, std::forward<A>(a)...)`.
|
||||
Initializes a new contained value as if using the expression
|
||||
`Ti(il, std::forward<A>(a)...)`, then destroys the currently contained value.
|
||||
Ensures: :: `index() == I`.
|
||||
Returns: :: A reference to the new contained value.
|
||||
Throws: ::
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <functional> // std::hash
|
||||
#include <cstdint>
|
||||
|
||||
//
|
||||
|
||||
@ -38,6 +39,8 @@ BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> struct hash;
|
||||
|
||||
namespace variant2
|
||||
{
|
||||
|
||||
@ -81,6 +84,8 @@ struct monostate
|
||||
{
|
||||
};
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1940)
|
||||
|
||||
constexpr bool operator<(monostate, monostate) noexcept { return false; }
|
||||
constexpr bool operator>(monostate, monostate) noexcept { return false; }
|
||||
constexpr bool operator<=(monostate, monostate) noexcept { return true; }
|
||||
@ -88,6 +93,17 @@ constexpr bool operator>=(monostate, monostate) noexcept { return true; }
|
||||
constexpr bool operator==(monostate, monostate) noexcept { return true; }
|
||||
constexpr bool operator!=(monostate, monostate) noexcept { return false; }
|
||||
|
||||
#else
|
||||
|
||||
constexpr bool operator<(monostate const&, monostate const&) noexcept { return false; }
|
||||
constexpr bool operator>(monostate const&, monostate const&) noexcept { return false; }
|
||||
constexpr bool operator<=(monostate const&, monostate const&) noexcept { return true; }
|
||||
constexpr bool operator>=(monostate const&, monostate const&) noexcept { return true; }
|
||||
constexpr bool operator==(monostate const&, monostate const&) noexcept { return true; }
|
||||
constexpr bool operator!=(monostate const&, monostate const&) noexcept { return false; }
|
||||
|
||||
#endif
|
||||
|
||||
// variant forward declaration
|
||||
|
||||
template<class... T> class variant;
|
||||
@ -520,11 +536,11 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_false, T1, T.
|
||||
T1 first_;
|
||||
variant_storage<T...> rest_;
|
||||
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
||||
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
@ -564,18 +580,18 @@ template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, c
|
||||
|
||||
variant_storage<T...> rest_;
|
||||
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
||||
|
||||
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
|
||||
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()
|
||||
{
|
||||
@ -637,11 +653,11 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_true, T1, T..
|
||||
T1 first_;
|
||||
variant_storage<T...> rest_;
|
||||
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
||||
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
@ -687,18 +703,18 @@ template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, c
|
||||
|
||||
variant_storage<T...> rest_;
|
||||
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
||||
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
||||
|
||||
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
|
||||
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)... ); }
|
||||
@ -814,21 +830,21 @@ struct none {};
|
||||
// trivially destructible, single buffered
|
||||
template<class... T> struct variant_base_impl<true, true, T...>
|
||||
{
|
||||
int ix_;
|
||||
variant_storage<none, T...> st1_;
|
||||
unsigned ix_;
|
||||
variant_storage<none, T...> st_;
|
||||
|
||||
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() )
|
||||
constexpr variant_base_impl(): ix_( 0 ), st_( mp11::mp_size_t<0>() )
|
||||
{
|
||||
}
|
||||
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
// requires: ix_ == 0
|
||||
template<class I, class... A> void _replace( I, A&&... a )
|
||||
{
|
||||
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
::new( &st_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
ix_ = I::value + 1;
|
||||
}
|
||||
|
||||
@ -843,7 +859,7 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
||||
|
||||
assert( ix_ == J );
|
||||
|
||||
return st1_.get( mp11::mp_size_t<J>() );
|
||||
return st_.get( mp11::mp_size_t<J>() );
|
||||
}
|
||||
|
||||
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
||||
@ -851,14 +867,14 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
||||
// size_t const J = I+1;
|
||||
// assert( ix_ == I+1 );
|
||||
|
||||
return st1_.get( mp11::mp_size_t<I+1>() );
|
||||
return st_.get( mp11::mp_size_t<I+1>() );
|
||||
}
|
||||
|
||||
template<std::size_t J, class U, class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_true, A&&... a )
|
||||
{
|
||||
static_assert( std::is_nothrow_constructible<U, A&&...>::value, "Logic error: U must be nothrow constructible from A&&..." );
|
||||
|
||||
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
st_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
ix_ = J;
|
||||
}
|
||||
|
||||
@ -868,7 +884,7 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
||||
|
||||
U tmp( std::forward<A>(a)... );
|
||||
|
||||
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
||||
st_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
||||
ix_ = J;
|
||||
}
|
||||
|
||||
@ -884,84 +900,78 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
||||
// trivially destructible, double buffered
|
||||
template<class... T> struct variant_base_impl<true, false, T...>
|
||||
{
|
||||
int ix_;
|
||||
variant_storage<none, T...> st1_;
|
||||
variant_storage<none, T...> st2_;
|
||||
unsigned ix_;
|
||||
variant_storage<none, T...> st_[ 2 ];
|
||||
|
||||
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() ), st2_( mp11::mp_size_t<0>() )
|
||||
constexpr variant_base_impl(): ix_( 0 ), st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }
|
||||
{
|
||||
}
|
||||
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... ), st2_( mp11::mp_size_t<0>() )
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( ( I::value + 1 ) * 2 ), st_{ { mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... }, { mp11::mp_size_t<0>() } }
|
||||
{
|
||||
}
|
||||
|
||||
// requires: ix_ == 0
|
||||
template<class I, class... A> void _replace( I, A&&... a )
|
||||
{
|
||||
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
ix_ = I::value + 1;
|
||||
::new( &st_[ 0 ] ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
ix_ = ( I::value + 1 ) * 2;
|
||||
}
|
||||
|
||||
constexpr std::size_t index() const noexcept
|
||||
{
|
||||
return ix_ >= 0? ix_ - 1: -ix_ - 1;
|
||||
return ix_ / 2 - 1;
|
||||
}
|
||||
|
||||
template<std::size_t I> BOOST_CXX14_CONSTEXPR mp11::mp_at_c<variant<T...>, I>& _get_impl( mp11::mp_size_t<I> ) noexcept
|
||||
{
|
||||
assert( index() == I );
|
||||
|
||||
size_t const J = I+1;
|
||||
|
||||
assert( ix_ == J || -ix_ == J );
|
||||
|
||||
constexpr mp11::mp_size_t<J> j{};
|
||||
return ix_ >= 0? st1_.get( j ): st2_.get( j );
|
||||
return st_[ ix_ & 1 ].get( j );
|
||||
}
|
||||
|
||||
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
||||
{
|
||||
// assert( index() == I );
|
||||
// size_t const J = I+1;
|
||||
// assert( ix_ == J || -ix_ == J );
|
||||
// constexpr mp_size_t<J> j{};
|
||||
|
||||
return ix_ >= 0? st1_.get( mp11::mp_size_t<I+1>() ): st2_.get( mp11::mp_size_t<I+1>() );
|
||||
return st_[ ix_ & 1 ].get( mp11::mp_size_t<I+1>() );
|
||||
}
|
||||
|
||||
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( A&&... a )
|
||||
{
|
||||
size_t const J = I+1;
|
||||
|
||||
if( ix_ >= 0 )
|
||||
{
|
||||
st2_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
ix_ = -static_cast<int>( J );
|
||||
}
|
||||
else
|
||||
{
|
||||
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
ix_ = J;
|
||||
}
|
||||
unsigned i2 = 1 - ( ix_ & 1 );
|
||||
|
||||
st_[ i2 ].emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
|
||||
ix_ = J * 2 + i2;
|
||||
}
|
||||
};
|
||||
|
||||
// not trivially destructible, single buffered
|
||||
template<class... T> struct variant_base_impl<false, true, T...>
|
||||
{
|
||||
int ix_;
|
||||
variant_storage<none, T...> st1_;
|
||||
unsigned ix_;
|
||||
variant_storage<none, T...> st_;
|
||||
|
||||
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() )
|
||||
constexpr variant_base_impl(): ix_( 0 ), st_( mp11::mp_size_t<0>() )
|
||||
{
|
||||
}
|
||||
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
// requires: ix_ == 0
|
||||
template<class I, class... A> void _replace( I, A&&... a )
|
||||
{
|
||||
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
::new( &st_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
ix_ = I::value + 1;
|
||||
}
|
||||
|
||||
@ -977,7 +987,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
||||
template<class I> void operator()( I ) const noexcept
|
||||
{
|
||||
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
|
||||
this_->st1_.get( I() ).~U();
|
||||
this_->st_.get( I() ).~U();
|
||||
}
|
||||
};
|
||||
|
||||
@ -1005,7 +1015,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
||||
|
||||
assert( ix_ == J );
|
||||
|
||||
return st1_.get( mp11::mp_size_t<J>() );
|
||||
return st_.get( mp11::mp_size_t<J>() );
|
||||
}
|
||||
|
||||
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
||||
@ -1013,7 +1023,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
||||
// size_t const J = I+1;
|
||||
// assert( ix_ == J );
|
||||
|
||||
return st1_.get( mp11::mp_size_t<I+1>() );
|
||||
return st_.get( mp11::mp_size_t<I+1>() );
|
||||
}
|
||||
|
||||
template<std::size_t I, class... A> void emplace( A&&... a )
|
||||
@ -1028,7 +1038,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
||||
|
||||
_destroy();
|
||||
|
||||
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
||||
st_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
||||
ix_ = J;
|
||||
}
|
||||
};
|
||||
@ -1036,23 +1046,61 @@ 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...>
|
||||
{
|
||||
int ix_;
|
||||
variant_storage<none, T...> st1_;
|
||||
variant_storage<none, T...> st2_;
|
||||
unsigned ix_;
|
||||
|
||||
#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_;
|
||||
|
||||
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() ), st2_( mp11::mp_size_t<0>() )
|
||||
{
|
||||
}
|
||||
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... ), st2_( mp11::mp_size_t<0>() )
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( ( I::value + 1 ) * 2 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... ), st2_( mp11::mp_size_t<0>() )
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR variant_storage<none, T...>& storage( unsigned i2 ) noexcept
|
||||
{
|
||||
return i2 == 0? st1_: st2_;
|
||||
}
|
||||
|
||||
constexpr variant_storage<none, T...> const& storage( unsigned i2 ) const noexcept
|
||||
{
|
||||
return i2 == 0? st1_: st2_;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
variant_storage<none, T...> st_[ 2 ];
|
||||
|
||||
constexpr variant_base_impl(): ix_( 0 ), st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }
|
||||
{
|
||||
}
|
||||
|
||||
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( ( I::value + 1 ) * 2 ), st_{ { mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... }, { mp11::mp_size_t<0>() } }
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR variant_storage<none, T...>& storage( unsigned i2 ) noexcept
|
||||
{
|
||||
return st_[ i2 ];
|
||||
}
|
||||
|
||||
constexpr variant_storage<none, T...> const& storage( unsigned i2 ) const noexcept
|
||||
{
|
||||
return st_[ i2 ];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// requires: ix_ == 0
|
||||
template<class I, class... A> void _replace( I, A&&... a )
|
||||
{
|
||||
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
ix_ = I::value + 1;
|
||||
::new( &storage( 0 ) ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
||||
ix_ = ( I::value + 1 ) * 2;
|
||||
}
|
||||
|
||||
//[&]( auto I ){
|
||||
@ -1063,35 +1111,18 @@ template<class... T> struct variant_base_impl<false, false, T...>
|
||||
struct _destroy_L1
|
||||
{
|
||||
variant_base_impl * this_;
|
||||
unsigned i2_;
|
||||
|
||||
template<class I> void operator()( I ) const noexcept
|
||||
{
|
||||
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
|
||||
this_->st1_.get( I() ).~U();
|
||||
}
|
||||
};
|
||||
|
||||
struct _destroy_L2
|
||||
{
|
||||
variant_base_impl * this_;
|
||||
|
||||
template<class I> void operator()( I ) const noexcept
|
||||
{
|
||||
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
|
||||
this_->st2_.get( I() ).~U();
|
||||
this_->storage( i2_ ).get( I() ).~U();
|
||||
}
|
||||
};
|
||||
|
||||
void _destroy() noexcept
|
||||
{
|
||||
if( ix_ > 0 )
|
||||
{
|
||||
mp11::mp_with_index<1 + sizeof...(T)>( ix_, _destroy_L1{ this } );
|
||||
}
|
||||
else if( ix_ < 0 )
|
||||
{
|
||||
mp11::mp_with_index<1 + sizeof...(T)>( -ix_, _destroy_L2{ this } );
|
||||
}
|
||||
mp11::mp_with_index<1 + sizeof...(T)>( ix_ / 2, _destroy_L1{ this, ix_ & 1 } );
|
||||
}
|
||||
|
||||
~variant_base_impl() noexcept
|
||||
@ -1101,46 +1132,38 @@ template<class... T> struct variant_base_impl<false, false, T...>
|
||||
|
||||
constexpr std::size_t index() const noexcept
|
||||
{
|
||||
return ix_ >= 0? ix_ - 1: -ix_ - 1;
|
||||
return ix_ / 2 - 1;
|
||||
}
|
||||
|
||||
template<std::size_t I> BOOST_CXX14_CONSTEXPR mp11::mp_at_c<variant<T...>, I>& _get_impl( mp11::mp_size_t<I> ) noexcept
|
||||
{
|
||||
assert( index() == I );
|
||||
|
||||
size_t const J = I+1;
|
||||
|
||||
assert( ix_ == J || -ix_ == J );
|
||||
|
||||
constexpr mp11::mp_size_t<J> j{};
|
||||
return ix_ >= 0? st1_.get( j ): st2_.get( j );
|
||||
return storage( ix_ & 1 ).get( j );
|
||||
}
|
||||
|
||||
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
||||
{
|
||||
// assert( index() == I );
|
||||
// size_t const J = I+1;
|
||||
// assert( ix_ == J || -ix_ == J );
|
||||
// constexpr mp_size_t<J> j{};
|
||||
|
||||
return ix_ >= 0? st1_.get( mp11::mp_size_t<I+1>() ): st2_.get( mp11::mp_size_t<I+1>() );
|
||||
return storage( ix_ & 1 ).get( mp11::mp_size_t<I+1>() );
|
||||
}
|
||||
|
||||
template<std::size_t I, class... A> void emplace( A&&... a )
|
||||
{
|
||||
size_t const J = I+1;
|
||||
|
||||
if( ix_ >= 0 )
|
||||
{
|
||||
st2_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
_destroy();
|
||||
unsigned i2 = 1 - ( ix_ & 1 );
|
||||
|
||||
ix_ = -static_cast<int>( J );
|
||||
}
|
||||
else
|
||||
{
|
||||
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
_destroy();
|
||||
storage( i2 ).emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
||||
_destroy();
|
||||
|
||||
ix_ = J;
|
||||
}
|
||||
ix_ = J * 2 + i2;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1561,7 +1584,7 @@ public:
|
||||
|
||||
template<class U,
|
||||
class Ud = typename std::decay<U>::type,
|
||||
class E1 = typename std::enable_if< !std::is_same<Ud, variant>::value && !detail::is_in_place_index<Ud>::value && !detail::is_in_place_type<Ud>::value >::type,
|
||||
class E1 = typename std::enable_if< !std::is_same<Ud, variant>::value && !std::is_base_of<variant, Ud>::value && !detail::is_in_place_index<Ud>::value && !detail::is_in_place_type<Ud>::value >::type,
|
||||
class V = detail::resolve_overload_type<U&&, T...>,
|
||||
class E2 = typename std::enable_if<std::is_constructible<V, U&&>::value>::type
|
||||
>
|
||||
@ -2085,7 +2108,7 @@ template<class R, class F, class V1, class V2> struct visit_L2
|
||||
template<class I> auto operator()( I ) const -> Vret<R, F, V1, V2>
|
||||
{
|
||||
auto f2 = bind_front( std::forward<F>(f), unsafe_get<I::value>( std::forward<V1>(v1) ) );
|
||||
return visit<R>( f2, std::forward<V2>(v2) );
|
||||
return visit<R>( f2, std::forward<V2>(v2) );
|
||||
}
|
||||
};
|
||||
|
||||
@ -2175,31 +2198,59 @@ void swap( variant<T...> & v, variant<T...> & w )
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class V> struct hash_value_L
|
||||
inline std::size_t hash_value_impl_( mp11::mp_true, std::size_t index, std::size_t value )
|
||||
{
|
||||
boost::ulong_long_type hv = ( boost::ulong_long_type( 0xCBF29CE4 ) << 32 ) + 0x84222325;
|
||||
boost::ulong_long_type const prime = ( boost::ulong_long_type( 0x00000100 ) << 32 ) + 0x000001B3;
|
||||
|
||||
hv ^= index;
|
||||
hv *= prime;
|
||||
|
||||
hv ^= value;
|
||||
hv *= prime;
|
||||
|
||||
return static_cast<std::size_t>( hv );
|
||||
}
|
||||
|
||||
inline std::size_t hash_value_impl_( mp11::mp_false, std::size_t index, std::size_t value )
|
||||
{
|
||||
std::size_t hv = 0x811C9DC5;
|
||||
std::size_t const prime = 0x01000193;
|
||||
|
||||
hv ^= index;
|
||||
hv *= prime;
|
||||
|
||||
hv ^= value;
|
||||
hv *= prime;
|
||||
|
||||
return hv;
|
||||
}
|
||||
|
||||
inline std::size_t hash_value_impl( std::size_t index, std::size_t value )
|
||||
{
|
||||
return hash_value_impl_( mp11::mp_bool< (SIZE_MAX > UINT32_MAX) >(), index, value );
|
||||
}
|
||||
|
||||
template<template<class> class H, class V> struct hash_value_L
|
||||
{
|
||||
V const & v;
|
||||
|
||||
template<class I> std::size_t operator()( I ) const
|
||||
{
|
||||
boost::ulong_long_type hv = ( boost::ulong_long_type( 0xCBF29CE4 ) << 32 ) + 0x84222325;
|
||||
boost::ulong_long_type const prime = ( boost::ulong_long_type( 0x00000100 ) << 32 ) + 0x000001B3;
|
||||
|
||||
// index
|
||||
|
||||
hv ^= I::value;
|
||||
hv *= prime;
|
||||
|
||||
// value
|
||||
|
||||
auto const & t = unsafe_get<I::value>( v );
|
||||
|
||||
hv ^= std::hash<remove_cv_ref_t<decltype(t)>>()( t );
|
||||
hv *= prime;
|
||||
std::size_t index = I::value;
|
||||
std::size_t value = H<remove_cv_ref_t<decltype(t)>>()( t );
|
||||
|
||||
return static_cast<std::size_t>( hv );
|
||||
return hash_value_impl( index, value );
|
||||
}
|
||||
};
|
||||
|
||||
template<class... T> std::size_t hash_value_std( variant<T...> const & v )
|
||||
{
|
||||
return mp11::mp_with_index<sizeof...(T)>( v.index(), detail::hash_value_L< std::hash, variant<T...> >{ v } );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
inline std::size_t hash_value( monostate const & )
|
||||
@ -2209,7 +2260,7 @@ inline std::size_t hash_value( monostate const & )
|
||||
|
||||
template<class... T> std::size_t hash_value( variant<T...> const & v )
|
||||
{
|
||||
return mp11::mp_with_index<sizeof...(T)>( v.index(), detail::hash_value_L< variant<T...> >{ v } );
|
||||
return mp11::mp_with_index<sizeof...(T)>( v.index(), detail::hash_value_L< boost::hash, variant<T...> >{ v } );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
@ -2230,7 +2281,7 @@ template<class V> struct std_hash_impl<V, true>
|
||||
{
|
||||
std::size_t operator()( V const & v ) const
|
||||
{
|
||||
return hash_value( v );
|
||||
return detail::hash_value_std( v );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -119,3 +119,5 @@ run variant_visit_r.cpp : : :
|
||||
<toolset>gcc,<target-os>windows:<variant>release
|
||||
<toolset>gcc,<target-os>cygwin:<variant>release
|
||||
;
|
||||
|
||||
compile variant_derived_construct.cpp ;
|
||||
|
33
test/variant_derived_construct.cpp
Normal file
33
test/variant_derived_construct.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
|
||||
using namespace boost::variant2;
|
||||
|
||||
template<class... T> class X: variant<T...>
|
||||
{
|
||||
using base = variant<T...>;
|
||||
using base::base;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y( Y const& rhs ) = default;
|
||||
|
||||
template<class T> Y( T const& t )
|
||||
{
|
||||
t.bar();
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using W = X<int, double, Y>;
|
||||
|
||||
W a( 1 );
|
||||
W b( a );
|
||||
|
||||
(void)b;
|
||||
}
|
@ -88,5 +88,12 @@ int main()
|
||||
BOOST_TEST_NOT( v1 != v2 );
|
||||
}
|
||||
|
||||
{
|
||||
variant<monostate> v1, v2;
|
||||
|
||||
BOOST_TEST( v1 == v2 );
|
||||
BOOST_TEST_NOT( v1 != v2 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@ -93,6 +93,13 @@ int main()
|
||||
STATIC_ASSERT( !(v1 == v2) );
|
||||
STATIC_ASSERT( !(v1 != v2) );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr variant<monostate> v1, v2;
|
||||
|
||||
STATIC_ASSERT( v1 == v2 );
|
||||
STATIC_ASSERT( !(v1 != v2) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost::variant2;
|
||||
|
||||
@ -47,7 +48,17 @@ template<template<class...> class Hash, class T> void test2()
|
||||
BOOST_TEST_NE( h2, h3 );
|
||||
}
|
||||
|
||||
struct X {};
|
||||
struct X
|
||||
{
|
||||
int m = 0;
|
||||
};
|
||||
|
||||
std::size_t hash_value( X const& x )
|
||||
{
|
||||
return boost::hash<int>()( x.m );
|
||||
}
|
||||
|
||||
struct Y {}; // no hash support
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -57,6 +68,8 @@ int main()
|
||||
test<boost::hash, monostate, monostate, monostate>();
|
||||
test<boost::hash, int, int, float>();
|
||||
|
||||
test<boost::hash, monostate, X, std::vector<X>>();
|
||||
|
||||
test2<std::hash, int>();
|
||||
test2<std::hash, float>();
|
||||
|
||||
@ -65,7 +78,7 @@ int main()
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) && ( !defined(_LIBCPP_STD_VER) || _LIBCPP_STD_VER > 11 )
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( detail::is_hash_enabled<X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( detail::is_hash_enabled<Y> ));
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -105,7 +105,7 @@ int main()
|
||||
STATIC_ASSERT( v.index() == 4 );
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 100200)
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 110000)
|
||||
|
||||
// no idea why this fails on g++ 10
|
||||
|
||||
|
@ -102,7 +102,7 @@ int main()
|
||||
STATIC_ASSERT( holds_alternative<X>(v) );
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 100200)
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 110000)
|
||||
|
||||
// no idea why this fails on g++ 10
|
||||
|
||||
|
@ -81,5 +81,14 @@ int main()
|
||||
BOOST_TEST_NOT( v1 >= v2 );
|
||||
}
|
||||
|
||||
{
|
||||
variant<monostate> v1, v2;
|
||||
|
||||
BOOST_TEST_NOT( v1 < v2 );
|
||||
BOOST_TEST_NOT( v1 > v2 );
|
||||
BOOST_TEST( v1 <= v2 );
|
||||
BOOST_TEST( v1 >= v2 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@ -86,6 +86,15 @@ int main()
|
||||
STATIC_ASSERT( !(v1 <= v2) );
|
||||
STATIC_ASSERT( !(v1 >= v2) );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr variant<monostate> v1, v2;
|
||||
|
||||
STATIC_ASSERT( !(v1 < v2) );
|
||||
STATIC_ASSERT( !(v1 > v2) );
|
||||
STATIC_ASSERT( v1 <= v2 );
|
||||
STATIC_ASSERT( v1 >= v2 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user