util: update bundled copies of {any,optional,variant}-lite
any-lite commit b210d89239c3ffa969bffe8731d287674901a7fb
optional-lite commit a08fda6c674ae4c9ff43dcad89f630da512c24d6
variant-lite commit 94e2844cae3bfe19ab3c0f3a9aaa13f69a43c026
Change-Id: I859eb3d2fca8a74899d887a14f4e1a4361b79a8e
diff --git a/ndn-cxx/util/nonstd/any.hpp b/ndn-cxx/util/nonstd/any.hpp
index 41b7056..cf5071e 100644
--- a/ndn-cxx/util/nonstd/any.hpp
+++ b/ndn-cxx/util/nonstd/any.hpp
@@ -316,16 +316,34 @@
# include <tr1/type_traits>
#endif
+// Method enabling
+
+#if any_CPP11_OR_GREATER
+
+#define any_REQUIRES_0(...) \
+ template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
+
+#define any_REQUIRES_T(...) \
+ , typename = typename std::enable_if< (__VA_ARGS__), nonstd::any_lite::detail::enabler >::type
+
+#define any_REQUIRES_R(R, ...) \
+ typename std::enable_if<__VA_ARGS__, R>::type
+
+#define any_REQUIRES_A(...) \
+ , typename std::enable_if<__VA_ARGS__, void*>::type = nullptr
+
+#endif
+
//
// any:
//
namespace nonstd { namespace any_lite {
-namespace detail {
-
// C++11 emulation:
+namespace std11 {
+
#if any_HAVE_ADD_CONST
using std::add_const;
@@ -355,6 +373,14 @@
#endif // any_HAVE_REMOVE_REFERENCE
+} // namespace std11
+
+namespace detail {
+
+// for any_REQUIRES_T
+
+/*enum*/ class enabler{};
+
} // namespace detail
#if ! any_CONFIG_NO_EXCEPTIONS
@@ -395,7 +421,7 @@
template<
class ValueType, class T = typename std::decay<ValueType>::type
- , typename = typename std::enable_if< ! std::is_same<T, any>::value >::type
+ any_REQUIRES_T( ! std::is_same<T, any>::value )
>
any( ValueType && value ) any_noexcept
: content( new holder<T>( std::move( value ) ) )
@@ -403,7 +429,7 @@
template<
class T, class... Args
- , typename = typename std::enable_if< std::is_constructible<T, Args...>::value >::type
+ any_REQUIRES_T( std::is_constructible<T, Args&&...>::value )
>
explicit any( nonstd_lite_in_place_type_t(T), Args&&... args )
: content( new holder<T>( T( std::forward<Args>(args)... ) ) )
@@ -411,7 +437,7 @@
template<
class T, class U, class... Args
- , typename = typename std::enable_if< std::is_constructible<T, std::initializer_list<U>&, Args...>::value >::type
+ any_REQUIRES_T( std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value )
>
explicit any( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
: content( new holder<T>( T( il, std::forward<Args>(args)... ) ) )
@@ -447,7 +473,7 @@
template<
class ValueType, class T = typename std::decay<ValueType>::type
- , typename = typename std::enable_if< ! std::is_same<T, any>::value >::type
+ any_REQUIRES_T( ! std::is_same<T, any>::value )
>
any & operator=( ValueType && value )
{
@@ -463,7 +489,7 @@
template<
class T, class U, class... Args
- , typename = typename std::enable_if< std::is_constructible<T, std::initializer_list<U>&, Args...>::value >::type
+ any_REQUIRES_T( std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value )
>
void emplace( std::initializer_list<U> il, Args&&... args )
{
@@ -584,12 +610,13 @@
template<
class ValueType
#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
- , typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type
+// any_REQUIRES_T(...) Allow for VC120 (VS2013):
+ , typename = typename std::enable_if< (std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value), nonstd::any_lite::detail::enabler >::type
#endif
>
any_nodiscard inline ValueType any_cast( any const & operand )
{
- const ValueType * result = any_cast< typename detail::add_const< typename detail::remove_reference<ValueType>::type >::type >( &operand );
+ const ValueType * result = any_cast< typename std11::add_const< typename std11::remove_reference<ValueType>::type >::type >( &operand );
#if any_CONFIG_NO_EXCEPTIONS
assert( result );
@@ -606,12 +633,13 @@
template<
class ValueType
#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
- , typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type
+// any_REQUIRES_T(...) Allow for VC120 (VS2013):
+ , typename = typename std::enable_if< (std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value), nonstd::any_lite::detail::enabler >::type
#endif
>
any_nodiscard inline ValueType any_cast( any & operand )
{
- const ValueType * result = any_cast< typename detail::remove_reference<ValueType>::type >( &operand );
+ const ValueType * result = any_cast< typename std11::remove_reference<ValueType>::type >( &operand );
#if any_CONFIG_NO_EXCEPTIONS
assert( result );
@@ -630,12 +658,12 @@
template<
class ValueType
#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
- , typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type
+ any_REQUIRES_T( std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value )
#endif
>
any_nodiscard inline ValueType any_cast( any && operand )
{
- const ValueType * result = any_cast< typename detail::remove_reference<ValueType>::type >( &operand );
+ const ValueType * result = any_cast< typename std11::remove_reference<ValueType>::type >( &operand );
#if any_CONFIG_NO_EXCEPTIONS
assert( result );
diff --git a/ndn-cxx/util/nonstd/optional.hpp b/ndn-cxx/util/nonstd/optional.hpp
index 898bbd5..d05d1c5 100644
--- a/ndn-cxx/util/nonstd/optional.hpp
+++ b/ndn-cxx/util/nonstd/optional.hpp
@@ -126,25 +126,25 @@
struct in_place_t {};
template< class T >
-inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
+inline in_place_t in_place( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
{
return in_place_t();
}
template< std::size_t K >
-inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
+inline in_place_t in_place( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
{
return in_place_t();
}
template< class T >
-inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
+inline in_place_t in_place_type( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
{
return in_place_t();
}
template< std::size_t K >
-inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
+inline in_place_t in_place_index( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
{
return in_place_t();
}
@@ -246,7 +246,7 @@
# define optional_COMPILER_MSVC_VERSION 0
#endif
-#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * major + minor ) + patch )
+#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) )
#if defined(__GNUC__) && !defined(__clang__)
# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
@@ -298,6 +298,7 @@
// Presence of C++11 language features:
#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
+#define optional_HAVE_IS_DEFAULT optional_CPP11_140
#define optional_HAVE_NOEXCEPT optional_CPP11_140
#define optional_HAVE_NULLPTR optional_CPP11_100
#define optional_HAVE_REF_QUALIFIER optional_CPP11_140
@@ -308,7 +309,7 @@
// Presence of C++17 language features:
-// no flag
+#define optional_HAVE_NODISCARD optional_CPP17_000
// Presence of C++ library features:
@@ -327,12 +328,24 @@
# define optional_constexpr /*constexpr*/
#endif
+#if optional_HAVE( IS_DEFAULT )
+# define optional_is_default = default;
+#else
+# define optional_is_default {}
+#endif
+
#if optional_HAVE( CONSTEXPR_14 )
# define optional_constexpr14 constexpr
#else
# define optional_constexpr14 /*constexpr*/
#endif
+#if optional_HAVE( NODISCARD )
+# define optional_nodiscard [[nodiscard]]
+#else
+# define optional_nodiscard /*[[nodiscard]]*/
+#endif
+
#if optional_HAVE( NOEXCEPT )
# define optional_noexcept noexcept
#else
@@ -346,6 +359,7 @@
#endif
#if optional_HAVE( REF_QUALIFIER )
+// NOLINTNEXTLINE( bugprone-macro-parentheses )
# define optional_ref_qual &
# define optional_refref_qual &&
#else
@@ -379,14 +393,17 @@
#if optional_CPP11_OR_GREATER
-# define optional_REQUIRES_T(...) \
- , typename = typename std::enable_if<__VA_ARGS__>::type
+#define optional_REQUIRES_0(...) \
+ template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
-# define optional_REQUIRES_R(R, ...) \
- typename std::enable_if<__VA_ARGS__, R>::type
+#define optional_REQUIRES_T(...) \
+ , typename = typename std::enable_if< (__VA_ARGS__), nonstd::optional_lite::detail::enabler >::type
-# define optional_REQUIRES_A(...) \
- , typename std::enable_if<__VA_ARGS__, void*>::type = optional_nullptr
+#define optional_REQUIRES_R(R, ...) \
+ typename std::enable_if< (__VA_ARGS__), R>::type
+
+#define optional_REQUIRES_A(...) \
+ , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
#endif
@@ -396,7 +413,13 @@
namespace nonstd { namespace optional_lite {
-namespace detail {
+namespace std11 {
+
+#if optional_CPP11_OR_GREATER
+ using std::move;
+#else
+ template< typename T > T & move( T & t ) { return t; }
+#endif
#if optional_HAVE( CONDITIONAL )
using std::conditional;
@@ -405,13 +428,68 @@
template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
#endif // optional_HAVE_CONDITIONAL
-} // namespace detail
+} // namespace std11
#if optional_CPP11_OR_GREATER
-namespace std20 {
+/// type traits C++17:
-// type traits C++20:
+namespace std17 {
+
+#if optional_CPP17_OR_GREATER
+
+using std::is_swappable;
+using std::is_nothrow_swappable;
+
+#elif optional_CPP11_OR_GREATER
+
+namespace detail {
+
+using std::swap;
+
+struct is_swappable
+{
+ template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
+ static std::true_type test( int /*unused*/ );
+
+ template< typename >
+ static std::false_type test(...);
+};
+
+struct is_nothrow_swappable
+{
+ // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
+
+ template< typename T >
+ static constexpr bool satisfies()
+ {
+ return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
+ }
+
+ template< typename T >
+ static auto test( int /*unused*/ ) -> std::integral_constant<bool, satisfies<T>()>{}
+
+ template< typename >
+ static auto test(...) -> std::false_type;
+};
+
+} // namespace detail
+
+// is [nothow] swappable:
+
+template< typename T >
+struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
+
+template< typename T >
+struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
+
+#endif // optional_CPP17_OR_GREATER
+
+} // namespace std17
+
+/// type traits C++20:
+
+namespace std20 {
template< typename T >
struct remove_cvref
@@ -430,6 +508,12 @@
namespace detail {
+// for optional_REQUIRES_T
+
+#if optional_CPP11_OR_GREATER
+enum class enabler{};
+#endif
+
// C++11 emulation:
struct nulltype{};
@@ -535,7 +619,7 @@
template< typename List, size_t N >
struct type_of_size
{
- typedef typename conditional<
+ typedef typename std11::conditional<
N == sizeof( typename List::head ),
typename List::head,
typename type_of_size<typename List::tail, N >::type >::type type;
@@ -596,9 +680,9 @@
typedef T value_type;
- storage_t() {}
+ storage_t() optional_is_default
- storage_t( value_type const & v )
+ explicit storage_t( value_type const & v )
{
construct_value( v );
}
@@ -610,7 +694,7 @@
#if optional_CPP11_OR_GREATER
- storage_t( value_type && v )
+ explicit storage_t( value_type && v )
{
construct_value( std::move( v ) );
}
@@ -639,7 +723,7 @@
value_ptr()->~T();
}
- value_type const * value_ptr() const
+ optional_nodiscard value_type const * value_ptr() const
{
return as<value_type>();
}
@@ -649,7 +733,7 @@
return as<value_type>();
}
- value_type const & value() const optional_ref_qual
+ optional_nodiscard value_type const & value() const optional_ref_qual
{
return * value_ptr();
}
@@ -661,7 +745,7 @@
#if optional_CPP11_OR_GREATER
- value_type const && value() const optional_refref_qual
+ optional_nodiscard value_type const && value() const optional_refref_qual
{
return std::move( value() );
}
@@ -695,24 +779,24 @@
#endif // optional_CONFIG_MAX_ALIGN_HACK
- void * ptr() optional_noexcept
+ optional_nodiscard void * ptr() optional_noexcept
{
return &data;
}
- void const * ptr() const optional_noexcept
+ optional_nodiscard void const * ptr() const optional_noexcept
{
return &data;
}
template <typename U>
- U * as()
+ optional_nodiscard U * as()
{
return reinterpret_cast<U*>( ptr() );
}
template <typename U>
- U const * as() const
+ optional_nodiscard U const * as() const
{
return reinterpret_cast<U const *>( ptr() );
}
@@ -725,7 +809,7 @@
struct nullopt_t
{
struct init{};
- optional_constexpr nullopt_t( init ) {}
+ explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {}
};
#if optional_HAVE( CONSTEXPR_11 )
@@ -770,7 +854,8 @@
{}
// 1b - construct explicitly empty
- optional_constexpr optional( nullopt_t ) optional_noexcept
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
+ optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept
: has_value_( false )
, contained()
{}
@@ -786,7 +871,9 @@
: has_value_( other.has_value() )
{
if ( other.has_value() )
+ {
contained.construct_value( other.contained.value() );
+ }
}
#if optional_CPP11_OR_GREATER
@@ -796,14 +883,17 @@
optional_REQUIRES_A(
true || std::is_move_constructible<T>::value
)
+ // NOLINTNEXTLINE( performance-noexcept-move-constructor )
) noexcept( std::is_nothrow_move_constructible<T>::value )
: has_value_( other.has_value() )
{
if ( other.has_value() )
+ {
contained.construct_value( std::move( other.contained.value() ) );
+ }
}
- // 4 (C++11) - explicit converting copy-construct from optional
+ // 4a (C++11) - explicit converting copy-construct from optional
template< typename U >
explicit optional( optional<U> const & other
optional_REQUIRES_A(
@@ -822,12 +912,15 @@
: has_value_( other.has_value() )
{
if ( other.has_value() )
- contained.construct_value( other.contained.value() );
+ {
+ contained.construct_value( T{ other.contained.value() } );
+ }
}
#endif // optional_CPP11_OR_GREATER
- // 4 (C++98 and later) - non-explicit converting copy-construct from optional
+ // 4b (C++98 and later) - non-explicit converting copy-construct from optional
template< typename U >
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
optional( optional<U> const & other
#if optional_CPP11_OR_GREATER
optional_REQUIRES_A(
@@ -847,16 +940,18 @@
: has_value_( other.has_value() )
{
if ( other.has_value() )
+ {
contained.construct_value( other.contained.value() );
+ }
}
#if optional_CPP11_OR_GREATER
// 5a (C++11) - explicit converting move-construct from optional
template< typename U >
- optional( optional<U> && other
+ explicit optional( optional<U> && other
optional_REQUIRES_A(
- std::is_constructible<T, U const &>::value
+ std::is_constructible<T, U &&>::value
&& !std::is_constructible<T, optional<U> & >::value
&& !std::is_constructible<T, optional<U> && >::value
&& !std::is_constructible<T, optional<U> const & >::value
@@ -871,14 +966,17 @@
: has_value_( other.has_value() )
{
if ( other.has_value() )
- contained.construct_value( std::move( other.contained.value() ) );
+ {
+ contained.construct_value( T{ std::move( other.contained.value() ) } );
+ }
}
// 5a (C++11) - non-explicit converting move-construct from optional
template< typename U >
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
optional( optional<U> && other
optional_REQUIRES_A(
- std::is_constructible<T, U const &>::value
+ std::is_constructible<T, U &&>::value
&& !std::is_constructible<T, optional<U> & >::value
&& !std::is_constructible<T, optional<U> && >::value
&& !std::is_constructible<T, optional<U> const & >::value
@@ -893,7 +991,9 @@
: has_value_( other.has_value() )
{
if ( other.has_value() )
+ {
contained.construct_value( std::move( other.contained.value() ) );
+ }
}
// 6 (C++11) - in-place construct
@@ -929,11 +1029,12 @@
)
)
: has_value_( true )
- , contained( std::forward<U>( value ) )
+ , contained( T{ std::forward<U>( value ) } )
{}
- // 8a (C++11) - non-explicit move construct from value
+ // 8b (C++11) - non-explicit move construct from value
template< typename U = value_type >
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
optional_constexpr optional( U && value
optional_REQUIRES_A(
std::is_constructible<T, U&&>::value
@@ -961,13 +1062,15 @@
~optional()
{
if ( has_value() )
+ {
contained.destruct_value();
+ }
}
// x.x.3.3, assignment
// 1 (C++98and later) - assign explicitly empty
- optional & operator=( nullopt_t ) optional_noexcept
+ optional & operator=( nullopt_t /*unused*/) optional_noexcept
{
reset();
return *this;
@@ -975,6 +1078,7 @@
// 2 (C++98and later) - copy-assign from optional
#if optional_CPP11_OR_GREATER
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
optional_REQUIRES_R(
optional &,
true
@@ -990,15 +1094,16 @@
optional & operator=( optional const & other )
#endif
{
- if ( has_value() == true && other.has_value() == false ) reset();
- else if ( has_value() == false && other.has_value() == true ) initialize( *other );
- else if ( has_value() == true && other.has_value() == true ) contained.value() = *other;
+ if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
+ else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); }
+ else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; }
return *this;
}
#if optional_CPP11_OR_GREATER
// 3 (C++11) - move-assign from optional
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
optional_REQUIRES_R(
optional &,
true
@@ -1007,26 +1112,33 @@
)
operator=( optional && other ) noexcept
{
- if ( has_value() == true && other.has_value() == false ) reset();
- else if ( has_value() == false && other.has_value() == true ) initialize( std::move( *other ) );
- else if ( has_value() == true && other.has_value() == true ) contained.value() = std::move( *other );
+ if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
+ else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); }
+ else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); }
return *this;
}
// 4 (C++11) - move-assign from value
template< typename U = T >
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
optional_REQUIRES_R(
optional &,
std::is_constructible<T , U>::value
&& std::is_assignable<T&, U>::value
&& !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
&& !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
-// && !(std::is_scalar<T>::value && std::is_same<T, typename std::decay<U>::type>::value)
+ && !(std::is_scalar<T>::value && std::is_same<T, typename std::decay<U>::type>::value)
)
operator=( U && value )
{
- if ( has_value() ) contained.value() = std::forward<U>( value );
- else initialize( T( std::forward<U>( value ) ) );
+ if ( has_value() )
+ {
+ contained.value() = std::forward<U>( value );
+ }
+ else
+ {
+ initialize( T( std::forward<U>( value ) ) );
+ }
return *this;
}
@@ -1046,6 +1158,7 @@
// 5 (C++98 and later) - converting copy-assign from optional
template< typename U >
#if optional_CPP11_OR_GREATER
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
optional_REQUIRES_R(
optional&,
std::is_constructible< T , U const &>::value
@@ -1075,6 +1188,7 @@
// 6 (C++11) - converting move-assign from optional
template< typename U >
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
optional_REQUIRES_R(
optional&,
std::is_constructible< T , U>::value
@@ -1133,14 +1247,14 @@
#if optional_CPP11_OR_GREATER
noexcept(
std::is_nothrow_move_constructible<T>::value
- && noexcept( std::swap( std::declval<T&>(), std::declval<T&>() ) )
+ && std17::is_nothrow_swappable<T>::value
)
#endif
{
using std::swap;
- if ( has_value() == true && other.has_value() == true ) { swap( **this, *other ); }
- else if ( has_value() == false && other.has_value() == true ) { initialize( *other ); other.reset(); }
- else if ( has_value() == true && other.has_value() == false ) { other.initialize( **this ); reset(); }
+ if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); }
+ else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); }
+ else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); }
}
// x.x.3.5, observers
@@ -1169,7 +1283,7 @@
contained.value();
}
-#if optional_CPP11_OR_GREATER
+#if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
optional_constexpr value_type const && operator *() const optional_refref_qual
{
@@ -1195,18 +1309,22 @@
}
#endif
- optional_constexpr bool has_value() const optional_noexcept
+ // NOLINTNEXTLINE( modernize-use-nodiscard )
+ /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept
{
return has_value_;
}
- optional_constexpr14 value_type const & value() const optional_ref_qual
+ // NOLINTNEXTLINE( modernize-use-nodiscard )
+ /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual
{
#if optional_CONFIG_NO_EXCEPTIONS
assert( has_value() );
#else
if ( ! has_value() )
+ {
throw bad_optional_access();
+ }
#endif
return contained.value();
}
@@ -1217,14 +1335,17 @@
assert( has_value() );
#else
if ( ! has_value() )
+ {
throw bad_optional_access();
+ }
#endif
return contained.value();
}
-#if optional_HAVE( REF_QUALIFIER )
+#if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
- optional_constexpr value_type const && value() const optional_refref_qual
+ // NOLINTNEXTLINE( modernize-use-nodiscard )
+ /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual
{
return std::move( value() );
}
@@ -1265,7 +1386,9 @@
void reset() optional_noexcept
{
if ( has_value() )
+ {
contained.destruct_value();
+ }
has_value_ = false;
}
@@ -1339,73 +1462,73 @@
// Comparison with nullopt
template< typename T >
-inline optional_constexpr bool operator==( optional<T> const & x, nullopt_t ) optional_noexcept
+inline optional_constexpr bool operator==( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
{
return (!x);
}
template< typename T >
-inline optional_constexpr bool operator==( nullopt_t, optional<T> const & x ) optional_noexcept
+inline optional_constexpr bool operator==( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
{
return (!x);
}
template< typename T >
-inline optional_constexpr bool operator!=( optional<T> const & x, nullopt_t ) optional_noexcept
+inline optional_constexpr bool operator!=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
{
return bool(x);
}
template< typename T >
-inline optional_constexpr bool operator!=( nullopt_t, optional<T> const & x ) optional_noexcept
+inline optional_constexpr bool operator!=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
{
return bool(x);
}
template< typename T >
-inline optional_constexpr bool operator<( optional<T> const &, nullopt_t ) optional_noexcept
+inline optional_constexpr bool operator<( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
{
return false;
}
template< typename T >
-inline optional_constexpr bool operator<( nullopt_t, optional<T> const & x ) optional_noexcept
+inline optional_constexpr bool operator<( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
{
return bool(x);
}
template< typename T >
-inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t ) optional_noexcept
+inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
{
return (!x);
}
template< typename T >
-inline optional_constexpr bool operator<=( nullopt_t, optional<T> const & ) optional_noexcept
+inline optional_constexpr bool operator<=( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
{
return true;
}
template< typename T >
-inline optional_constexpr bool operator>( optional<T> const & x, nullopt_t ) optional_noexcept
+inline optional_constexpr bool operator>( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
{
return bool(x);
}
template< typename T >
-inline optional_constexpr bool operator>( nullopt_t, optional<T> const & ) optional_noexcept
+inline optional_constexpr bool operator>( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
{
return false;
}
template< typename T >
-inline optional_constexpr bool operator>=( optional<T> const &, nullopt_t ) optional_noexcept
+inline optional_constexpr bool operator>=( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
{
return true;
}
template< typename T >
-inline optional_constexpr bool operator>=( nullopt_t, optional<T> const & x ) optional_noexcept
+inline optional_constexpr bool operator>=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
{
return (!x);
}
@@ -1486,7 +1609,13 @@
// Specialized algorithms
-template< typename T >
+template< typename T
+#if optional_CPP11_OR_GREATER
+ optional_REQUIRES_T(
+ std::is_move_constructible<T>::value
+ && std17::is_swappable<T>::value )
+#endif
+>
void swap( optional<T> & x, optional<T> & y )
#if optional_CPP11_OR_GREATER
noexcept( noexcept( x.swap(y) ) )
@@ -1527,7 +1656,12 @@
} // namespace optional_lite
-using namespace optional_lite;
+using optional_lite::optional;
+using optional_lite::nullopt_t;
+using optional_lite::nullopt;
+using optional_lite::bad_optional_access;
+
+using optional_lite::make_optional;
} // namespace nonstd
@@ -1543,7 +1677,7 @@
public:
std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
{
- return bool( v ) ? hash<T>()( *v ) : 0;
+ return bool( v ) ? std::hash<T>{}( *v ) : 0;
}
};
diff --git a/ndn-cxx/util/nonstd/variant.hpp b/ndn-cxx/util/nonstd/variant.hpp
index 4833de7..f0e70b9 100644
--- a/ndn-cxx/util/nonstd/variant.hpp
+++ b/ndn-cxx/util/nonstd/variant.hpp
@@ -223,6 +223,11 @@
# include <stdexcept>
#endif
+// variant-lite type and visitor argument count configuration (script/generate_header.py):
+
+#define variant_CONFIG_MAX_TYPE_COUNT 16
+#define variant_CONFIG_MAX_VISITOR_ARG_COUNT 5
+
// variant-lite alignment configuration:
#ifndef variant_CONFIG_MAX_ALIGN_HACK
@@ -385,14 +390,17 @@
#if variant_CPP11_OR_GREATER
-# define variant_REQUIRES_T(...) \
- , typename = typename std::enable_if<__VA_ARGS__>::type
+#define variant_REQUIRES_0(...) \
+ template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
-# define variant_REQUIRES_R(R, ...) \
- typename std::enable_if<__VA_ARGS__, R>::type
+#define variant_REQUIRES_T(...) \
+ , typename = typename std::enable_if< (__VA_ARGS__), nonstd::variants::detail::enabler >::type
-# define variant_REQUIRES_A(...) \
- , typename std::enable_if<__VA_ARGS__, void*>::type = variant_nullptr
+#define variant_REQUIRES_R(R, ...) \
+ typename std::enable_if< (__VA_ARGS__), R>::type
+
+#define variant_REQUIRES_A(...) \
+ , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
#endif
@@ -402,10 +410,10 @@
namespace nonstd { namespace variants {
-namespace detail {
-
// C++11 emulation:
+namespace std11 {
+
#if variant_HAVE_STD_ADD_POINTER
using std::add_pointer;
@@ -463,6 +471,71 @@
#endif // variant_HAVE_CONDITIONAL
+} // namespace std11
+
+/// type traits C++17:
+
+namespace std17 {
+
+#if variant_CPP17_OR_GREATER
+
+using std::is_swappable;
+using std::is_nothrow_swappable;
+
+#elif variant_CPP11_OR_GREATER
+
+namespace detail {
+
+using std::swap;
+
+struct is_swappable
+{
+ template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
+ static std::true_type test( int );
+
+ template< typename >
+ static std::false_type test(...);
+};
+
+struct is_nothrow_swappable
+{
+ // wrap noexcept(epr) in separate function as work-around for VC140 (VS2015):
+
+ template< typename T >
+ static constexpr bool test()
+ {
+ return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
+ }
+
+ template< typename T >
+ static auto test( int ) -> std::integral_constant<bool, test<T>()>{}
+
+ template< typename >
+ static std::false_type test(...);
+};
+
+} // namespace detail
+
+// is [nothow] swappable:
+
+template< typename T >
+struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
+
+template< typename T >
+struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
+
+#endif // variant_CPP17_OR_GREATER
+
+} // namespace std17
+
+// detail:
+
+namespace detail {
+
+// for variant_REQUIRES_T():
+
+/*enum*/ class enabler{};
+
// typelist:
#define variant_TL1( T1 ) detail::typelist< T1, detail::nulltype >
@@ -567,7 +640,7 @@
public:
enum V { value = (sizeof( Head ) > tail_value) ? sizeof( Head ) : std::size_t( tail_value ) } ;
- typedef typename conditional< (sizeof( Head ) > tail_value), Head, tail_type>::type type;
+ typedef typename std11::conditional< (sizeof( Head ) > tail_value), Head, tail_type>::type type;
};
#if variant_CPP11_OR_GREATER
@@ -767,7 +840,7 @@
template< typename List, size_t N >
struct type_of_size
{
- typedef typename conditional<
+ typedef typename std11::conditional<
N == sizeof( typename List::head ),
typename List::head,
typename type_of_size<typename List::tail, N >::type >::type type;
@@ -818,24 +891,34 @@
#endif // variant_CONFIG_MAX_ALIGN_HACK
+#if variant_CPP11_OR_GREATER
+
template< typename T>
inline std::size_t hash( T const & v )
{
- // primes:
- unsigned const int a = 54059;
- unsigned const int b = 76963;
- unsigned const int h0 = 37;
-
- unsigned int h = h0;
- unsigned char const * s = reinterpret_cast<unsigned char const *>( &v );
-
- for ( std::size_t i = 0; i < sizeof(v); ++i, ++s )
- {
- h = (h * a) ^ (*s * b);
- }
- return h;
+ return std::hash<T>()( v );
}
+inline std::size_t hash( T0 const & ) { return 0; }
+inline std::size_t hash( T1 const & ) { return 0; }
+inline std::size_t hash( T2 const & ) { return 0; }
+inline std::size_t hash( T3 const & ) { return 0; }
+inline std::size_t hash( T4 const & ) { return 0; }
+inline std::size_t hash( T5 const & ) { return 0; }
+inline std::size_t hash( T6 const & ) { return 0; }
+inline std::size_t hash( T7 const & ) { return 0; }
+inline std::size_t hash( T8 const & ) { return 0; }
+inline std::size_t hash( T9 const & ) { return 0; }
+inline std::size_t hash( T10 const & ) { return 0; }
+inline std::size_t hash( T11 const & ) { return 0; }
+inline std::size_t hash( T12 const & ) { return 0; }
+inline std::size_t hash( T13 const & ) { return 0; }
+inline std::size_t hash( T14 const & ) { return 0; }
+inline std::size_t hash( T15 const & ) { return 0; }
+
+
+#endif // variant_CPP11_OR_GREATER
+
@@ -910,22 +993,22 @@
{
switch ( from_index )
{
- case 0: new( to_value ) T0( std::forward<T0>( *as<T0>( from_value ) ) ); break;
- case 1: new( to_value ) T1( std::forward<T1>( *as<T1>( from_value ) ) ); break;
- case 2: new( to_value ) T2( std::forward<T2>( *as<T2>( from_value ) ) ); break;
- case 3: new( to_value ) T3( std::forward<T3>( *as<T3>( from_value ) ) ); break;
- case 4: new( to_value ) T4( std::forward<T4>( *as<T4>( from_value ) ) ); break;
- case 5: new( to_value ) T5( std::forward<T5>( *as<T5>( from_value ) ) ); break;
- case 6: new( to_value ) T6( std::forward<T6>( *as<T6>( from_value ) ) ); break;
- case 7: new( to_value ) T7( std::forward<T7>( *as<T7>( from_value ) ) ); break;
- case 8: new( to_value ) T8( std::forward<T8>( *as<T8>( from_value ) ) ); break;
- case 9: new( to_value ) T9( std::forward<T9>( *as<T9>( from_value ) ) ); break;
- case 10: new( to_value ) T10( std::forward<T10>( *as<T10>( from_value ) ) ); break;
- case 11: new( to_value ) T11( std::forward<T11>( *as<T11>( from_value ) ) ); break;
- case 12: new( to_value ) T12( std::forward<T12>( *as<T12>( from_value ) ) ); break;
- case 13: new( to_value ) T13( std::forward<T13>( *as<T13>( from_value ) ) ); break;
- case 14: new( to_value ) T14( std::forward<T14>( *as<T14>( from_value ) ) ); break;
- case 15: new( to_value ) T15( std::forward<T15>( *as<T15>( from_value ) ) ); break;
+ case 0: new( to_value ) T0( std::move( *as<T0>( from_value ) ) ); break;
+ case 1: new( to_value ) T1( std::move( *as<T1>( from_value ) ) ); break;
+ case 2: new( to_value ) T2( std::move( *as<T2>( from_value ) ) ); break;
+ case 3: new( to_value ) T3( std::move( *as<T3>( from_value ) ) ); break;
+ case 4: new( to_value ) T4( std::move( *as<T4>( from_value ) ) ); break;
+ case 5: new( to_value ) T5( std::move( *as<T5>( from_value ) ) ); break;
+ case 6: new( to_value ) T6( std::move( *as<T6>( from_value ) ) ); break;
+ case 7: new( to_value ) T7( std::move( *as<T7>( from_value ) ) ); break;
+ case 8: new( to_value ) T8( std::move( *as<T8>( from_value ) ) ); break;
+ case 9: new( to_value ) T9( std::move( *as<T9>( from_value ) ) ); break;
+ case 10: new( to_value ) T10( std::move( *as<T10>( from_value ) ) ); break;
+ case 11: new( to_value ) T11( std::move( *as<T11>( from_value ) ) ); break;
+ case 12: new( to_value ) T12( std::move( *as<T12>( from_value ) ) ); break;
+ case 13: new( to_value ) T13( std::move( *as<T13>( from_value ) ) ); break;
+ case 14: new( to_value ) T14( std::move( *as<T14>( from_value ) ) ); break;
+ case 15: new( to_value ) T15( std::move( *as<T15>( from_value ) ) ); break;
}
return from_index;
@@ -1017,8 +1100,12 @@
template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
class variant;
+// 19.7.8 Class monostate
+
class monostate{};
+// 19.7.9 monostate relational operators
+
inline variant_constexpr bool operator< ( monostate, monostate ) variant_noexcept { return false; }
inline variant_constexpr bool operator> ( monostate, monostate ) variant_noexcept { return false; }
inline variant_constexpr bool operator<=( monostate, monostate ) variant_noexcept { return true; }
@@ -1026,6 +1113,8 @@
inline variant_constexpr bool operator==( monostate, monostate ) variant_noexcept { return true; }
inline variant_constexpr bool operator!=( monostate, monostate ) variant_noexcept { return false; }
+// 19.7.4 variant helper classes
+
// obtain the size of the variant's list of alternatives at compile time
template< class T >
@@ -1077,6 +1166,10 @@
static const std::size_t variant_npos = static_cast<std::size_t>( -1 );
#endif
+#if ! variant_CONFIG_NO_EXCEPTIONS
+
+// 19.7.11 Class bad_variant_access
+
class bad_variant_access : public std::exception
{
public:
@@ -1090,6 +1183,10 @@
}
};
+#endif // variant_CONFIG_NO_EXCEPTIONS
+
+// 19.7.3 Class template variant
+
template<
class T0,
class T1 = detail::T1,
@@ -1114,6 +1211,8 @@
typedef variant_TL16( T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 ) variant_types;
public:
+ // 19.7.3.1 Constructors
+
variant() : type_index( 0 ) { new( ptr() ) T0(); }
variant( T0 const & t0 ) : type_index( 0 ) { new( ptr() ) T0( t0 ); }
@@ -1225,11 +1324,18 @@
#endif // variant_CPP11_OR_GREATER
+ // 19.7.3.2 Destructor
+
~variant()
{
- helper_type::destroy( type_index, ptr() );
+ if ( ! valueless_by_exception() )
+ {
+ helper_type::destroy( type_index, ptr() );
+ }
}
+ // 19.7.3.3 Assignment
+
variant & operator=( variant const & other )
{
return copy_assign( other );
@@ -1255,56 +1361,54 @@
std::is_nothrow_move_assignable<T14>::value &&
std::is_nothrow_move_assignable<T15>::value)
{
- return move_assign( std::forward<variant>( other ) );
+ return move_assign( std::move( other ) );
}
- variant & operator=( T0 && t0 ) { return move_assign_value<T0,0>( std::forward<T0>( t0 ) ); }
- variant & operator=( T1 && t1 ) { return move_assign_value<T1,1>( std::forward<T1>( t1 ) ); }
- variant & operator=( T2 && t2 ) { return move_assign_value<T2,2>( std::forward<T2>( t2 ) ); }
- variant & operator=( T3 && t3 ) { return move_assign_value<T3,3>( std::forward<T3>( t3 ) ); }
- variant & operator=( T4 && t4 ) { return move_assign_value<T4,4>( std::forward<T4>( t4 ) ); }
- variant & operator=( T5 && t5 ) { return move_assign_value<T5,5>( std::forward<T5>( t5 ) ); }
- variant & operator=( T6 && t6 ) { return move_assign_value<T6,6>( std::forward<T6>( t6 ) ); }
- variant & operator=( T7 && t7 ) { return move_assign_value<T7,7>( std::forward<T7>( t7 ) ); }
- variant & operator=( T8 && t8 ) { return move_assign_value<T8,8>( std::forward<T8>( t8 ) ); }
- variant & operator=( T9 && t9 ) { return move_assign_value<T9,9>( std::forward<T9>( t9 ) ); }
- variant & operator=( T10 && t10 ) { return move_assign_value<T10,10>( std::forward<T10>( t10 ) ); }
- variant & operator=( T11 && t11 ) { return move_assign_value<T11,11>( std::forward<T11>( t11 ) ); }
- variant & operator=( T12 && t12 ) { return move_assign_value<T12,12>( std::forward<T12>( t12 ) ); }
- variant & operator=( T13 && t13 ) { return move_assign_value<T13,13>( std::forward<T13>( t13 ) ); }
- variant & operator=( T14 && t14 ) { return move_assign_value<T14,14>( std::forward<T14>( t14 ) ); }
- variant & operator=( T15 && t15 ) { return move_assign_value<T15,15>( std::forward<T15>( t15 ) ); }
+ variant & operator=( T0 && t0 ) { return assign_value<0>( std::move( t0 ) ); }
+ variant & operator=( T1 && t1 ) { return assign_value<1>( std::move( t1 ) ); }
+ variant & operator=( T2 && t2 ) { return assign_value<2>( std::move( t2 ) ); }
+ variant & operator=( T3 && t3 ) { return assign_value<3>( std::move( t3 ) ); }
+ variant & operator=( T4 && t4 ) { return assign_value<4>( std::move( t4 ) ); }
+ variant & operator=( T5 && t5 ) { return assign_value<5>( std::move( t5 ) ); }
+ variant & operator=( T6 && t6 ) { return assign_value<6>( std::move( t6 ) ); }
+ variant & operator=( T7 && t7 ) { return assign_value<7>( std::move( t7 ) ); }
+ variant & operator=( T8 && t8 ) { return assign_value<8>( std::move( t8 ) ); }
+ variant & operator=( T9 && t9 ) { return assign_value<9>( std::move( t9 ) ); }
+ variant & operator=( T10 && t10 ) { return assign_value<10>( std::move( t10 ) ); }
+ variant & operator=( T11 && t11 ) { return assign_value<11>( std::move( t11 ) ); }
+ variant & operator=( T12 && t12 ) { return assign_value<12>( std::move( t12 ) ); }
+ variant & operator=( T13 && t13 ) { return assign_value<13>( std::move( t13 ) ); }
+ variant & operator=( T14 && t14 ) { return assign_value<14>( std::move( t14 ) ); }
+ variant & operator=( T15 && t15 ) { return assign_value<15>( std::move( t15 ) ); }
-#else
- variant & operator=( T0 const & t0 ) { return copy_assign_value<T0,0>( t0 ); }
- variant & operator=( T1 const & t1 ) { return copy_assign_value<T1,1>( t1 ); }
- variant & operator=( T2 const & t2 ) { return copy_assign_value<T2,2>( t2 ); }
- variant & operator=( T3 const & t3 ) { return copy_assign_value<T3,3>( t3 ); }
- variant & operator=( T4 const & t4 ) { return copy_assign_value<T4,4>( t4 ); }
- variant & operator=( T5 const & t5 ) { return copy_assign_value<T5,5>( t5 ); }
- variant & operator=( T6 const & t6 ) { return copy_assign_value<T6,6>( t6 ); }
- variant & operator=( T7 const & t7 ) { return copy_assign_value<T7,7>( t7 ); }
- variant & operator=( T8 const & t8 ) { return copy_assign_value<T8,8>( t8 ); }
- variant & operator=( T9 const & t9 ) { return copy_assign_value<T9,9>( t9 ); }
- variant & operator=( T10 const & t10 ) { return copy_assign_value<T10,10>( t10 ); }
- variant & operator=( T11 const & t11 ) { return copy_assign_value<T11,11>( t11 ); }
- variant & operator=( T12 const & t12 ) { return copy_assign_value<T12,12>( t12 ); }
- variant & operator=( T13 const & t13 ) { return copy_assign_value<T13,13>( t13 ); }
- variant & operator=( T14 const & t14 ) { return copy_assign_value<T14,14>( t14 ); }
- variant & operator=( T15 const & t15 ) { return copy_assign_value<T15,15>( t15 ); }
-
+
#endif
+ variant & operator=( T0 const & t0 ) { return assign_value<0>( t0 ); }
+ variant & operator=( T1 const & t1 ) { return assign_value<1>( t1 ); }
+ variant & operator=( T2 const & t2 ) { return assign_value<2>( t2 ); }
+ variant & operator=( T3 const & t3 ) { return assign_value<3>( t3 ); }
+ variant & operator=( T4 const & t4 ) { return assign_value<4>( t4 ); }
+ variant & operator=( T5 const & t5 ) { return assign_value<5>( t5 ); }
+ variant & operator=( T6 const & t6 ) { return assign_value<6>( t6 ); }
+ variant & operator=( T7 const & t7 ) { return assign_value<7>( t7 ); }
+ variant & operator=( T8 const & t8 ) { return assign_value<8>( t8 ); }
+ variant & operator=( T9 const & t9 ) { return assign_value<9>( t9 ); }
+ variant & operator=( T10 const & t10 ) { return assign_value<10>( t10 ); }
+ variant & operator=( T11 const & t11 ) { return assign_value<11>( t11 ); }
+ variant & operator=( T12 const & t12 ) { return assign_value<12>( t12 ); }
+ variant & operator=( T13 const & t13 ) { return assign_value<13>( t13 ); }
+ variant & operator=( T14 const & t14 ) { return assign_value<14>( t14 ); }
+ variant & operator=( T15 const & t15 ) { return assign_value<15>( t15 ); }
+
+
std::size_t index() const
{
return variant_npos_internal() == type_index ? variant_npos : static_cast<std::size_t>( type_index );
}
- bool valueless_by_exception() const
- {
- return type_index == variant_npos_internal();
- }
-
+ // 19.7.3.4 Modifiers
+
#if variant_CPP11_OR_GREATER
template< class T, class... Args
variant_REQUIRES_T( std::is_constructible< T, Args...>::value )
@@ -1348,7 +1452,37 @@
#endif // variant_CPP11_OR_GREATER
- void swap( variant & other ) variant_noexcept
+ // 19.7.3.5 Value status
+
+ bool valueless_by_exception() const
+ {
+ return type_index == variant_npos_internal();
+ }
+
+ // 19.7.3.6 Swap
+
+ void swap( variant & other )
+#if variant_CPP11_OR_GREATER
+ noexcept(
+ std::is_nothrow_move_constructible<T0>::value && std17::is_nothrow_swappable<T0>::value &&
+ std::is_nothrow_move_constructible<T1>::value && std17::is_nothrow_swappable<T1>::value &&
+ std::is_nothrow_move_constructible<T2>::value && std17::is_nothrow_swappable<T2>::value &&
+ std::is_nothrow_move_constructible<T3>::value && std17::is_nothrow_swappable<T3>::value &&
+ std::is_nothrow_move_constructible<T4>::value && std17::is_nothrow_swappable<T4>::value &&
+ std::is_nothrow_move_constructible<T5>::value && std17::is_nothrow_swappable<T5>::value &&
+ std::is_nothrow_move_constructible<T6>::value && std17::is_nothrow_swappable<T6>::value &&
+ std::is_nothrow_move_constructible<T7>::value && std17::is_nothrow_swappable<T7>::value &&
+ std::is_nothrow_move_constructible<T8>::value && std17::is_nothrow_swappable<T8>::value &&
+ std::is_nothrow_move_constructible<T9>::value && std17::is_nothrow_swappable<T9>::value &&
+ std::is_nothrow_move_constructible<T10>::value && std17::is_nothrow_swappable<T10>::value &&
+ std::is_nothrow_move_constructible<T11>::value && std17::is_nothrow_swappable<T11>::value &&
+ std::is_nothrow_move_constructible<T12>::value && std17::is_nothrow_swappable<T12>::value &&
+ std::is_nothrow_move_constructible<T13>::value && std17::is_nothrow_swappable<T13>::value &&
+ std::is_nothrow_move_constructible<T14>::value && std17::is_nothrow_swappable<T14>::value &&
+ std::is_nothrow_move_constructible<T15>::value && std17::is_nothrow_swappable<T15>::value
+
+ )
+#endif
{
if ( valueless_by_exception() && other.valueless_by_exception() )
{
@@ -1360,9 +1494,15 @@
}
else
{
+#if variant_CPP11_OR_GREATER
+ variant tmp( std::move( *this ) );
+ *this = std::move( other );
+ other = std::move( tmp );
+#else
variant tmp( *this );
*this = other;
other = tmp;
+#endif
}
}
@@ -1373,7 +1513,7 @@
template< class T >
static variant_constexpr std::size_t index_of() variant_noexcept
{
- return to_size_t( detail::typelist_index_of<variant_types, typename detail::remove_cv<T>::type >::value );
+ return to_size_t( detail::typelist_index_of<variant_types, typename std11::remove_cv<T>::type >::value );
}
template< class T >
@@ -1384,7 +1524,7 @@
#if variant_CONFIG_NO_EXCEPTIONS
assert( i == index() );
#else
- if ( i != index() || i == max_index() )
+ if ( i != index() )
{
throw bad_variant_access();
}
@@ -1400,7 +1540,7 @@
#if variant_CONFIG_NO_EXCEPTIONS
assert( i == index() );
#else
- if ( i != index() || i == max_index() )
+ if ( i != index() )
{
throw bad_variant_access();
}
@@ -1453,11 +1593,6 @@
return static_cast<std::size_t>( index );
}
- variant_constexpr std::size_t max_index() const variant_noexcept
- {
- return data_size;
- }
-
variant_constexpr type_index_t variant_npos_internal() const variant_noexcept
{
return static_cast<type_index_t>( -1 );
@@ -1476,20 +1611,13 @@
}
else if ( index() == other.index() )
{
- type_index = variant_npos_internal();
type_index = helper_type::copy_assign( other.type_index, other.ptr(), ptr() );
}
else
{
- // for exception safety, first move to an intermediate copy:
- variant tmp( other );
helper_type::destroy( type_index, ptr() );
type_index = variant_npos_internal();
-#if variant_CPP11_OR_GREATER
- type_index = helper_type::move_construct( other.type_index, tmp.ptr(), ptr() );
-#else
- type_index = helper_type::copy_construct( other.type_index, tmp.ptr(), ptr() );
-#endif
+ type_index = helper_type::copy_construct( other.type_index, other.ptr(), ptr() );
}
return *this;
}
@@ -1509,22 +1637,19 @@
}
else if ( index() == other.index() )
{
- type_index = variant_npos_internal();
type_index = helper_type::move_assign( other.type_index, other.ptr(), ptr() );
}
else
{
- // for exception safety, first move to an intermediate copy:
- variant tmp( std::move( other ) );
helper_type::destroy( type_index, ptr() );
type_index = variant_npos_internal();
- type_index = helper_type::move_construct( other.type_index, tmp.ptr(), ptr() );
+ type_index = helper_type::move_construct( other.type_index, other.ptr(), ptr() );
}
return *this;
}
- template< class T, std::size_t K >
- variant & move_assign_value( T && value )
+ template< std::size_t K, class T >
+ variant & assign_value( T && value )
{
if( index() == K )
{
@@ -1539,9 +1664,11 @@
}
return *this;
}
-#else
- template< class T, std::size_t K >
- variant & copy_assign_value( T const & value )
+
+#endif // variant_CPP11_OR_GREATER
+
+ template< std::size_t K, class T >
+ variant & assign_value( T const & value )
{
if( index() == K )
{
@@ -1557,8 +1684,6 @@
return *this;
}
-#endif // variant_CPP11_OR_GREATER
-
void swap_value( type_index_t index, variant & other )
{
using std::swap;
@@ -1616,6 +1741,8 @@
type_index_t type_index;
};
+// 19.7.5 Value access
+
template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
inline bool holds_alternative( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const & v ) variant_noexcept
{
@@ -1711,41 +1838,69 @@
#endif // variant_CPP11_OR_GREATER
template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
-inline typename detail::add_pointer<T>::type
+inline typename std11::add_pointer<T>::type
get_if( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> * pv, nonstd_lite_in_place_type_t(T) = nonstd_lite_in_place_type(T) )
{
return ( pv->index() == variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::template index_of<T>() ) ? &get<T>( *pv ) : variant_nullptr;
}
template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
-inline typename detail::add_pointer<const T>::type
+inline typename std11::add_pointer<const T>::type
get_if( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const * pv, nonstd_lite_in_place_type_t(T) = nonstd_lite_in_place_type(T))
{
return ( pv->index() == variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::template index_of<T>() ) ? &get<T>( *pv ) : variant_nullptr;
}
template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
-inline typename detail::add_pointer< typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type >::type
+inline typename std11::add_pointer< typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type >::type
get_if( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> * pv, nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K) )
{
return ( pv->index() == K ) ? &get<K>( *pv ) : variant_nullptr;
}
template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
-inline typename detail::add_pointer< const typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type >::type
+inline typename std11::add_pointer< const typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type >::type
get_if( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const * pv, nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K) )
{
return ( pv->index() == K ) ? &get<K>( *pv ) : variant_nullptr;
}
-template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
+// 19.7.10 Specialized algorithms
+
+template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15
+#if variant_CPP11_OR_GREATER
+ variant_REQUIRES_T(
+ std::is_move_constructible<T0>::value && std17::is_swappable<T0>::value &&
+ std::is_move_constructible<T1>::value && std17::is_swappable<T1>::value &&
+ std::is_move_constructible<T2>::value && std17::is_swappable<T2>::value &&
+ std::is_move_constructible<T3>::value && std17::is_swappable<T3>::value &&
+ std::is_move_constructible<T4>::value && std17::is_swappable<T4>::value &&
+ std::is_move_constructible<T5>::value && std17::is_swappable<T5>::value &&
+ std::is_move_constructible<T6>::value && std17::is_swappable<T6>::value &&
+ std::is_move_constructible<T7>::value && std17::is_swappable<T7>::value &&
+ std::is_move_constructible<T8>::value && std17::is_swappable<T8>::value &&
+ std::is_move_constructible<T9>::value && std17::is_swappable<T9>::value &&
+ std::is_move_constructible<T10>::value && std17::is_swappable<T10>::value &&
+ std::is_move_constructible<T11>::value && std17::is_swappable<T11>::value &&
+ std::is_move_constructible<T12>::value && std17::is_swappable<T12>::value &&
+ std::is_move_constructible<T13>::value && std17::is_swappable<T13>::value &&
+ std::is_move_constructible<T14>::value && std17::is_swappable<T14>::value &&
+ std::is_move_constructible<T15>::value && std17::is_swappable<T15>::value
+ )
+#endif
+>
inline void swap(
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> & a,
- variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> & b ) variant_noexcept
+ variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> & b )
+#if variant_CPP11_OR_GREATER
+ noexcept( noexcept( a.swap( b ) ) )
+#endif
{
a.swap( b );
}
+// 19.7.7 Visitation
+
// Variant 'visitor' implementation
namespace detail
@@ -2067,6 +2222,7 @@
#endif
+// 19.7.6 Relational operators
namespace detail {
@@ -2188,7 +2344,7 @@
#if variant_CPP11_OR_GREATER
-// specialize the std::hash algorithm:
+// 19.7.12 Hash support
namespace std {
@@ -2206,7 +2362,29 @@
{
std::size_t operator()( nonstd::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const & v ) const variant_noexcept
{
- return nonstd::variants::detail::hash( v );
+ namespace nvd = nonstd::variants::detail;
+
+ switch( v.index() )
+ {
+ case 0: return nvd::hash( 0 ) ^ nvd::hash( get<0>( v ) );
+ case 1: return nvd::hash( 1 ) ^ nvd::hash( get<1>( v ) );
+ case 2: return nvd::hash( 2 ) ^ nvd::hash( get<2>( v ) );
+ case 3: return nvd::hash( 3 ) ^ nvd::hash( get<3>( v ) );
+ case 4: return nvd::hash( 4 ) ^ nvd::hash( get<4>( v ) );
+ case 5: return nvd::hash( 5 ) ^ nvd::hash( get<5>( v ) );
+ case 6: return nvd::hash( 6 ) ^ nvd::hash( get<6>( v ) );
+ case 7: return nvd::hash( 7 ) ^ nvd::hash( get<7>( v ) );
+ case 8: return nvd::hash( 8 ) ^ nvd::hash( get<8>( v ) );
+ case 9: return nvd::hash( 9 ) ^ nvd::hash( get<9>( v ) );
+ case 10: return nvd::hash( 10 ) ^ nvd::hash( get<10>( v ) );
+ case 11: return nvd::hash( 11 ) ^ nvd::hash( get<11>( v ) );
+ case 12: return nvd::hash( 12 ) ^ nvd::hash( get<12>( v ) );
+ case 13: return nvd::hash( 13 ) ^ nvd::hash( get<13>( v ) );
+ case 14: return nvd::hash( 14 ) ^ nvd::hash( get<14>( v ) );
+ case 15: return nvd::hash( 15 ) ^ nvd::hash( get<15>( v ) );
+
+ default: return false;
+ }
}
};