``_LIBCPP_ABI_VERSION``, which is controlled by the ``LIBCXX_ABI_VERSION`` set
at build time. Libc++ does not intend users to interact with these C++ macros
directly.
+
+-----------------
+MSVC environments
+-----------------
+
+The exception to this is MSVC environments. Libc++ does not currently have users
+that require a stable ABI in MSVC environments, so MSVC-only changes may be
+applied unconditionally.
macOS 10.9+ i386, x86_64, arm64 Building the shared library itself requires targetting macOS 10.13+
FreeBSD 12+ i386, x86_64, arm
Linux i386, x86_64, arm, arm64 Only glibc-2.24 and later and no other libc is officially supported
-Windows i386, x86_64 Both MSVC and MinGW style environments
+Windows i386, x86_64 Both MSVC and MinGW style environments, ABI in MSVC environments is :doc:`unstable <DesignDocs/ABIVersioning>`
AIX 7.2TL5+ powerpc, powerpc64
=============== ========================= ============================
template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
template <class _Tp>
-class optional
+class _LIBCPP_DECLSPEC_EMPTY_BASES optional
: private __optional_move_assign_base<_Tp>
, private __optional_sfinae_ctor_base_t<_Tp>
, private __optional_sfinae_assign_base_t<_Tp>
} // namespace __variant_detail
template <class... _Types>
-class _LIBCPP_TEMPLATE_VIS variant
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant
: private __sfinae_ctor_base<
__all<is_copy_constructible_v<_Types>...>::value,
__all<is_move_constructible_v<_Types>...>::value>,
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <optional>
+
+// template <class T> class optional;
+
+#include <optional>
+
+template <class T>
+struct type_with_bool {
+ T value;
+ bool has_value;
+};
+
+int main(int, char**) {
+ // Test that std::optional achieves the expected size. See https://llvm.org/PR61095.
+ static_assert(sizeof(std::optional<char>) == sizeof(type_with_bool<char>));
+ static_assert(sizeof(std::optional<int>) == sizeof(type_with_bool<int>));
+ static_assert(sizeof(std::optional<long>) == sizeof(type_with_bool<long>));
+ static_assert(sizeof(std::optional<std::size_t>) == sizeof(type_with_bool<std::size_t>));
+
+ return 0;
+}
static_assert(std::__variant_npos<IndexT> == IndexLim::max(), "");
}
+template <class LargestType>
+struct type_with_index {
+ LargestType largest;
+#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+ unsigned char index;
+#else
+ unsigned int index;
+#endif
+};
+
int main(int, char**) {
test_index_type<unsigned char>();
// This won't compile due to template depth issues.
test_index_internals<unsigned char>();
test_index_internals<unsigned short>();
+ // Test that std::variant achieves the expected size. See https://llvm.org/PR61095.
+ static_assert(sizeof(std::variant<char, char, char>) == sizeof(type_with_index<char>));
+ static_assert(sizeof(std::variant<int, int, int>) == sizeof(type_with_index<int>));
+ static_assert(sizeof(std::variant<long, long, long>) == sizeof(type_with_index<long>));
+ static_assert(sizeof(std::variant<char, int, long>) == sizeof(type_with_index<long>));
+ static_assert(sizeof(std::variant<std::size_t, std::size_t, std::size_t>) == sizeof(type_with_index<std::size_t>));
+
return 0;
}