# error Supported values for _LIBCPP_DEBUG are 0 and 1
#endif
-// _LIBCPP_DEBUG_LEVEL is always defined to one of [0, 1, 2] at this point
-#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE)
-# define _LIBCPP_EXTERN_TEMPLATE(...)
-#endif
-
-#ifdef _LIBCPP_DISABLE_EXTERN_TEMPLATE
-# define _LIBCPP_EXTERN_TEMPLATE(...)
-# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...)
-#endif
-
-#ifndef _LIBCPP_EXTERN_TEMPLATE
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-#endif
-
-// When the Debug mode is enabled, we disable extern declarations because we
-// don't want to use the functions compiled in the library, which might not
-// have had the debug mode enabled when built. However, some extern declarations
-// need to be used, because code correctness depends on it (several instances
-// in the <locale>). Those special declarations are declared with
-// _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled even
-// when the debug mode is enabled.
-#ifndef _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE
-# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
+// Libc++ allows disabling extern template instantiation declarations by
+// means of users defining _LIBCPP_DISABLE_EXTERN_TEMPLATE.
+//
+// Furthermore, when the Debug mode is enabled, we disable extern declarations
+// when building user code because we don't want to use the functions compiled
+// in the library, which might not have had the debug mode enabled when built.
+// However, some extern declarations need to be used, because code correctness
+// depends on it (several instances in <locale>). Those special declarations
+// are declared with _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled
+// even when the debug mode is enabled.
+#if defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE)
+# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
+# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) /* nothing */
+#elif _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_BUILDING_LIBRARY)
+# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */
+# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
+#else
+# define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__;
#endif
-#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
-
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \
defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__)
#define _LIBCPP_LOCALE__L_EXTENSIONS 1
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>;
+#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
#endif
+#undef _LIBCPP_EXTERN_TEMPLATE_DEFINE
-template
- string
- operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
+template string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
namespace
{