diff --git a/config.h b/config.h
index a3b2f31b..8607cbb6 100644
--- a/config.h
+++ b/config.h
@@ -787,113 +787,127 @@ NAMESPACE_END
// C++11 or C++14 is available
#if defined(CRYPTOPP_CXX11)
-// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; Intel 13.0; SunCC 12.5.
+// Compatibility with non-clang compilers.
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; Intel 13.0; SunCC 5.14.
#if (CRYPTOPP_MSC_VERSION >= 1700)
# define CRYPTOPP_CXX11_ATOMICS 1
+#elif __has_feature(cxx_atomic)
+# define CRYPTOPP_CXX11_ATOMICS 1
#elif (__INTEL_COMPILER >= 1300)
# define CRYPTOPP_CXX11_ATOMICS 1
-#elif defined(__clang__)
-# if __has_feature(cxx_atomic)
-# define CRYPTOPP_CXX11_ATOMICS 1
-# endif
#elif (CRYPTOPP_GCC_VERSION >= 40400)
# define CRYPTOPP_CXX11_ATOMICS 1
#elif (__SUNPRO_CC >= 0x5140)
# define CRYPTOPP_CXX11_ATOMICS 1
#endif // atomics
-// synchronization: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Xcode 5.0; Intel 12.0; SunCC 12.4.
+// synchronization: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Xcode 5.0; Intel 12.0; SunCC 5.13.
// TODO: verify Clang and Intel versions; find __has_feature(x) extension for Clang
#if (CRYPTOPP_MSC_VERSION >= 1700)
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
-#elif (__INTEL_COMPILER >= 1200)
-# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000)
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
+#elif (__INTEL_COMPILER >= 1200)
+# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
#elif (CRYPTOPP_GCC_VERSION >= 40400)
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
#elif (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
#endif // synchronization
-// alignof/alignas: MS at VS2015 (19.00); GCC at 4.8; Clang at 3.3; Intel 15.0; SunCC 12.4.
+// Dynamic Initialization and Destruction with Concurrency ("Magic Statics")
+// MS at VS2015 (19.00); GCC at 4.3; LLVM Clang at 2.9; Apple Clang at 4.0; Intel 11.1; SunCC 5.13.
+// Microsoft's implementation only works for Vista and above, so its further
+// limited. http://connect.microsoft.com/VisualStudio/feedback/details/1789709
+#if (CRYPTOPP_MSC_VERSION >= 1900) && ((WINVER >= 0x0600 /*_WIN32_WINNT_VISTA*/) || (_WIN32_WINNT >= 0x0600 /*_WIN32_WINNT_VISTA*/))
+# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
+#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000)
+# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
+#elif (__INTEL_COMPILER >= 1110)
+# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
+#elif (CRYPTOPP_GCC_VERSION >= 40300)
+# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
+#elif (__SUNPRO_CC >= 0x5130)
+# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
+#endif // Dynamic Initialization compilers
+
+// alignof/alignas: MS at VS2015 (19.00); GCC at 4.8; Clang at 3.0; Intel 15.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900)
# define CRYPTOPP_CXX11_ALIGNAS 1
-# define CRYPTOPP_CXX11_ALIGNOF 1
+#elif __has_feature(cxx_alignas)
+# define CRYPTOPP_CXX11_ALIGNAS 1
#elif (__INTEL_COMPILER >= 1500)
# define CRYPTOPP_CXX11_ALIGNAS 1
-# define CRYPTOPP_CXX11_ALIGNOF 1
-#elif defined(__clang__)
-# if __has_feature(cxx_alignas)
-# define CRYPTOPP_CXX11_ALIGNAS 1
-# endif
-# if __has_feature(cxx_alignof)
-# define CRYPTOPP_CXX11_ALIGNOF 1
-# endif
#elif (CRYPTOPP_GCC_VERSION >= 40800)
# define CRYPTOPP_CXX11_ALIGNAS 1
-# define CRYPTOPP_CXX11_ALIGNOF 1
#elif (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_ALIGNAS 1
-# define CRYPTOPP_CXX11_ALIGNOF 1
-#endif // alignof/alignas
+#endif // alignas
-// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 14.0; SunCC 12.4.
+// alignof: MS at VS2015 (19.00); GCC at 4.5; Clang at 2.9; Intel 15.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900)
+# define CRYPTOPP_CXX11_ALIGNOF 1
+#elif __has_feature(cxx_alignof)
+# define CRYPTOPP_CXX11_ALIGNOF 1
+#elif (__INTEL_COMPILER >= 1500)
+# define CRYPTOPP_CXX11_ALIGNOF 1
+#elif (CRYPTOPP_GCC_VERSION >= 40500)
+# define CRYPTOPP_CXX11_ALIGNOF 1
+#elif (__SUNPRO_CC >= 0x5130)
+# define CRYPTOPP_CXX11_ALIGNOF 1
+#endif // alignof
+
+// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 14.0; SunCC 5.13.
+#if (CRYPTOPP_MSC_VERSION >= 1900)
+# define CRYPTOPP_CXX11_NOEXCEPT 1
+#elif __has_feature(cxx_noexcept)
# define CRYPTOPP_CXX11_NOEXCEPT 1
#elif (__INTEL_COMPILER >= 1400)
# define CRYPTOPP_CXX11_NOEXCEPT 1
-#elif defined(__clang__)
-# if __has_feature(cxx_noexcept)
-# define CRYPTOPP_CXX11_NOEXCEPT 1
-# endif
#elif (CRYPTOPP_GCC_VERSION >= 40600)
# define CRYPTOPP_CXX11_NOEXCEPT 1
#elif (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_NOEXCEPT 1
#endif // noexcept compilers
-// variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 12.4.
+// variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1800)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
+#elif __has_feature(cxx_variadic_templates)
+# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
#elif (__INTEL_COMPILER >= 1210)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
-#elif defined(__clang__)
-# if __has_feature(cxx_variadic_templates)
-# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
-# endif
#elif (CRYPTOPP_GCC_VERSION >= 40300)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
#elif (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
#endif // variadic templates
-// constexpr: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 16.0; SunCC 12.4.
+// constexpr: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.1; Intel 16.0; SunCC 5.13.
// Intel has mis-supported the feature since at least ICPC 13.00
#if (CRYPTOPP_MSC_VERSION >= 1900)
# define CRYPTOPP_CXX11_CONSTEXPR 1
+#elif __has_feature(cxx_constexpr)
+# define CRYPTOPP_CXX11_CONSTEXPR 1
#elif (__INTEL_COMPILER >= 1600)
# define CRYPTOPP_CXX11_CONSTEXPR 1
-#elif defined(__clang__)
-# if __has_feature(cxx_constexpr)
-# define CRYPTOPP_CXX11_CONSTEXPR 1
-# endif
#elif (CRYPTOPP_GCC_VERSION >= 40600)
# define CRYPTOPP_CXX11_CONSTEXPR 1
#elif (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_CONSTEXPR 1
#endif // constexpr compilers
-// nullptr_t: MS at VS2010 (16.00); GCC at 4.6; Clang at 3.3; Intel 12.0; SunCC 12.4.
-// Intel has upported the feature since at least ICPC 12.00
+// nullptr_t: MS at VS2010 (16.00); GCC at 4.6; Clang at 3.3; Intel 10.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1600)
# define CRYPTOPP_CXX11_NULLPTR 1
-#elif (__INTEL_COMPILER >= 1200)
+#elif __has_feature(cxx_nullptr)
+# define CRYPTOPP_CXX11_NULLPTR 1
+#elif (__INTEL_COMPILER >= 1000)
# define CRYPTOPP_CXX11_NULLPTR 1
-#elif defined(__clang__)
-# if __has_feature(cxx_nullptr)
-# define CRYPTOPP_CXX11_NULLPTR 1
-# endif
#elif (CRYPTOPP_GCC_VERSION >= 40600)
# define CRYPTOPP_CXX11_NULLPTR 1
#elif (__SUNPRO_CC >= 0x5130)
diff --git a/misc.h b/misc.h
index 0841045c..6bb2d4c2 100644
--- a/misc.h
+++ b/misc.h
@@ -290,7 +290,7 @@ struct NewObject
//! \brief Restricts the instantiation of a class to one static object without locks
//! \tparam T the class or type
//! \tparam F the object factory for T
-//! \tparam instance the initiali instance count
+//! \tparam instance an instance counter for the class object
//! \details This class safely initializes a static object in a multithreaded environment. For C++03
//! and below it will do so without using locks for portability. If two threads call Ref() at the same
//! time, they may get back different references, and one object may end up being memory leaked. This
@@ -298,8 +298,14 @@ struct NewObject
//! local storage on early Windows platforms, like Windows XP and Windows 2003.
//! \details For C++11 and above, a standard double-checked locking pattern with thread fences
//! are used. The locks and fences are standard and do not hinder portability.
-//! \sa Double-Checked
-//! Locking is Fixed In C++11
+//! \details Microsoft's C++11 implementation provides the necessary primitive support on Windows Vista and
+//! above when using Visual Studio 2015 (cl.exe version 19.00). If C++11 is desired, you should
+//! set WINVER or _WIN32_WINNT to 0x600 (or above), and compile with Visual Studio 2015.
+//! \sa Double-Checked Locking
+//! is Fixed In C++11, Dynamic
+//! Initialization and Destruction with Concurrency and
+//! Thread Local Storage (TLS) on MSDN.
+//! \since Crypto++ 5.2
template , int instance=0>
class Singleton
{
@@ -316,13 +322,15 @@ private:
//! \brief Return a reference to the inner Singleton object
//! \tparam T the class or type
//! \tparam F the object factory for T
+//! \tparam instance an instance counter for the class object
//! \details Ref() is used to create the object using the object factory. The
//! object is only created once with the limitations discussed in the class documentation.
//! \sa Double-Checked Locking is Fixed In C++11
-#if defined(CRYPTOPP_CXX11_ATOMICS) && defined(CRYPTOPP_CXX11_SYNCHRONIZATION)
+//! \since Crypto++ 5.2
template
const T & Singleton::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
{
+#if defined(CRYPTOPP_CXX11_ATOMICS) && defined(CRYPTOPP_CXX11_SYNCHRONIZATION) && defined(CRYPTOPP_CXX11_DYNAMIC_INIT)
static std::mutex s_mutex;
static std::atomic s_pObject;
@@ -344,11 +352,7 @@ template
std::atomic_thread_fence(std::memory_order_release);
return *newObject;
-}
#else
-template
-const T & Singleton::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
-{
static volatile simple_ptr s_pObject;
T *p = s_pObject.m_p;
MEMORY_BARRIER();
@@ -370,8 +374,8 @@ const T & Singleton::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
MEMORY_BARRIER();
return *newObject;
-}
#endif
+}
// ************** misc functions ***************
diff --git a/trdlocal.cpp b/trdlocal.cpp
index beb21e98..a4c3b683 100644
--- a/trdlocal.cpp
+++ b/trdlocal.cpp
@@ -26,6 +26,8 @@ ThreadLocalStorage::Err::Err(const std::string& operation, int error)
{
}
+// Windows: "a process may have up to TLS_MINIMUM_AVAILABLE indexes (guaranteed to be greater than
+// or equal to 64)", https://support.microsoft.com/en-us/help/94804/info-thread-local-storage-overview
ThreadLocalStorage::ThreadLocalStorage()
{
#ifdef HAS_WINTHREADS