mirror of
https://github.com/boostorg/variant2.git
synced 2026-06-11 11:51:24 +02:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d69db1441 | |||
| 095d9770c4 | |||
| cca476fbbc | |||
| c76af4d3cf | |||
| 1af7b165cf | |||
| 49bff72be0 | |||
| 59780ba08e | |||
| edd70cfd66 | |||
| 86c2782dff | |||
| dce8174550 | |||
| 9d40bc80f1 | |||
| be6ddf9fdc | |||
| 4153a535a0 | |||
| f374ad68a3 | |||
| 3bc9a57c9b | |||
| 3ca95a65df | |||
| ae1f72671e | |||
| a2dab8c7d3 |
+30
-33
@@ -19,18 +19,15 @@ jobs:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-18.04
|
||||
install: g++-4.8
|
||||
- toolset: gcc-4.9
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-16.04
|
||||
install: g++-4.9
|
||||
- toolset: gcc-5
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-18.04
|
||||
install: g++-5
|
||||
- toolset: gcc-6
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-18.04
|
||||
install: g++-6
|
||||
- toolset: gcc-7
|
||||
cxxstd: "03,11,14,17"
|
||||
@@ -38,51 +35,38 @@ jobs:
|
||||
- toolset: gcc-8
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
install: g++-8
|
||||
- toolset: gcc-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
os: ubuntu-20.04
|
||||
- toolset: gcc-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
- toolset: clang
|
||||
compiler: clang++-3.5
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-16.04
|
||||
install: clang-3.5
|
||||
- toolset: clang
|
||||
compiler: clang++-3.6
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-16.04
|
||||
install: clang-3.6
|
||||
- toolset: clang
|
||||
compiler: clang++-3.7
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-16.04
|
||||
install: clang-3.7
|
||||
- toolset: clang
|
||||
compiler: clang++-3.8
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-16.04
|
||||
install: clang-3.8
|
||||
os: ubuntu-20.04
|
||||
install: g++-10
|
||||
- toolset: gcc-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-11
|
||||
- toolset: clang
|
||||
compiler: clang++-3.9
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-18.04
|
||||
install: clang-3.9
|
||||
- toolset: clang
|
||||
compiler: clang++-4.0
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-18.04
|
||||
install: clang-4.0
|
||||
- toolset: clang
|
||||
compiler: clang++-5.0
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-18.04
|
||||
install: clang-5.0
|
||||
- toolset: clang
|
||||
compiler: clang++-6.0
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-6.0
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
cxxstd: "03,11,14,17"
|
||||
@@ -90,16 +74,29 @@ jobs:
|
||||
install: clang-7
|
||||
- toolset: clang
|
||||
compiler: clang++-8
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-20.04
|
||||
install: clang-8
|
||||
- toolset: clang
|
||||
compiler: clang++-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-9
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-10
|
||||
- toolset: clang
|
||||
compiler: clang++-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-11
|
||||
- toolset: clang
|
||||
compiler: clang++-12
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-12
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-10.15
|
||||
|
||||
+1
-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
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
# variant2
|
||||
# Boost.Variant2
|
||||
|
||||
This repository contains a never-valueless, strong guarantee, C++11/14/17
|
||||
implementation of [std::variant](http://en.cppreference.com/w/cpp/utility/variant).
|
||||
See [the documentation](https://www.boost.org/libs/variant2)
|
||||
for more information.
|
||||
|
||||
The code requires [Boost.Mp11](https://github.com/boostorg/mp11) and
|
||||
Boost.Config.
|
||||
|
||||
The library is part of Boost, starting from release 1.71, but the header
|
||||
`variant.hpp` will also work [standalone](https://godbolt.org/z/nVUNKX).
|
||||
The library is part of Boost, starting from release 1.71. It depends on
|
||||
Boost.Mp11, Boost.Config, and Boost.Assert.
|
||||
|
||||
Supported compilers:
|
||||
|
||||
* g++ 4.8 or later with `-std=c++11` or above
|
||||
* clang++ 3.5 or later with `-std=c++11` or above
|
||||
* clang++ 3.9 or later with `-std=c++11` or above
|
||||
* Visual Studio 2015, 2017, 2019
|
||||
|
||||
Tested on [Travis](https://travis-ci.org/boostorg/variant2/) and
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
////
|
||||
Copyright 2019-2021 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#changelog]
|
||||
# Revision History
|
||||
:idprefix: changelog_
|
||||
|
||||
## Changes in 1.78.0
|
||||
|
||||
* Added `<boost/variant2.hpp>`.
|
||||
* Added `unsafe_get<I>`.
|
||||
|
||||
## Changes in 1.76.0
|
||||
|
||||
* Improved generated code for the double buffered case.
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
////
|
||||
Copyright 2019 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#implementation]
|
||||
@@ -13,13 +10,13 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
## Dependencies
|
||||
|
||||
This implementation only depends on Boost.Config and Boost.Mp11.
|
||||
This implementation only depends on Boost.Config, Boost.Assert, and Boost.Mp11.
|
||||
|
||||
## Supported Compilers
|
||||
|
||||
* GCC 4.8 or later with `-std=c++11` or above
|
||||
* Clang 3.5 or later with `-std=c++11` or above
|
||||
* Clang 3.9 or later with `-std=c++11` or above
|
||||
* Visual Studio 2015, 2017, 2019
|
||||
|
||||
Tested on https://travis-ci.org/boostorg/variant2/[Travis] and
|
||||
Tested on https://github.com/boostorg/variant2/actions[Github Actions] and
|
||||
https://ci.appveyor.com/project/pdimov/variant2-fkab9[Appveyor].
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
////
|
||||
Copyright 2018, 2019 Peter Dimov
|
||||
|
||||
Copyright 2018-2021 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#reference]
|
||||
@@ -117,6 +114,21 @@ template<class U, class... T>
|
||||
constexpr add_pointer_t<const U>
|
||||
get_if(const variant<T...>* v) noexcept;
|
||||
|
||||
// unsafe_get (extension)
|
||||
|
||||
template<size_t I, class... T>
|
||||
constexpr variant_alternative_t<I, variant<T...>>&
|
||||
unsafe_get(variant<T...>& v);
|
||||
template<size_t I, class... T>
|
||||
constexpr variant_alternative_t<I, variant<T...>>&&
|
||||
unsafe_get(variant<T...>&& v);
|
||||
template<size_t I, class... T>
|
||||
constexpr const variant_alternative_t<I, variant<T...>>&
|
||||
unsafe_get(const variant<T...>& v);
|
||||
template<size_t I, class... T>
|
||||
constexpr const variant_alternative_t<I, variant<T...>>&&
|
||||
unsafe_get(const variant<T...>&& v);
|
||||
|
||||
// relational operators
|
||||
|
||||
template<class... T>
|
||||
@@ -775,6 +787,34 @@ Requires: :: The type `U` occurs exactly once in `T...`. Otherwise, the
|
||||
Effects: :: Equivalent to: `return get_if<I>(v);` with `I` being
|
||||
the zero-based index of `U` in `T...`.
|
||||
|
||||
### unsafe_get (extension)
|
||||
|
||||
```
|
||||
template<size_t I, class... T>
|
||||
constexpr variant_alternative_t<I, variant<T...>>&
|
||||
unsafe_get(variant<T...>& v);
|
||||
```
|
||||
```
|
||||
template<size_t I, class... T>
|
||||
constexpr variant_alternative_t<I, variant<T...>>&&
|
||||
unsafe_get(variant<T...>&& v);
|
||||
```
|
||||
```
|
||||
template<size_t I, class... T>
|
||||
constexpr const variant_alternative_t<I, variant<T...>>&
|
||||
unsafe_get(const variant<T...>& v);
|
||||
```
|
||||
```
|
||||
template<size_t I, class... T>
|
||||
constexpr const variant_alternative_t<I, variant<T...>>&&
|
||||
unsafe_get(const variant<T...>&& v);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires: :: `v.index() == I`.
|
||||
Returns: :: a reference to the object stored in the variant.
|
||||
|
||||
### Relational Operators
|
||||
|
||||
```
|
||||
@@ -878,3 +918,7 @@ public:
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## <boost/variant2.hpp>
|
||||
|
||||
This convenience header includes `<boost/variant2/variant.hpp>`.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef BOOST_VARIANT2_HPP_INCLUDED
|
||||
#define BOOST_VARIANT2_HPP_INCLUDED
|
||||
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_VARIANT2_HPP_INCLUDED
|
||||
@@ -13,19 +13,18 @@
|
||||
# pragma warning( disable: 4521 4522 ) // multiple copy operators
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MP11_HPP_INCLUDED
|
||||
#include <boost/mp11.hpp>
|
||||
#endif
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <exception>
|
||||
#include <cassert>
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <functional> // std::hash
|
||||
#include <cstdint>
|
||||
|
||||
//
|
||||
|
||||
@@ -38,6 +37,8 @@ BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> struct hash;
|
||||
|
||||
namespace variant2
|
||||
{
|
||||
|
||||
@@ -364,37 +365,50 @@ template<std::size_t I, class... T> constexpr variant_alternative_t<I, variant<T
|
||||
#endif
|
||||
}
|
||||
|
||||
// detail::unsafe_get (for visit)
|
||||
// unsafe_get
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
# define BOOST_VARIANT2_CX14_ASSERT(expr) BOOST_ASSERT(expr);
|
||||
#else
|
||||
# define BOOST_VARIANT2_CX14_ASSERT(expr)
|
||||
#endif
|
||||
|
||||
template<std::size_t I, class... T> constexpr variant_alternative_t<I, variant<T...>>& unsafe_get(variant<T...>& v)
|
||||
{
|
||||
static_assert( I < sizeof...(T), "Index out of bounds" );
|
||||
|
||||
BOOST_VARIANT2_CX14_ASSERT( v.index() == I )
|
||||
|
||||
return v._get_impl( mp11::mp_size_t<I>() );
|
||||
}
|
||||
|
||||
template<std::size_t I, class... T> constexpr variant_alternative_t<I, variant<T...>>&& unsafe_get(variant<T...>&& v)
|
||||
{
|
||||
static_assert( I < sizeof...(T), "Index out of bounds" );
|
||||
|
||||
BOOST_VARIANT2_CX14_ASSERT( v.index() == I )
|
||||
|
||||
return std::move( v._get_impl( mp11::mp_size_t<I>() ) );
|
||||
}
|
||||
|
||||
template<std::size_t I, class... T> constexpr variant_alternative_t<I, variant<T...>> const& unsafe_get(variant<T...> const& v)
|
||||
{
|
||||
static_assert( I < sizeof...(T), "Index out of bounds" );
|
||||
|
||||
BOOST_VARIANT2_CX14_ASSERT( v.index() == I )
|
||||
|
||||
return v._get_impl( mp11::mp_size_t<I>() );
|
||||
}
|
||||
|
||||
template<std::size_t I, class... T> constexpr variant_alternative_t<I, variant<T...>> const&& unsafe_get(variant<T...> const&& v)
|
||||
{
|
||||
static_assert( I < sizeof...(T), "Index out of bounds" );
|
||||
|
||||
BOOST_VARIANT2_CX14_ASSERT( v.index() == I )
|
||||
|
||||
return std::move( v._get_impl( mp11::mp_size_t<I>() ) );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// get (type)
|
||||
|
||||
template<class U, class... T> constexpr U& get(variant<T...>& v)
|
||||
@@ -854,7 +868,7 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
||||
{
|
||||
size_t const J = I+1;
|
||||
|
||||
assert( ix_ == J );
|
||||
BOOST_ASSERT( ix_ == J );
|
||||
|
||||
return st_.get( mp11::mp_size_t<J>() );
|
||||
}
|
||||
@@ -862,7 +876,8 @@ 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;
|
||||
// assert( ix_ == I+1 );
|
||||
|
||||
BOOST_VARIANT2_CX14_ASSERT( ix_ == I+1 )
|
||||
|
||||
return st_.get( mp11::mp_size_t<I+1>() );
|
||||
}
|
||||
@@ -922,7 +937,7 @@ template<class... T> struct variant_base_impl<true, false, T...>
|
||||
|
||||
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 );
|
||||
BOOST_ASSERT( index() == I );
|
||||
|
||||
size_t const J = I+1;
|
||||
|
||||
@@ -932,7 +947,8 @@ template<class... T> struct variant_base_impl<true, false, T...>
|
||||
|
||||
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 );
|
||||
BOOST_VARIANT2_CX14_ASSERT( index() == I )
|
||||
|
||||
// size_t const J = I+1;
|
||||
// constexpr mp_size_t<J> j{};
|
||||
|
||||
@@ -1010,7 +1026,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
||||
{
|
||||
size_t const J = I+1;
|
||||
|
||||
assert( ix_ == J );
|
||||
BOOST_ASSERT( ix_ == J );
|
||||
|
||||
return st_.get( mp11::mp_size_t<J>() );
|
||||
}
|
||||
@@ -1018,7 +1034,8 @@ 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;
|
||||
// assert( ix_ == J );
|
||||
|
||||
BOOST_VARIANT2_CX14_ASSERT( ix_ == I+1 )
|
||||
|
||||
return st_.get( mp11::mp_size_t<I+1>() );
|
||||
}
|
||||
@@ -1134,7 +1151,7 @@ template<class... T> struct variant_base_impl<false, false, T...>
|
||||
|
||||
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 );
|
||||
BOOST_ASSERT( index() == I );
|
||||
|
||||
size_t const J = I+1;
|
||||
|
||||
@@ -1144,7 +1161,8 @@ template<class... T> struct variant_base_impl<false, false, T...>
|
||||
|
||||
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 );
|
||||
BOOST_VARIANT2_CX14_ASSERT( index() == I )
|
||||
|
||||
// size_t const J = I+1;
|
||||
// constexpr mp_size_t<J> j{};
|
||||
|
||||
@@ -2173,7 +2191,7 @@ template<class R = detail::deduced, class F, class V1, class V2, class... V> con
|
||||
{
|
||||
return mp11::mp_with_index<detail::variant_base_size<V1>>( v1.index(), [&]( auto I ){
|
||||
|
||||
auto f2 = [&]( auto&&... a ){ return std::forward<F>(f)( detail::unsafe_get<I.value>( std::forward<V1>(v1) ), std::forward<decltype(a)>(a)... ); };
|
||||
auto f2 = [&]( auto&&... a ){ return std::forward<F>(f)( unsafe_get<I.value>( std::forward<V1>(v1) ), std::forward<decltype(a)>(a)... ); };
|
||||
return visit<R>( f2, std::forward<V2>(v2), std::forward<V>(v)... );
|
||||
|
||||
});
|
||||
@@ -2195,31 +2213,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 & )
|
||||
@@ -2229,7 +2275,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
|
||||
@@ -2250,7 +2296,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 );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2276,6 +2322,8 @@ template<> struct hash< ::boost::variant2::monostate >
|
||||
|
||||
} // namespace std
|
||||
|
||||
#undef BOOST_VARIANT2_CX14_ASSERT
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||
# pragma warning( pop )
|
||||
#endif
|
||||
|
||||
+2
-4
@@ -1,10 +1,8 @@
|
||||
|
||||
// Copyright 2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/variant2.hpp>
|
||||
|
||||
using namespace boost::variant2;
|
||||
|
||||
|
||||
+15
-2
@@ -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,9 +105,9 @@ int main()
|
||||
STATIC_ASSERT( v.index() == 4 );
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 110000)
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 120000)
|
||||
|
||||
// no idea why this fails on g++ 10
|
||||
// no idea why this fails on g++ 10/11
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@@ -102,9 +102,9 @@ int main()
|
||||
STATIC_ASSERT( holds_alternative<X>(v) );
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 110000)
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 120000)
|
||||
|
||||
// no idea why this fails on g++ 10
|
||||
// no idea why this fails on g++ 10/11
|
||||
|
||||
#else
|
||||
|
||||
|
||||
Reference in New Issue
Block a user