detail: update bundled copies of {any,optional,scope,variant}-lite

any-lite commit 9bf947336e8b7c25d897e6d4b9dd5b4a68767240
optional-lite commit 0854335c64461d07d00f85b068075ed8871859ec
scope-lite commit 9281968974c68ae1e07f3cac4837393449e42177
variant-lite commit 9499655b9c263eaef735efeeb53892c770d447e1

Change-Id: I7c72dac65a0850b9b7f4e6e89150dffb54a3c797
diff --git a/ndn-cxx/detail/nonstd/any-lite.hpp b/ndn-cxx/detail/nonstd/any-lite.hpp
index aaea3cc..a0ff4d9 100644
--- a/ndn-cxx/detail/nonstd/any-lite.hpp
+++ b/ndn-cxx/detail/nonstd/any-lite.hpp
@@ -12,7 +12,7 @@
 #define NONSTD_ANY_LITE_HPP
 
 #define any_lite_MAJOR  0
-#define any_lite_MINOR  2
+#define any_lite_MINOR  4
 #define any_lite_PATCH  0
 
 #define any_lite_VERSION  any_STRINGIFY(any_lite_MAJOR) "." any_STRINGIFY(any_lite_MINOR) "." any_STRINGIFY(any_lite_PATCH)
@@ -26,6 +26,20 @@
 #define any_ANY_NONSTD   1
 #define any_ANY_STD      2
 
+// tweak header support:
+
+#ifdef __has_include
+# if __has_include(<nonstd/any.tweak.hpp>)
+#  include <nonstd/any.tweak.hpp>
+# endif
+#define any_HAVE_TWEAK_HEADER  1
+#else
+#define any_HAVE_TWEAK_HEADER  0
+//# pragma message("any.hpp: Note: Tweak header not supported.")
+#endif
+
+// any selection and configuration:
+
 #if !defined( any_CONFIG_SELECT_ANY )
 # define any_CONFIG_SELECT_ANY  ( any_HAVE_STD_ANY ? any_ANY_STD : any_ANY_NONSTD )
 #endif
@@ -33,7 +47,10 @@
 // Control presence of exception handling (try and auto discover):
 
 #ifndef any_CONFIG_NO_EXCEPTIONS
-# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
+# if _MSC_VER
+#  include <cstddef>    // for _HAS_EXCEPTIONS
+# endif
+# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
 #  define any_CONFIG_NO_EXCEPTIONS  0
 # else
 #  define any_CONFIG_NO_EXCEPTIONS  1
@@ -249,6 +266,7 @@
 #define any_HAVE_TYPE_TRAITS            any_CPP11_90
 #define any_HAVE_STATIC_ASSERT          any_CPP11_100
 #define any_HAVE_ADD_CONST              any_CPP11_90
+#define any_HAVE_OVERRIDE               any_CPP11_90
 #define any_HAVE_REMOVE_REFERENCE       any_CPP11_90
 
 #define any_HAVE_TR1_ADD_CONST          (!! any_COMPILER_GNUC_VERSION )
@@ -295,6 +313,12 @@
 # define any_nodiscard /*[[nodiscard]]*/
 #endif
 
+#if any_HAVE_OVERRIDE
+# define any_override override
+#else
+# define any_override /*override*/
+#endif
+
 // additional includes:
 
 #if any_CONFIG_NO_EXCEPTIONS
@@ -390,7 +414,7 @@
 {
 public:
 #if any_CPP11_OR_GREATER
-    virtual const char* what() const any_noexcept
+    virtual const char* what() const any_noexcept any_override
 #else
     virtual const char* what() const throw()
 #endif
@@ -476,7 +500,7 @@
         class ValueType, class T = typename std::decay<ValueType>::type
         any_REQUIRES_T( ! std::is_same<T, any>::value )
     >
-    any & operator=( ValueType && value )
+    any & operator=( T && value )
     {
         any( std::move( value ) ).swap( *this );
         return *this;
@@ -571,12 +595,12 @@
         {}
 #endif
 
-        virtual std::type_info const & type() const
+        virtual std::type_info const & type() const any_override
         {
             return typeid( ValueType );
         }
 
-        virtual placeholder * clone() const
+        virtual placeholder * clone() const any_override
         {
             return new holder( held );
         }
diff --git a/ndn-cxx/detail/nonstd/optional-lite.hpp b/ndn-cxx/detail/nonstd/optional-lite.hpp
index 133673a..b4fde93 100644
--- a/ndn-cxx/detail/nonstd/optional-lite.hpp
+++ b/ndn-cxx/detail/nonstd/optional-lite.hpp
@@ -12,7 +12,7 @@
 #define NONSTD_OPTIONAL_LITE_HPP
 
 #define optional_lite_MAJOR  3
-#define optional_lite_MINOR  2
+#define optional_lite_MINOR  4
 #define optional_lite_PATCH  0
 
 #define optional_lite_VERSION  optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
@@ -26,6 +26,20 @@
 #define optional_OPTIONAL_NONSTD   1
 #define optional_OPTIONAL_STD      2
 
+// tweak header support:
+
+#ifdef __has_include
+# if __has_include(<nonstd/optional.tweak.hpp>)
+#  include <nonstd/optional.tweak.hpp>
+# endif
+#define optional_HAVE_TWEAK_HEADER  1
+#else
+#define optional_HAVE_TWEAK_HEADER  0
+//# pragma message("optional.hpp: Note: Tweak header not supported.")
+#endif
+
+// optional selection and configuration:
+
 #if !defined( optional_CONFIG_SELECT_OPTIONAL )
 # define optional_CONFIG_SELECT_OPTIONAL  ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
 #endif
@@ -33,7 +47,10 @@
 // Control presence of exception handling (try and auto discover):
 
 #ifndef optional_CONFIG_NO_EXCEPTIONS
-# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
+# if _MSC_VER
+# include <cstddef>     // for _HAS_EXCEPTIONS
+# endif
+# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
 #  define optional_CONFIG_NO_EXCEPTIONS  0
 # else
 #  define optional_CONFIG_NO_EXCEPTIONS  1
@@ -293,18 +310,29 @@
 #define optional_CPP11_140  (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
 #define optional_CPP11_141  (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
 
-#define optional_CPP11_140_490  ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || (optional_COMPILER_MSVC_VER >= 1910))
-
 #define optional_CPP14_000  (optional_CPP14_OR_GREATER)
 #define optional_CPP17_000  (optional_CPP17_OR_GREATER)
 
+// clang >= 2.9, gcc >= 4.9, msvc >= vc14.0/1900 (vs15):
+#define optional_CPP11_140_C290_G490    ((optional_CPP11_OR_GREATER_ && (optional_COMPILER_CLANG_VERSION >= 290 || optional_COMPILER_GNUC_VERSION >= 490)) || (optional_COMPILER_MSVC_VER >= 1900))
+
+// clang >= 3.5, msvc >= vc11 (vs12):
+#define optional_CPP11_110_C350         ( optional_CPP11_110 && !optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) )
+
+// clang >= 3.5, gcc >= 5.0, msvc >= vc11 (vs12):
+#define optional_CPP11_110_C350_G500 \
+    (  optional_CPP11_110 && \
+    !( optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) \
+    || optional_BETWEEN( optional_COMPILER_GNUC_VERSION , 1, 500 ) ) )
+
 // 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_490
+#define optional_HAVE_REF_QUALIFIER     optional_CPP11_140_C290_G490
+#define optional_HAVE_STATIC_ASSERT     optional_CPP11_110
 #define optional_HAVE_INITIALIZER_LIST  optional_CPP11_140
 
 // Presence of C++14 language features:
@@ -324,6 +352,13 @@
 #define optional_HAVE_TR1_TYPE_TRAITS   (!! optional_COMPILER_GNUC_VERSION )
 #define optional_HAVE_TR1_ADD_POINTER   (!! optional_COMPILER_GNUC_VERSION )
 
+#define optional_HAVE_IS_ASSIGNABLE                     optional_CPP11_110_C350
+#define optional_HAVE_IS_MOVE_CONSTRUCTIBLE             optional_CPP11_110_C350
+#define optional_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE        optional_CPP11_110_C350
+#define optional_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE     optional_CPP11_110_C350
+#define optional_HAVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE   optional_CPP11_110_C350_G500
+#define optional_HAVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE   optional_CPP11_110_C350_G500
+
 // C++ feature usage:
 
 #if optional_HAVE( CONSTEXPR_11 )
@@ -371,6 +406,12 @@
 # define optional_refref_qual  /*&&*/
 #endif
 
+#if optional_HAVE( STATIC_ASSERT )
+# define optional_static_assert(expr, text)    static_assert(expr, text);
+#else
+# define optional_static_assert(expr, text)  /*static_assert(expr, text);*/
+#endif
+
 // additional includes:
 
 #if optional_CONFIG_NO_EXCEPTIONS
@@ -419,6 +460,12 @@
 
 namespace std11 {
 
+template< class T, T v > struct integral_constant { enum { value = v }; };
+template< bool B       > struct bool_constant : integral_constant<bool, B>{};
+
+typedef bool_constant< true  > true_type;
+typedef bool_constant< false > false_type;
+
 #if optional_CPP11_OR_GREATER
     using std::move;
 #else
@@ -432,16 +479,42 @@
     template<         typename T, typename F > struct conditional<false, T, F> { typedef F type; };
 #endif // optional_HAVE_CONDITIONAL
 
-// gcc < 5:
-#if optional_CPP11_OR_GREATER
-#if optional_BETWEEN( optional_COMPILER_GNUC_VERSION, 1, 500 )
-    template< typename T > struct is_trivially_copy_constructible : std::true_type{};
-    template< typename T > struct is_trivially_move_constructible : std::true_type{};
+#if optional_HAVE( IS_ASSIGNABLE )
+    using std::is_assignable;
 #else
+    template< class T, class U > struct is_assignable : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_MOVE_CONSTRUCTIBLE )
+    using std::is_move_constructible;
+#else
+    template< class T > struct is_move_constructible : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE )
+    using std::is_nothrow_move_assignable;
+#else
+    template< class T > struct is_nothrow_move_assignable : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE )
+    using std::is_nothrow_move_constructible;
+#else
+    template< class T > struct is_nothrow_move_constructible : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_TRIVIALLY_COPY_CONSTRUCTIBLE )
     using std::is_trivially_copy_constructible;
+#else
+    template< class T > struct is_trivially_copy_constructible : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_TRIVIALLY_MOVE_CONSTRUCTIBLE )
     using std::is_trivially_move_constructible;
+#else
+    template< class T > struct is_trivially_move_constructible : std11::true_type{};
 #endif
-#endif
+
 } // namespace std11
 
 #if optional_CPP11_OR_GREATER
@@ -464,10 +537,10 @@
 struct is_swappable
 {
     template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
-    static std::true_type test( int /*unused*/ );
+    static std11::true_type test( int /*unused*/ );
 
     template< typename >
-    static std::false_type test(...);
+    static std11::false_type test(...);
 };
 
 struct is_nothrow_swappable
@@ -481,10 +554,10 @@
     }
 
     template< typename T >
-    static auto test( int /*unused*/ ) -> std::integral_constant<bool, satisfies<T>()>{}
+    static auto test( int /*unused*/ ) -> std11::integral_constant<bool, satisfies<T>()>{}
 
     template< typename >
-    static auto test(...) -> std::false_type;
+    static auto test(...) -> std11::false_type;
 };
 
 } // namespace detail
@@ -713,6 +786,12 @@
     }
 
     template< class... Args >
+    storage_t( nonstd_lite_in_place_t(T), Args&&... args )
+    {
+        emplace( std::forward<Args>(args)... );
+    }
+
+    template< class... Args >
     void emplace( Args&&... args )
     {
         ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
@@ -845,6 +924,15 @@
 template< typename T>
 class optional
 {
+    optional_static_assert(( !std::is_same<typename std::remove_cv<T>::type, nullopt_t>::value  ),
+        "T in optional<T> must not be of type 'nullopt_t'.")
+
+    optional_static_assert(( !std::is_same<typename std::remove_cv<T>::type, in_place_t>::value ),
+        "T in optional<T> must not be of type 'in_place_t'.")
+
+    optional_static_assert(( std::is_object<T>::value && std::is_destructible<T>::value && !std::is_array<T>::value ),
+        "T in optional<T> must meet the Cpp17Destructible requirements.")
+
 private:
     template< typename > friend class optional;
 
@@ -853,7 +941,7 @@
 public:
     typedef T value_type;
 
-    // x.x.3.1, constructors
+     // x.x.3.1, constructors
 
     // 1a - default construct
     optional_constexpr optional() optional_noexcept
@@ -891,13 +979,13 @@
     // 3 (C++11) - move-construct from optional
     template< typename U = T
         optional_REQUIRES_T(
-            std::is_move_constructible<U>::value
+            std11::is_move_constructible<U>::value
             || std11::is_trivially_move_constructible<U>::value
         )
     >
     optional_constexpr14 optional( optional && other )
     // NOLINTNEXTLINE( performance-noexcept-move-constructor )
-        noexcept( std::is_nothrow_move_constructible<T>::value )
+        noexcept( std11::is_nothrow_move_constructible<T>::value )
     : has_value_( other.has_value() )
     {
         if ( other.has_value() )
@@ -1043,7 +1131,7 @@
     >
     optional_constexpr explicit optional( U && value )
     : has_value_( true )
-    , contained( T{ std::forward<U>( value ) } )
+    , contained( nonstd_lite_in_place(T), std::forward<U>( value ) )
     {}
 
     // 8b (C++11) - non-explicit move construct from value
@@ -1058,7 +1146,7 @@
     // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
     optional_constexpr /*non-explicit*/ optional( U && value )
     : has_value_( true )
-    , contained( std::forward<U>( value ) )
+    , contained( nonstd_lite_in_place(T), std::forward<U>( value ) )
     {}
 
 #else // optional_CPP11_OR_GREATER
@@ -1101,8 +1189,8 @@
     )
     operator=( optional const & other )
         noexcept(
-            std::is_nothrow_move_assignable<T>::value
-            && std::is_nothrow_move_constructible<T>::value
+            std11::is_nothrow_move_assignable<T>::value
+            && std11::is_nothrow_move_constructible<T>::value
         )
 #else
     optional & operator=( optional const & other )
@@ -1121,7 +1209,7 @@
     optional_REQUIRES_R(
         optional &,
         true
-//      std::is_move_constructible<T>::value
+//      std11::is_move_constructible<T>::value
 //      && std::is_move_assignable<T>::value
     )
     operator=( optional && other ) noexcept
@@ -1138,7 +1226,7 @@
         optional_REQUIRES_R(
             optional &,
             std::is_constructible<T , U>::value
-            && std::is_assignable<T&, U>::value
+            && std11::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)
@@ -1176,7 +1264,7 @@
         optional_REQUIRES_R(
             optional&,
             std::is_constructible<  T , U const &>::value
-            &&  std::is_assignable< T&, U const &>::value
+            &&  std11::is_assignable< T&, U const &>::value
             && !std::is_constructible<T, optional<U> &          >::value
             && !std::is_constructible<T, optional<U> &&         >::value
             && !std::is_constructible<T, optional<U> const &    >::value
@@ -1185,10 +1273,10 @@
             && !std::is_convertible<     optional<U> &&      , T>::value
             && !std::is_convertible<     optional<U> const & , T>::value
             && !std::is_convertible<     optional<U> const &&, T>::value
-            && !std::is_assignable<  T&, optional<U> &          >::value
-            && !std::is_assignable<  T&, optional<U> &&         >::value
-            && !std::is_assignable<  T&, optional<U> const &    >::value
-            && !std::is_assignable<  T&, optional<U> const &&   >::value
+            && !std11::is_assignable<  T&, optional<U> &          >::value
+            && !std11::is_assignable<  T&, optional<U> &&         >::value
+            && !std11::is_assignable<  T&, optional<U> const &    >::value
+            && !std11::is_assignable<  T&, optional<U> const &&   >::value
         )
 #else
     optional&
@@ -1206,7 +1294,7 @@
         optional_REQUIRES_R(
             optional&,
             std::is_constructible<  T , U>::value
-            &&  std::is_assignable< T&, U>::value
+            &&  std11::is_assignable< 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
@@ -1215,10 +1303,10 @@
             && !std::is_convertible<     optional<U> &&      , T>::value
             && !std::is_convertible<     optional<U> const & , T>::value
             && !std::is_convertible<     optional<U> const &&, T>::value
-            && !std::is_assignable<  T&, optional<U> &          >::value
-            && !std::is_assignable<  T&, optional<U> &&         >::value
-            && !std::is_assignable<  T&, optional<U> const &    >::value
-            && !std::is_assignable<  T&, optional<U> const &&   >::value
+            && !std11::is_assignable<  T&, optional<U> &          >::value
+            && !std11::is_assignable<  T&, optional<U> &&         >::value
+            && !std11::is_assignable<  T&, optional<U> const &    >::value
+            && !std11::is_assignable<  T&, optional<U> const &&   >::value
         )
     operator=( optional<U> && other )
     {
@@ -1260,7 +1348,7 @@
     void swap( optional & other )
 #if optional_CPP11_OR_GREATER
         noexcept(
-            std::is_nothrow_move_constructible<T>::value
+            std11::is_nothrow_move_constructible<T>::value
             && std17::is_nothrow_swappable<T>::value
         )
 #endif
@@ -1371,7 +1459,7 @@
 
 #endif
 
-#if optional_CPP11_OR_GREATER
+#if optional_HAVE( REF_QUALIFIER )
 
     template< typename U >
     optional_constexpr value_type value_or( U && v ) const optional_ref_qual
@@ -1382,7 +1470,11 @@
     template< typename U >
     optional_constexpr14 value_type value_or( U && v ) optional_refref_qual
     {
+#if optional_COMPILER_CLANG_VERSION
+        return has_value() ? /*std::move*/( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
+#else
         return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
+#endif
     }
 
 #else
@@ -1626,7 +1718,7 @@
 template< typename T
 #if optional_CPP11_OR_GREATER
     optional_REQUIRES_T(
-        std::is_move_constructible<T>::value
+        std11::is_move_constructible<T>::value
         && std17::is_swappable<T>::value )
 #endif
 >
diff --git a/ndn-cxx/detail/nonstd/scope-lite.hpp b/ndn-cxx/detail/nonstd/scope-lite.hpp
index 8a4c346..03699d3 100644
--- a/ndn-cxx/detail/nonstd/scope-lite.hpp
+++ b/ndn-cxx/detail/nonstd/scope-lite.hpp
@@ -331,7 +331,7 @@
 namespace nonstd {
 namespace scope {
 
-// for bit_ENABLE_IF_():
+// for scope_ENABLE_IF_():
 
 /*enum*/ class enabler{};
 
@@ -894,18 +894,19 @@
         , execute_on_reset( execute )
     {}
 
-    // TODO:Move constructor.
+    // Move constructor.
+    //
     // The stored resource handle is initialized from the one of other, using std::move if
     // std::is_nothrow_move_constructible_v<RS> is true.
-
+    //
     // If initialization of the stored resource handle throws an exception, other is not modified.
-
+    //
     // Then, the deleter is initialized with the one of other, using std::move if
     // std::is_nothrow_move_constructible_v<D> is true.
-
+    //
     // If initialization of the deleter throws an exception and std::is_nothrow_move_constructible_v<RS> is true and
     // other owns the resource, calls the deleter of other with res_ to dispose the resource, then calls other.release().
-
+    //
     // After construction, the constructed unique_resource owns its resource if and only if other owned the resource before
     // the construction, and other is set to not own the resource.
 
@@ -920,7 +921,7 @@
     {}
     catch(...)
     {
-        if ( other.execute_on_reset && std::is_nothrow_move_constructible<R>::value )
+        if ( other.execute_on_reset && std11::is_nothrow_move_constructible<R>::value )
         {
             other.get_deleter()( this->get() );
             other.release();
diff --git a/ndn-cxx/detail/nonstd/variant-lite.hpp b/ndn-cxx/detail/nonstd/variant-lite.hpp
index 86a1d21..05a8cd9 100644
--- a/ndn-cxx/detail/nonstd/variant-lite.hpp
+++ b/ndn-cxx/detail/nonstd/variant-lite.hpp
@@ -10,9 +10,9 @@
 #ifndef NONSTD_VARIANT_LITE_HPP
 #define NONSTD_VARIANT_LITE_HPP
 
-#define variant_lite_MAJOR  1
-#define variant_lite_MINOR  2
-#define variant_lite_PATCH  2
+#define variant_lite_MAJOR  2
+#define variant_lite_MINOR  0
+#define variant_lite_PATCH  0
 
 #define variant_lite_VERSION  variant_STRINGIFY(variant_lite_MAJOR) "." variant_STRINGIFY(variant_lite_MINOR) "." variant_STRINGIFY(variant_lite_PATCH)
 
@@ -25,10 +25,20 @@
 #define variant_VARIANT_NONSTD   1
 #define variant_VARIANT_STD      2
 
-#if !defined( variant_CONFIG_SELECT_VARIANT )
-# define variant_CONFIG_SELECT_VARIANT  ( variant_HAVE_STD_VARIANT ? variant_VARIANT_STD : variant_VARIANT_NONSTD )
+// tweak header support:
+
+#ifdef __has_include
+# if __has_include(<nonstd/variant.tweak.hpp>)
+#  include <nonstd/variant.tweak.hpp>
+# endif
+#define variant_HAVE_TWEAK_HEADER  1
+#else
+#define variant_HAVE_TWEAK_HEADER  0
+//# pragma message("variant.hpp: Note: Tweak header not supported.")
 #endif
 
+// variant selection and configuration:
+
 #ifndef  variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
 # define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO  0
 #endif
@@ -40,7 +50,10 @@
 // Control presence of exception handling (try and auto discover):
 
 #ifndef variant_CONFIG_NO_EXCEPTIONS
-# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
+# if _MSC_VER
+#  include <cstddef>    // for _HAS_EXCEPTIONS
+# endif
+# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
 #  define variant_CONFIG_NO_EXCEPTIONS  0
 # else
 #  define variant_CONFIG_NO_EXCEPTIONS  1
@@ -77,6 +90,10 @@
 # define  variant_HAVE_STD_VARIANT  0
 #endif
 
+#if !defined( variant_CONFIG_SELECT_VARIANT )
+# define variant_CONFIG_SELECT_VARIANT  ( variant_HAVE_STD_VARIANT ? variant_VARIANT_STD : variant_VARIANT_NONSTD )
+#endif
+
 #define  variant_USES_STD_VARIANT  ( (variant_CONFIG_SELECT_VARIANT == variant_VARIANT_STD) || ((variant_CONFIG_SELECT_VARIANT == variant_VARIANT_DEFAULT) && variant_HAVE_STD_VARIANT) )
 
 //
@@ -167,6 +184,25 @@
 #endif // variant_CPP17_OR_GREATER
 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
 
+// in_place_index-like disambiguation tag identical for all C++ versions:
+
+namespace nonstd {
+namespace variants {
+namespace detail {
+
+template< std::size_t K >
+struct index_tag_t {};
+
+template< std::size_t K >
+inline void index_tag ( index_tag_t<K> = index_tag_t<K>() ) { }
+
+#define variant_index_tag_t(K)  void(&)( nonstd::variants::detail::index_tag_t<K> )
+#define variant_index_tag(K)    nonstd::variants::detail::index_tag<K>
+
+} // namespace detail
+} // namespace variants
+} // namespace nonstd
+
 //
 // Use C++17 std::variant:
 //
@@ -335,6 +371,8 @@
 #define variant_HAVE_REMOVE_CV          variant_CPP11_120
 #define variant_HAVE_STD_ADD_POINTER    variant_CPP11_90
 #define variant_HAVE_TYPE_TRAITS        variant_CPP11_90
+#define variant_HAVE_ENABLE_IF          variant_CPP11_90
+#define variant_HAVE_IS_SAME            variant_CPP11_90
 
 #define variant_HAVE_TR1_TYPE_TRAITS    (!! variant_COMPILER_GNUC_VERSION )
 #define variant_HAVE_TR1_ADD_POINTER    (!! variant_COMPILER_GNUC_VERSION )
@@ -387,24 +425,6 @@
 # include <tr1/type_traits>
 #endif
 
-// Method enabling
-
-#if variant_CPP11_OR_GREATER
-
-#define variant_REQUIRES_0(...) \
-    template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
-
-#define variant_REQUIRES_T(...) \
-    , typename std::enable_if< (__VA_ARGS__), int >::type = 0
-
-#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
-
 //
 // variant:
 //
@@ -472,8 +492,61 @@
 
 #endif // variant_HAVE_CONDITIONAL
 
+#if variant_HAVE_ENABLE_IF
+
+using std::enable_if;
+
+#else
+
+template< bool B, class T = void >
+struct enable_if { };
+
+template< class T >
+struct enable_if< true, T > { typedef T type; };
+
+#endif // variant_HAVE_ENABLE_IF
+
+#if variant_HAVE_IS_SAME
+
+using std::is_same;
+
+#else
+
+template< class T, class U >
+struct is_same {
+    enum V { value = 0 } ;
+};
+
+template< class T >
+struct is_same< T, T > {
+    enum V { value = 1 } ;
+};
+
+#endif // variant_HAVE_IS_SAME
+
 } // namespace std11
 
+// Method enabling
+
+#if variant_CPP11_OR_GREATER
+
+#define variant_REQUIRES_T(...) \
+    , typename std::enable_if< (__VA_ARGS__), int >::type = 0
+
+#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 // variant_CPP11_OR_GREATER
+
+#define variant_REQUIRES_0(...) \
+    template< bool B = (__VA_ARGS__), typename std11::enable_if<B, int>::type = 0 >
+
+#define variant_REQUIRES_B(...) \
+    , bool B = (__VA_ARGS__), typename std11::enable_if<B, int>::type = 0
+
 /// type traits C++17:
 
 namespace std17 {
@@ -696,7 +769,7 @@
 template< class Head, class Tail >
 struct typelist_size< typelist<Head, Tail> >
 {
-    enum V { value = typelist_size<Head>::value + typelist_size<Tail>::value };
+    enum V { value = size_t(typelist_size<Head>::value) + size_t(typelist_size<Tail>::value) };
 };
 
 // typelist index of type:
@@ -743,6 +816,31 @@
     typedef typename typelist_type_at<Tail, i - 1>::type type;
 };
 
+// typelist type is unique:
+
+template< class List, std::size_t CmpIndex, std::size_t LastChecked = typelist_size<List>::value >
+struct typelist_type_is_unique
+{
+private:
+    typedef typename typelist_type_at<List, CmpIndex>::type cmp_type;
+    typedef typename typelist_type_at<List, LastChecked - 1>::type cur_type;
+
+public:
+    enum V { value = ((CmpIndex == (LastChecked - 1)) | !std11::is_same<cmp_type, cur_type>::value)
+        && typelist_type_is_unique<List, CmpIndex, LastChecked - 1>::value } ;
+};
+
+template< class List, std::size_t CmpIndex >
+struct typelist_type_is_unique< List, CmpIndex, 0 >
+{
+    enum V { value = 1 } ;
+};
+
+template< class List, class T >
+struct typelist_contains_unique_type : typelist_type_is_unique< List, typelist_index_of< List, T >::value >
+{
+};
+
 #if variant_CONFIG_MAX_ALIGN_HACK
 
 // Max align, use most restricted type for alignment:
@@ -963,7 +1061,7 @@
         case 13: as<T13>( data )->~T13(); break;
         case 14: as<T14>( data )->~T14(); break;
         case 15: as<T15>( data )->~T15(); break;
-        
+
         }
     }
 
@@ -1006,7 +1104,7 @@
         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;
     }
@@ -1031,7 +1129,7 @@
         case 13: *as<T13>( to_value ) = std::move( *as<T13>( from_value ) ); break;
         case 14: *as<T14>( to_value ) = std::move( *as<T14>( from_value ) ); break;
         case 15: *as<T15>( to_value ) = std::move( *as<T15>( from_value ) ); break;
-        
+
         }
         return from_index;
     }
@@ -1057,7 +1155,7 @@
         case 13: new( to_value ) T13( *as<T13>( from_value ) ); break;
         case 14: new( to_value ) T14( *as<T14>( from_value ) ); break;
         case 15: new( to_value ) T15( *as<T15>( from_value ) ); break;
-        
+
         }
         return from_index;
     }
@@ -1082,7 +1180,7 @@
         case 13: *as<T13>( to_value ) = *as<T13>( from_value ); break;
         case 14: *as<T14>( to_value ) = *as<T14>( from_value ); break;
         case 15: *as<T15>( to_value ) = *as<T15>( from_value ); break;
-        
+
         }
         return from_index;
     }
@@ -1209,9 +1307,76 @@
 
 public:
     // 19.7.3.1 Constructors
-    
+
     variant() : type_index( 0 ) { new( ptr() ) T0(); }
 
+#if variant_CPP11_OR_GREATER
+    template < variant_index_tag_t( 0 ) = variant_index_tag( 0 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 0 >::value) >
+    variant( T0 const & t0 ) : type_index( 0 ) { new( ptr() ) T0( t0 ); }
+
+    template < variant_index_tag_t( 1 ) = variant_index_tag( 1 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 1 >::value) >
+    variant( T1 const & t1 ) : type_index( 1 ) { new( ptr() ) T1( t1 ); }
+
+    template < variant_index_tag_t( 2 ) = variant_index_tag( 2 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 2 >::value) >
+    variant( T2 const & t2 ) : type_index( 2 ) { new( ptr() ) T2( t2 ); }
+
+    template < variant_index_tag_t( 3 ) = variant_index_tag( 3 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 3 >::value) >
+    variant( T3 const & t3 ) : type_index( 3 ) { new( ptr() ) T3( t3 ); }
+
+    template < variant_index_tag_t( 4 ) = variant_index_tag( 4 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 4 >::value) >
+    variant( T4 const & t4 ) : type_index( 4 ) { new( ptr() ) T4( t4 ); }
+
+    template < variant_index_tag_t( 5 ) = variant_index_tag( 5 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 5 >::value) >
+    variant( T5 const & t5 ) : type_index( 5 ) { new( ptr() ) T5( t5 ); }
+
+    template < variant_index_tag_t( 6 ) = variant_index_tag( 6 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 6 >::value) >
+    variant( T6 const & t6 ) : type_index( 6 ) { new( ptr() ) T6( t6 ); }
+
+    template < variant_index_tag_t( 7 ) = variant_index_tag( 7 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 7 >::value) >
+    variant( T7 const & t7 ) : type_index( 7 ) { new( ptr() ) T7( t7 ); }
+
+    template < variant_index_tag_t( 8 ) = variant_index_tag( 8 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 8 >::value) >
+    variant( T8 const & t8 ) : type_index( 8 ) { new( ptr() ) T8( t8 ); }
+
+    template < variant_index_tag_t( 9 ) = variant_index_tag( 9 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 9 >::value) >
+    variant( T9 const & t9 ) : type_index( 9 ) { new( ptr() ) T9( t9 ); }
+
+    template < variant_index_tag_t( 10 ) = variant_index_tag( 10 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 10 >::value) >
+    variant( T10 const & t10 ) : type_index( 10 ) { new( ptr() ) T10( t10 ); }
+
+    template < variant_index_tag_t( 11 ) = variant_index_tag( 11 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 11 >::value) >
+    variant( T11 const & t11 ) : type_index( 11 ) { new( ptr() ) T11( t11 ); }
+
+    template < variant_index_tag_t( 12 ) = variant_index_tag( 12 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 12 >::value) >
+    variant( T12 const & t12 ) : type_index( 12 ) { new( ptr() ) T12( t12 ); }
+
+    template < variant_index_tag_t( 13 ) = variant_index_tag( 13 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 13 >::value) >
+    variant( T13 const & t13 ) : type_index( 13 ) { new( ptr() ) T13( t13 ); }
+
+    template < variant_index_tag_t( 14 ) = variant_index_tag( 14 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 14 >::value) >
+    variant( T14 const & t14 ) : type_index( 14 ) { new( ptr() ) T14( t14 ); }
+
+    template < variant_index_tag_t( 15 ) = variant_index_tag( 15 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 15 >::value) >
+    variant( T15 const & t15 ) : type_index( 15 ) { new( ptr() ) T15( t15 ); }
+
+#else
+
     variant( T0 const & t0 ) : type_index( 0 ) { new( ptr() ) T0( t0 ); }
     variant( T1 const & t1 ) : type_index( 1 ) { new( ptr() ) T1( t1 ); }
     variant( T2 const & t2 ) : type_index( 2 ) { new( ptr() ) T2( t2 ); }
@@ -1228,26 +1393,89 @@
     variant( T13 const & t13 ) : type_index( 13 ) { new( ptr() ) T13( t13 ); }
     variant( T14 const & t14 ) : type_index( 14 ) { new( ptr() ) T14( t14 ); }
     variant( T15 const & t15 ) : type_index( 15 ) { new( ptr() ) T15( t15 ); }
-    
+
+#endif
 
 #if variant_CPP11_OR_GREATER
-    variant( T0 && t0 ) : type_index( 0 ) { new( ptr() ) T0( std::move(t0) ); }
-    variant( T1 && t1 ) : type_index( 1 ) { new( ptr() ) T1( std::move(t1) ); }
-    variant( T2 && t2 ) : type_index( 2 ) { new( ptr() ) T2( std::move(t2) ); }
-    variant( T3 && t3 ) : type_index( 3 ) { new( ptr() ) T3( std::move(t3) ); }
-    variant( T4 && t4 ) : type_index( 4 ) { new( ptr() ) T4( std::move(t4) ); }
-    variant( T5 && t5 ) : type_index( 5 ) { new( ptr() ) T5( std::move(t5) ); }
-    variant( T6 && t6 ) : type_index( 6 ) { new( ptr() ) T6( std::move(t6) ); }
-    variant( T7 && t7 ) : type_index( 7 ) { new( ptr() ) T7( std::move(t7) ); }
-    variant( T8 && t8 ) : type_index( 8 ) { new( ptr() ) T8( std::move(t8) ); }
-    variant( T9 && t9 ) : type_index( 9 ) { new( ptr() ) T9( std::move(t9) ); }
-    variant( T10 && t10 ) : type_index( 10 ) { new( ptr() ) T10( std::move(t10) ); }
-    variant( T11 && t11 ) : type_index( 11 ) { new( ptr() ) T11( std::move(t11) ); }
-    variant( T12 && t12 ) : type_index( 12 ) { new( ptr() ) T12( std::move(t12) ); }
-    variant( T13 && t13 ) : type_index( 13 ) { new( ptr() ) T13( std::move(t13) ); }
-    variant( T14 && t14 ) : type_index( 14 ) { new( ptr() ) T14( std::move(t14) ); }
-    variant( T15 && t15 ) : type_index( 15 ) { new( ptr() ) T15( std::move(t15) ); }
-    
+    template < variant_index_tag_t( 0 ) = variant_index_tag( 0 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 0 >::value) >
+    variant( T0 && t0 )
+        : type_index( 0 ) { new( ptr() ) T0( std::move(t0) ); }
+
+    template < variant_index_tag_t( 1 ) = variant_index_tag( 1 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 1 >::value) >
+    variant( T1 && t1 )
+        : type_index( 1 ) { new( ptr() ) T1( std::move(t1) ); }
+
+    template < variant_index_tag_t( 2 ) = variant_index_tag( 2 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 2 >::value) >
+    variant( T2 && t2 )
+        : type_index( 2 ) { new( ptr() ) T2( std::move(t2) ); }
+
+    template < variant_index_tag_t( 3 ) = variant_index_tag( 3 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 3 >::value) >
+    variant( T3 && t3 )
+        : type_index( 3 ) { new( ptr() ) T3( std::move(t3) ); }
+
+    template < variant_index_tag_t( 4 ) = variant_index_tag( 4 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 4 >::value) >
+    variant( T4 && t4 )
+        : type_index( 4 ) { new( ptr() ) T4( std::move(t4) ); }
+
+    template < variant_index_tag_t( 5 ) = variant_index_tag( 5 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 5 >::value) >
+    variant( T5 && t5 )
+        : type_index( 5 ) { new( ptr() ) T5( std::move(t5) ); }
+
+    template < variant_index_tag_t( 6 ) = variant_index_tag( 6 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 6 >::value) >
+    variant( T6 && t6 )
+        : type_index( 6 ) { new( ptr() ) T6( std::move(t6) ); }
+
+    template < variant_index_tag_t( 7 ) = variant_index_tag( 7 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 7 >::value) >
+    variant( T7 && t7 )
+        : type_index( 7 ) { new( ptr() ) T7( std::move(t7) ); }
+
+    template < variant_index_tag_t( 8 ) = variant_index_tag( 8 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 8 >::value) >
+    variant( T8 && t8 )
+        : type_index( 8 ) { new( ptr() ) T8( std::move(t8) ); }
+
+    template < variant_index_tag_t( 9 ) = variant_index_tag( 9 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 9 >::value) >
+    variant( T9 && t9 )
+        : type_index( 9 ) { new( ptr() ) T9( std::move(t9) ); }
+
+    template < variant_index_tag_t( 10 ) = variant_index_tag( 10 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 10 >::value) >
+    variant( T10 && t10 )
+        : type_index( 10 ) { new( ptr() ) T10( std::move(t10) ); }
+
+    template < variant_index_tag_t( 11 ) = variant_index_tag( 11 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 11 >::value) >
+    variant( T11 && t11 )
+        : type_index( 11 ) { new( ptr() ) T11( std::move(t11) ); }
+
+    template < variant_index_tag_t( 12 ) = variant_index_tag( 12 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 12 >::value) >
+    variant( T12 && t12 )
+        : type_index( 12 ) { new( ptr() ) T12( std::move(t12) ); }
+
+    template < variant_index_tag_t( 13 ) = variant_index_tag( 13 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 13 >::value) >
+    variant( T13 && t13 )
+        : type_index( 13 ) { new( ptr() ) T13( std::move(t13) ); }
+
+    template < variant_index_tag_t( 14 ) = variant_index_tag( 14 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 14 >::value) >
+    variant( T14 && t14 )
+        : type_index( 14 ) { new( ptr() ) T14( std::move(t14) ); }
+
+    template < variant_index_tag_t( 15 ) = variant_index_tag( 15 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 15 >::value) >
+    variant( T15 && t15 )
+        : type_index( 15 ) { new( ptr() ) T15( std::move(t15) ); }
 #endif
 
     variant(variant const & other)
@@ -1322,7 +1550,7 @@
 #endif // variant_CPP11_OR_GREATER
 
     // 19.7.3.2 Destructor
-    
+
     ~variant()
     {
         if ( ! valueless_by_exception() )
@@ -1332,7 +1560,7 @@
     }
 
     // 19.7.3.3 Assignment
-    
+
     variant & operator=( variant const & other )
     {
         return copy_assign( other );
@@ -1361,26 +1589,140 @@
         return move_assign( std::move( other ) );
     }
 
+    template < variant_index_tag_t( 0 ) = variant_index_tag( 0 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 0 >::value) >
     variant & operator=( T0 &&      t0 ) { return assign_value<0>( std::move( t0 ) ); }
+
+    template < variant_index_tag_t( 1 ) = variant_index_tag( 1 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 1 >::value) >
     variant & operator=( T1 &&      t1 ) { return assign_value<1>( std::move( t1 ) ); }
+
+    template < variant_index_tag_t( 2 ) = variant_index_tag( 2 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 2 >::value) >
     variant & operator=( T2 &&      t2 ) { return assign_value<2>( std::move( t2 ) ); }
+
+    template < variant_index_tag_t( 3 ) = variant_index_tag( 3 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 3 >::value) >
     variant & operator=( T3 &&      t3 ) { return assign_value<3>( std::move( t3 ) ); }
+
+    template < variant_index_tag_t( 4 ) = variant_index_tag( 4 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 4 >::value) >
     variant & operator=( T4 &&      t4 ) { return assign_value<4>( std::move( t4 ) ); }
+
+    template < variant_index_tag_t( 5 ) = variant_index_tag( 5 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 5 >::value) >
     variant & operator=( T5 &&      t5 ) { return assign_value<5>( std::move( t5 ) ); }
+
+    template < variant_index_tag_t( 6 ) = variant_index_tag( 6 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 6 >::value) >
     variant & operator=( T6 &&      t6 ) { return assign_value<6>( std::move( t6 ) ); }
+
+    template < variant_index_tag_t( 7 ) = variant_index_tag( 7 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 7 >::value) >
     variant & operator=( T7 &&      t7 ) { return assign_value<7>( std::move( t7 ) ); }
+
+    template < variant_index_tag_t( 8 ) = variant_index_tag( 8 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 8 >::value) >
     variant & operator=( T8 &&      t8 ) { return assign_value<8>( std::move( t8 ) ); }
+
+    template < variant_index_tag_t( 9 ) = variant_index_tag( 9 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 9 >::value) >
     variant & operator=( T9 &&      t9 ) { return assign_value<9>( std::move( t9 ) ); }
+
+    template < variant_index_tag_t( 10 ) = variant_index_tag( 10 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 10 >::value) >
     variant & operator=( T10 &&      t10 ) { return assign_value<10>( std::move( t10 ) ); }
+
+    template < variant_index_tag_t( 11 ) = variant_index_tag( 11 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 11 >::value) >
     variant & operator=( T11 &&      t11 ) { return assign_value<11>( std::move( t11 ) ); }
+
+    template < variant_index_tag_t( 12 ) = variant_index_tag( 12 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 12 >::value) >
     variant & operator=( T12 &&      t12 ) { return assign_value<12>( std::move( t12 ) ); }
+
+    template < variant_index_tag_t( 13 ) = variant_index_tag( 13 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 13 >::value) >
     variant & operator=( T13 &&      t13 ) { return assign_value<13>( std::move( t13 ) ); }
+
+    template < variant_index_tag_t( 14 ) = variant_index_tag( 14 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 14 >::value) >
     variant & operator=( T14 &&      t14 ) { return assign_value<14>( std::move( t14 ) ); }
+
+    template < variant_index_tag_t( 15 ) = variant_index_tag( 15 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 15 >::value) >
     variant & operator=( T15 &&      t15 ) { return assign_value<15>( std::move( t15 ) ); }
-    
 
 #endif
 
+#if variant_CPP11_OR_GREATER
+
+    template < variant_index_tag_t( 0 ) = variant_index_tag( 0 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 0 >::value) >
+    variant & operator=( T0 const & t0 ) { return assign_value<0>( t0 ); }
+
+    template < variant_index_tag_t( 1 ) = variant_index_tag( 1 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 1 >::value) >
+    variant & operator=( T1 const & t1 ) { return assign_value<1>( t1 ); }
+
+    template < variant_index_tag_t( 2 ) = variant_index_tag( 2 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 2 >::value) >
+    variant & operator=( T2 const & t2 ) { return assign_value<2>( t2 ); }
+
+    template < variant_index_tag_t( 3 ) = variant_index_tag( 3 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 3 >::value) >
+    variant & operator=( T3 const & t3 ) { return assign_value<3>( t3 ); }
+
+    template < variant_index_tag_t( 4 ) = variant_index_tag( 4 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 4 >::value) >
+    variant & operator=( T4 const & t4 ) { return assign_value<4>( t4 ); }
+
+    template < variant_index_tag_t( 5 ) = variant_index_tag( 5 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 5 >::value) >
+    variant & operator=( T5 const & t5 ) { return assign_value<5>( t5 ); }
+
+    template < variant_index_tag_t( 6 ) = variant_index_tag( 6 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 6 >::value) >
+    variant & operator=( T6 const & t6 ) { return assign_value<6>( t6 ); }
+
+    template < variant_index_tag_t( 7 ) = variant_index_tag( 7 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 7 >::value) >
+    variant & operator=( T7 const & t7 ) { return assign_value<7>( t7 ); }
+
+    template < variant_index_tag_t( 8 ) = variant_index_tag( 8 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 8 >::value) >
+    variant & operator=( T8 const & t8 ) { return assign_value<8>( t8 ); }
+
+    template < variant_index_tag_t( 9 ) = variant_index_tag( 9 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 9 >::value) >
+    variant & operator=( T9 const & t9 ) { return assign_value<9>( t9 ); }
+
+    template < variant_index_tag_t( 10 ) = variant_index_tag( 10 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 10 >::value) >
+    variant & operator=( T10 const & t10 ) { return assign_value<10>( t10 ); }
+
+    template < variant_index_tag_t( 11 ) = variant_index_tag( 11 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 11 >::value) >
+    variant & operator=( T11 const & t11 ) { return assign_value<11>( t11 ); }
+
+    template < variant_index_tag_t( 12 ) = variant_index_tag( 12 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 12 >::value) >
+    variant & operator=( T12 const & t12 ) { return assign_value<12>( t12 ); }
+
+    template < variant_index_tag_t( 13 ) = variant_index_tag( 13 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 13 >::value) >
+    variant & operator=( T13 const & t13 ) { return assign_value<13>( t13 ); }
+
+    template < variant_index_tag_t( 14 ) = variant_index_tag( 14 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 14 >::value) >
+    variant & operator=( T14 const & t14 ) { return assign_value<14>( t14 ); }
+
+    template < variant_index_tag_t( 15 ) = variant_index_tag( 15 )
+        variant_REQUIRES_B(detail::typelist_type_is_unique< variant_types, 15 >::value) >
+    variant & operator=( T15 const & t15 ) { return assign_value<15>( t15 ); }
+
+#else
+
     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 ); }
@@ -1397,7 +1739,8 @@
     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 ); }
-    
+
+#endif
 
     std::size_t index() const
     {
@@ -1405,10 +1748,12 @@
     }
 
     // 19.7.3.4 Modifiers
-    
+
 #if variant_CPP11_OR_GREATER
+
     template< class T, class... Args
         variant_REQUIRES_T( std::is_constructible< T, Args...>::value )
+        variant_REQUIRES_T( detail::typelist_contains_unique_type< variant_types, T >::value )
     >
     T& emplace( Args&&... args )
     {
@@ -1421,6 +1766,7 @@
 
     template< class T, class U, class... Args
         variant_REQUIRES_T( std::is_constructible< T, std::initializer_list<U>&, Args...>::value )
+        variant_REQUIRES_T( detail::typelist_contains_unique_type< variant_types, T >::value )
     >
     T& emplace( std::initializer_list<U> il, Args&&... args )
     {
@@ -1450,14 +1796,14 @@
 #endif // variant_CPP11_OR_GREATER
 
     // 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(
@@ -1476,8 +1822,8 @@
             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 
-            
+            std::is_nothrow_move_constructible<T15>::value && std17::is_nothrow_swappable<T15>::value
+
         )
 #endif
     {
@@ -1698,7 +2044,7 @@
             case 13: swap( this->get<13>(), other.get<13>() ); break;
             case 14: swap( this->get<14>(), other.get<14>() ); break;
             case 15: swap( this->get<15>(), other.get<15>() ); break;
-            
+
         }
     }
 
@@ -1878,13 +2224,13 @@
         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 
+        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<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
@@ -1938,11 +2284,11 @@
 {
     const Visitor& visitor;
     T2 const& val2;
-    
+
     TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_)
         : visitor(visitor_)
         , val2(val2_)
-        
+
     {
     }
 
@@ -1959,12 +2305,12 @@
     const Visitor& visitor;
     T2 const& val2;
     T3 const& val3;
-    
+
     TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_)
         : visitor(visitor_)
         , val2(val2_)
         , val3(val3_)
-        
+
     {
     }
 
@@ -1982,13 +2328,13 @@
     T2 const& val2;
     T3 const& val3;
     T4 const& val4;
-    
+
     TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_, T4 const& val4_)
         : visitor(visitor_)
         , val2(val2_)
         , val3(val3_)
         , val4(val4_)
-        
+
     {
     }
 
@@ -2007,14 +2353,14 @@
     T3 const& val3;
     T4 const& val4;
     T5 const& val5;
-    
+
     TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_, T4 const& val4_, T5 const& val5_)
         : visitor(visitor_)
         , val2(val2_)
         , val3(val3_)
         , val4(val4_)
         , val5(val5_)
-        
+
     {
     }
 
@@ -2039,42 +2385,42 @@
     {
     }
 
-    
+
     template< typename T1 >
     R operator()(T1 const& val1) const
     {
         typedef TypedVisitorUnwrapper<2, R, Visitor, T1> visitor_type;
         return VisitorApplicator<R>::apply(visitor_type(visitor, val1), r);
     }
-    
+
     template< typename T1, typename T2 >
     R operator()(T1 const& val1, T2 const& val2) const
     {
         typedef TypedVisitorUnwrapper<3, R, Visitor, T1, T2> visitor_type;
         return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2), r);
     }
-    
+
     template< typename T1, typename T2, typename T3 >
     R operator()(T1 const& val1, T2 const& val2, T3 const& val3) const
     {
         typedef TypedVisitorUnwrapper<4, R, Visitor, T1, T2, T3> visitor_type;
         return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3), r);
     }
-    
+
     template< typename T1, typename T2, typename T3, typename T4 >
     R operator()(T1 const& val1, T2 const& val2, T3 const& val3, T4 const& val4) const
     {
         typedef TypedVisitorUnwrapper<5, R, Visitor, T1, T2, T3, T4> visitor_type;
         return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3, val4), r);
     }
-    
+
     template< typename T1, typename T2, typename T3, typename T4, typename T5 >
     R operator()(T1 const& val1, T2 const& val2, T3 const& val3, T4 const& val4, T5 const& val5) const
     {
         typedef TypedVisitorUnwrapper<6, R, Visitor, T1, T2, T3, T4, T5> visitor_type;
         return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3, val4, val5), r);
     }
-    
+
 };
 
 
@@ -2102,7 +2448,7 @@
             case 13: return apply_visitor<13>(v, arg);
             case 14: return apply_visitor<14>(v, arg);
             case 15: return apply_visitor<15>(v, arg);
-            
+
             // prevent default construction of a const reference, see issue #39:
             default: std::terminate();
         }
@@ -2129,7 +2475,7 @@
         return apply(unwrapper, arg2, args ...);
     }
 #else
-    
+
     template< typename Visitor, typename V1, typename V2 >
     static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2)
     {
@@ -2137,7 +2483,7 @@
         Unwrapper unwrapper(v, arg1);
         return apply(unwrapper, arg2);
     }
-    
+
     template< typename Visitor, typename V1, typename V2, typename V3 >
     static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3)
     {
@@ -2145,7 +2491,7 @@
         Unwrapper unwrapper(v, arg1);
         return apply(unwrapper, arg2, arg3);
     }
-    
+
     template< typename Visitor, typename V1, typename V2, typename V3, typename V4 >
     static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4)
     {
@@ -2153,7 +2499,7 @@
         Unwrapper unwrapper(v, arg1);
         return apply(unwrapper, arg2, arg3, arg4);
     }
-    
+
     template< typename Visitor, typename V1, typename V2, typename V3, typename V4, typename V5 >
     static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4, V5 const& arg5)
     {
@@ -2161,7 +2507,7 @@
         Unwrapper unwrapper(v, arg1);
         return apply(unwrapper, arg2, arg3, arg4, arg5);
     }
-    
+
 #endif
 };
 
@@ -2244,7 +2590,7 @@
             case 13: return get<13>( v ) == get<13>( w );
             case 14: return get<14>( v ) == get<14>( w );
             case 15: return get<15>( v ) == get<15>( w );
-            
+
             default: return false;
         }
     }
@@ -2269,7 +2615,7 @@
             case 13: return get<13>( v ) < get<13>( w );
             case 14: return get<14>( v ) < get<14>( w );
             case 15: return get<15>( v ) < get<15>( w );
-            
+
             default: return false;
         }
     }
@@ -2377,7 +2723,7 @@
             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 0;
         }
     }