aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-08-02 17:33:33 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-08-02 17:33:33 +0000
commit315d10f09ee888005b1da55e7bbb57d8a79b8447 (patch)
tree99a16e8c2272e507281e63fac5970e0548df04ea
parentf36202620b428c45a1c8d91743727c9313424fb2 (diff)
downloadsrc-315d10f09ee888005b1da55e7bbb57d8a79b8447.tar.gz
src-315d10f09ee888005b1da55e7bbb57d8a79b8447.zip
Vendor import of libc++ trunk r338536:vendor/libc++/libc++-trunk-r338536
Notes
Notes: svn path=/vendor/libc++/dist/; revision=337143 svn path=/vendor/libc++/libc++-trunk-r338536/; revision=337144; tag=vendor/libc++/libc++-trunk-r338536
-rw-r--r--include/CMakeLists.txt2
-rw-r--r--include/__config6
-rw-r--r--include/__functional_base2
-rw-r--r--include/__hash_table120
-rw-r--r--include/__mutex_base2
-rw-r--r--include/__node_handle212
-rw-r--r--include/__tree170
-rw-r--r--include/cfloat10
-rw-r--r--include/charconv610
-rw-r--r--include/ctime14
-rw-r--r--include/experimental/__config7
-rw-r--r--include/experimental/simd381
-rw-r--r--include/float.h11
-rw-r--r--include/functional4
-rw-r--r--include/map83
-rw-r--r--include/memory6
-rw-r--r--include/module.modulemap5
-rw-r--r--include/new6
-rw-r--r--include/set81
-rw-r--r--include/shared_mutex2
-rw-r--r--include/support/newlib/xlocale.h2
-rw-r--r--include/system_error2
-rw-r--r--include/unordered_map87
-rw-r--r--include/unordered_set84
-rw-r--r--include/utility2
-rw-r--r--lib/abi/x86_64-unknown-linux-gnu.v1.abilist2
-rw-r--r--src/bind.cpp1
-rw-r--r--src/charconv.cpp233
-rw-r--r--src/future.cpp44
-rw-r--r--src/memory.cpp1
-rw-r--r--src/mutex.cpp1
-rw-r--r--src/new.cpp2
-rw-r--r--src/shared_mutex.cpp1
-rw-r--r--src/system_error.cpp1
-rw-r--r--src/utility.cpp1
-rw-r--r--test/libcxx/double_include.sh.cpp1
-rw-r--r--test/libcxx/language.support/has_c11_features.pass.cpp29
-rw-r--r--test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp67
-rw-r--r--test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp76
-rw-r--r--test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp85
-rw-r--r--test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp64
-rw-r--r--test/std/containers/associative/multimap/multimap.modifiers/extract_iterator.pass.cpp67
-rw-r--r--test/std/containers/associative/multimap/multimap.modifiers/extract_key.pass.cpp76
-rw-r--r--test/std/containers/associative/multimap/multimap.modifiers/insert_node_type.pass.cpp78
-rw-r--r--test/std/containers/associative/multimap/multimap.modifiers/insert_node_type_hint.pass.cpp64
-rw-r--r--test/std/containers/associative/multiset/extract_iterator.pass.cpp60
-rw-r--r--test/std/containers/associative/multiset/extract_key.pass.cpp71
-rw-r--r--test/std/containers/associative/multiset/insert_node_type.pass.cpp77
-rw-r--r--test/std/containers/associative/multiset/insert_node_type_hint.pass.cpp59
-rw-r--r--test/std/containers/associative/set/extract_iterator.pass.cpp60
-rw-r--r--test/std/containers/associative/set/extract_key.pass.cpp71
-rw-r--r--test/std/containers/associative/set/insert_node_type.pass.cpp83
-rw-r--r--test/std/containers/associative/set/insert_node_type_hint.pass.cpp61
-rw-r--r--test/std/containers/container.node/node_handle.pass.cpp145
-rw-r--r--test/std/containers/unord/unord.map/unord.map.modifiers/extract_iterator.pass.cpp67
-rw-r--r--test/std/containers/unord/unord.map/unord.map.modifiers/extract_key.pass.cpp76
-rw-r--r--test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type.pass.cpp84
-rw-r--r--test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type_hint.pass.cpp64
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_iterator.pass.cpp67
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_key.pass.cpp77
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type.pass.cpp77
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type_hint.pass.cpp63
-rw-r--r--test/std/containers/unord/unord.multiset/extract_iterator.pass.cpp60
-rw-r--r--test/std/containers/unord/unord.multiset/extract_key.pass.cpp71
-rw-r--r--test/std/containers/unord/unord.multiset/insert_node_type.pass.cpp76
-rw-r--r--test/std/containers/unord/unord.multiset/insert_node_type_hint.pass.cpp59
-rw-r--r--test/std/containers/unord/unord.set/extract_iterator.pass.cpp60
-rw-r--r--test/std/containers/unord/unord.set/extract_key.pass.cpp71
-rw-r--r--test/std/containers/unord/unord.set/insert_node_type.pass.cpp83
-rw-r--r--test/std/containers/unord/unord.set/insert_node_type_hint.pass.cpp61
-rw-r--r--test/std/depr/depr.c.headers/float_h.pass.cpp42
-rw-r--r--test/std/depr/depr.c.headers/stdlib_h.pass.cpp10
-rw-r--r--test/std/experimental/simd/simd.abi/vector_extension.pass.cpp67
-rw-r--r--test/std/experimental/simd/simd.access/default.pass.cpp217
-rw-r--r--test/std/experimental/simd/simd.casts/simd_cast.pass.cpp38
-rw-r--r--test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp27
-rw-r--r--test/std/experimental/simd/simd.cons/broadcast.pass.cpp38
-rw-r--r--test/std/experimental/simd/simd.cons/default.pass.cpp28
-rw-r--r--test/std/experimental/simd/simd.cons/generator.pass.cpp73
-rw-r--r--test/std/experimental/simd/simd.cons/load.pass.cpp118
-rw-r--r--test/std/experimental/simd/simd.mem/load.pass.cpp122
-rw-r--r--test/std/experimental/simd/simd.mem/store.pass.cpp95
-rw-r--r--test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp18
-rw-r--r--test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp180
-rw-r--r--test/std/experimental/simd/simd.traits/is_simd.pass.cpp216
-rw-r--r--test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp58
-rw-r--r--test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp239
-rw-r--r--test/std/language.support/support.limits/c.limits/cfloat.pass.cpp42
-rw-r--r--test/std/language.support/support.runtime/cstdlib.pass.cpp10
-rw-r--r--test/std/language.support/support.runtime/ctime.pass.cpp14
-rw-r--r--test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp30
-rw-r--r--test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp182
-rw-r--r--test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp30
-rw-r--r--test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp80
-rw-r--r--test/std/utilities/time/date.time/ctime.pass.cpp16
-rw-r--r--test/support/Counter.h4
-rw-r--r--test/support/charconv_test_helpers.h232
-rw-r--r--test/support/test_macros.h47
-rw-r--r--www/cxx1z_status.html8
99 files changed, 6362 insertions, 527 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index c5e92e4c4bda..d9def18d725c 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -11,6 +11,7 @@ set(files
__libcpp_version
__locale
__mutex_base
+ __node_handle
__nullptr
__split_buffer
__sso_allocator
@@ -31,6 +32,7 @@ set(files
cerrno
cfenv
cfloat
+ charconv
chrono
cinttypes
ciso646
diff --git a/include/__config b/include/__config
index c01ac12be4b8..639d06c9f5d7 100644
--- a/include/__config
+++ b/include/__config
@@ -510,7 +510,7 @@ namespace std {
#define _LIBCPP_HAS_IS_BASE_OF
#endif
-#if !__EXCEPTIONS
+#if !__EXCEPTIONS && !defined(_LIBCPP_NO_EXCEPTIONS)
#define _LIBCPP_NO_EXCEPTIONS
#endif
@@ -620,6 +620,8 @@ namespace std {
#define _LIBCPP_ALWAYS_INLINE __forceinline
+#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
#elif defined(_LIBCPP_COMPILER_IBM)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
@@ -652,6 +654,8 @@ namespace std {
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
+#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
#endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM]
#if _LIBCPP_STD_VER >= 17
diff --git a/include/__functional_base b/include/__functional_base
index 1a90bd6280f6..57fdf2b9f663 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -561,7 +561,7 @@ struct __is_transparent<_Tp, _Up,
struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_MEMORY)
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern const allocator_arg_t allocator_arg;
#else
/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
diff --git a/include/__hash_table b/include/__hash_table
index 44ba268a0ec8..c77de961be6b 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -859,6 +859,17 @@ public:
template <class> friend class __hash_map_node_destructor;
};
+#if _LIBCPP_STD_VER > 14
+template <class _NodeType, class _Alloc>
+struct __generic_container_node_destructor;
+
+template <class _Tp, class _VoidPtr, class _Alloc>
+struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
+ : __hash_node_destructor<_Alloc>
+{
+ using __hash_node_destructor<_Alloc>::__hash_node_destructor;
+};
+#endif
#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Hash, class _Equal, class _Alloc>
@@ -1151,6 +1162,30 @@ public:
return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
}
+#if _LIBCPP_STD_VER > 14
+ template <class _NodeHandle, class _InsertReturnType>
+ _LIBCPP_INLINE_VISIBILITY
+ _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator __node_handle_insert_unique(const_iterator __hint,
+ _NodeHandle&& __nh);
+
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator __node_handle_insert_multi(_NodeHandle&& __nh);
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
+
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ _NodeHandle __node_handle_extract(key_type const& __key);
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ _NodeHandle __node_handle_extract(const_iterator __it);
+#endif
+
void clear() _NOEXCEPT;
void rehash(size_type __n);
_LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)
@@ -2126,6 +2161,91 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
#endif // _LIBCPP_CXX03_LANG
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle, class _InsertReturnType>
+_LIBCPP_INLINE_VISIBILITY
+_InsertReturnType
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
+ _NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return _InsertReturnType{end(), false, _NodeHandle()};
+ pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
+ if (__result.second)
+ __nh.__release();
+ return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
+ const_iterator, _NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return end();
+ pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
+ if (__result.second)
+ __nh.__release();
+ return __result.first;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
+ key_type const& __key)
+{
+ iterator __i = find(__key);
+ if (__i == end())
+ return _NodeHandle();
+ return __node_handle_extract<_NodeHandle>(__i);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
+ const_iterator __p)
+{
+ allocator_type __alloc(__node_alloc());
+ return _NodeHandle(remove(__p).release(), __alloc);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
+ _NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return end();
+ iterator __result = __node_insert_multi(__nh.__ptr_);
+ __nh.__release();
+ return __result;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
+ const_iterator __hint, _NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return end();
+ iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
+ __nh.__release();
+ return __result;
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)
diff --git a/include/__mutex_base b/include/__mutex_base
index 402a52d945e1..4659ca9298c9 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -74,7 +74,7 @@ struct _LIBCPP_TYPE_VIS defer_lock_t {};
struct _LIBCPP_TYPE_VIS try_to_lock_t {};
struct _LIBCPP_TYPE_VIS adopt_lock_t {};
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_MUTEX)
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern const defer_lock_t defer_lock;
extern const try_to_lock_t try_to_lock;
diff --git a/include/__node_handle b/include/__node_handle
new file mode 100644
index 000000000000..fe09f3c1e51c
--- /dev/null
+++ b/include/__node_handle
@@ -0,0 +1,212 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___NODE_HANDLE
+#define _LIBCPP___NODE_HANDLE
+
+#include <__config>
+#include <memory>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+#define __cpp_lib_node_extract 201606L
+
+// Specialized in __tree & __hash_table for their _NodeType.
+template <class _NodeType, class _Alloc>
+struct __generic_container_node_destructor;
+
+template <class _NodeType, class _Alloc,
+ template <class, class> class _MapOrSetSpecifics>
+class _LIBCPP_TEMPLATE_VIS __basic_node_handle
+ : public _MapOrSetSpecifics<
+ _NodeType,
+ __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>
+{
+ template <class _Tp, class _Compare, class _Allocator>
+ friend class __tree;
+ template <class _Tp, class _Hash, class _Equal, class _Allocator>
+ friend class __hash_table;
+ friend struct _MapOrSetSpecifics<
+ _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>;
+
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_pointer<typename __alloc_traits::void_pointer,
+ _NodeType>::type
+ __node_pointer_type;
+
+public:
+ typedef _Alloc allocator_type;
+
+private:
+ __node_pointer_type __ptr_ = nullptr;
+ optional<allocator_type> __alloc_;
+
+ _LIBCPP_INLINE_VISIBILITY
+ void __release()
+ {
+ __ptr_ = nullptr;
+ __alloc_ = _VSTD::nullopt;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void __destroy_node_pointer()
+ {
+ if (__ptr_ != nullptr)
+ {
+ typedef typename __allocator_traits_rebind<
+ allocator_type, _NodeType>::type __node_alloc_type;
+ __node_alloc_type __alloc(*__alloc_);
+ __generic_container_node_destructor<_NodeType, __node_alloc_type>(
+ __alloc, true)(__ptr_);
+ __ptr_ = nullptr;
+ }
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __basic_node_handle(__node_pointer_type __ptr,
+ allocator_type const& __alloc)
+ : __ptr_(__ptr), __alloc_(__alloc)
+ {
+ }
+
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ __basic_node_handle() = default;
+
+ _LIBCPP_INLINE_VISIBILITY
+ __basic_node_handle(__basic_node_handle&& __other) noexcept
+ : __ptr_(__other.__ptr_),
+ __alloc_(_VSTD::move(__other.__alloc_))
+ {
+ __other.__ptr_ = nullptr;
+ __other.__alloc_ = _VSTD::nullopt;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __basic_node_handle& operator=(__basic_node_handle&& __other)
+ {
+ _LIBCPP_ASSERT(
+ __alloc_ == _VSTD::nullopt ||
+ __alloc_traits::propagate_on_container_move_assignment::value ||
+ __alloc_ == __other.__alloc_,
+ "node_type with incompatible allocator passed to "
+ "node_type::operator=(node_type&&)");
+
+ __destroy_node_pointer();
+ __ptr_ = __other.__ptr_;
+
+ if (__alloc_traits::propagate_on_container_move_assignment::value ||
+ __alloc_ == _VSTD::nullopt)
+ __alloc_ = _VSTD::move(__other.__alloc_);
+
+ __other.__ptr_ = nullptr;
+ __other.__alloc_ = _VSTD::nullopt;
+
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ allocator_type get_allocator() const { return *__alloc_; }
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit operator bool() const { return __ptr_ != nullptr; }
+
+ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+ bool empty() const { return __ptr_ == nullptr; }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void swap(__basic_node_handle& __other) noexcept(
+ __alloc_traits::propagate_on_container_swap::value ||
+ __alloc_traits::is_always_equal::value)
+ {
+ using _VSTD::swap;
+ swap(__ptr_, __other.__ptr_);
+ if (__alloc_traits::propagate_on_container_swap::value ||
+ __alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt)
+ swap(__alloc_, __other.__alloc_);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ friend void swap(__basic_node_handle& __a, __basic_node_handle& __b)
+ noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ ~__basic_node_handle()
+ {
+ __destroy_node_pointer();
+ }
+};
+
+template <class _NodeType, class _Derived>
+struct __set_node_handle_specifics
+{
+ typedef typename _NodeType::__node_value_type value_type;
+
+ _LIBCPP_INLINE_VISIBILITY
+ value_type& value() const
+ {
+ return static_cast<_Derived const*>(this)->__ptr_->__value_;
+ }
+};
+
+template <class _NodeType, class _Derived>
+struct __map_node_handle_specifics
+{
+ typedef typename _NodeType::__node_value_type::key_type key_type;
+ typedef typename _NodeType::__node_value_type::mapped_type mapped_type;
+
+ _LIBCPP_INLINE_VISIBILITY
+ key_type& key() const
+ {
+ return static_cast<_Derived const*>(this)->
+ __ptr_->__value_.__ref().first;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ mapped_type& mapped() const
+ {
+ return static_cast<_Derived const*>(this)->
+ __ptr_->__value_.__ref().second;
+ }
+};
+
+template <class _NodeType, class _Alloc>
+using __set_node_handle =
+ __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>;
+
+template <class _NodeType, class _Alloc>
+using __map_node_handle =
+ __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>;
+
+template <class _Iterator, class _NodeType>
+_LIBCPP_TEMPLATE_VIS
+struct __insert_return_type
+{
+ _Iterator position;
+ bool inserted;
+ _NodeType node;
+};
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
+#endif
diff --git a/include/__tree b/include/__tree
index 30c32f163935..af9b9616df8a 100644
--- a/include/__tree
+++ b/include/__tree
@@ -796,6 +796,16 @@ public:
template <class> friend class __map_node_destructor;
};
+#if _LIBCPP_STD_VER > 14
+template <class _NodeType, class _Alloc>
+struct __generic_container_node_destructor;
+template <class _Tp, class _VoidPtr, class _Alloc>
+struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
+ : __tree_node_destructor<_Alloc>
+{
+ using __tree_node_destructor<_Alloc>::__tree_node_destructor;
+};
+#endif
template <class _Tp, class _NodePtr, class _DiffType>
class _LIBCPP_TEMPLATE_VIS __tree_iterator
@@ -1338,6 +1348,33 @@ public:
iterator __node_insert_multi(__node_pointer __nd);
iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
+
+ _LIBCPP_INLINE_VISIBILITY iterator __remove_node_pointer(__node_pointer);
+
+#if _LIBCPP_STD_VER > 14
+ template <class _NodeHandle, class _InsertReturnType>
+ _LIBCPP_INLINE_VISIBILITY
+ _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
+
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator __node_handle_insert_multi(_NodeHandle&&);
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
+
+
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ _NodeHandle __node_handle_extract(key_type const&);
+ template <class _NodeHandle>
+ _LIBCPP_INLINE_VISIBILITY
+ _NodeHandle __node_handle_extract(const_iterator);
+#endif
+
iterator erase(const_iterator __p);
iterator erase(const_iterator __f, const_iterator __l);
template <class _Key>
@@ -2347,17 +2384,138 @@ __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
-__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
+__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr)
{
- __node_pointer __np = __p.__get_np();
- iterator __r(__p.__ptr_);
+ iterator __r(__ptr);
++__r;
- if (__begin_node() == __p.__ptr_)
+ if (__begin_node() == __ptr)
__begin_node() = __r.__ptr_;
--size();
- __node_allocator& __na = __node_alloc();
__tree_remove(__end_node()->__left_,
- static_cast<__node_base_pointer>(__np));
+ static_cast<__node_base_pointer>(__ptr));
+ return __r;
+}
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle, class _InsertReturnType>
+_LIBCPP_INLINE_VISIBILITY
+_InsertReturnType
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
+ _NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return _InsertReturnType{end(), false, _NodeHandle()};
+
+ __node_pointer __ptr = __nh.__ptr_;
+ __parent_pointer __parent;
+ __node_base_pointer& __child = __find_equal(__parent,
+ __ptr->__value_);
+ if (__child != nullptr)
+ return _InsertReturnType{
+ iterator(static_cast<__node_pointer>(__child)),
+ false, _VSTD::move(__nh)};
+
+ __insert_node_at(__parent, __child,
+ static_cast<__node_base_pointer>(__ptr));
+ __nh.__release();
+ return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
+ const_iterator __hint, _NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return end();
+
+ __node_pointer __ptr = __nh.__ptr_;
+ __parent_pointer __parent;
+ __node_base_pointer __dummy;
+ __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
+ __ptr->__value_);
+ __node_pointer __r = static_cast<__node_pointer>(__child);
+ if (__child == nullptr)
+ {
+ __insert_node_at(__parent, __child,
+ static_cast<__node_base_pointer>(__ptr));
+ __r = __ptr;
+ __nh.__release();
+ }
+ return iterator(__r);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
+{
+ iterator __it = find(__key);
+ if (__it == end())
+ return _NodeHandle();
+ return __node_handle_extract<_NodeHandle>(__it);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+_NodeHandle
+__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
+{
+ __node_pointer __np = __p.__get_np();
+ __remove_node_pointer(__np);
+ return _NodeHandle(__np, __alloc());
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return end();
+ __node_pointer __ptr = __nh.__ptr_;
+ __parent_pointer __parent;
+ __node_base_pointer& __child = __find_leaf_high(
+ __parent, _NodeTypes::__get_key(__ptr->__value_));
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+ __nh.__release();
+ return iterator(__ptr);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _NodeHandle>
+_LIBCPP_INLINE_VISIBILITY
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
+ const_iterator __hint, _NodeHandle&& __nh)
+{
+ if (__nh.empty())
+ return end();
+
+ __node_pointer __ptr = __nh.__ptr_;
+ __parent_pointer __parent;
+ __node_base_pointer& __child = __find_leaf(__hint, __parent,
+ _NodeTypes::__get_key(__ptr->__value_));
+ __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+ __nh.__release();
+ return iterator(__ptr);
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
+{
+ __node_pointer __np = __p.__get_np();
+ iterator __r = __remove_node_pointer(__np);
+ __node_allocator& __na = __node_alloc();
__node_traits::destroy(__na, _NodeTypes::__get_ptr(
const_cast<__node_value_type&>(*__p)));
__node_traits::deallocate(__na, __np, 1);
diff --git a/include/cfloat b/include/cfloat
index 176fa9de3cec..0abe84bf175d 100644
--- a/include/cfloat
+++ b/include/cfloat
@@ -20,11 +20,18 @@ Macros:
FLT_EVAL_METHOD // C99
FLT_RADIX
+ FLT_HAS_SUBNORM // C11
+ DBL_HAS_SUBNORM // C11
+ LDBL_HAS_SUBNORM // C11
+
FLT_MANT_DIG
DBL_MANT_DIG
LDBL_MANT_DIG
DECIMAL_DIG // C99
+ FLT_DECIMAL_DIG // C11
+ DBL_DECIMAL_DIG // C11
+ LDBL_DECIMAL_DIG // C11
FLT_DIG
DBL_DIG
@@ -58,6 +65,9 @@ Macros:
DBL_MIN
LDBL_MIN
+ FLT_TRUE_MIN // C11
+ DBL_TRUE_MIN // C11
+ LDBL_TRUE_MIN // C11
*/
#include <__config>
diff --git a/include/charconv b/include/charconv
new file mode 100644
index 000000000000..7cb790e1beec
--- /dev/null
+++ b/include/charconv
@@ -0,0 +1,610 @@
+// -*- C++ -*-
+//===------------------------------ charconv ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CHARCONV
+#define _LIBCPP_CHARCONV
+
+/*
+ charconv synopsis
+
+namespace std {
+
+ // floating-point format for primitive numerical conversion
+ enum class chars_format {
+ scientific = unspecified,
+ fixed = unspecified,
+ hex = unspecified,
+ general = fixed | scientific
+ };
+
+ // 23.20.2, primitive numerical output conversion
+ struct to_chars_result {
+ char* ptr;
+ errc ec;
+ };
+
+ to_chars_result to_chars(char* first, char* last, see below value,
+ int base = 10);
+
+ to_chars_result to_chars(char* first, char* last, float value);
+ to_chars_result to_chars(char* first, char* last, double value);
+ to_chars_result to_chars(char* first, char* last, long double value);
+
+ to_chars_result to_chars(char* first, char* last, float value,
+ chars_format fmt);
+ to_chars_result to_chars(char* first, char* last, double value,
+ chars_format fmt);
+ to_chars_result to_chars(char* first, char* last, long double value,
+ chars_format fmt);
+
+ to_chars_result to_chars(char* first, char* last, float value,
+ chars_format fmt, int precision);
+ to_chars_result to_chars(char* first, char* last, double value,
+ chars_format fmt, int precision);
+ to_chars_result to_chars(char* first, char* last, long double value,
+ chars_format fmt, int precision);
+
+ // 23.20.3, primitive numerical input conversion
+ struct from_chars_result {
+ const char* ptr;
+ errc ec;
+ };
+
+ from_chars_result from_chars(const char* first, const char* last,
+ see below& value, int base = 10);
+
+ from_chars_result from_chars(const char* first, const char* last,
+ float& value,
+ chars_format fmt = chars_format::general);
+ from_chars_result from_chars(const char* first, const char* last,
+ double& value,
+ chars_format fmt = chars_format::general);
+ from_chars_result from_chars(const char* first, const char* last,
+ long double& value,
+ chars_format fmt = chars_format::general);
+
+} // namespace std
+
+*/
+
+#include <__errc>
+#include <type_traits>
+#include <limits>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 11
+
+enum class _LIBCPP_ENUM_VIS chars_format
+{
+ scientific = 0x1,
+ fixed = 0x2,
+ hex = 0x4,
+ general = fixed | scientific
+};
+
+struct _LIBCPP_TYPE_VIS to_chars_result
+{
+ char* ptr;
+ errc ec;
+};
+
+struct _LIBCPP_TYPE_VIS from_chars_result
+{
+ const char* ptr;
+ errc ec;
+};
+
+void to_chars(char*, char*, bool, int = 10) = delete;
+void from_chars(const char*, const char*, bool, int = 10) = delete;
+
+namespace __itoa
+{
+
+static constexpr uint64_t __pow10_64[] = {
+ UINT64_C(0),
+ UINT64_C(10),
+ UINT64_C(100),
+ UINT64_C(1000),
+ UINT64_C(10000),
+ UINT64_C(100000),
+ UINT64_C(1000000),
+ UINT64_C(10000000),
+ UINT64_C(100000000),
+ UINT64_C(1000000000),
+ UINT64_C(10000000000),
+ UINT64_C(100000000000),
+ UINT64_C(1000000000000),
+ UINT64_C(10000000000000),
+ UINT64_C(100000000000000),
+ UINT64_C(1000000000000000),
+ UINT64_C(10000000000000000),
+ UINT64_C(100000000000000000),
+ UINT64_C(1000000000000000000),
+ UINT64_C(10000000000000000000),
+};
+
+static constexpr uint32_t __pow10_32[] = {
+ UINT32_C(0), UINT32_C(10), UINT32_C(100),
+ UINT32_C(1000), UINT32_C(10000), UINT32_C(100000),
+ UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000),
+ UINT32_C(1000000000),
+};
+
+_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
+_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
+
+template <typename _Tp, typename = void>
+struct _LIBCPP_HIDDEN __traits_base
+{
+ using type = uint64_t;
+
+#if !defined(_LIBCPP_COMPILER_MSVC)
+ static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
+ {
+ auto __t = (64 - __builtin_clzll(__v | 1)) * 1233 >> 12;
+ return __t - (__v < __pow10_64[__t]) + 1;
+ }
+#endif
+
+ static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
+ {
+ return __u64toa(__v, __p);
+ }
+
+ static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_64; }
+};
+
+template <typename _Tp>
+struct _LIBCPP_HIDDEN
+ __traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))>
+{
+ using type = uint32_t;
+
+#if !defined(_LIBCPP_COMPILER_MSVC)
+ static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
+ {
+ auto __t = (32 - __builtin_clz(__v | 1)) * 1233 >> 12;
+ return __t - (__v < __pow10_32[__t]) + 1;
+ }
+#endif
+
+ static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
+ {
+ return __u32toa(__v, __p);
+ }
+
+ static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_32; }
+};
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY bool
+__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
+{
+ auto __c = __a * __b;
+ __r = __c;
+ return __c > (numeric_limits<unsigned char>::max)();
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY bool
+__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
+{
+ auto __c = __a * __b;
+ __r = __c;
+ return __c > (numeric_limits<unsigned short>::max)();
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY bool
+__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
+{
+ static_assert(is_unsigned<_Tp>::value, "");
+#if !defined(_LIBCPP_COMPILER_MSVC)
+ return __builtin_mul_overflow(__a, __b, &__r);
+#else
+ bool __did = __b && ((numeric_limits<_Tp>::max)() / __b) < __a;
+ __r = __a * __b;
+ return __did;
+#endif
+}
+
+template <typename _Tp, typename _Up>
+inline _LIBCPP_INLINE_VISIBILITY bool
+__mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
+{
+ return __mul_overflowed(__a, static_cast<_Tp>(__b), __r);
+}
+
+template <typename _Tp>
+struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
+{
+ static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
+ using __traits_base<_Tp>::__pow;
+ using typename __traits_base<_Tp>::type;
+
+ // precondition: at least one non-zero character available
+ static _LIBCPP_INLINE_VISIBILITY char const*
+ __read(char const* __p, char const* __ep, type& __a, type& __b)
+ {
+ type __cprod[digits];
+ int __j = digits - 1;
+ int __i = digits;
+ do
+ {
+ if (!('0' <= *__p && *__p <= '9'))
+ break;
+ __cprod[--__i] = *__p++ - '0';
+ } while (__p != __ep && __i != 0);
+
+ __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1,
+ __cprod[__i]);
+ if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
+ --__p;
+ return __p;
+ }
+
+ template <typename _It1, typename _It2, class _Up>
+ static _LIBCPP_INLINE_VISIBILITY _Up
+ __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
+ {
+ for (; __first1 < __last1; ++__first1, ++__first2)
+ __init = __init + *__first1 * *__first2;
+ return __init;
+ }
+};
+
+} // namespace __itoa
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _Tp
+__complement(_Tp __x)
+{
+ static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
+ return _Tp(~__x + 1);
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY auto
+__to_unsigned(_Tp __x)
+{
+ return static_cast<make_unsigned_t<_Tp>>(__x);
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
+{
+ auto __x = __to_unsigned(__value);
+ if (__value < 0 && __first != __last)
+ {
+ *__first++ = '-';
+ __x = __complement(__x);
+ }
+
+ return __to_chars_itoa(__first, __last, __x, false_type());
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
+{
+ using __tx = __itoa::__traits<_Tp>;
+ auto __diff = __last - __first;
+
+#if !defined(_LIBCPP_COMPILER_MSVC)
+ if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
+ return {__tx::__convert(__value, __first), {}};
+ else
+ return {__last, errc::value_too_large};
+#else
+ if (__tx::digits <= __diff)
+ return {__tx::__convert(__value, __first), {}};
+ else
+ {
+ char __buf[__tx::digits];
+ auto __p = __tx::__convert(__value, __buf);
+ auto __len = __p - __buf;
+ if (__len <= __diff)
+ {
+ memcpy(__first, __buf, __len);
+ return {__first + __len, {}};
+ }
+ else
+ return {__last, errc::value_too_large};
+ }
+#endif
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
+ true_type)
+{
+ auto __x = __to_unsigned(__value);
+ if (__value < 0 && __first != __last)
+ {
+ *__first++ = '-';
+ __x = __complement(__x);
+ }
+
+ return __to_chars_integral(__first, __last, __x, __base, false_type());
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
+ false_type)
+{
+ if (__base == 10)
+ return __to_chars_itoa(__first, __last, __value, false_type());
+
+ auto __p = __last;
+ while (__p != __first)
+ {
+ auto __c = __value % __base;
+ __value /= __base;
+ *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
+ if (__value == 0)
+ break;
+ }
+
+ auto __len = __last - __p;
+ if (__value != 0 || !__len)
+ return {__last, errc::value_too_large};
+ else
+ {
+ memmove(__first, __p, __len);
+ return {__first + __len, {}};
+ }
+}
+
+template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+to_chars(char* __first, char* __last, _Tp __value)
+{
+ return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>());
+}
+
+template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY to_chars_result
+to_chars(char* __first, char* __last, _Tp __value, int __base)
+{
+ _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
+ return __to_chars_integral(__first, __last, __value, __base,
+ is_signed<_Tp>());
+}
+
+template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
+{
+ using __tl = numeric_limits<_Tp>;
+ decltype(__to_unsigned(__value)) __x;
+
+ bool __neg = (__first != __last && *__first == '-');
+ auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
+ switch (__r.ec)
+ {
+ case errc::invalid_argument:
+ return {__first, __r.ec};
+ case errc::result_out_of_range:
+ return __r;
+ default:
+ break;
+ }
+
+ if (__neg)
+ {
+ if (__x <= __complement(__to_unsigned(__tl::min())))
+ {
+ __x = __complement(__x);
+ memcpy(&__value, &__x, sizeof(__x));
+ return __r;
+ }
+ }
+ else
+ {
+ if (__x <= (__tl::max)())
+ {
+ __value = __x;
+ return __r;
+ }
+ }
+
+ return {__r.ptr, errc::result_out_of_range};
+}
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY bool
+__in_pattern(_Tp __c)
+{
+ return '0' <= __c && __c <= '9';
+}
+
+struct _LIBCPP_HIDDEN __in_pattern_result
+{
+ bool __ok;
+ int __val;
+
+ explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; }
+};
+
+template <typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY __in_pattern_result
+__in_pattern(_Tp __c, int __base)
+{
+ if (__base <= 10)
+ return {'0' <= __c && __c < '0' + __base, __c - '0'};
+ else if (__in_pattern(__c))
+ return {true, __c - '0'};
+ else if ('a' <= __c && __c < 'a' + __base - 10)
+ return {true, __c - 'a' + 10};
+ else
+ return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
+}
+
+template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
+ _Ts... __args)
+{
+ auto __find_non_zero = [](_It __first, _It __last) {
+ for (; __first != __last; ++__first)
+ if (*__first != '0')
+ break;
+ return __first;
+ };
+
+ auto __p = __find_non_zero(__first, __last);
+ if (__p == __last || !__in_pattern(*__p, __args...))
+ {
+ if (__p == __first)
+ return {__first, errc::invalid_argument};
+ else
+ {
+ __value = 0;
+ return {__p, {}};
+ }
+ }
+
+ auto __r = __f(__p, __last, __value, __args...);
+ if (__r.ec == errc::result_out_of_range)
+ {
+ for (; __r.ptr != __last; ++__r.ptr)
+ {
+ if (!__in_pattern(*__r.ptr, __args...))
+ break;
+ }
+ }
+
+ return __r;
+}
+
+template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
+{
+ using __tx = __itoa::__traits<_Tp>;
+ using __output_type = typename __tx::type;
+
+ return __subject_seq_combinator(
+ __first, __last, __value,
+ [](const char* __first, const char* __last,
+ _Tp& __value) -> from_chars_result {
+ __output_type __a, __b;
+ auto __p = __tx::__read(__first, __last, __a, __b);
+ if (__p == __last || !__in_pattern(*__p))
+ {
+ __output_type __m = (numeric_limits<_Tp>::max)();
+ if (__m >= __a && __m - __a >= __b)
+ {
+ __value = __a + __b;
+ return {__p, {}};
+ }
+ }
+ return {__p, errc::result_out_of_range};
+ });
+}
+
+template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
+{
+ using __t = decltype(__to_unsigned(__value));
+ return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
+}
+
+template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
+ int __base)
+{
+ if (__base == 10)
+ return __from_chars_atoi(__first, __last, __value);
+
+ return __subject_seq_combinator(
+ __first, __last, __value,
+ [](const char* __p, const char* __last, _Tp& __value,
+ int __base) -> from_chars_result {
+ using __tl = numeric_limits<_Tp>;
+ auto __digits = __tl::digits / log2f(float(__base));
+ _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0;
+
+ for (int __i = 1; __p != __last; ++__i, ++__p)
+ {
+ if (auto __c = __in_pattern(*__p, __base))
+ {
+ if (__i < __digits - 1)
+ __a = __a * __base + __c.__val;
+ else
+ {
+ if (!__itoa::__mul_overflowed(__a, __base, __a))
+ ++__p;
+ __b = __c.__val;
+ break;
+ }
+ }
+ else
+ break;
+ }
+
+ if (__p == __last || !__in_pattern(*__p, __base))
+ {
+ if ((__tl::max)() - __a >= __b)
+ {
+ __value = __a + __b;
+ return {__p, {}};
+ }
+ }
+ return {__p, errc::result_out_of_range};
+ },
+ __base);
+}
+
+template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
+ int __base)
+{
+ using __t = decltype(__to_unsigned(__value));
+ return __sign_combinator(__first, __last, __value,
+ __from_chars_integral<__t>, __base);
+}
+
+template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+from_chars(const char* __first, const char* __last, _Tp& __value)
+{
+ return __from_chars_atoi(__first, __last, __value);
+}
+
+template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
+inline _LIBCPP_INLINE_VISIBILITY from_chars_result
+from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
+{
+ _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
+ return __from_chars_integral(__first, __last, __value, __base);
+}
+
+#endif // _LIBCPP_STD_VER > 11
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_CHARCONV
diff --git a/include/ctime b/include/ctime
index da9e3290bbb2..81cf11a466c2 100644
--- a/include/ctime
+++ b/include/ctime
@@ -18,7 +18,8 @@ Macros:
NULL
CLOCKS_PER_SEC
-
+ TIME_UTC // C++17
+
namespace std
{
@@ -28,7 +29,8 @@ Types:
size_t
time_t
tm
-
+ timespec // C++17
+
clock_t clock();
double difftime(time_t time1, time_t time0);
time_t mktime(tm* timeptr);
@@ -39,7 +41,7 @@ tm* gmtime(const time_t* timer);
tm* localtime(const time_t* timer);
size_t strftime(char* restrict s, size_t maxsize, const char* restrict format,
const tm* restrict timeptr);
-
+int timespec_get( struct timespec *ts, int base); // C++17
} // std
*/
@@ -57,6 +59,9 @@ using ::clock_t;
using ::size_t;
using ::time_t;
using ::tm;
+#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES)
+using ::timespec;
+#endif
using ::clock;
using ::difftime;
using ::mktime;
@@ -68,6 +73,9 @@ using ::gmtime;
using ::localtime;
#endif
using ::strftime;
+#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES)
+using ::timespec_get;
+#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/include/experimental/__config b/include/experimental/__config
index 55ae31b8aea3..c6f177620224 100644
--- a/include/experimental/__config
+++ b/include/experimental/__config
@@ -64,4 +64,11 @@
#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI \
} _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
+// TODO: support more targets
+#if defined(__AVX__)
+#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32
+#else
+#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16
+#endif
+
#endif
diff --git a/include/experimental/simd b/include/experimental/simd
index 4876ccb82d20..6580443f7b03 100644
--- a/include/experimental/simd
+++ b/include/experimental/simd
@@ -651,6 +651,7 @@ public:
*/
#include <experimental/__config>
+#include <algorithm>
#include <array>
#include <cstddef>
#include <functional>
@@ -661,26 +662,246 @@ public:
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
+#if _LIBCPP_STD_VER >= 17
+
enum class _StorageKind {
_Scalar,
_Array,
+ _VecExt,
};
template <_StorageKind __kind, int _Np>
struct __simd_abi {};
template <class _Tp, class _Abi>
-struct __simd_storage_traits {};
+class __simd_storage {};
template <class _Tp, int __num_element>
-struct __simd_storage_traits<_Tp,
- __simd_abi<_StorageKind::_Array, __num_element>> {
- using type = std::array<_Tp, __num_element>;
+class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
+ std::array<_Tp, __num_element> __storage_;
+
+ template <class, class>
+ friend struct simd;
+
+ template <class, class>
+ friend struct simd_mask;
+
+public:
+ _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
+ void __set(size_t __index, _Tp __val) noexcept {
+ __storage_[__index] = __val;
+ }
};
template <class _Tp>
-struct __simd_storage_traits<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
- using type = _Tp;
+class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
+ _Tp __storage_;
+
+ template <class, class>
+ friend struct simd;
+
+ template <class, class>
+ friend struct simd_mask;
+
+public:
+ _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; };
+ void __set(size_t __index, _Tp __val) noexcept {
+ (&__storage_)[__index] = __val;
+ }
+};
+
+#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
+constexpr size_t __floor_pow_of_2(size_t __val) {
+ return ((__val - 1) & __val) == 0 ? __val
+ : __floor_pow_of_2((__val - 1) & __val);
+}
+
+constexpr size_t __ceil_pow_of_2(size_t __val) {
+ return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1;
+}
+
+template <class _Tp, size_t __bytes>
+struct __vec_ext_traits {
+#if !defined(_LIBCPP_COMPILER_CLANG)
+ typedef _Tp type __attribute__((vector_size(__ceil_pow_of_2(__bytes))));
+#endif
+};
+
+#if defined(_LIBCPP_COMPILER_CLANG)
+#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT) \
+ template <> \
+ struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> { \
+ using type = \
+ _TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT))); \
+ }
+
+#define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE) \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 1); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 2); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 3); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 4); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 5); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 6); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 7); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 8); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 9); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 10); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 11); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 12); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 13); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 14); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 15); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 16); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 17); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 18); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 19); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 20); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 21); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 22); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 23); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 24); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 25); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 26); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 27); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 28); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 29); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 30); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 31); \
+ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32);
+
+_LIBCPP_SPECIALIZE_VEC_EXT_32(char);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(char16_t);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(char32_t);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(wchar_t);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(signed char);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(signed short);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(signed int);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long long);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned char);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned short);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned int);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long long);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(float);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(double);
+_LIBCPP_SPECIALIZE_VEC_EXT_32(long double);
+
+#undef _LIBCPP_SPECIALIZE_VEC_EXT_32
+#undef _LIBCPP_SPECIALIZE_VEC_EXT
+#endif
+
+template <class _Tp, int __num_element>
+class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
+ using _StorageType =
+ typename __vec_ext_traits<_Tp, sizeof(_Tp) * __num_element>::type;
+
+ _StorageType __storage_;
+
+ template <class, class>
+ friend struct simd;
+
+ template <class, class>
+ friend struct simd_mask;
+
+public:
+ _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
+ void __set(size_t __index, _Tp __val) noexcept {
+ __storage_[__index] = __val;
+ }
+};
+
+#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
+template <class _Vp, class _Tp, class _Abi>
+class __simd_reference {
+ static_assert(std::is_same<_Vp, _Tp>::value, "");
+
+ template <class, class>
+ friend struct simd;
+
+ template <class, class>
+ friend struct simd_mask;
+
+ __simd_storage<_Tp, _Abi>* __ptr_;
+ size_t __index_;
+
+ __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
+ : __ptr_(__ptr), __index_(__index) {}
+
+ __simd_reference(const __simd_reference&) = default;
+
+public:
+ __simd_reference() = delete;
+ __simd_reference& operator=(const __simd_reference&) = delete;
+
+ operator _Vp() const { return __ptr_->__get(__index_); }
+
+ __simd_reference operator=(_Vp __value) && {
+ __ptr_->__set(__index_, __value);
+ return *this;
+ }
+
+ __simd_reference operator++() && {
+ return std::move(*this) = __ptr_->__get(__index_) + 1;
+ }
+
+ _Vp operator++(int) && {
+ auto __val = __ptr_->__get(__index_);
+ __ptr_->__set(__index_, __val + 1);
+ return __val;
+ }
+
+ __simd_reference operator--() && {
+ return std::move(*this) = __ptr_->__get(__index_) - 1;
+ }
+
+ _Vp operator--(int) && {
+ auto __val = __ptr_->__get(__index_);
+ __ptr_->__set(__index_, __val - 1);
+ return __val;
+ }
+
+ __simd_reference operator+=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) + __value;
+ }
+
+ __simd_reference operator-=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) - __value;
+ }
+
+ __simd_reference operator*=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) * __value;
+ }
+
+ __simd_reference operator/=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) / __value;
+ }
+
+ __simd_reference operator%=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) % __value;
+ }
+
+ __simd_reference operator>>=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) >> __value;
+ }
+
+ __simd_reference operator<<=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) << __value;
+ }
+
+ __simd_reference operator&=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) & __value;
+ }
+
+ __simd_reference operator|=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) | __value;
+ }
+
+ __simd_reference operator^=(_Vp __value) && {
+ return std::move(*this) = __ptr_->__get(__index_) ^ __value;
+ }
};
template <class _To, class _From>
@@ -720,6 +941,17 @@ constexpr _Tp __variadic_sum(_Up __first, _Args... __rest) {
return static_cast<_Tp>(__first) + __variadic_sum<_Tp>(__rest...);
}
+template <class _Tp>
+struct __nodeduce {
+ using type = _Tp;
+};
+
+template <class _Tp>
+constexpr bool __vectorizable() {
+ return std::is_arithmetic<_Tp>::value && !std::is_const<_Tp>::value &&
+ !std::is_volatile<_Tp>::value && !std::is_same<_Tp, bool>::value;
+}
+
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD_ABI
@@ -728,14 +960,21 @@ using scalar = __simd_abi<_StorageKind::_Scalar, 1>;
template <int _Np>
using fixed_size = __simd_abi<_StorageKind::_Array, _Np>;
-#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
-_LIBCPP_INLINE_VAR constexpr int max_fixed_size = 32;
-#endif
+_LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 32;
+
template <class _Tp>
using compatible = fixed_size<16 / sizeof(_Tp)>;
+
+#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
template <class _Tp>
-using native = compatible<_Tp>;
+using native = __simd_abi<_StorageKind::_VecExt,
+ _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
+#else
+template <class _Tp>
+using native =
+ fixed_size<_Tp, _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
+#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
@@ -749,14 +988,10 @@ struct element_aligned_tag {};
struct vector_aligned_tag {};
template <size_t>
struct overaligned_tag {};
-#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VAR constexpr element_aligned_tag element_aligned{};
_LIBCPP_INLINE_VAR constexpr vector_aligned_tag vector_aligned{};
-#if !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <size_t _Np>
_LIBCPP_INLINE_VAR constexpr overaligned_tag<_Np> overaligned{};
-#endif
-#endif
// traits [simd.traits]
template <class _Tp>
@@ -794,7 +1029,6 @@ template <size_t _Align>
struct is_simd_flag_type<overaligned_tag<_Align>>
: std::integral_constant<bool, true> {};
-#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value;
template <class _Tp>
@@ -804,7 +1038,6 @@ _LIBCPP_INLINE_VAR constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value;
template <class _Tp>
_LIBCPP_INLINE_VAR constexpr bool is_simd_flag_type_v =
is_simd_flag_type<_Tp>::value;
-#endif
template <class _Tp, size_t _Np>
struct abi_for_size {
using type = simd_abi::fixed_size<_Np>;
@@ -824,17 +1057,16 @@ struct simd_size<_Tp, __simd_abi<__kind, _Np>>
"Element type should be vectorizable");
};
+// TODO: implement it.
template <class _Tp, class _Up = typename _Tp::value_type>
struct memory_alignment;
-#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
_LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
template <class _Tp, class _Up = typename _Tp::value_type>
_LIBCPP_INLINE_VAR constexpr size_t memory_alignment_v =
memory_alignment<_Tp, _Up>::value;
-#endif
// class template simd [simd.class]
template <class _Tp>
@@ -972,11 +1204,6 @@ template <class _MaskType, class _Tp>
class where_expression;
// masked assignment [simd.mask.where]
-template <class _Tp>
-struct __nodeduce {
- using type = _Tp;
-};
-
template <class _Tp, class _Abi>
where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>>
where(const typename simd<_Tp, _Abi>::mask_type&, simd<_Tp, _Abi>&) noexcept;
@@ -1113,7 +1340,23 @@ public:
// TODO: implement simd
template <class _Tp, class _Abi>
class simd {
+public:
+ using value_type = _Tp;
+ using reference = __simd_reference<_Tp, _Tp, _Abi>;
+ using mask_type = simd_mask<_Tp, _Abi>;
+ using abi_type = _Abi;
+
+ simd() = default;
+ simd(const simd&) = default;
+ simd& operator=(const simd&) = default;
+
+ static constexpr size_t size() noexcept {
+ return simd_size<_Tp, _Abi>::value;
+ }
+
private:
+ __simd_storage<_Tp, _Abi> __s_;
+
template <class _Up>
static constexpr bool __can_broadcast() {
return (std::is_arithmetic<_Up>::value &&
@@ -1126,57 +1369,97 @@ private:
std::is_unsigned<_Tp>::value);
}
-public:
- using value_type = _Tp;
- // TODO: this is strawman implementation. Turn it into a proxy type.
- using reference = _Tp&;
- using mask_type = simd_mask<_Tp, _Abi>;
-
- using abi_type = _Abi;
+ template <class _Generator, size_t... __indicies>
+ static constexpr decltype(
+ std::forward_as_tuple(std::declval<_Generator>()(
+ std::integral_constant<size_t, __indicies>())...),
+ bool())
+ __can_generate(std::index_sequence<__indicies...>) {
+ return !__variadic_sum<bool>(
+ !__can_broadcast<decltype(std::declval<_Generator>()(
+ std::integral_constant<size_t, __indicies>()))>()...);
+ }
- static constexpr size_t size() noexcept {
- return simd_size<_Tp, _Abi>::value;
+ template <class _Generator>
+ static bool __can_generate(...) {
+ return false;
}
- simd() = default;
+ template <class _Generator, size_t... __indicies>
+ void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
+ int __not_used[]{((*this)[__indicies] =
+ __g(std::integral_constant<size_t, __indicies>()),
+ 0)...};
+ (void)__not_used;
+ }
+public:
// implicit type conversion constructor
template <class _Up,
class = typename std::enable_if<
std::is_same<_Abi, simd_abi::fixed_size<size()>>::value &&
__is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type>
- simd(const simd<_Up, simd_abi::fixed_size<size()>>&) {}
+ simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) {
+ for (size_t __i = 0; __i < size(); __i++) {
+ (*this)[__i] = static_cast<_Tp>(__v[__i]);
+ }
+ }
// implicit broadcast constructor
template <class _Up,
class = typename std::enable_if<__can_broadcast<_Up>()>::type>
- simd(_Up&&);
+ simd(_Up&& __rv) {
+ auto __v = static_cast<_Tp>(__rv);
+ for (size_t __i = 0; __i < size(); __i++) {
+ (*this)[__i] = __v;
+ }
+ }
// generator constructor
- // TODO: for now only check for the index 0. This is because C++11 doesn't
- // have index_sequence, and it's hard to check for all indicies without using
- // index_sequence.
template <class _Generator,
- int = decltype(simd(std::declval<_Generator>()(
- std::integral_constant<size_t, 0>())),
- int())()>
- explicit simd(_Generator&&);
+ int = typename std::enable_if<
+ __can_generate<_Generator>(std::make_index_sequence<size()>()),
+ int>::type()>
+ explicit simd(_Generator&& __g) {
+ __generator_init(std::forward<_Generator>(__g),
+ std::make_index_sequence<size()>());
+ }
// load constructor
- template <class _Up, class _Flags>
- simd(const _Up*, _Flags);
+ template <
+ class _Up, class _Flags,
+ class = typename std::enable_if<__vectorizable<_Up>()>::type,
+ class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type>
+ simd(const _Up* __buffer, _Flags) {
+ // TODO: optimize for overaligned flags
+ for (size_t __i = 0; __i < size(); __i++) {
+ (*this)[__i] = static_cast<_Tp>(__buffer[__i]);
+ }
+ }
// loads [simd.load]
template <class _Up, class _Flags>
- void copy_from(const _Up*, _Flags);
+ typename std::enable_if<__vectorizable<_Up>() &&
+ is_simd_flag_type<_Flags>::value>::type
+ copy_from(const _Up* __buffer, _Flags) {
+ *this = simd(__buffer, _Flags());
+ }
// stores [simd.store]
template <class _Up, class _Flags>
- void copy_to(_Up*, _Flags) const;
+ typename std::enable_if<__vectorizable<_Up>() &&
+ is_simd_flag_type<_Flags>::value>::type
+ copy_to(_Up* __buffer, _Flags) const {
+ // TODO: optimize for overaligned flags
+ for (size_t __i = 0; __i < size(); __i++) {
+ __buffer[__i] = static_cast<_Up>((*this)[__i]);
+ }
+ }
// scalar access [simd.subscr]
- reference operator[](size_t);
- value_type operator[](size_t) const;
+ reference operator[](size_t __i) { return reference(&__s_, __i); }
+
+ value_type operator[](size_t __i) const { return __s_.__get(__i); }
// unary operators [simd.unary]
simd& operator++();
@@ -1280,6 +1563,8 @@ public:
friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept;
};
+#endif // _LIBCPP_STD_VER >= 17
+
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
#endif /* _LIBCPP_EXPERIMENTAL_SIMD */
diff --git a/include/float.h b/include/float.h
index 1acfdc6188f2..759ac8e79543 100644
--- a/include/float.h
+++ b/include/float.h
@@ -24,7 +24,14 @@ Macros:
DBL_MANT_DIG
LDBL_MANT_DIG
+ FLT_HAS_SUBNORM // C11
+ DBL_HAS_SUBNORM // C11
+ LDBL_HAS_SUBNORM // C11
+
DECIMAL_DIG // C99
+ FLT_DECIMAL_DIG // C11
+ DBL_DECIMAL_DIG // C11
+ LDBL_DECIMAL_DIG // C11
FLT_DIG
DBL_DIG
@@ -58,6 +65,10 @@ Macros:
DBL_MIN
LDBL_MIN
+ FLT_TRUE_MIN // C11
+ DBL_TRUE_MIN // C11
+ LDBL_TRUE_MIN // C11
+
*/
#include <__config>
diff --git a/include/functional b/include/functional
index 80261895e6e5..6b70f731e1cc 100644
--- a/include/functional
+++ b/include/functional
@@ -2005,7 +2005,7 @@ namespace placeholders
template <int _Np> struct __ph {};
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND)
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
_LIBCPP_FUNC_VIS extern const __ph<1> _1;
_LIBCPP_FUNC_VIS extern const __ph<2> _2;
_LIBCPP_FUNC_VIS extern const __ph<3> _3;
@@ -2027,7 +2027,7 @@ _LIBCPP_FUNC_VIS extern const __ph<10> _10;
/* _LIBCPP_INLINE_VAR */ constexpr __ph<8> _8{};
/* _LIBCPP_INLINE_VAR */ constexpr __ph<9> _9{};
/* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{};
-#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND)
+#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
} // placeholders
diff --git a/include/map b/include/map
index 97ce4d0b18c7..559ec484aca0 100644
--- a/include/map
+++ b/include/map
@@ -40,6 +40,8 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef unspecified node_type; // C++17
+ typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
class value_compare
: public binary_function<value_type, value_type, bool>
@@ -137,6 +139,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ insert_return_type insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
template <class... Args>
@@ -260,6 +267,7 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef unspecified node_type; // C++17
class value_compare
: public binary_function<value_type,value_type,bool>
@@ -349,6 +357,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ iterator insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -440,6 +453,7 @@ swap(multimap<Key, T, Compare, Allocator>& x,
#include <__config>
#include <__tree>
+#include <__node_handle>
#include <iterator>
#include <memory>
#include <utility>
@@ -906,6 +920,11 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
+ typedef __insert_return_type<iterator, node_type> insert_return_type;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
map()
_NOEXCEPT_(
@@ -1253,6 +1272,35 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__tree_.clear();}
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ insert_return_type insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to map::insert()");
+ return __tree_.template __node_handle_insert_unique<
+ node_type, insert_return_type>(_VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __hint, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to map::insert()");
+ return __tree_.template __node_handle_insert_unique<node_type>(
+ __hint.__i_, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __tree_.template __node_handle_extract<node_type>(__key);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __it)
+ {
+ return __tree_.template __node_handle_extract<node_type>(__it.__i_);
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
void swap(map& __m)
_NOEXCEPT_(__is_nothrow_swappable<__base>::value)
@@ -1562,6 +1610,10 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
multimap()
_NOEXCEPT_(
@@ -1800,6 +1852,37 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __f, const_iterator __l)
{return __tree_.erase(__f.__i_, __l.__i_);}
+
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to multimap::insert()");
+ return __tree_.template __node_handle_insert_multi<node_type>(
+ _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __hint, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to multimap::insert()");
+ return __tree_.template __node_handle_insert_multi<node_type>(
+ __hint.__i_, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __tree_.template __node_handle_extract<node_type>(__key);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __it)
+ {
+ return __tree_.template __node_handle_extract<node_type>(
+ __it.__i_);
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
void clear() {__tree_.clear();}
diff --git a/include/memory b/include/memory
index fd830d7ed2cc..a4bf89b495ad 100644
--- a/include/memory
+++ b/include/memory
@@ -3511,7 +3511,7 @@ public:
explicit __shared_count(long __refs = 0) _NOEXCEPT
: __shared_owners_(__refs) {}
-#if defined(_LIBCPP_BUILDING_MEMORY) && \
+#if defined(_LIBCPP_BUILDING_LIBRARY) && \
defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
void __add_shared() _NOEXCEPT;
bool __release_shared() _NOEXCEPT;
@@ -3549,7 +3549,7 @@ protected:
virtual ~__shared_weak_count();
public:
-#if defined(_LIBCPP_BUILDING_MEMORY) && \
+#if defined(_LIBCPP_BUILDING_LIBRARY) && \
defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
void __add_shared() _NOEXCEPT;
void __add_weak() _NOEXCEPT;
@@ -5549,7 +5549,7 @@ struct _LIBCPP_TYPE_VIS pointer_safety
#endif
#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
- defined(_LIBCPP_BUILDING_MEMORY)
+ defined(_LIBCPP_BUILDING_LIBRARY)
_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
#else
// This function is only offered in C++03 under ABI v1.
diff --git a/include/module.modulemap b/include/module.modulemap
index 127a42b0633d..089505586fb3 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -235,6 +235,10 @@ module std [system] {
export *
}
// No submodule for cassert. It fundamentally needs repeated, textual inclusion.
+ module charconv {
+ header "charconv"
+ export *
+ }
module chrono {
header "chrono"
export *
@@ -498,6 +502,7 @@ module std [system] {
module __tree { header "__tree" export * }
module __tuple { header "__tuple" export * }
module __undef_macros { header "__undef_macros" export * }
+ module __node_handle { header "__node_handle" export * }
module experimental {
requires cplusplus11
diff --git a/include/new b/include/new
index b5dc05542b59..e70b9c621570 100644
--- a/include/new
+++ b/include/new
@@ -103,13 +103,13 @@ void operator delete[](void* ptr, void*) noexcept;
#pragma GCC system_header
#endif
-#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
+#if !(defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_STD_VER >= 14 || \
(defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309))
# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#endif
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
- (!(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \
+ (!(defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_STD_VER > 14 || \
(defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606)))
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
#endif
@@ -167,7 +167,7 @@ public:
#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
-#endif // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
+#endif // defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11)
#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14
diff --git a/include/set b/include/set
index 94db8c79d107..108a9e97f88d 100644
--- a/include/set
+++ b/include/set
@@ -40,6 +40,8 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef unspecified node_type; // C++17
+ typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
// construct/copy/destroy:
set()
@@ -115,6 +117,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ insert_return_type insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -222,6 +229,7 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef unspecified node_type; // C++17
// construct/copy/destroy:
multiset()
@@ -297,6 +305,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ iterator insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -387,6 +400,7 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
#include <__config>
#include <__tree>
+#include <__node_handle>
#include <functional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -429,6 +443,11 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
+ typedef __insert_return_type<iterator, node_type> insert_return_type;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
set()
_NOEXCEPT_(
@@ -634,6 +653,35 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__tree_.clear();}
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ insert_return_type insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to set::insert()");
+ return __tree_.template __node_handle_insert_unique<
+ node_type, insert_return_type>(_VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __hint, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to set::insert()");
+ return __tree_.template __node_handle_insert_unique<node_type>(
+ __hint, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __tree_.template __node_handle_extract<node_type>(__key);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __it)
+ {
+ return __tree_.template __node_handle_extract<node_type>(__it);
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
{__tree_.swap(__s.__tree_);}
@@ -838,6 +886,10 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
+#endif
+
// construct/copy/destroy:
_LIBCPP_INLINE_VISIBILITY
multiset()
@@ -1042,6 +1094,35 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__tree_.clear();}
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to multiset::insert()");
+ return __tree_.template __node_handle_insert_multi<node_type>(
+ _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __hint, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to multiset::insert()");
+ return __tree_.template __node_handle_insert_multi<node_type>(
+ __hint, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __tree_.template __node_handle_extract<node_type>(__key);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __it)
+ {
+ return __tree_.template __node_handle_extract<node_type>(__it);
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
void swap(multiset& __s)
_NOEXCEPT_(__is_nothrow_swappable<__base>::value)
diff --git a/include/shared_mutex b/include/shared_mutex
index 9cb81528cd9d..a7735d6732c5 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -129,7 +129,7 @@ _LIBCPP_PUSH_MACROS
#include <__undef_macros>
-#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX)
+#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_LIBRARY)
#include <__mutex_base>
diff --git a/include/support/newlib/xlocale.h b/include/support/newlib/xlocale.h
index 4b7e9b7495a0..09f9e3987526 100644
--- a/include/support/newlib/xlocale.h
+++ b/include/support/newlib/xlocale.h
@@ -19,9 +19,9 @@
#if !defined(__NEWLIB__) || __NEWLIB__ < 2 || \
__NEWLIB__ == 2 && __NEWLIB_MINOR__ < 5
#include <support/xlocale/__nop_locale_mgmt.h>
-#endif
#include <support/xlocale/__posix_l_fallback.h>
#include <support/xlocale/__strtonum_fallback.h>
+#endif
#endif // _NEWLIB_VERSION
diff --git a/include/system_error b/include/system_error
index 917c710290ac..6e2c8388f17e 100644
--- a/include/system_error
+++ b/include/system_error
@@ -199,7 +199,7 @@ class _LIBCPP_TYPE_VIS error_category
public:
virtual ~error_category() _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_SYSTEM_ERROR) && \
+#if defined(_LIBCPP_BUILDING_LIBRARY) && \
defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
error_category() _NOEXCEPT;
#else
diff --git a/include/unordered_map b/include/unordered_map
index f34d82efdc33..348f57923b52 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -44,6 +44,9 @@ public:
typedef /unspecified/ local_iterator;
typedef /unspecified/ const_local_iterator;
+ typedef unspecified node_type; // C++17
+ typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
+
unordered_map()
noexcept(
is_nothrow_default_constructible<hasher>::value &&
@@ -122,6 +125,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ insert_return_type insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
template <class... Args>
@@ -226,6 +234,8 @@ public:
typedef /unspecified/ local_iterator;
typedef /unspecified/ const_local_iterator;
+ typedef unspecified node_type; // C++17
+
unordered_multimap()
noexcept(
is_nothrow_default_constructible<hasher>::value &&
@@ -304,6 +314,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ iterator insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -367,6 +382,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
#include <__config>
#include <__hash_table>
+#include <__node_handle>
#include <functional>
#include <stdexcept>
#include <tuple>
@@ -843,6 +859,11 @@ public:
typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __map_node_handle<__node, allocator_type> node_type;
+ typedef __insert_return_type<iterator, node_type> insert_return_type;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
unordered_map()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -1136,7 +1157,37 @@ public:
iterator erase(const_iterator __first, const_iterator __last)
{return __table_.erase(__first.__i_, __last.__i_);}
_LIBCPP_INLINE_VISIBILITY
- void clear() _NOEXCEPT {__table_.clear();}
+ void clear() _NOEXCEPT {__table_.clear();}
+
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ insert_return_type insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_map::insert()");
+ return __table_.template __node_handle_insert_unique<
+ node_type, insert_return_type>(_VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __hint, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_map::insert()");
+ return __table_.template __node_handle_insert_unique<node_type>(
+ __hint.__i_, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __table_.template __node_handle_extract<node_type>(__key);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __it)
+ {
+ return __table_.template __node_handle_extract<node_type>(
+ __it.__i_);
+ }
+#endif
_LIBCPP_INLINE_VISIBILITY
void swap(unordered_map& __u)
@@ -1590,6 +1641,10 @@ public:
typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __map_node_handle<__node, allocator_type> node_type;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
unordered_multimap()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -1763,6 +1818,36 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__table_.clear();}
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_multimap::insert()");
+ return __table_.template __node_handle_insert_multi<node_type>(
+ _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __hint, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_multimap::insert()");
+ return __table_.template __node_handle_insert_multi<node_type>(
+ __hint.__i_, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __table_.template __node_handle_extract<node_type>(__key);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __it)
+ {
+ return __table_.template __node_handle_extract<node_type>(
+ __it.__i_);
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
void swap(unordered_multimap& __u)
_NOEXCEPT_(__is_nothrow_swappable<__table>::value)
diff --git a/include/unordered_set b/include/unordered_set
index 3ae024a45eed..9b8560da494a 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -43,6 +43,9 @@ public:
typedef /unspecified/ local_iterator;
typedef /unspecified/ const_local_iterator;
+ typedef unspecified node_type unspecified; // C++17
+ typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
+
unordered_set()
noexcept(
is_nothrow_default_constructible<hasher>::value &&
@@ -113,6 +116,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ insert_return_type insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -191,6 +199,8 @@ public:
typedef /unspecified/ local_iterator;
typedef /unspecified/ const_local_iterator;
+ typedef unspecified node_type unspecified; // C++17
+
unordered_multiset()
noexcept(
is_nothrow_default_constructible<hasher>::value &&
@@ -261,6 +271,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
+ node_type extract(const_iterator position); // C++17
+ node_type extract(const key_type& x); // C++17
+ iterator insert(node_type&& nh); // C++17
+ iterator insert(const_iterator hint, node_type&& nh); // C++17
+
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -321,6 +336,7 @@ template <class Value, class Hash, class Pred, class Alloc>
#include <__config>
#include <__hash_table>
+#include <__node_handle>
#include <functional>
#include <__debug>
@@ -363,6 +379,11 @@ public:
typedef typename __table::const_local_iterator local_iterator;
typedef typename __table::const_local_iterator const_local_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
+ typedef __insert_return_type<iterator, node_type> insert_return_type;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
unordered_set()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -541,6 +562,35 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__table_.clear();}
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ insert_return_type insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_set::insert()");
+ return __table_.template __node_handle_insert_unique<
+ node_type, insert_return_type>(_VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __h, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_set::insert()");
+ return __table_.template __node_handle_insert_unique<node_type>(
+ __h, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __table_.template __node_handle_extract<node_type>(__key);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __it)
+ {
+ return __table_.template __node_handle_extract<node_type>(__it);
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
void swap(unordered_set& __u)
_NOEXCEPT_(__is_nothrow_swappable<__table>::value)
@@ -883,6 +933,10 @@ public:
typedef typename __table::const_local_iterator local_iterator;
typedef typename __table::const_local_iterator const_local_iterator;
+#if _LIBCPP_STD_VER > 14
+ typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
unordered_multiset()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -1019,6 +1073,36 @@ public:
_LIBCPP_INLINE_VISIBILITY
void insert(_InputIterator __first, _InputIterator __last);
+#if _LIBCPP_STD_VER > 14
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_multiset::insert()");
+ return __table_.template __node_handle_insert_multi<node_type>(
+ _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert(const_iterator __hint, node_type&& __nh)
+ {
+ _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
+ "node_type with incompatible allocator passed to unordered_multiset::insert()");
+ return __table_.template __node_handle_insert_multi<node_type>(
+ __hint, _VSTD::move(__nh));
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(const_iterator __position)
+ {
+ return __table_.template __node_handle_extract<node_type>(
+ __position);
+ }
+ _LIBCPP_INLINE_VISIBILITY
+ node_type extract(key_type const& __key)
+ {
+ return __table_.template __node_handle_extract<node_type>(__key);
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __p) {return __table_.erase(__p);}
_LIBCPP_INLINE_VISIBILITY
diff --git a/include/utility b/include/utility
index 8fdaf65db6a6..ed9bf030d499 100644
--- a/include/utility
+++ b/include/utility
@@ -295,7 +295,7 @@ template <class _Tp> void as_const(const _Tp&&) = delete;
#endif
struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { };
-#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_UTILITY)
+#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
#else
/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
diff --git a/lib/abi/x86_64-unknown-linux-gnu.v1.abilist b/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
index c883a593ee8e..833342ca8992 100644
--- a/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
+++ b/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
@@ -1192,6 +1192,8 @@
{'name': '_ZNSt3__15wclogE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
{'name': '_ZNSt3__15wcoutE', 'is_defined': True, 'type': 'OBJECT', 'size': 160}
{'name': '_ZNSt3__16__clocEv', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'is_defined': True, 'type': 'FUNC'}
+{'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__16__sortIRNS_6__lessIccEEPcEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__16__sortIRNS_6__lessIddEEPdEEvT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
diff --git a/src/bind.cpp b/src/bind.cpp
index b318fc16979e..b4c76ffe6a4d 100644
--- a/src/bind.cpp
+++ b/src/bind.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_BIND
#include "functional"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/src/charconv.cpp b/src/charconv.cpp
new file mode 100644
index 000000000000..ec241db74471
--- /dev/null
+++ b/src/charconv.cpp
@@ -0,0 +1,233 @@
+//===------------------------- charconv.cpp -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "charconv"
+#include <string.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __itoa
+{
+
+static constexpr char cDigitsLut[200] = {
+ '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0',
+ '7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4',
+ '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0', '2', '1', '2',
+ '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
+ '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3',
+ '7', '3', '8', '3', '9', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',
+ '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '5', '0', '5', '1', '5',
+ '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
+ '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6',
+ '7', '6', '8', '6', '9', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4',
+ '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '8', '0', '8', '1', '8',
+ '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
+ '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9',
+ '7', '9', '8', '9', '9'};
+
+template <typename T>
+inline _LIBCPP_INLINE_VISIBILITY char*
+append1(char* buffer, T i)
+{
+ *buffer = '0' + static_cast<char>(i);
+ return buffer + 1;
+}
+
+template <typename T>
+inline _LIBCPP_INLINE_VISIBILITY char*
+append2(char* buffer, T i)
+{
+ memcpy(buffer, &cDigitsLut[(i)*2], 2);
+ return buffer + 2;
+}
+
+template <typename T>
+inline _LIBCPP_INLINE_VISIBILITY char*
+append3(char* buffer, T i)
+{
+ return append2(append1(buffer, (i) / 100), (i) % 100);
+}
+
+template <typename T>
+inline _LIBCPP_INLINE_VISIBILITY char*
+append4(char* buffer, T i)
+{
+ return append2(append2(buffer, (i) / 100), (i) % 100);
+}
+
+char*
+__u32toa(uint32_t value, char* buffer)
+{
+ if (value < 10000)
+ {
+ if (value < 100)
+ {
+ if (value < 10)
+ buffer = append1(buffer, value);
+ else
+ buffer = append2(buffer, value);
+ }
+ else
+ {
+ if (value < 1000)
+ buffer = append3(buffer, value);
+ else
+ buffer = append4(buffer, value);
+ }
+ }
+ else if (value < 100000000)
+ {
+ // value = bbbbcccc
+ const uint32_t b = value / 10000;
+ const uint32_t c = value % 10000;
+
+ if (value < 1000000)
+ {
+ if (value < 100000)
+ buffer = append1(buffer, b);
+ else
+ buffer = append2(buffer, b);
+ }
+ else
+ {
+ if (value < 10000000)
+ buffer = append3(buffer, b);
+ else
+ buffer = append4(buffer, b);
+ }
+
+ buffer = append4(buffer, c);
+ }
+ else
+ {
+ // value = aabbbbcccc in decimal
+ const uint32_t a = value / 100000000; // 1 to 42
+ value %= 100000000;
+
+ if (a < 10)
+ buffer = append1(buffer, a);
+ else
+ buffer = append2(buffer, a);
+
+ buffer = append4(buffer, value / 10000);
+ buffer = append4(buffer, value % 10000);
+ }
+
+ return buffer;
+}
+
+char*
+__u64toa(uint64_t value, char* buffer)
+{
+ if (value < 100000000)
+ {
+ uint32_t v = static_cast<uint32_t>(value);
+ if (v < 10000)
+ {
+ if (v < 100)
+ {
+ if (v < 10)
+ buffer = append1(buffer, v);
+ else
+ buffer = append2(buffer, v);
+ }
+ else
+ {
+ if (v < 1000)
+ buffer = append3(buffer, v);
+ else
+ buffer = append4(buffer, v);
+ }
+ }
+ else
+ {
+ // value = bbbbcccc
+ const uint32_t b = v / 10000;
+ const uint32_t c = v % 10000;
+
+ if (v < 1000000)
+ {
+ if (v < 100000)
+ buffer = append1(buffer, b);
+ else
+ buffer = append2(buffer, b);
+ }
+ else
+ {
+ if (v < 10000000)
+ buffer = append3(buffer, b);
+ else
+ buffer = append4(buffer, b);
+ }
+
+ buffer = append4(buffer, c);
+ }
+ }
+ else if (value < 10000000000000000)
+ {
+ const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
+ const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
+
+ const uint32_t b0 = v0 / 10000;
+ const uint32_t c0 = v0 % 10000;
+
+ if (v0 < 1000000)
+ {
+ if (v0 < 100000)
+ buffer = append1(buffer, b0);
+ else
+ buffer = append2(buffer, b0);
+ }
+ else
+ {
+ if (v0 < 10000000)
+ buffer = append3(buffer, b0);
+ else
+ buffer = append4(buffer, b0);
+ }
+
+ buffer = append4(buffer, c0);
+ buffer = append4(buffer, v1 / 10000);
+ buffer = append4(buffer, v1 % 10000);
+ }
+ else
+ {
+ const uint32_t a =
+ static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844
+ value %= 10000000000000000;
+
+ if (a < 100)
+ {
+ if (a < 10)
+ buffer = append1(buffer, a);
+ else
+ buffer = append2(buffer, a);
+ }
+ else
+ {
+ if (a < 1000)
+ buffer = append3(buffer, a);
+ else
+ buffer = append4(buffer, a);
+ }
+
+ const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
+ const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
+ buffer = append4(buffer, v0 / 10000);
+ buffer = append4(buffer, v0 % 10000);
+ buffer = append4(buffer, v1 / 10000);
+ buffer = append4(buffer, v1 % 10000);
+ }
+
+ return buffer;
+}
+
+} // namespace __itoa
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/src/future.cpp b/src/future.cpp
index e1758f39df3a..07e4602f567f 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -92,10 +92,8 @@ void
__assoc_sub_state::set_value()
{
unique_lock<mutex> __lk(__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__has_value())
- throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+ __throw_future_error(future_errc::promise_already_satisfied);
__state_ |= __constructed | ready;
__cv_.notify_all();
}
@@ -104,10 +102,8 @@ void
__assoc_sub_state::set_value_at_thread_exit()
{
unique_lock<mutex> __lk(__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__has_value())
- throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+ __throw_future_error(future_errc::promise_already_satisfied);
__state_ |= __constructed;
__thread_local_data()->__make_ready_at_thread_exit(this);
}
@@ -116,10 +112,8 @@ void
__assoc_sub_state::set_exception(exception_ptr __p)
{
unique_lock<mutex> __lk(__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__has_value())
- throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+ __throw_future_error(future_errc::promise_already_satisfied);
__exception_ = __p;
__state_ |= ready;
__cv_.notify_all();
@@ -129,10 +123,8 @@ void
__assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p)
{
unique_lock<mutex> __lk(__mut_);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__has_value())
- throw future_error(make_error_code(future_errc::promise_already_satisfied));
-#endif
+ __throw_future_error(future_errc::promise_already_satisfied);
__exception_ = __p;
__thread_local_data()->__make_ready_at_thread_exit(this);
}
@@ -181,18 +173,14 @@ __assoc_sub_state::__sub_wait(unique_lock<mutex>& __lk)
void
__assoc_sub_state::__execute()
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw future_error(make_error_code(future_errc::no_state));
-#endif
+ __throw_future_error(future_errc::no_state);
}
future<void>::future(__assoc_sub_state* __state)
: __state_(__state)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__state_->__has_future_attached())
- throw future_error(make_error_code(future_errc::future_already_retrieved));
-#endif
+ __throw_future_error(future_errc::future_already_retrieved);
__state_->__add_shared();
__state_->__set_future_attached();
}
@@ -234,50 +222,40 @@ promise<void>::~promise()
future<void>
promise<void>::get_future()
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__state_ == nullptr)
- throw future_error(make_error_code(future_errc::no_state));
-#endif
+ __throw_future_error(future_errc::no_state);
return future<void>(__state_);
}
void
promise<void>::set_value()
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__state_ == nullptr)
- throw future_error(make_error_code(future_errc::no_state));
-#endif
+ __throw_future_error(future_errc::no_state);
__state_->set_value();
}
void
promise<void>::set_exception(exception_ptr __p)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__state_ == nullptr)
- throw future_error(make_error_code(future_errc::no_state));
-#endif
+ __throw_future_error(future_errc::no_state);
__state_->set_exception(__p);
}
void
promise<void>::set_value_at_thread_exit()
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__state_ == nullptr)
- throw future_error(make_error_code(future_errc::no_state));
-#endif
+ __throw_future_error(future_errc::no_state);
__state_->set_value_at_thread_exit();
}
void
promise<void>::set_exception_at_thread_exit(exception_ptr __p)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__state_ == nullptr)
- throw future_error(make_error_code(future_errc::no_state));
-#endif
+ __throw_future_error(future_errc::no_state);
__state_->set_exception_at_thread_exit(__p);
}
diff --git a/src/memory.cpp b/src/memory.cpp
index 4e0d3af9167e..77ebe837c73c 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_MEMORY
#include "memory"
#ifndef _LIBCPP_HAS_NO_THREADS
#include "mutex"
diff --git a/src/mutex.cpp b/src/mutex.cpp
index c36bd5549da8..c61d34bb885b 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_MUTEX
#include "mutex"
#include "limits"
#include "system_error"
diff --git a/src/new.cpp b/src/new.cpp
index e228a0d83d8e..8013d89ae3c2 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_NEW
-
#include <stdlib.h>
#include "new"
diff --git a/src/shared_mutex.cpp b/src/shared_mutex.cpp
index 874aceb1b03a..6185f15deabd 100644
--- a/src/shared_mutex.cpp
+++ b/src/shared_mutex.cpp
@@ -10,7 +10,6 @@
#include "__config"
#ifndef _LIBCPP_HAS_NO_THREADS
-#define _LIBCPP_BUILDING_SHARED_MUTEX
#include "shared_mutex"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/src/system_error.cpp b/src/system_error.cpp
index 72623ea6bc81..06caa6fecd9f 100644
--- a/src/system_error.cpp
+++ b/src/system_error.cpp
@@ -9,7 +9,6 @@
#include "__config"
-#define _LIBCPP_BUILDING_SYSTEM_ERROR
#include "system_error"
#include "include/config_elast.h"
diff --git a/src/utility.cpp b/src/utility.cpp
index e9830e7c24f0..7dccffb73e5a 100644
--- a/src/utility.cpp
+++ b/src/utility.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_UTILITY
#include "utility"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/test/libcxx/double_include.sh.cpp b/test/libcxx/double_include.sh.cpp
index c98cc8065eb9..8d08db4fd105 100644
--- a/test/libcxx/double_include.sh.cpp
+++ b/test/libcxx/double_include.sh.cpp
@@ -34,6 +34,7 @@
#include <cerrno>
#include <cfenv>
#include <cfloat>
+#include <charconv>
#include <chrono>
#include <cinttypes>
#include <ciso646>
diff --git a/test/libcxx/language.support/has_c11_features.pass.cpp b/test/libcxx/language.support/has_c11_features.pass.cpp
new file mode 100644
index 000000000000..cdccc00e21b4
--- /dev/null
+++ b/test/libcxx/language.support/has_c11_features.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// We have two macros for checking whether or not the underlying C library
+// has C11 features:
+// TEST_HAS_C11_FEATURES - which is defined in "test_macros.h"
+// _LIBCPP_HAS_C11_FEATURES - which is defined in <__config>
+// They should always be the same
+
+#ifdef TEST_HAS_C11_FEATURES
+# ifndef _LIBCPP_HAS_C11_FEATURES
+# error "TEST_HAS_C11_FEATURES is defined, but _LIBCPP_HAS_C11_FEATURES is not"
+# endif
+#endif
+
+#ifdef _LIBCPP_HAS_C11_FEATURES
+# ifndef TEST_HAS_C11_FEATURES
+# error "_LIBCPP_HAS_C11_FEATURES is defined, but TEST_HAS_C11_FEATURES is not"
+# endif
+#endif
+
+int main() {}
diff --git a/test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp b/test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..ea7fd890764b
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class map
+
+// node_type extract(const_iterator);
+
+#include <map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ auto some_key = c.cbegin()->first;
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = first->first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.key() == key_value);
+ t.key() = some_key;
+ assert(t.key() == some_key);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using map_type = std::map<int, int>;
+ map_type m = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ test(m);
+ }
+
+ {
+ std::map<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ assert(Counter_base::gConstructed == 12);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::map<int, int, std::less<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ test(m);
+ }
+}
diff --git a/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp b/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp
new file mode 100644
index 000000000000..41cd09300b2a
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class map
+
+// node_type extract(key_type const&);
+
+#include <map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.key() == *copy);
+ t.key() = *first; // We should be able to mutate key.
+ assert(t.key() == *first);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::map<int, int> m = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::map<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 12+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::map<int, int, std::less<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..cc1704c30873
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class map
+
+// insert_return_type insert(node_type&&);
+
+#include <map>
+#include <type_traits>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto p = c.insert({key, mapped});
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ typename Container::insert_return_type irt = c.insert(std::move(node));
+ assert(node.empty());
+ assert(irt.inserted);
+ assert(irt.node.empty());
+ assert(irt.position->first == i && irt.position->second == i + 1);
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto irt = c.insert(std::move(def));
+ assert(def.empty());
+ assert(!irt.inserted);
+ assert(irt.node.empty());
+ assert(irt.position == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0, 42);
+ auto irt = c.insert(std::move(dupl));
+ assert(dupl.empty());
+ assert(!irt.inserted);
+ assert(!irt.node.empty());
+ assert(irt.position == c.find(0));
+ assert(irt.node.key() == 0 && irt.node.mapped() == 42);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c[i] == i + 1);
+ }
+}
+
+int main()
+{
+ std::map<int, int> m;
+ test(m);
+ std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..3c6b3e31af46
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class map
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <map>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto p = c.insert({key, mapped});
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(node.empty());
+ assert(prev + 1 == c.size());
+ assert(it->first == i);
+ assert(it->second == i + 1);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c[i] == i + 1);
+ }
+}
+
+int main()
+{
+ std::map<int, int> m;
+ test(m);
+ std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/extract_iterator.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..3e00d2b98d70
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.modifiers/extract_iterator.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class multimap
+
+// node_type extract(const_iterator);
+
+#include <map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ auto some_key = c.cbegin()->first;
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = first->first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.key() == key_value);
+ t.key() = some_key;
+ assert(t.key() == some_key);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using map_type = std::multimap<int, int>;
+ map_type m = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ test(m);
+ }
+
+ {
+ std::multimap<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ assert(Counter_base::gConstructed == 12);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::multimap<int, int, std::less<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ test(m);
+ }
+}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/extract_key.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/extract_key.pass.cpp
new file mode 100644
index 000000000000..ca69cca6b0ec
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.modifiers/extract_key.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class multimap
+
+// node_type extract(key_type const&);
+
+#include <map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.key() == *copy);
+ t.key() = *first; // We should be able to mutate key.
+ assert(t.key() == *first);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::multimap<int, int> m = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::multimap<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 12+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::multimap<int, int, std::less<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_node_type.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..906770514196
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_node_type.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class multimap
+
+// iterator insert(node_type&&);
+
+#include <map>
+#include <type_traits>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto it = c.insert({key, mapped});
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ typename Container::iterator it = c.insert(std::move(node));
+ assert(node.empty());
+ assert(it == c.find(i) && it != c.end());
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto it = c.insert(std::move(def));
+ assert(def.empty());
+ assert(it == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0, 42);
+ auto it = c.insert(std::move(dupl));
+ assert(dupl.empty());
+ assert(it != c.end());
+ assert(it->second == 42);
+ }
+
+ assert(c.size() == 11);
+ assert(c.count(0) == 2);
+ for (int i = 1; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c.find(i)->second == i + 1);
+ }
+}
+
+int main()
+{
+ std::multimap<int, int> m;
+ test(m);
+ std::multimap<int, int, std::less<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_node_type_hint.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..82e7d80c06e6
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_node_type_hint.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class multimap
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <map>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto it = c.insert({key, mapped});
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(node.empty());
+ assert(prev + 1 == c.size());
+ assert(it == c.find(i));
+ assert(it->first == i);
+ assert(it->second == i + 1);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c.find(i)->second == i + 1);
+ }
+}
+
+int main()
+{
+ std::multimap<int, int> m;
+ test(m);
+ std::multimap<int, int, std::less<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/associative/multiset/extract_iterator.pass.cpp b/test/std/containers/associative/multiset/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..0f41169e9fe0
--- /dev/null
+++ b/test/std/containers/associative/multiset/extract_iterator.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class multiset
+
+// node_type extract(const_iterator);
+
+#include <set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = *first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.value() == key_value);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using set_type = std::multiset<int>;
+ set_type m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+
+ {
+ std::multiset<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::multiset<int, std::less<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+}
diff --git a/test/std/containers/associative/multiset/extract_key.pass.cpp b/test/std/containers/associative/multiset/extract_key.pass.cpp
new file mode 100644
index 000000000000..9ad0184100b6
--- /dev/null
+++ b/test/std/containers/associative/multiset/extract_key.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class multiset
+
+// node_type extract(key_type const&);
+
+#include <set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.value() == *copy);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::multiset<int> m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::multiset<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::multiset<int, std::less<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/associative/multiset/insert_node_type.pass.cpp b/test/std/containers/associative/multiset/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..ca51ec9f0930
--- /dev/null
+++ b/test/std/containers/associative/multiset/insert_node_type.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class multiset
+
+// iterator insert(node_type&&);
+
+#include <set>
+#include <type_traits>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto it = c.insert(key);
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ typename Container::iterator it = c.insert(std::move(node));
+ assert(node.empty());
+ assert(it == c.find(i) && it != c.end());
+ assert(*it == i);
+ assert(node.empty());
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto it = c.insert(std::move(def));
+ assert(def.empty());
+ assert(it == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0);
+ auto it = c.insert(std::move(dupl));
+ assert(*it == 0);
+ }
+
+ assert(c.size() == 11);
+
+ assert(c.count(0) == 2);
+ for (int i = 1; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::multiset<int> m;
+ test(m);
+ std::multiset<int, std::less<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/associative/multiset/insert_node_type_hint.pass.cpp b/test/std/containers/associative/multiset/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..9d0af0653f6c
--- /dev/null
+++ b/test/std/containers/associative/multiset/insert_node_type_hint.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class multiset
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <set>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto it = c.insert(key);
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(prev + 1 == c.size());
+ assert(*it == i);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::multiset<int> m;
+ test(m);
+ std::multiset<int, std::less<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/associative/set/extract_iterator.pass.cpp b/test/std/containers/associative/set/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..ffcf71486883
--- /dev/null
+++ b/test/std/containers/associative/set/extract_iterator.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class set
+
+// node_type extract(const_iterator);
+
+#include <set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = *first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.value() == key_value);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using set_type = std::set<int>;
+ set_type m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+
+ {
+ std::set<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::set<int, std::less<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+}
diff --git a/test/std/containers/associative/set/extract_key.pass.cpp b/test/std/containers/associative/set/extract_key.pass.cpp
new file mode 100644
index 000000000000..1fb7ab9116eb
--- /dev/null
+++ b/test/std/containers/associative/set/extract_key.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class set
+
+// node_type extract(key_type const&);
+
+#include <set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.value() == *copy);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::set<int> m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::set<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::set<int, std::less<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/associative/set/insert_node_type.pass.cpp b/test/std/containers/associative/set/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..4186f20e771f
--- /dev/null
+++ b/test/std/containers/associative/set/insert_node_type.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class set
+
+// insert_return_type insert(node_type&&);
+
+#include <set>
+#include <type_traits>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto p = c.insert(key);
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ typename Container::insert_return_type irt = c.insert(std::move(node));
+ assert(node.empty());
+ assert(irt.inserted);
+ assert(irt.node.empty());
+ assert(*irt.position == i);
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto irt = c.insert(std::move(def));
+ assert(def.empty());
+ assert(!irt.inserted);
+ assert(irt.node.empty());
+ assert(irt.position == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0);
+ auto irt = c.insert(std::move(dupl));
+ assert(dupl.empty());
+ assert(!irt.inserted);
+ assert(!irt.node.empty());
+ assert(irt.position == c.find(0));
+ assert(irt.node.value() == 0);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::set<int> m;
+ test(m);
+ std::set<int, std::less<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/associative/set/insert_node_type_hint.pass.cpp b/test/std/containers/associative/set/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..761ceef6a4a1
--- /dev/null
+++ b/test/std/containers/associative/set/insert_node_type_hint.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class set
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <set>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto p = c.insert(key);
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(node.empty());
+ assert(prev + 1 == c.size());
+ assert(*it == i);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::set<int> m;
+ test(m);
+ std::set<int, std::less<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/container.node/node_handle.pass.cpp b/test/std/containers/container.node/node_handle.pass.cpp
new file mode 100644
index 000000000000..6314ec1fb771
--- /dev/null
+++ b/test/std/containers/container.node/node_handle.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+#include <unordered_set>
+#include <unordered_map>
+#include <set>
+#include <map>
+#include "min_allocator.h"
+
+using namespace std;
+
+// [container.node.overview] Table 83.
+template <class K, class T, class C1, class C2, class H1, class H2, class E1, class E2, class A_set, class A_map>
+struct node_compatibility_table
+{
+ static constexpr bool value =
+ is_same_v<typename map<K, T, C1, A_map>::node_type, typename map<K, T, C2, A_map>::node_type> &&
+ is_same_v<typename map<K, T, C1, A_map>::node_type, typename multimap<K, T, C2, A_map>::node_type> &&
+ is_same_v<typename set<K, C1, A_set>::node_type, typename set<K, C2, A_set>::node_type> &&
+ is_same_v<typename set<K, C1, A_set>::node_type, typename multiset<K, C2, A_set>::node_type> &&
+ is_same_v<typename unordered_map<K, T, H1, E1, A_map>::node_type, typename unordered_map<K, T, H2, E2, A_map>::node_type> &&
+ is_same_v<typename unordered_map<K, T, H1, E1, A_map>::node_type, typename unordered_multimap<K, T, H2, E2, A_map>::node_type> &&
+ is_same_v<typename unordered_set<K, H1, E1, A_set>::node_type, typename unordered_set<K, H2, E2, A_set>::node_type> &&
+ is_same_v<typename unordered_set<K, H1, E1, A_set>::node_type, typename unordered_multiset<K, H2, E2, A_set>::node_type>;
+};
+
+template <class T> struct my_hash
+{
+ using argument_type = T;
+ using result_type = size_t;
+ my_hash() = default;
+ size_t operator()(const T&) const {return 0;}
+};
+
+template <class T> struct my_compare
+{
+ my_compare() = default;
+ bool operator()(const T&, const T&) const {return true;}
+};
+
+template <class T> struct my_equal
+{
+ my_equal() = default;
+ bool operator()(const T&, const T&) const {return true;}
+};
+
+struct Static
+{
+ Static() = default;
+ Static(const Static&) = delete;
+ Static(Static&&) = delete;
+ Static& operator=(const Static&) = delete;
+ Static& operator=(Static&&) = delete;
+};
+
+namespace std
+{
+template <> struct hash<Static>
+{
+ using argument_type = Static;
+ using result_type = size_t;
+ hash() = default;
+ size_t operator()(const Static&) const;
+};
+}
+
+static_assert(node_compatibility_table<
+ int, int, std::less<int>, std::less<int>, std::hash<int>,
+ std::hash<int>, std::equal_to<int>, std::equal_to<int>,
+ std::allocator<int>,
+ std::allocator<std::pair<const int, int>>>::value,
+ "");
+
+static_assert(
+ node_compatibility_table<int, int, std::less<int>, my_compare<int>,
+ std::hash<int>, my_hash<int>, std::equal_to<int>,
+ my_equal<int>, allocator<int>,
+ allocator<std::pair<const int, int>>>::value,
+ "");
+
+static_assert(node_compatibility_table<
+ Static, int, my_compare<Static>, std::less<Static>,
+ my_hash<Static>, std::hash<Static>, my_equal<Static>,
+ std::equal_to<Static>, min_allocator<Static>,
+ min_allocator<std::pair<const Static, int>>>::value,
+ "");
+
+template <class Container>
+void test_node_handle_operations()
+{
+ Container c;
+
+ typename Container::node_type nt1, nt2 = c.extract(c.emplace().first);
+ assert(nt2.get_allocator() == c.get_allocator());
+ assert(!nt2.empty());
+ assert(nt1.empty());
+ std::swap(nt1, nt2);
+ assert(nt1.get_allocator() == c.get_allocator());
+ assert(nt2.empty());
+}
+
+template <class Container>
+void test_node_handle_operations_multi()
+{
+ Container c;
+
+ typename Container::node_type nt1, nt2 = c.extract(c.emplace());
+ assert(nt2.get_allocator() == c.get_allocator());
+ assert(!nt2.empty());
+ assert(nt1.empty());
+ std::swap(nt1, nt2);
+ assert(nt1.get_allocator() == c.get_allocator());
+ assert(nt2.empty());
+}
+
+template <class Container>
+void test_insert_return_type()
+{
+ using irt_type = typename Container::insert_return_type;
+}
+
+int main()
+{
+ test_node_handle_operations<std::map<int, int>>();
+ test_node_handle_operations_multi<std::multimap<int, int>>();
+ test_node_handle_operations<std::set<int>>();
+ test_node_handle_operations_multi<std::multiset<int>>();
+ test_node_handle_operations<std::unordered_map<int, int>>();
+ test_node_handle_operations_multi<std::unordered_multimap<int, int>>();
+ test_node_handle_operations<std::unordered_set<int>>();
+ test_node_handle_operations_multi<std::unordered_multiset<int>>();
+
+ test_insert_return_type<std::map<int, int>>();
+ test_insert_return_type<std::set<int>>();
+ test_insert_return_type<std::unordered_map<int, int>>();
+ test_insert_return_type<std::unordered_set<int>>();
+}
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/extract_iterator.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..4cc13ded23f8
--- /dev/null
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/extract_iterator.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_map
+
+// node_type extract(const_iterator);
+
+#include <unordered_map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ auto some_key = c.cbegin()->first;
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = first->first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.key() == key_value);
+ t.key() = some_key;
+ assert(t.key() == some_key);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using map_type = std::unordered_map<int, int>;
+ map_type m = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ test(m);
+ }
+
+ {
+ std::unordered_map<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ assert(Counter_base::gConstructed == 12);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::unordered_map<int, int, std::hash<int>, std::equal_to<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ test(m);
+ }
+}
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/extract_key.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/extract_key.pass.cpp
new file mode 100644
index 000000000000..25aa24888868
--- /dev/null
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/extract_key.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_map
+
+// node_type extract(key_type const&);
+
+#include <unordered_map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.key() == *copy);
+ t.key() = *first; // We should be able to mutate key.
+ assert(t.key() == *first);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::unordered_map<int, int> m = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::unordered_map<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 12+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::unordered_map<int, int, std::hash<int>, std::equal_to<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..d434864885fe
--- /dev/null
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_map
+
+// insert_return_type insert(node_type&&);
+
+#include <unordered_map>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto p = c.insert({key, mapped});
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ typename Container::insert_return_type irt = c.insert(std::move(node));
+ assert(node.empty());
+ assert(irt.inserted);
+ assert(irt.node.empty());
+ assert(irt.position->first == i && irt.position->second == i + 1);
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto irt = c.insert(std::move(def));
+ assert(def.empty());
+ assert(!irt.inserted);
+ assert(irt.node.empty());
+ assert(irt.position == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0, 42);
+ auto irt = c.insert(std::move(dupl));
+ assert(dupl.empty());
+ assert(!irt.inserted);
+ assert(!irt.node.empty());
+ assert(irt.position == c.find(0));
+ assert(irt.node.key() == 0 && irt.node.mapped() == 42);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c[i] == i + 1);
+ }
+}
+
+int main()
+{
+ std::unordered_map<int, int> m;
+ test(m);
+ std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type_hint.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..ef98453b6271
--- /dev/null
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_node_type_hint.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_map
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <unordered_map>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto p = c.insert({key, mapped});
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(node.empty());
+ assert(prev + 1 == c.size());
+ assert(it->first == i);
+ assert(it->second == i + 1);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c[i] == i + 1);
+ }
+}
+
+int main()
+{
+ std::unordered_map<int, int> m;
+ test(m);
+ std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_iterator.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..adb2ddb2ba80
--- /dev/null
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_iterator.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_multimap
+
+// node_type extract(const_iterator);
+
+#include <unordered_map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ auto some_key = c.cbegin()->first;
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = first->first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.key() == key_value);
+ t.key() = some_key;
+ assert(t.key() == some_key);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using map_type = std::unordered_multimap<int, int>;
+ map_type m = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ test(m);
+ }
+
+ {
+ std::unordered_multimap<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ assert(Counter_base::gConstructed == 12);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ test(m);
+ }
+}
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_key.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_key.pass.cpp
new file mode 100644
index 000000000000..8cf26fc77507
--- /dev/null
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/extract_key.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_multimap
+
+// node_type extract(key_type const&);
+
+#include <unordered_map>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.key() == *copy);
+ t.key() = *first; // We should be able to mutate key.
+ assert(t.key() == *first);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::unordered_multimap<int, int> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::unordered_multimap<Counter<int>, Counter<int>> m =
+ {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 12+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_map =
+ std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>,
+ min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..93c0462b3244
--- /dev/null
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_multimap
+
+// iterator insert(node_type&&);
+
+#include <unordered_map>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto it = c.insert({key, mapped});
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ typename Container::iterator it = c.insert(std::move(node));
+ assert(node.empty());
+ assert(it == c.find(i) && it != c.end());
+ assert(it->first == i && it->second == i + 1);
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto it = c.insert(std::move(def));
+ assert(def.empty());
+ assert(it == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0, 42);
+ auto it = c.insert(std::move(dupl));
+ assert(dupl.empty());
+ assert(it != c.end() && it->second == 42);
+ }
+
+ assert(c.size() == 11);
+ assert(c.count(0) == 2);
+ for (int i = 1; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c.find(i)->second == i + 1);
+ }
+}
+
+int main()
+{
+ std::unordered_multimap<int, int> m;
+ test(m);
+ std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type_hint.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..99a47cabb517
--- /dev/null
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_node_type_hint.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_multimap
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <unordered_map>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key,
+ typename Container::mapped_type const& mapped)
+{
+ static Container c;
+ auto it = c.insert({key, mapped});
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i, i + 1);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(node.empty());
+ assert(prev + 1 == c.size());
+ assert(it->first == i);
+ assert(it->second == i + 1);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ assert(c.find(i)->second == i + 1);
+ }
+}
+
+int main()
+{
+ std::unordered_multimap<int, int> m;
+ test(m);
+ std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/unord/unord.multiset/extract_iterator.pass.cpp b/test/std/containers/unord/unord.multiset/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..1595c55a4236
--- /dev/null
+++ b/test/std/containers/unord/unord.multiset/extract_iterator.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_multiset
+
+// node_type extract(const_iterator);
+
+#include <unordered_set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = *first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.value() == key_value);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using set_type = std::unordered_multiset<int>;
+ set_type m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+
+ {
+ std::unordered_multiset<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+}
diff --git a/test/std/containers/unord/unord.multiset/extract_key.pass.cpp b/test/std/containers/unord/unord.multiset/extract_key.pass.cpp
new file mode 100644
index 000000000000..ffe46fb30f17
--- /dev/null
+++ b/test/std/containers/unord/unord.multiset/extract_key.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_multiset>
+
+// class unordered_multiset
+
+// node_type extract(key_type const&);
+
+#include <unordered_set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.value() == *copy);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::unordered_multiset<int> m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::unordered_multiset<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/unord/unord.multiset/insert_node_type.pass.cpp b/test/std/containers/unord/unord.multiset/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..c3d4cd2a0e8c
--- /dev/null
+++ b/test/std/containers/unord/unord.multiset/insert_node_type.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_multiset
+
+// iterator insert(node_type&&);
+
+#include <unordered_set>
+#include <type_traits>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto it = c.insert(key);
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ typename Container::iterator it = c.insert(std::move(node));
+ assert(node.empty());
+ assert(it == c.find(i) && it != c.end());
+ assert(*it == i);
+ assert(node.empty());
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto it = c.insert(std::move(def));
+ assert(def.empty());
+ assert(it == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0);
+ auto it = c.insert(std::move(dupl));
+ assert(*it == 0);
+ }
+
+ assert(c.size() == 11);
+ assert(c.count(0) == 2);
+ for (int i = 1; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::unordered_multiset<int> m;
+ test(m);
+ std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/unord/unord.multiset/insert_node_type_hint.pass.cpp b/test/std/containers/unord/unord.multiset/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..79712d3ded79
--- /dev/null
+++ b/test/std/containers/unord/unord.multiset/insert_node_type_hint.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_multiset
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <unordered_set>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto it = c.insert(key);
+ return c.extract(it);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(prev + 1 == c.size());
+ assert(*it == i);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::unordered_multiset<int> m;
+ test(m);
+ std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/unord/unord.set/extract_iterator.pass.cpp b/test/std/containers/unord/unord.set/extract_iterator.pass.cpp
new file mode 100644
index 000000000000..40feb0e2f85b
--- /dev/null
+++ b/test/std/containers/unord/unord.set/extract_iterator.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_set
+
+// node_type extract(const_iterator);
+
+#include <unordered_set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container>
+void test(Container& c)
+{
+ size_t sz = c.size();
+
+ for (auto first = c.cbegin(); first != c.cend();)
+ {
+ auto key_value = *first;
+ typename Container::node_type t = c.extract(first++);
+ --sz;
+ assert(t.value() == key_value);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+}
+
+int main()
+{
+ {
+ using set_type = std::unordered_set<int>;
+ set_type m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+
+ {
+ std::unordered_set<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6);
+ test(m);
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ test(m);
+ }
+}
diff --git a/test/std/containers/unord/unord.set/extract_key.pass.cpp b/test/std/containers/unord/unord.set/extract_key.pass.cpp
new file mode 100644
index 000000000000..f686342b298e
--- /dev/null
+++ b/test/std/containers/unord/unord.set/extract_key.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_set
+
+// node_type extract(key_type const&);
+
+#include <unordered_set>
+#include "min_allocator.h"
+#include "Counter.h"
+
+template <class Container, class KeyTypeIter>
+void test(Container& c, KeyTypeIter first, KeyTypeIter last)
+{
+ size_t sz = c.size();
+ assert((size_t)std::distance(first, last) == sz);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(!t.empty());
+ --sz;
+ assert(t.value() == *copy);
+ assert(t.get_allocator() == c.get_allocator());
+ assert(sz == c.size());
+ }
+
+ assert(c.size() == 0);
+
+ for (KeyTypeIter copy = first; copy != last; ++copy)
+ {
+ typename Container::node_type t = c.extract(*copy);
+ assert(t.empty());
+ }
+}
+
+int main()
+{
+ {
+ std::unordered_set<int> m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+
+ {
+ std::unordered_set<Counter<int>> m = {1, 2, 3, 4, 5, 6};
+ {
+ Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
+ assert(Counter_base::gConstructed == 6+6);
+ test(m, std::begin(keys), std::end(keys));
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+
+ {
+ using min_alloc_set = std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>;
+ min_alloc_set m = {1, 2, 3, 4, 5, 6};
+ int keys[] = {1, 2, 3, 4, 5, 6};
+ test(m, std::begin(keys), std::end(keys));
+ }
+}
diff --git a/test/std/containers/unord/unord.set/insert_node_type.pass.cpp b/test/std/containers/unord/unord.set/insert_node_type.pass.cpp
new file mode 100644
index 000000000000..6c91b539356e
--- /dev/null
+++ b/test/std/containers/unord/unord.set/insert_node_type.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_set
+
+// insert_return_type insert(node_type&&);
+
+#include <unordered_set>
+#include <type_traits>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto p = c.insert(key);
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ typename Container::insert_return_type irt = c.insert(std::move(node));
+ assert(node.empty());
+ assert(irt.inserted);
+ assert(irt.node.empty());
+ assert(*irt.position == i);
+ }
+
+ assert(c.size() == 10);
+
+ { // Insert empty node.
+ typename Container::node_type def;
+ auto irt = c.insert(std::move(def));
+ assert(def.empty());
+ assert(!irt.inserted);
+ assert(irt.node.empty());
+ assert(irt.position == c.end());
+ }
+
+ { // Insert duplicate node.
+ typename Container::node_type dupl = nf(0);
+ auto irt = c.insert(std::move(dupl));
+ assert(dupl.empty());
+ assert(!irt.inserted);
+ assert(!irt.node.empty());
+ assert(irt.position == c.find(0));
+ assert(irt.node.value() == 0);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::unordered_set<int> m;
+ test(m);
+ std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/containers/unord/unord.set/insert_node_type_hint.pass.cpp b/test/std/containers/unord/unord.set/insert_node_type_hint.pass.cpp
new file mode 100644
index 000000000000..626f27271da4
--- /dev/null
+++ b/test/std/containers/unord/unord.set/insert_node_type_hint.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_set
+
+// iterator insert(const_iterator hint, node_type&&);
+
+#include <unordered_set>
+#include "min_allocator.h"
+
+template <class Container>
+typename Container::node_type
+node_factory(typename Container::key_type const& key)
+{
+ static Container c;
+ auto p = c.insert(key);
+ assert(p.second);
+ return c.extract(p.first);
+}
+
+template <class Container>
+void test(Container& c)
+{
+ auto* nf = &node_factory<Container>;
+
+ for (int i = 0; i != 10; ++i)
+ {
+ typename Container::node_type node = nf(i);
+ assert(!node.empty());
+ size_t prev = c.size();
+ auto it = c.insert(c.end(), std::move(node));
+ assert(node.empty());
+ assert(prev + 1 == c.size());
+ assert(*it == i);
+ }
+
+ assert(c.size() == 10);
+
+ for (int i = 0; i != 10; ++i)
+ {
+ assert(c.count(i) == 1);
+ }
+}
+
+int main()
+{
+ std::unordered_set<int> m;
+ test(m);
+ std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> m2;
+ test(m2);
+}
diff --git a/test/std/depr/depr.c.headers/float_h.pass.cpp b/test/std/depr/depr.c.headers/float_h.pass.cpp
index 5b2e45163705..3001c215cd19 100644
--- a/test/std/depr/depr.c.headers/float_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/float_h.pass.cpp
@@ -23,6 +23,20 @@
#error FLT_RADIX not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef FLT_HAS_SUBNORM
+#error FLT_HAS_SUBNORM not defined
+#endif
+
+#ifndef DBL_HAS_SUBNORM
+#error DBL_HAS_SUBNORM not defined
+#endif
+
+#ifndef LDBL_HAS_SUBNORM
+#error LDBL_HAS_SUBNORM not defined
+#endif
+#endif
+
#ifndef FLT_MANT_DIG
#error FLT_MANT_DIG not defined
#endif
@@ -39,6 +53,20 @@
#error DECIMAL_DIG not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef FLT_DECIMAL_DIG
+#error FLT_DECIMAL_DIG not defined
+#endif
+
+#ifndef DBL_DECIMAL_DIG
+#error DBL_DECIMAL_DIG not defined
+#endif
+
+#ifndef LDBL_DECIMAL_DIG
+#error LDBL_DECIMAL_DIG not defined
+#endif
+#endif
+
#ifndef FLT_DIG
#error FLT_DIG not defined
#endif
@@ -135,6 +163,20 @@
#error LDBL_MIN not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef FLT_TRUE_MIN
+#error FLT_TRUE_MIN not defined
+#endif
+
+#ifndef DBL_TRUE_MIN
+#error DBL_TRUE_MIN not defined
+#endif
+
+#ifndef LDBL_TRUE_MIN
+#error LDBL_TRUE_MIN not defined
+#endif
+#endif
+
int main()
{
}
diff --git a/test/std/depr/depr.c.headers/stdlib_h.pass.cpp b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
index 1680f4349bb5..07ffa0b75513 100644
--- a/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
@@ -12,6 +12,8 @@
#include <stdlib.h>
#include <type_traits>
+#include "test_macros.h"
+
// As of 1/10/2015 clang emits a -Wnonnull warnings even if the warning occurs
// in an unevaluated context. For this reason we manually suppress the warning.
#if defined(__clang__)
@@ -83,6 +85,14 @@ int main()
static_assert((std::is_same<decltype(strtoull("", endptr,0)), unsigned long long>::value), "");
static_assert((std::is_same<decltype(rand()), int>::value), "");
static_assert((std::is_same<decltype(srand(0)), void>::value), "");
+
+// Microsoft does not implement aligned_alloc in their C library
+#ifndef TEST_COMPILER_C1XX
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+ static_assert((std::is_same<decltype(aligned_alloc(0,0)), void*>::value), "");
+#endif
+#endif
+
static_assert((std::is_same<decltype(calloc(0,0)), void*>::value), "");
static_assert((std::is_same<decltype(free(0)), void>::value), "");
static_assert((std::is_same<decltype(malloc(0)), void*>::value), "");
diff --git a/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp b/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
new file mode 100644
index 000000000000..dd8436618111
--- /dev/null
+++ b/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// [simd.abi]
+
+#include <experimental/simd>
+#include <cstdint>
+
+namespace ex = std::experimental::parallelism_v2;
+
+constexpr inline int reg_width() {
+#if defined(__AVX__)
+ return 32;
+#else
+ return 16;
+#endif
+}
+
+#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
+static_assert(
+ sizeof(ex::simd<char, ex::__simd_abi<ex::_StorageKind::_VecExt, 1>>) == 1,
+ "");
+static_assert(
+ sizeof(ex::simd<char, ex::__simd_abi<ex::_StorageKind::_VecExt, 2>>) == 2,
+ "");
+static_assert(
+ sizeof(ex::simd<char, ex::__simd_abi<ex::_StorageKind::_VecExt, 3>>) == 4,
+ "");
+static_assert(
+ sizeof(ex::simd<char, ex::__simd_abi<ex::_StorageKind::_VecExt, 12>>) == 16,
+ "");
+static_assert(
+ sizeof(ex::simd<int32_t, ex::__simd_abi<ex::_StorageKind::_VecExt, 3>>) ==
+ 16,
+ "");
+static_assert(
+ sizeof(ex::simd<int32_t, ex::__simd_abi<ex::_StorageKind::_VecExt, 5>>) ==
+ 32,
+ "");
+static_assert(
+ std::is_same<ex::simd_abi::native<int8_t>,
+ ex::__simd_abi<ex::_StorageKind::_VecExt, reg_width()>>::value,
+ "");
+#else
+static_assert(
+ std::is_same<ex::simd_abi::native<int8_t>,
+ ex::__simd_abi<ex::_StorageKind::_Array, reg_width()>>::value,
+ "");
+
+#endif
+
+static_assert(std::is_same<ex::simd_abi::compatible<int8_t>,
+ ex::__simd_abi<ex::_StorageKind::_Array, 16>>::value,
+ "");
+
+int main() {}
diff --git a/test/std/experimental/simd/simd.access/default.pass.cpp b/test/std/experimental/simd/simd.access/default.pass.cpp
new file mode 100644
index 000000000000..6ce32cab8673
--- /dev/null
+++ b/test/std/experimental/simd/simd.access/default.pass.cpp
@@ -0,0 +1,217 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// scalar access [simd.subscr]
+// reference operator[](size_t);
+// value_type operator[](size_t) const;
+
+#include <experimental/simd>
+#include <cassert>
+#include <cstdint>
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <typename SimdType>
+void test_access() {
+ {
+ SimdType a(42), b(4);
+ static_assert(std::is_convertible<decltype(a[0]), int8_t>::value, "");
+
+ assert(a[0] == 42);
+ assert(!a[0] == !42);
+ assert(~a[0] == ~42);
+ assert(+a[0] == +42);
+ assert(-a[0] == -42);
+ assert(a[0] + b[0] == 42 + 4);
+ assert(a[0] - b[0] == 42 - 4);
+ assert(a[0] * b[0] == 42 * 4);
+ assert(a[0] / b[0] == 42 / 4);
+ assert(a[0] % b[0] == 42 % 4);
+ assert(a[0] << b[0] == (42 << 4));
+ assert(a[0] >> b[0] == (42 >> 4));
+ assert(a[0] < b[0] == false);
+ assert(a[0] <= b[0] == false);
+ assert(a[0] > b[0] == true);
+ assert(a[0] >= b[0] == true);
+ assert(a[0] == b[0] == false);
+ assert(a[0] != b[0] == true);
+ assert((a[0] & b[0]) == (42 & 4));
+ assert((a[0] | b[0]) == (42 | 4));
+ assert((a[0] ^ b[0]) == (42 ^ 4));
+ assert((a[0] && b[0]) == true);
+ assert((a[0] || b[0]) == true);
+
+ {
+ auto c = a;
+ ++c[0];
+ assert(c[0] == 42 + 1);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ auto ret = c[0]++;
+ assert(ret == 42);
+ assert(c[0] == 42 + 1);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ --c[0];
+ assert(c[0] == 42 - 1);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ auto ret = c[0]--;
+ assert(ret == 42);
+ assert(c[0] == 42 - 1);
+ assert(c[1] == 42);
+ }
+
+ {
+ auto c = a;
+ c[0] += b[0];
+ assert(c[0] == 42 + 4);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] -= b[0];
+ assert(c[0] == 42 - 4);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] *= b[0];
+ assert(c[0] == 42 * 4);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] /= b[0];
+ assert(c[0] == 42 / 4);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] %= b[0];
+ assert(c[0] == 42 % 4);
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] >>= b[0];
+ assert(c[0] == (42 >> 4));
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] <<= b[0];
+ assert(c[0] == (42 << 4));
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] &= b[0];
+ assert(c[0] == (42 & 4));
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] |= b[0];
+ assert(c[0] == (42 | 4));
+ assert(c[1] == 42);
+ }
+ {
+ auto c = a;
+ c[0] ^= b[0];
+ assert(c[0] == (42 ^ 4));
+ assert(c[1] == 42);
+ }
+
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] += a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] -= a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] *= a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] /= a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] %= a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] >>= b[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] <<= a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] &= a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] |= a[0]));
+ }
+ {
+ auto c = a;
+ (void)(a[0] + (c[0] ^= a[0]));
+ }
+ }
+ {
+ const SimdType a(42);
+ const SimdType b(4);
+ static_assert(std::is_same<decltype(a[0]), int>::value, "");
+
+ assert(a[0] == 42);
+ assert(!a[0] == !42);
+ assert(~a[0] == ~42);
+ assert(+a[0] == +42);
+ assert(-a[0] == -42);
+ assert(a[0] + b[0] == 42 + 4);
+ assert(a[0] - b[0] == 42 - 4);
+ assert(a[0] * b[0] == 42 * 4);
+ assert(a[0] / b[0] == 42 / 4);
+ assert(a[0] % b[0] == 42 % 4);
+ assert(a[0] << b[0] == (42 << 4));
+ assert(a[0] >> b[0] == (42 >> 4));
+ assert(a[0] < b[0] == false);
+ assert(a[0] <= b[0] == false);
+ assert(a[0] > b[0] == true);
+ assert(a[0] >= b[0] == true);
+ assert(a[0] == b[0] == false);
+ assert(a[0] != b[0] == true);
+ assert((a[0] & b[0]) == (42 & 4));
+ assert((a[0] | b[0]) == (42 | 4));
+ assert((a[0] ^ b[0]) == (42 ^ 4));
+ assert((a[0] && b[0]) == true);
+ assert((a[0] || b[0]) == true);
+ }
+}
+
+int main() {
+ test_access<ex::native_simd<int>>();
+ test_access<ex::fixed_size_simd<int, 4>>();
+}
diff --git a/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp b/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
index af6b13fe878d..d15f138d5b90 100644
--- a/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
+++ b/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
@@ -7,34 +7,40 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// <experimental/simd>
//
// [simd.casts]
-// template <class T, class U, class Abi> see below simd_cast(const simd<U, Abi>&);
+// template <class T, class U, class Abi> see below ex::simd_cast<(const
+// ex::simd<U, Abi>&);
+
#include <experimental/simd>
#include <cstdint>
-using namespace std::experimental::parallelism_v2;
-
-static_assert(std::is_same<decltype(simd_cast<int32_t>(native_simd<int32_t>())),
- native_simd<int32_t>>::value,
- "");
+namespace ex = std::experimental::parallelism_v2;
static_assert(
- std::is_same<decltype(simd_cast<int64_t>(fixed_size_simd<int32_t, 4>())),
- fixed_size_simd<int64_t, 4>>::value,
+ std::is_same<decltype(ex::simd_cast<int32_t>(ex::native_simd<int32_t>())),
+ ex::native_simd<int32_t>>::value,
"");
-static_assert(std::is_same<decltype(simd_cast<fixed_size_simd<int64_t, 1>>(
- simd<int32_t, simd_abi::scalar>())),
- fixed_size_simd<int64_t, 1>>::value,
+static_assert(std::is_same<decltype(ex::simd_cast<int64_t>(
+ ex::fixed_size_simd<int32_t, 4>())),
+ ex::fixed_size_simd<int64_t, 4>>::value,
"");
-static_assert(std::is_same<decltype(simd_cast<simd<int64_t, simd_abi::scalar>>(
- fixed_size_simd<int32_t, 1>())),
- simd<int64_t, simd_abi::scalar>>::value,
- "");
+static_assert(
+ std::is_same<decltype(ex::simd_cast<ex::fixed_size_simd<int64_t, 1>>(
+ ex::simd<int32_t, ex::simd_abi::scalar>())),
+ ex::fixed_size_simd<int64_t, 1>>::value,
+ "");
+
+static_assert(
+ std::is_same<
+ decltype(ex::simd_cast<ex::simd<int64_t, ex::simd_abi::scalar>>(
+ ex::fixed_size_simd<int32_t, 1>())),
+ ex::simd<int64_t, ex::simd_abi::scalar>>::value,
+ "");
int main() {}
diff --git a/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp b/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
index eb1fa55e0a44..b734664770ef 100644
--- a/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
+++ b/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
@@ -7,32 +7,35 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// <experimental/simd>
//
// [simd.casts]
-// template <class T, class U, class Abi> see below static_simd_cast(const simd<U, Abi>&);
+// template <class T, class U, class Abi> see below ex::static_simd_cast<(const
+// ex::simd<U, Abi>&);
#include <experimental/simd>
#include <cstdint>
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
static_assert(
- std::is_same<decltype(static_simd_cast<float>(native_simd<int>())),
- native_simd<float>>::value,
+ std::is_same<decltype(ex::static_simd_cast<float>(ex::native_simd<int>())),
+ ex::native_simd<float>>::value,
"");
-static_assert(std::is_same<decltype(static_simd_cast<fixed_size_simd<float, 1>>(
- simd<int, simd_abi::scalar>())),
- fixed_size_simd<float, 1>>::value,
- "");
+static_assert(
+ std::is_same<decltype(ex::static_simd_cast<ex::fixed_size_simd<float, 1>>(
+ ex::simd<int, ex::simd_abi::scalar>())),
+ ex::fixed_size_simd<float, 1>>::value,
+ "");
static_assert(
- std::is_same<decltype(static_simd_cast<simd<float, simd_abi::scalar>>(
- fixed_size_simd<int, 1>())),
- simd<float, simd_abi::scalar>>::value,
+ std::is_same<
+ decltype(ex::static_simd_cast<ex::simd<float, ex::simd_abi::scalar>>(
+ ex::fixed_size_simd<int, 1>())),
+ ex::simd<float, ex::simd_abi::scalar>>::value,
"");
int main() {}
diff --git a/test/std/experimental/simd/simd.cons/broadcast.pass.cpp b/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
index 60230cc63735..49b2b5572842 100644
--- a/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
+++ b/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// See GCC PR63723.
// UNSUPPORTED: gcc-4.9
@@ -20,18 +20,19 @@
#include <cstdint>
#include <experimental/simd>
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
template <class T, class... Args>
auto not_supported_native_simd_ctor(Args&&... args)
- -> decltype(native_simd<T>(std::forward<Args>(args)...), void()) = delete;
+ -> decltype(ex::native_simd<T>(std::forward<Args>(args)...),
+ void()) = delete;
template <class T>
void not_supported_native_simd_ctor(...) {}
template <class T, class... Args>
auto supported_native_simd_ctor(Args&&... args)
- -> decltype(native_simd<T>(std::forward<Args>(args)...), void()) {}
+ -> decltype(ex::native_simd<T>(std::forward<Args>(args)...), void()) {}
template <class T>
void supported_native_simd_ctor(...) = delete;
@@ -55,4 +56,31 @@ void compile_narrowing_conversion() {
not_supported_native_simd_ctor<int>(3.);
}
-int main() {}
+void compile_convertible() {
+ struct ConvertibleToInt {
+ operator int64_t() const;
+ };
+ supported_native_simd_ctor<int64_t>(ConvertibleToInt());
+
+ struct NotConvertibleToInt {};
+ not_supported_native_simd_ctor<int64_t>(NotConvertibleToInt());
+}
+
+void compile_unsigned() {
+ not_supported_native_simd_ctor<int>(3u);
+ supported_native_simd_ctor<uint16_t>(3u);
+}
+
+template <typename SimdType>
+void test_broadcast() {
+ SimdType a(3);
+ for (size_t i = 0; i < a.size(); i++) {
+ assert(a[i] == 3);
+ }
+}
+
+int main() {
+ test_broadcast<ex::native_simd<int>>();
+ test_broadcast<ex::fixed_size_simd<int, 4>>();
+ test_broadcast<ex::fixed_size_simd<int, 15>>();
+}
diff --git a/test/std/experimental/simd/simd.cons/default.pass.cpp b/test/std/experimental/simd/simd.cons/default.pass.cpp
new file mode 100644
index 000000000000..0f12eced0aaf
--- /dev/null
+++ b/test/std/experimental/simd/simd.cons/default.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// [simd.class]
+// simd() = default;
+
+#include <cstdint>
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+int main() {
+ static_assert(ex::native_simd<int32_t>().size() > 0, "");
+ static_assert(ex::fixed_size_simd<int32_t, 4>().size() == 4, "");
+ static_assert(ex::fixed_size_simd<int32_t, 5>().size() == 5, "");
+ static_assert(ex::fixed_size_simd<int32_t, 1>().size() == 1, "");
+ static_assert(ex::fixed_size_simd<char, 32>().size() == 32, "");
+}
diff --git a/test/std/experimental/simd/simd.cons/generator.pass.cpp b/test/std/experimental/simd/simd.cons/generator.pass.cpp
index baf7d936c6a3..43273e896b41 100644
--- a/test/std/experimental/simd/simd.cons/generator.pass.cpp
+++ b/test/std/experimental/simd/simd.cons/generator.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// See GCC PR63723.
// UNSUPPORTED: gcc-4.9
@@ -17,30 +17,75 @@
// [simd.class]
// template <class G> explicit simd(G&& gen);
-#include <cstdint>
#include <experimental/simd>
+#include <cstdint>
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
template <class T, class... Args>
-auto not_supported_native_simd_ctor(Args&&... args)
- -> decltype(native_simd<T>(std::forward<Args>(args)...), void()) = delete;
+auto not_supported_simd128_ctor(Args&&... args) -> decltype(
+ ex::fixed_size_simd<T, 16 / sizeof(T)>(std::forward<Args>(args)...),
+ void()) = delete;
template <class T>
-void not_supported_native_simd_ctor(...) {}
+void not_supported_simd128_ctor(...) {}
template <class T, class... Args>
-auto supported_native_simd_ctor(Args&&... args)
- -> decltype(native_simd<T>(std::forward<Args>(args)...), void()) {}
+auto supported_simd128_ctor(Args&&... args) -> decltype(
+ ex::fixed_size_simd<T, 16 / sizeof(T)>(std::forward<Args>(args)...),
+ void()) {}
template <class T>
-void supported_native_simd_ctor(...) = delete;
+void supported_simd128_ctor(...) = delete;
+
+struct identity {
+ template <size_t value>
+ int operator()(std::integral_constant<size_t, value>) const {
+ return value;
+ }
+};
void compile_generator() {
- supported_native_simd_ctor<int>([](int i) { return i; });
- not_supported_native_simd_ctor<int>([](int i) { return float(i); });
- not_supported_native_simd_ctor<int>([](intptr_t i) { return (int*)(i); });
- not_supported_native_simd_ctor<int>([](int* i) { return i; });
+ supported_simd128_ctor<int>(identity());
+ not_supported_simd128_ctor<int>([](int i) { return float(i); });
+ not_supported_simd128_ctor<int>([](intptr_t i) { return (int*)(i); });
+ not_supported_simd128_ctor<int>([](int* i) { return i; });
}
-int main() {}
+struct limited_identity {
+ template <size_t value>
+ typename std::conditional<value <= 2, int32_t, int64_t>::type
+ operator()(std::integral_constant<size_t, value>) const {
+ return value;
+ }
+};
+
+void compile_limited_identity() {
+ supported_simd128_ctor<int64_t>(limited_identity());
+ not_supported_simd128_ctor<int32_t>(limited_identity());
+}
+
+template <typename SimdType>
+void test_generator() {
+ {
+ SimdType a([](int i) { return i; });
+ assert(a[0] == 0);
+ assert(a[1] == 1);
+ assert(a[2] == 2);
+ assert(a[3] == 3);
+ }
+ {
+ SimdType a([](int i) { return 2 * i - 1; });
+ assert(a[0] == -1);
+ assert(a[1] == 1);
+ assert(a[2] == 3);
+ assert(a[3] == 5);
+ }
+}
+
+int main() {
+ // TODO: adjust the tests when this assertion fails.
+ assert(ex::native_simd<int32_t>::size() >= 4);
+ test_generator<ex::native_simd<int32_t>>();
+ test_generator<ex::fixed_size_simd<int32_t, 4>>();
+}
diff --git a/test/std/experimental/simd/simd.cons/load.pass.cpp b/test/std/experimental/simd/simd.cons/load.pass.cpp
new file mode 100644
index 000000000000..8c87fe7a5554
--- /dev/null
+++ b/test/std/experimental/simd/simd.cons/load.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// [simd.class]
+// template <class U, class Flags> simd(const U* mem, Flags f);
+
+#include <cstdint>
+#include <experimental/simd>
+
+#include "test_macros.h"
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, class... Args>
+auto not_supported_native_simd_ctor(Args&&... args)
+ -> decltype(ex::native_simd<T>(std::forward<Args>(args)...),
+ void()) = delete;
+
+template <class T>
+void not_supported_native_simd_ctor(...) {}
+
+template <class T, class... Args>
+auto supported_native_simd_ctor(Args&&... args)
+ -> decltype(ex::native_simd<T>(std::forward<Args>(args)...), void()) {}
+
+template <class T>
+void supported_native_simd_ctor(...) = delete;
+
+void compile_load_ctor() {
+ supported_native_simd_ctor<int>((int*)nullptr, ex::element_aligned_tag());
+ supported_native_simd_ctor<uint32_t>((int*)nullptr,
+ ex::element_aligned_tag());
+ supported_native_simd_ctor<double>((float*)nullptr,
+ ex::element_aligned_tag());
+ supported_native_simd_ctor<uint16_t>((unsigned int*)nullptr,
+ ex::element_aligned_tag());
+ supported_native_simd_ctor<uint32_t>((float*)nullptr,
+ ex::element_aligned_tag());
+
+ not_supported_native_simd_ctor<int>((int*)nullptr, int());
+}
+
+template <typename SimdType>
+void test_load_ctor() {
+ alignas(32) int32_t buffer[] = {4, 3, 2, 1};
+ {
+ SimdType a(buffer, ex::element_aligned_tag());
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a(buffer, ex::vector_aligned_tag());
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a(buffer, ex::overaligned_tag<32>());
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+
+ {
+ SimdType a(buffer, ex::element_aligned);
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a(buffer, ex::vector_aligned);
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a(buffer, ex::overaligned<32>);
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+}
+
+template <typename SimdType>
+void test_converting_load_ctor() {
+ float buffer[] = {1., 2., 4., 8.};
+ SimdType a(buffer, ex::element_aligned_tag());
+ assert(a[0] == 1);
+ assert(a[1] == 2);
+ assert(a[2] == 4);
+ assert(a[3] == 8);
+}
+
+int main() {
+ // TODO: adjust the tests when this assertion fails.
+ assert(ex::native_simd<int32_t>::size() >= 4);
+ test_load_ctor<ex::native_simd<int32_t>>();
+ test_load_ctor<ex::fixed_size_simd<int32_t, 4>>();
+ test_converting_load_ctor<ex::native_simd<int32_t>>();
+ test_converting_load_ctor<ex::fixed_size_simd<int32_t, 4>>();
+}
diff --git a/test/std/experimental/simd/simd.mem/load.pass.cpp b/test/std/experimental/simd/simd.mem/load.pass.cpp
new file mode 100644
index 000000000000..b1a3a2b1d3b5
--- /dev/null
+++ b/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// loads [simd.load]
+// template <class U, class Flags> void copy_from(const U* mem, Flags f);
+
+#include <experimental/simd>
+#include <cstdint>
+
+#include "test_macros.h"
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, class... Args>
+auto not_supported_load(Args&&... args) -> decltype(
+ std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
+ void()) = delete;
+
+template <class T>
+void not_supported_load(...) {}
+
+template <class T, class... Args>
+auto supported_load(Args&&... args) -> decltype(
+ std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
+ void()) {}
+
+template <class T>
+void supported_load(...) = delete;
+
+void compile_load() {
+ supported_load<int>((int*)nullptr, ex::element_aligned_tag());
+ supported_load<uint32_t>((int*)nullptr, ex::element_aligned_tag());
+ supported_load<double>((float*)nullptr, ex::element_aligned_tag());
+ supported_load<uint16_t>((unsigned int*)nullptr, ex::element_aligned_tag());
+ supported_load<uint32_t>((float*)nullptr, ex::element_aligned_tag());
+
+ not_supported_load<int>((int*)nullptr, int());
+}
+
+template <typename SimdType>
+void test_load() {
+ alignas(32) int32_t buffer[] = {4, 3, 2, 1};
+ {
+ SimdType a;
+ a.copy_from(buffer, ex::element_aligned_tag());
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a;
+ a.copy_from(buffer, ex::vector_aligned_tag());
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a;
+ a.copy_from(buffer, ex::overaligned_tag<32>());
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+
+ {
+ SimdType a;
+ a.copy_from(buffer, ex::element_aligned);
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a;
+ a.copy_from(buffer, ex::vector_aligned);
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+ {
+ SimdType a;
+ a.copy_from(buffer, ex::overaligned<32>);
+ assert(a[0] == 4);
+ assert(a[1] == 3);
+ assert(a[2] == 2);
+ assert(a[3] == 1);
+ }
+}
+
+template <typename SimdType>
+void test_converting_load() {
+ float buffer[] = {1., 2., 4., 8.};
+ SimdType a;
+ a.copy_from(buffer, ex::element_aligned_tag());
+ assert(a[0] == 1);
+ assert(a[1] == 2);
+ assert(a[2] == 4);
+ assert(a[3] == 8);
+}
+
+int main() {
+ // TODO: adjust the tests when this assertion fails.
+ assert(ex::native_simd<int32_t>::size() >= 4);
+ test_load<ex::native_simd<int32_t>>();
+ test_load<ex::fixed_size_simd<int32_t, 4>>();
+ test_converting_load<ex::native_simd<int32_t>>();
+ test_converting_load<ex::fixed_size_simd<int32_t, 4>>();
+}
diff --git a/test/std/experimental/simd/simd.mem/store.pass.cpp b/test/std/experimental/simd/simd.mem/store.pass.cpp
new file mode 100644
index 000000000000..2025a79f21a0
--- /dev/null
+++ b/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// // stores [simd.store]
+// template <class U, class Flags> void copy_to(U* mem, Flags f) const;
+
+#include <experimental/simd>
+#include <cstdint>
+
+#include "test_macros.h"
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <typename SimdType>
+void test_store() {
+ SimdType a([](int i) { return 4 - i; });
+ {
+ alignas(32) int32_t buffer[4] = {0};
+ a.copy_to(buffer, ex::element_aligned_tag());
+ assert(buffer[0] == 4);
+ assert(buffer[1] == 3);
+ assert(buffer[2] == 2);
+ assert(buffer[3] == 1);
+ }
+ {
+ alignas(32) int32_t buffer[4] = {0};
+ a.copy_to(buffer, ex::vector_aligned_tag());
+ assert(buffer[0] == 4);
+ assert(buffer[1] == 3);
+ assert(buffer[2] == 2);
+ assert(buffer[3] == 1);
+ }
+ {
+ alignas(32) int32_t buffer[4] = {0};
+ a.copy_to(buffer, ex::overaligned_tag<32>());
+ assert(buffer[0] == 4);
+ assert(buffer[1] == 3);
+ assert(buffer[2] == 2);
+ assert(buffer[3] == 1);
+ }
+
+ {
+ alignas(32) int32_t buffer[4] = {0};
+ a.copy_to(buffer, ex::element_aligned);
+ assert(buffer[0] == 4);
+ assert(buffer[1] == 3);
+ assert(buffer[2] == 2);
+ assert(buffer[3] == 1);
+ }
+ {
+ alignas(32) int32_t buffer[4] = {0};
+ a.copy_to(buffer, ex::vector_aligned);
+ assert(buffer[0] == 4);
+ assert(buffer[1] == 3);
+ assert(buffer[2] == 2);
+ assert(buffer[3] == 1);
+ }
+ {
+ alignas(32) int32_t buffer[4] = {0};
+ a.copy_to(buffer, ex::overaligned<32>);
+ assert(buffer[0] == 4);
+ assert(buffer[1] == 3);
+ assert(buffer[2] == 2);
+ assert(buffer[3] == 1);
+ }
+}
+
+template <typename SimdType>
+void test_converting_store() {
+ float buffer[4] = {0.};
+ SimdType a([](int i) { return 1 << i; });
+ a.copy_to(buffer, ex::element_aligned_tag());
+ assert(buffer[0] == 1.);
+ assert(buffer[1] == 2.);
+ assert(buffer[2] == 4.);
+ assert(buffer[3] == 8.);
+}
+
+int main() {
+ // TODO: adjust the tests when this assertion fails.
+ test_store<ex::native_simd<int32_t>>();
+ test_store<ex::fixed_size_simd<int32_t, 4>>();
+ test_converting_store<ex::native_simd<int32_t>>();
+ test_converting_store<ex::fixed_size_simd<int32_t, 4>>();
+}
diff --git a/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp b/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
index 6e244220d7e2..b3cd92add537 100644
--- a/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
+++ b/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
@@ -7,24 +7,26 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// <experimental/simd>
//
// [simd.traits]
-// template <class T, size_t N> struct abi_for_size { using type = see below ; };
-// template <class T, size_t N> using abi_for_size_t = typename abi_for_size<T, N>::type;
+// template <class T, size_t N> struct abi_for_size { using type = see below ;
+// }; template <class T, size_t N> using ex::abi_for_size_t = typename
+// ex::abi_for_size<T, N>::type;
#include <cstdint>
#include <experimental/simd>
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
-static_assert(std::is_same<typename abi_for_size<int, 4>::type,
- simd_abi::fixed_size<4>>::value,
+static_assert(std::is_same<typename ex::abi_for_size<int, 4>::type,
+ ex::simd_abi::fixed_size<4>>::value,
"");
-static_assert(
- std::is_same<abi_for_size_t<int, 4>, simd_abi::fixed_size<4>>::value, "");
+static_assert(std::is_same<ex::abi_for_size_t<int, 4>,
+ ex::simd_abi::fixed_size<4>>::value,
+ "");
int main() {}
diff --git a/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp b/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
index 4f4f738a8351..e87eafbdb1d4 100644
--- a/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
+++ b/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
@@ -7,109 +7,107 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// <experimental/simd>
//
// [simd.traits]
// template <class T> struct is_abi_tag;
-// template <class T> inline constexpr bool is_abi_tag_v = is_abi_tag<T>::value;
+// template <class T> inline constexpr bool ex::is_abi_tag_v =
+// ex::is_abi_tag<T>::value;
#include <cstdint>
#include <experimental/simd>
#include "test_macros.h"
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
struct UserType {};
-static_assert( is_abi_tag<simd_abi::native<int8_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<int16_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<int32_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<int64_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<uint8_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<uint16_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<uint32_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<uint64_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<float>>::value, "");
-static_assert( is_abi_tag<simd_abi::native<double>>::value, "");
-
-static_assert( is_abi_tag<simd_abi::compatible<int8_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<int16_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<int32_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<int64_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<uint8_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<uint16_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<uint32_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<uint64_t>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<float>>::value, "");
-static_assert( is_abi_tag<simd_abi::compatible<double>>::value, "");
-
-static_assert( is_abi_tag<simd_abi::scalar>::value, "");
-static_assert(!std::is_same<simd_abi::scalar, simd_abi::fixed_size<1>>::value,
- "");
-
-static_assert( is_abi_tag<simd_abi::fixed_size<1>>::value, "");
-static_assert( is_abi_tag<simd_abi::fixed_size<2>>::value, "");
-static_assert( is_abi_tag<simd_abi::fixed_size<3>>::value, "");
-static_assert( is_abi_tag<simd_abi::fixed_size<4>>::value, "");
-static_assert( is_abi_tag<simd_abi::fixed_size<5>>::value, "");
-static_assert( is_abi_tag<simd_abi::fixed_size<32>>::value, "");
-
-static_assert(!is_abi_tag<void>::value, "");
-static_assert(!is_abi_tag<int>::value, "");
-static_assert(!is_abi_tag<float>::value, "");
-static_assert(!is_abi_tag<UserType>::value, "");
-static_assert(!is_abi_tag<simd<int>>::value, "");
-static_assert(!is_abi_tag<simd<float>>::value, "");
-static_assert(!is_abi_tag<simd_mask<int>>::value, "");
-static_assert(!is_abi_tag<simd_mask<float>>::value, "");
-
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \
- !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
-
-static_assert( is_abi_tag_v<simd_abi::native<int8_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<int16_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<int32_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<int64_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<uint8_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<uint16_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<uint32_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<uint64_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<float>>, "");
-static_assert( is_abi_tag_v<simd_abi::native<double>>, "");
-
-static_assert( is_abi_tag_v<simd_abi::compatible<int8_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<int16_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<int32_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<int64_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<uint8_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<uint16_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<uint32_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<uint64_t>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<float>>, "");
-static_assert( is_abi_tag_v<simd_abi::compatible<double>>, "");
-
-static_assert( is_abi_tag_v<simd_abi::scalar>, "");
-static_assert(!std::is_same<simd_abi::scalar, simd_abi::fixed_size<1>>::value,
- "");
-
-static_assert( is_abi_tag_v<simd_abi::fixed_size<1>>, "");
-static_assert( is_abi_tag_v<simd_abi::fixed_size<2>>, "");
-static_assert( is_abi_tag_v<simd_abi::fixed_size<3>>, "");
-static_assert( is_abi_tag_v<simd_abi::fixed_size<4>>, "");
-static_assert( is_abi_tag_v<simd_abi::fixed_size<5>>, "");
-static_assert( is_abi_tag_v<simd_abi::fixed_size<32>>, "");
-
-static_assert(!is_abi_tag_v<void>, "");
-static_assert(!is_abi_tag_v<int>, "");
-static_assert(!is_abi_tag_v<float>, "");
-static_assert(!is_abi_tag_v<UserType>, "");
-static_assert(!is_abi_tag_v<simd<int>>, "");
-static_assert(!is_abi_tag_v<simd<float>>, "");
-static_assert(!is_abi_tag_v<simd_mask<int>>, "");
-static_assert(!is_abi_tag_v<simd_mask<float>>, "");
-
-#endif
+static_assert(ex::is_abi_tag<ex::simd_abi::native<int8_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<int16_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<int32_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<int64_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<uint8_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<uint16_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<uint32_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<uint64_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<float>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::native<double>>::value, "");
+
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<int8_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<int16_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<int32_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<int64_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<uint8_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<uint16_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<uint32_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<uint64_t>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<float>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::compatible<double>>::value, "");
+
+static_assert(ex::is_abi_tag<ex::simd_abi::scalar>::value, "");
+static_assert(
+ !std::is_same<ex::simd_abi::scalar, ex::simd_abi::fixed_size<1>>::value,
+ "");
+
+static_assert(ex::is_abi_tag<ex::simd_abi::fixed_size<1>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::fixed_size<2>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::fixed_size<3>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::fixed_size<4>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::fixed_size<5>>::value, "");
+static_assert(ex::is_abi_tag<ex::simd_abi::fixed_size<32>>::value, "");
+
+static_assert(!ex::is_abi_tag<void>::value, "");
+static_assert(!ex::is_abi_tag<int>::value, "");
+static_assert(!ex::is_abi_tag<float>::value, "");
+static_assert(!ex::is_abi_tag<UserType>::value, "");
+static_assert(!ex::is_abi_tag<ex::simd<int>>::value, "");
+static_assert(!ex::is_abi_tag<ex::simd<float>>::value, "");
+static_assert(!ex::is_abi_tag<ex::simd_mask<int>>::value, "");
+static_assert(!ex::is_abi_tag<ex::simd_mask<float>>::value, "");
+
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<int8_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<int16_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<int32_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<int64_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<uint8_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<uint16_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<uint32_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<uint64_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<float>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::native<double>>, "");
+
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<int8_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<int16_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<int32_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<int64_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<uint8_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<uint16_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<uint32_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<uint64_t>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<float>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::compatible<double>>, "");
+
+static_assert(ex::is_abi_tag_v<ex::simd_abi::scalar>, "");
+static_assert(
+ !std::is_same<ex::simd_abi::scalar, ex::simd_abi::fixed_size<1>>::value,
+ "");
+
+static_assert(ex::is_abi_tag_v<ex::simd_abi::fixed_size<1>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::fixed_size<2>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::fixed_size<3>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::fixed_size<4>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::fixed_size<5>>, "");
+static_assert(ex::is_abi_tag_v<ex::simd_abi::fixed_size<32>>, "");
+
+static_assert(!ex::is_abi_tag_v<void>, "");
+static_assert(!ex::is_abi_tag_v<int>, "");
+static_assert(!ex::is_abi_tag_v<float>, "");
+static_assert(!ex::is_abi_tag_v<UserType>, "");
+static_assert(!ex::is_abi_tag_v<ex::simd<int>>, "");
+static_assert(!ex::is_abi_tag_v<ex::simd<float>>, "");
+static_assert(!ex::is_abi_tag_v<ex::simd_mask<int>>, "");
+static_assert(!ex::is_abi_tag_v<ex::simd_mask<float>>, "");
int main() {}
diff --git a/test/std/experimental/simd/simd.traits/is_simd.pass.cpp b/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
index 77f5d10ed3a8..8d7c0946c730 100644
--- a/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
+++ b/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
@@ -7,127 +7,123 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// <experimental/simd>
//
// [simd.traits]
-// template <class T> struct is_simd;
-// template <class T> inline constexpr bool is_simd_v = is_simd<T>::value;
+// template <class T> struct ex::is_simd;
+// template <class T> inline constexpr bool ex::is_simd_v =
+// ex::is_simd<T>::value;
#include <cstdint>
#include <experimental/simd>
#include "test_macros.h"
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
struct UserType {};
-static_assert( is_simd<native_simd<int8_t>>::value, "");
-static_assert( is_simd<native_simd<int16_t>>::value, "");
-static_assert( is_simd<native_simd<int32_t>>::value, "");
-static_assert( is_simd<native_simd<int64_t>>::value, "");
-static_assert( is_simd<native_simd<uint8_t>>::value, "");
-static_assert( is_simd<native_simd<uint16_t>>::value, "");
-static_assert( is_simd<native_simd<uint32_t>>::value, "");
-static_assert( is_simd<native_simd<uint64_t>>::value, "");
-static_assert( is_simd<native_simd<float>>::value, "");
-static_assert( is_simd<native_simd<double>>::value, "");
-
-static_assert( is_simd<fixed_size_simd<int8_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<int16_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<int32_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<int64_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint8_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint16_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint32_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint64_t, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<float, 1>>::value, "");
-static_assert( is_simd<fixed_size_simd<double, 1>>::value, "");
-
-static_assert( is_simd<fixed_size_simd<int8_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<int16_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<int32_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<int64_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint8_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint16_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint32_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint64_t, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<float, 3>>::value, "");
-static_assert( is_simd<fixed_size_simd<double, 3>>::value, "");
-
-static_assert( is_simd<fixed_size_simd<int8_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<int16_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<int32_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<int64_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint8_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint16_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint32_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<uint64_t, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<float, 32>>::value, "");
-static_assert( is_simd<fixed_size_simd<double, 32>>::value, "");
-
-static_assert(!is_simd<void>::value, "");
-static_assert(!is_simd<int>::value, "");
-static_assert(!is_simd<float>::value, "");
-static_assert(!is_simd<simd_mask<int>>::value, "");
-static_assert(!is_simd<simd_mask<float>>::value, "");
-static_assert(!is_simd<UserType>::value, "");
-
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \
- !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
-
-static_assert( is_simd_v<native_simd<int8_t>>, "");
-static_assert( is_simd_v<native_simd<int16_t>>, "");
-static_assert( is_simd_v<native_simd<int32_t>>, "");
-static_assert( is_simd_v<native_simd<int64_t>>, "");
-static_assert( is_simd_v<native_simd<uint8_t>>, "");
-static_assert( is_simd_v<native_simd<uint16_t>>, "");
-static_assert( is_simd_v<native_simd<uint32_t>>, "");
-static_assert( is_simd_v<native_simd<uint64_t>>, "");
-static_assert( is_simd_v<native_simd<float>>, "");
-static_assert( is_simd_v<native_simd<double>>, "");
-
-static_assert( is_simd_v<fixed_size_simd<int8_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<int16_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<int32_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<int64_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint8_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint16_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint32_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint64_t, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<float, 1>>, "");
-static_assert( is_simd_v<fixed_size_simd<double, 1>>, "");
-
-static_assert( is_simd_v<fixed_size_simd<int8_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<int16_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<int32_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<int64_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint8_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint16_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint32_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint64_t, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<float, 3>>, "");
-static_assert( is_simd_v<fixed_size_simd<double, 3>>, "");
-
-static_assert( is_simd_v<fixed_size_simd<int8_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<int16_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<int32_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<int64_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint8_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint16_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint32_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<uint64_t, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<float, 32>>, "");
-static_assert( is_simd_v<fixed_size_simd<double, 32>>, "");
-
-static_assert(!is_simd_v<void>, "");
-static_assert(!is_simd_v<int>, "");
-static_assert(!is_simd_v<float>, "");
-static_assert(!is_simd_v<simd_mask<int>>, "");
-static_assert(!is_simd_v<simd_mask<float>>, "");
-static_assert(!is_simd_v<UserType>, "");
-
-#endif
+static_assert(ex::is_simd<ex::native_simd<int8_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<int16_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<int32_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<int64_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<uint8_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<uint16_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<uint32_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<uint64_t>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<float>>::value, "");
+static_assert(ex::is_simd<ex::native_simd<double>>::value, "");
+
+static_assert(ex::is_simd<ex::fixed_size_simd<int8_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int16_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int32_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int64_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint8_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint16_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint32_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint64_t, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<float, 1>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<double, 1>>::value, "");
+
+static_assert(ex::is_simd<ex::fixed_size_simd<int8_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int16_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int32_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int64_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint8_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint16_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint32_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint64_t, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<float, 3>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<double, 3>>::value, "");
+
+static_assert(ex::is_simd<ex::fixed_size_simd<int8_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int16_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int32_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<int64_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint8_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint16_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint32_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<uint64_t, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<float, 32>>::value, "");
+static_assert(ex::is_simd<ex::fixed_size_simd<double, 32>>::value, "");
+
+static_assert(!ex::is_simd<void>::value, "");
+static_assert(!ex::is_simd<int>::value, "");
+static_assert(!ex::is_simd<float>::value, "");
+static_assert(!ex::is_simd<ex::simd_mask<int>>::value, "");
+static_assert(!ex::is_simd<ex::simd_mask<float>>::value, "");
+static_assert(!ex::is_simd<UserType>::value, "");
+
+static_assert(ex::is_simd_v<ex::native_simd<int8_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<int16_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<int32_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<int64_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<uint8_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<uint16_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<uint32_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<uint64_t>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<float>>, "");
+static_assert(ex::is_simd_v<ex::native_simd<double>>, "");
+
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int8_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int16_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int32_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int64_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint8_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint16_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint32_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint64_t, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<float, 1>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<double, 1>>, "");
+
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int8_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int16_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int32_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int64_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint8_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint16_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint32_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint64_t, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<float, 3>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<double, 3>>, "");
+
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int8_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int16_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int32_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<int64_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint8_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint16_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint32_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<uint64_t, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<float, 32>>, "");
+static_assert(ex::is_simd_v<ex::fixed_size_simd<double, 32>>, "");
+
+static_assert(!ex::is_simd_v<void>, "");
+static_assert(!ex::is_simd_v<int>, "");
+static_assert(!ex::is_simd_v<float>, "");
+static_assert(!ex::is_simd_v<ex::simd_mask<int>>, "");
+static_assert(!ex::is_simd_v<ex::simd_mask<float>>, "");
+static_assert(!ex::is_simd_v<UserType>, "");
int main() {}
diff --git a/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp b/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
index a6fe409057c2..ecb68fb62844 100644
--- a/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
+++ b/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
@@ -7,49 +7,45 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// <experimental/simd>
//
// [simd.traits]
// template <class T> struct is_simd_flag_type;
-// template <class T> inline constexpr bool is_simd_flag_type_v = is_simd_flag_type<T>::value;
+// template <class T> inline constexpr bool ex::is_simd_flag_type_v =
+// ex::is_simd_flag_type<T>::value;
#include <cstdint>
#include <experimental/simd>
#include "test_macros.h"
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
struct UserType {};
-static_assert( is_simd_flag_type<element_aligned_tag>::value, "");
-static_assert( is_simd_flag_type<vector_aligned_tag>::value, "");
-static_assert( is_simd_flag_type<overaligned_tag<16>>::value, "");
-static_assert( is_simd_flag_type<overaligned_tag<32>>::value, "");
-
-static_assert(!is_simd_flag_type<void>::value, "");
-static_assert(!is_simd_flag_type<int>::value, "");
-static_assert(!is_simd_flag_type<float>::value, "");
-static_assert(!is_simd_flag_type<UserType>::value, "");
-static_assert(!is_simd_flag_type<simd<int8_t>>::value, "");
-static_assert(!is_simd_flag_type<simd_mask<int8_t>>::value, "");
-
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \
- !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
-
-static_assert( is_simd_flag_type_v<element_aligned_tag>, "");
-static_assert( is_simd_flag_type_v<vector_aligned_tag>, "");
-static_assert( is_simd_flag_type_v<overaligned_tag<16>>, "");
-static_assert( is_simd_flag_type_v<overaligned_tag<32>>, "");
-
-static_assert(!is_simd_flag_type_v<void>, "");
-static_assert(!is_simd_flag_type_v<int>, "");
-static_assert(!is_simd_flag_type_v<float>, "");
-static_assert(!is_simd_flag_type_v<UserType>, "");
-static_assert(!is_simd_flag_type_v<simd<int8_t>>, "");
-static_assert(!is_simd_flag_type_v<simd_mask<int8_t>>, "");
-
-#endif
+static_assert(ex::is_simd_flag_type<ex::element_aligned_tag>::value, "");
+static_assert(ex::is_simd_flag_type<ex::vector_aligned_tag>::value, "");
+static_assert(ex::is_simd_flag_type<ex::overaligned_tag<16>>::value, "");
+static_assert(ex::is_simd_flag_type<ex::overaligned_tag<32>>::value, "");
+
+static_assert(!ex::is_simd_flag_type<void>::value, "");
+static_assert(!ex::is_simd_flag_type<int>::value, "");
+static_assert(!ex::is_simd_flag_type<float>::value, "");
+static_assert(!ex::is_simd_flag_type<UserType>::value, "");
+static_assert(!ex::is_simd_flag_type<ex::simd<int8_t>>::value, "");
+static_assert(!ex::is_simd_flag_type<ex::simd_mask<int8_t>>::value, "");
+
+static_assert(ex::is_simd_flag_type_v<ex::element_aligned_tag>, "");
+static_assert(ex::is_simd_flag_type_v<ex::vector_aligned_tag>, "");
+static_assert(ex::is_simd_flag_type_v<ex::overaligned_tag<16>>, "");
+static_assert(ex::is_simd_flag_type_v<ex::overaligned_tag<32>>, "");
+
+static_assert(!ex::is_simd_flag_type_v<void>, "");
+static_assert(!ex::is_simd_flag_type_v<int>, "");
+static_assert(!ex::is_simd_flag_type_v<float>, "");
+static_assert(!ex::is_simd_flag_type_v<UserType>, "");
+static_assert(!ex::is_simd_flag_type_v<ex::simd<int8_t>>, "");
+static_assert(!ex::is_simd_flag_type_v<ex::simd_mask<int8_t>>, "");
int main() {}
diff --git a/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp b/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
index 8c2e0ed5bf43..736802443012 100644
--- a/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
+++ b/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -7,127 +7,146 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
// <experimental/simd>
//
// [simd.traits]
-// template <class T> struct is_simd_mask;
-// template <class T> inline constexpr bool is_simd_mask_v = is_simd_mask<T>::value;
+// template <class T> struct ex::is_simd_mask;
+// template <class T> inline constexpr bool ex::is_simd_mask_v =
+// ex::is_simd_mask<T>::value;
#include <cstdint>
#include <experimental/simd>
#include "test_macros.h"
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
struct UserType {};
-static_assert( is_simd_mask<native_simd_mask<int8_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<int16_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<int32_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<int64_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<uint8_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<uint16_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<uint32_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<uint64_t>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<float>>::value, "");
-static_assert( is_simd_mask<native_simd_mask<double>>::value, "");
-
-static_assert( is_simd_mask<fixed_size_simd_mask<int8_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int16_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int32_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int64_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint8_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint16_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint32_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint64_t, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<float, 1>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<double, 1>>::value, "");
-
-static_assert( is_simd_mask<fixed_size_simd_mask<int8_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int16_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int32_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int64_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint8_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint16_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint32_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint64_t, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<float, 3>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<double, 3>>::value, "");
-
-static_assert( is_simd_mask<fixed_size_simd_mask<int8_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int16_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int32_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<int64_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint8_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint16_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint32_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<uint64_t, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<float, 32>>::value, "");
-static_assert( is_simd_mask<fixed_size_simd_mask<double, 32>>::value, "");
-
-static_assert(!is_simd_mask<void>::value, "");
-static_assert(!is_simd_mask<int>::value, "");
-static_assert(!is_simd_mask<float>::value, "");
-static_assert(!is_simd_mask<simd<int>>::value, "");
-static_assert(!is_simd_mask<simd<float>>::value, "");
-static_assert(!is_simd_mask<UserType>::value, "");
-
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \
- !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
-
-static_assert( is_simd_mask_v<native_simd_mask<int8_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<int16_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<int32_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<int64_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<uint8_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<uint16_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<uint32_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<uint64_t>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<float>>, "");
-static_assert( is_simd_mask_v<native_simd_mask<double>>, "");
-
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int8_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int16_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int32_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int64_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint8_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint16_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint32_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint64_t, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<float, 1>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<double, 1>>, "");
-
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int8_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int16_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int32_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int64_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint8_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint16_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint32_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint64_t, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<float, 3>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<double, 3>>, "");
-
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int8_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int16_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int32_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<int64_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint8_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint16_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint32_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<uint64_t, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<float, 32>>, "");
-static_assert( is_simd_mask_v<fixed_size_simd_mask<double, 32>>, "");
-
-static_assert(!is_simd_mask_v<void>, "");
-static_assert(!is_simd_mask_v<int>, "");
-static_assert(!is_simd_mask_v<float>, "");
-static_assert(!is_simd_mask_v<simd<int>>, "");
-static_assert(!is_simd_mask_v<simd<float>>, "");
-static_assert(!is_simd_mask_v<UserType>, "");
-
-#endif
+static_assert(ex::is_simd_mask<ex::native_simd_mask<int8_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<int16_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<int32_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<int64_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<uint8_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<uint16_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<uint32_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<uint64_t>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<float>>::value, "");
+static_assert(ex::is_simd_mask<ex::native_simd_mask<double>>::value, "");
+
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int8_t, 1>>::value, "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int16_t, 1>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int32_t, 1>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int64_t, 1>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint8_t, 1>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint16_t, 1>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint32_t, 1>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint64_t, 1>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<float, 1>>::value, "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<double, 1>>::value, "");
+
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int8_t, 3>>::value, "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int16_t, 3>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int32_t, 3>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int64_t, 3>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint8_t, 3>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint16_t, 3>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint32_t, 3>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint64_t, 3>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<float, 3>>::value, "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<double, 3>>::value, "");
+
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int8_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int16_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int32_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<int64_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint8_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint16_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint32_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<uint64_t, 32>>::value,
+ "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<float, 32>>::value, "");
+static_assert(ex::is_simd_mask<ex::fixed_size_simd_mask<double, 32>>::value,
+ "");
+
+static_assert(!ex::is_simd_mask<void>::value, "");
+static_assert(!ex::is_simd_mask<int>::value, "");
+static_assert(!ex::is_simd_mask<float>::value, "");
+static_assert(!ex::is_simd_mask<ex::simd<int>>::value, "");
+static_assert(!ex::is_simd_mask<ex::simd<float>>::value, "");
+static_assert(!ex::is_simd_mask<UserType>::value, "");
+
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<int8_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<int16_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<int32_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<int64_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<uint8_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<uint16_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<uint32_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<uint64_t>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<float>>, "");
+static_assert(ex::is_simd_mask_v<ex::native_simd_mask<double>>, "");
+
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int8_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int16_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int32_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int64_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint8_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint16_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint32_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint64_t, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<float, 1>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<double, 1>>, "");
+
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int8_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int16_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int32_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int64_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint8_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint16_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint32_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint64_t, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<float, 3>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<double, 3>>, "");
+
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int8_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int16_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int32_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<int64_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint8_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint16_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint32_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<uint64_t, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<float, 32>>, "");
+static_assert(ex::is_simd_mask_v<ex::fixed_size_simd_mask<double, 32>>, "");
+
+static_assert(!ex::is_simd_mask_v<void>, "");
+static_assert(!ex::is_simd_mask_v<int>, "");
+static_assert(!ex::is_simd_mask_v<float>, "");
+static_assert(!ex::is_simd_mask_v<ex::simd<int>>, "");
+static_assert(!ex::is_simd_mask_v<ex::simd<float>>, "");
+static_assert(!ex::is_simd_mask_v<UserType>, "");
int main() {}
diff --git a/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp b/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp
index 5f63af68f701..6e399d0934bf 100644
--- a/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp
+++ b/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp
@@ -23,6 +23,20 @@
#error FLT_RADIX not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef FLT_HAS_SUBNORM
+#error FLT_HAS_SUBNORM not defined
+#endif
+
+#ifndef DBL_HAS_SUBNORM
+#error DBL_HAS_SUBNORM not defined
+#endif
+
+#ifndef LDBL_HAS_SUBNORM
+#error LDBL_HAS_SUBNORM not defined
+#endif
+#endif
+
#ifndef FLT_MANT_DIG
#error FLT_MANT_DIG not defined
#endif
@@ -39,6 +53,20 @@
#error DECIMAL_DIG not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef FLT_DECIMAL_DIG
+#error FLT_DECIMAL_DIG not defined
+#endif
+
+#ifndef DBL_DECIMAL_DIG
+#error DBL_DECIMAL_DIG not defined
+#endif
+
+#ifndef LDBL_DECIMAL_DIG
+#error LDBL_DECIMAL_DIG not defined
+#endif
+#endif
+
#ifndef FLT_DIG
#error FLT_DIG not defined
#endif
@@ -135,6 +163,20 @@
#error LDBL_MIN not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef FLT_TRUE_MIN
+#error FLT_TRUE_MIN not defined
+#endif
+
+#ifndef DBL_TRUE_MIN
+#error DBL_TRUE_MIN not defined
+#endif
+
+#ifndef LDBL_TRUE_MIN
+#error LDBL_TRUE_MIN not defined
+#endif
+#endif
+
int main()
{
}
diff --git a/test/std/language.support/support.runtime/cstdlib.pass.cpp b/test/std/language.support/support.runtime/cstdlib.pass.cpp
index 60f7d954db54..e9dda6cee4ee 100644
--- a/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -13,6 +13,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
// As of 1/10/2015 clang emits a -Wnonnull warnings even if the warning occurs
// in an unevaluated context. For this reason we manually suppress the warning.
#if defined(__clang__)
@@ -71,6 +73,14 @@ int main()
static_assert((std::is_same<decltype(std::strtoull("", endptr,0)), unsigned long long>::value), "");
static_assert((std::is_same<decltype(std::rand()), int>::value), "");
static_assert((std::is_same<decltype(std::srand(0)), void>::value), "");
+
+// Microsoft does not implement aligned_alloc in their C library
+#ifndef TEST_COMPILER_C1XX
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+ static_assert((std::is_same<decltype(std::aligned_alloc(0,0)), void*>::value), "");
+#endif
+#endif
+
static_assert((std::is_same<decltype(std::calloc(0,0)), void*>::value), "");
static_assert((std::is_same<decltype(std::free(0)), void>::value), "");
static_assert((std::is_same<decltype(std::malloc(0)), void*>::value), "");
diff --git a/test/std/language.support/support.runtime/ctime.pass.cpp b/test/std/language.support/support.runtime/ctime.pass.cpp
index 34343b247f21..908dc480884c 100644
--- a/test/std/language.support/support.runtime/ctime.pass.cpp
+++ b/test/std/language.support/support.runtime/ctime.pass.cpp
@@ -11,6 +11,7 @@
#include <ctime>
#include <type_traits>
+#include "test_macros.h"
#ifndef NULL
#error NULL not defined
@@ -20,12 +21,22 @@
#error CLOCKS_PER_SEC not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef TIME_UTC
+#error TIME_UTC not defined
+#endif
+#endif
+
int main()
{
std::clock_t c = 0;
std::size_t s = 0;
std::time_t t = 0;
std::tm tm = {};
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+ std::timespec tmspec = {};
+ ((void)tmspec); // Prevent unused warning
+#endif
((void)c); // Prevent unused warning
((void)s); // Prevent unused warning
((void)t); // Prevent unused warning
@@ -34,6 +45,9 @@ int main()
static_assert((std::is_same<decltype(std::difftime(t,t)), double>::value), "");
static_assert((std::is_same<decltype(std::mktime(&tm)), std::time_t>::value), "");
static_assert((std::is_same<decltype(std::time(&t)), std::time_t>::value), "");
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+ static_assert((std::is_same<decltype(std::timespec_get(nullptr, 0)), int>::value), "");
+#endif
#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
static_assert((std::is_same<decltype(std::asctime(&tm)), char*>::value), "");
static_assert((std::is_same<decltype(std::ctime(&t)), char*>::value), "");
diff --git a/test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp b/test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
new file mode 100644
index 000000000000..d21b638d0fc7
--- /dev/null
+++ b/test/std/utilities/charconv/charconv.from.chars/integral.bool.fail.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <charconv>
+
+// In
+//
+// from_chars_result from_chars(const char* first, const char* last,
+// Integral& value, int base = 10)
+//
+// Integral cannot be bool.
+
+#include <charconv>
+
+int main()
+{
+ using std::from_chars;
+ char buf[] = "01001";
+ bool lv;
+
+ from_chars(buf, buf + sizeof(buf), lv); // expected-error {{call to deleted function}}
+ from_chars(buf, buf + sizeof(buf), lv, 16); // expected-error {{call to deleted function}}
+}
diff --git a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
new file mode 100644
index 000000000000..3fc533a772fa
--- /dev/null
+++ b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -0,0 +1,182 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <charconv>
+
+// from_chars_result from_chars(const char* first, const char* last,
+// Integral& value, int base = 10)
+
+#include "charconv_test_helpers.h"
+
+template <typename T>
+struct test_basics : roundtrip_test_base<T>
+{
+ using roundtrip_test_base<T>::test;
+
+ void operator()()
+ {
+ test(0);
+ test(42);
+ test(32768);
+ test(0, 10);
+ test(42, 10);
+ test(32768, 10);
+ test(0xf, 16);
+ test(0xdeadbeaf, 16);
+ test(0755, 8);
+
+ for (int b = 2; b < 37; ++b)
+ {
+ using xl = std::numeric_limits<T>;
+
+ test(1, b);
+ test(-1, b);
+ test(xl::lowest(), b);
+ test((xl::max)(), b);
+ test((xl::max)() / 2, b);
+ }
+
+ using std::from_chars;
+ std::from_chars_result r;
+ T x;
+
+ {
+ char s[] = "001x";
+
+ // the expected form of the subject sequence is a sequence of
+ // letters and digits representing an integer with the radix
+ // specified by base (C11 7.22.1.4/3)
+ r = from_chars(s, s + sizeof(s), x);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 3);
+ assert(x == 1);
+ }
+
+ {
+ char s[] = "0X7BAtSGHDkEIXZg ";
+
+ // The letters from a (or A) through z (or Z) are ascribed the
+ // values 10 through 35; (C11 7.22.1.4/3)
+ r = from_chars(s, s + sizeof(s), x, 36);
+ assert(r.ec == std::errc::result_out_of_range);
+ // The member ptr of the return value points to the first character
+ // not matching the pattern
+ assert(r.ptr == s + sizeof(s) - 2);
+ assert(x == 1);
+
+ // no "0x" or "0X" prefix shall appear if the value of base is 16
+ r = from_chars(s, s + sizeof(s), x, 16);
+ assert(r.ec == std::errc{});
+ assert(r.ptr == s + 1);
+ assert(x == 0);
+
+ // only letters and digits whose ascribed values are less than that
+ // of base are permitted. (C11 7.22.1.4/3)
+ r = from_chars(s + 2, s + sizeof(s), x, 12);
+ // If the parsed value is not in the range representable by the type
+ // of value,
+ if (!fits_in<T>(1150))
+ {
+ // value is unmodified and
+ assert(x == 0);
+ // the member ec of the return value is equal to
+ // errc::result_out_of_range
+ assert(r.ec == std::errc::result_out_of_range);
+ }
+ else
+ {
+ // Otherwise, value is set to the parsed value,
+ assert(x == 1150);
+ // and the member ec is value-initialized.
+ assert(r.ec == std::errc{});
+ }
+ assert(r.ptr == s + 5);
+ }
+ }
+};
+
+template <typename T>
+struct test_signed : roundtrip_test_base<T>
+{
+ using roundtrip_test_base<T>::test;
+
+ void operator()()
+ {
+ test(-1);
+ test(-12);
+ test(-1, 10);
+ test(-12, 10);
+ test(-21734634, 10);
+ test(-2647, 2);
+ test(-0xcc1, 16);
+
+ for (int b = 2; b < 37; ++b)
+ {
+ using xl = std::numeric_limits<T>;
+
+ test(0, b);
+ test(xl::lowest(), b);
+ test((xl::max)(), b);
+ }
+
+ using std::from_chars;
+ std::from_chars_result r;
+ T x;
+
+ {
+ // If the pattern allows for an optional sign,
+ // but the string has no digit characters following the sign,
+ char s[] = "- 9+12";
+ r = from_chars(s, s + sizeof(s), x);
+ // no characters match the pattern.
+ assert(r.ptr == s);
+ assert(r.ec == std::errc::invalid_argument);
+ }
+
+ {
+ char s[] = "9+12";
+ r = from_chars(s, s + sizeof(s), x);
+ assert(r.ec == std::errc{});
+ // The member ptr of the return value points to the first character
+ // not matching the pattern,
+ assert(r.ptr == s + 1);
+ assert(x == 9);
+ }
+
+ {
+ char s[] = "12";
+ r = from_chars(s, s + 2, x);
+ assert(r.ec == std::errc{});
+ // or has the value last if all characters match.
+ assert(r.ptr == s + 2);
+ assert(x == 12);
+ }
+
+ {
+ // '-' is the only sign that may appear
+ char s[] = "+30";
+ // If no characters match the pattern,
+ r = from_chars(s, s + sizeof(s), x);
+ // value is unmodified,
+ assert(x == 12);
+ // the member ptr of the return value is first and
+ assert(r.ptr == s);
+ // the member ec is equal to errc::invalid_argument.
+ assert(r.ec == std::errc::invalid_argument);
+ }
+ }
+};
+
+int
+main()
+{
+ run<test_basics>(integrals);
+ run<test_signed>(all_signed);
+}
diff --git a/test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp b/test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
new file mode 100644
index 000000000000..e3d702a3a9c3
--- /dev/null
+++ b/test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <charconv>
+
+// In
+//
+// to_chars_result to_chars(char* first, char* last, Integral value,
+// int base = 10)
+//
+// Integral cannot be bool.
+
+#include <charconv>
+
+int main()
+{
+ using std::to_chars;
+ char buf[10];
+ bool lv = true;
+
+ to_chars(buf, buf + sizeof(buf), false); // expected-error {{call to deleted function}}
+ to_chars(buf, buf + sizeof(buf), lv, 16); // expected-error {{call to deleted function}}
+}
diff --git a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
new file mode 100644
index 000000000000..50ca5b1906ea
--- /dev/null
+++ b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// <charconv>
+
+// to_chars_result to_chars(char* first, char* last, Integral value,
+// int base = 10)
+
+#include "charconv_test_helpers.h"
+
+template <typename T>
+struct test_basics : to_chars_test_base<T>
+{
+ using to_chars_test_base<T>::test;
+ using to_chars_test_base<T>::test_value;
+
+ void operator()()
+ {
+ test(0, "0");
+ test(42, "42");
+ test(32768, "32768");
+ test(0, "0", 10);
+ test(42, "42", 10);
+ test(32768, "32768", 10);
+ test(0xf, "f", 16);
+ test(0xdeadbeaf, "deadbeaf", 16);
+ test(0755, "755", 8);
+
+ for (int b = 2; b < 37; ++b)
+ {
+ using xl = std::numeric_limits<T>;
+
+ test_value(1, b);
+ test_value(xl::lowest(), b);
+ test_value((xl::max)(), b);
+ test_value((xl::max)() / 2, b);
+ }
+ }
+};
+
+template <typename T>
+struct test_signed : to_chars_test_base<T>
+{
+ using to_chars_test_base<T>::test;
+ using to_chars_test_base<T>::test_value;
+
+ void operator()()
+ {
+ test(-1, "-1");
+ test(-12, "-12");
+ test(-1, "-1", 10);
+ test(-12, "-12", 10);
+ test(-21734634, "-21734634", 10);
+ test(-2647, "-101001010111", 2);
+ test(-0xcc1, "-cc1", 16);
+
+ for (int b = 2; b < 37; ++b)
+ {
+ using xl = std::numeric_limits<T>;
+
+ test_value(0, b);
+ test_value(xl::lowest(), b);
+ test_value((xl::max)(), b);
+ }
+ }
+};
+
+int
+main()
+{
+ run<test_basics>(integrals);
+ run<test_signed>(all_signed);
+}
diff --git a/test/std/utilities/time/date.time/ctime.pass.cpp b/test/std/utilities/time/date.time/ctime.pass.cpp
index b9e19af32952..fe9f38daa3ff 100644
--- a/test/std/utilities/time/date.time/ctime.pass.cpp
+++ b/test/std/utilities/time/date.time/ctime.pass.cpp
@@ -10,6 +10,8 @@
#include <ctime>
#include <type_traits>
+#include "test_macros.h"
+
#ifndef NULL
#error NULL not defined
#endif
@@ -18,6 +20,12 @@
#error CLOCKS_PER_SEC not defined
#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#ifndef TIME_UTC
+#error TIME_UTC not defined
+#endif
+#endif
+
int main()
{
std::clock_t c = 0;
@@ -30,10 +38,18 @@ int main()
((void)t); // Prevent unused warning
((void)tm); // Prevent unused warning
((void)str); // Prevent unused warning
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+ std::timespec tmspec = {};
+ ((void)tmspec); // Prevent unused warning
+#endif
+
static_assert((std::is_same<decltype(std::clock()), std::clock_t>::value), "");
static_assert((std::is_same<decltype(std::difftime(t,t)), double>::value), "");
static_assert((std::is_same<decltype(std::mktime(&tm)), std::time_t>::value), "");
static_assert((std::is_same<decltype(std::time(&t)), std::time_t>::value), "");
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+ static_assert((std::is_same<decltype(std::timespec_get(nullptr, 0)), int>::value), "");
+#endif
#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
static_assert((std::is_same<decltype(std::asctime(&tm)), char*>::value), "");
static_assert((std::is_same<decltype(std::ctime(&t)), char*>::value), "");
diff --git a/test/support/Counter.h b/test/support/Counter.h
index 4a658c58c064..63ed60801555 100644
--- a/test/support/Counter.h
+++ b/test/support/Counter.h
@@ -23,7 +23,7 @@ public:
Counter() : data_() { ++gConstructed; }
Counter(const T &data) : data_(data) { ++gConstructed; }
Counter(const Counter& rhs) : data_(rhs.data_) { ++gConstructed; }
- Counter& operator=(const Counter& rhs) { ++gConstructed; data_ = rhs.data_; return *this; }
+ Counter& operator=(const Counter& rhs) { data_ = rhs.data_; return *this; }
#if TEST_STD_VER >= 11
Counter(Counter&& rhs) : data_(std::move(rhs.data_)) { ++gConstructed; }
Counter& operator=(Counter&& rhs) { ++gConstructed; data_ = std::move(rhs.data_); return *this; }
@@ -49,7 +49,7 @@ struct hash<Counter<T> >
typedef Counter<T> argument_type;
typedef std::size_t result_type;
- std::size_t operator()(const Counter<T>& x) const {return std::hash<T>(x.get());}
+ std::size_t operator()(const Counter<T>& x) const {return std::hash<T>()(x.get());}
};
}
diff --git a/test/support/charconv_test_helpers.h b/test/support/charconv_test_helpers.h
new file mode 100644
index 000000000000..1560fa79aad8
--- /dev/null
+++ b/test/support/charconv_test_helpers.h
@@ -0,0 +1,232 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
+#define SUPPORT_CHARCONV_TEST_HELPERS_H
+
+#include <charconv>
+#include <cassert>
+#include <limits>
+#include <string.h>
+#include <stdlib.h>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 11
+#error This file requires C++14
+#endif
+
+using std::false_type;
+using std::true_type;
+
+template <typename To, typename From>
+constexpr auto
+is_non_narrowing(From a) -> decltype(To{a}, true_type())
+{
+ return {};
+}
+
+template <typename To>
+constexpr auto
+is_non_narrowing(...) -> false_type
+{
+ return {};
+}
+
+template <typename X, typename T>
+constexpr bool
+_fits_in(T, true_type /* non-narrowing*/, ...)
+{
+ return true;
+}
+
+template <typename X, typename T, typename xl = std::numeric_limits<X>>
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
+{
+ return xl::lowest() <= v && v <= (xl::max)();
+}
+
+template <typename X, typename T, typename xl = std::numeric_limits<X>>
+constexpr bool
+_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
+{
+ return 0 <= v && std::make_unsigned_t<T>(v) <= (xl::max)();
+}
+
+template <typename X, typename T, typename xl = std::numeric_limits<X>>
+constexpr bool
+_fits_in(T v, false_type, false_type /* T unsigned */, ...)
+{
+ return v <= std::make_unsigned_t<X>((xl::max)());
+}
+
+template <typename X, typename T>
+constexpr bool
+fits_in(T v)
+{
+ return _fits_in<X>(v, is_non_narrowing<X>(v), std::is_signed<T>(),
+ std::is_signed<X>());
+}
+
+template <typename X>
+struct to_chars_test_base
+{
+ template <typename T, size_t N, typename... Ts>
+ void test(T v, char const (&expect)[N], Ts... args)
+ {
+ using std::to_chars;
+ std::to_chars_result r;
+
+ constexpr size_t len = N - 1;
+ static_assert(len > 0, "expected output won't be empty");
+
+ if (!fits_in<X>(v))
+ return;
+
+ r = to_chars(buf, buf + len - 1, X(v), args...);
+ assert(r.ptr == buf + len - 1);
+ assert(r.ec == std::errc::value_too_large);
+
+ r = to_chars(buf, buf + sizeof(buf), X(v), args...);
+ assert(r.ptr == buf + len);
+ assert(r.ec == std::errc{});
+ assert(memcmp(buf, expect, len) == 0);
+ }
+
+ template <typename... Ts>
+ void test_value(X v, Ts... args)
+ {
+ using std::to_chars;
+ std::to_chars_result r;
+
+ r = to_chars(buf, buf + sizeof(buf), v, args...);
+ assert(r.ec == std::errc{});
+ *r.ptr = '\0';
+
+ auto a = fromchars(buf, r.ptr, args...);
+ assert(v == a);
+
+ auto ep = r.ptr - 1;
+ r = to_chars(buf, ep, v, args...);
+ assert(r.ptr == ep);
+ assert(r.ec == std::errc::value_too_large);
+ }
+
+private:
+ static auto fromchars(char const* p, char const* ep, int base, true_type)
+ {
+ char* last;
+ auto r = strtoll(p, &last, base);
+ assert(last == ep);
+
+ return r;
+ }
+
+ static auto fromchars(char const* p, char const* ep, int base, false_type)
+ {
+ char* last;
+ auto r = strtoull(p, &last, base);
+ assert(last == ep);
+
+ return r;
+ }
+
+ static auto fromchars(char const* p, char const* ep, int base = 10)
+ {
+ return fromchars(p, ep, base, std::is_signed<X>());
+ }
+
+ char buf[100];
+};
+
+template <typename X>
+struct roundtrip_test_base
+{
+ template <typename T, typename... Ts>
+ void test(T v, Ts... args)
+ {
+ using std::from_chars;
+ using std::to_chars;
+ std::from_chars_result r2;
+ std::to_chars_result r;
+ X x = 0xc;
+
+ if (fits_in<X>(v))
+ {
+ r = to_chars(buf, buf + sizeof(buf), v, args...);
+ assert(r.ec == std::errc{});
+
+ r2 = from_chars(buf, r.ptr, x, args...);
+ assert(r2.ptr == r.ptr);
+ assert(x == X(v));
+ }
+ else
+ {
+ r = to_chars(buf, buf + sizeof(buf), v, args...);
+ assert(r.ec == std::errc{});
+
+ r2 = from_chars(buf, r.ptr, x, args...);
+
+ if (std::is_signed<T>::value && v < 0 && std::is_unsigned<X>::value)
+ {
+ assert(x == 0xc);
+ assert(r2.ptr == buf);
+ assert(r2.ec == std::errc::invalid_argument);
+ }
+ else
+ {
+ assert(x == 0xc);
+ assert(r2.ptr == r.ptr);
+ assert(r2.ec == std::errc::result_out_of_range);
+ }
+ }
+ }
+
+private:
+ char buf[100];
+};
+
+template <typename... T>
+struct type_list
+{
+};
+
+template <typename L1, typename L2>
+struct type_concat;
+
+template <typename... Xs, typename... Ys>
+struct type_concat<type_list<Xs...>, type_list<Ys...>>
+{
+ using type = type_list<Xs..., Ys...>;
+};
+
+template <typename L1, typename L2>
+using concat_t = typename type_concat<L1, L2>::type;
+
+template <typename L1, typename L2>
+constexpr auto concat(L1, L2) -> concat_t<L1, L2>
+{
+ return {};
+}
+
+auto all_signed = type_list<char, signed char, short, int, long, long long>();
+auto all_unsigned = type_list<unsigned char, unsigned short, unsigned int,
+ unsigned long, unsigned long long>();
+auto integrals = concat(all_signed, all_unsigned);
+
+template <template <typename> class Fn, typename... Ts>
+void
+run(type_list<Ts...>)
+{
+ int ls[sizeof...(Ts)] = {(Fn<Ts>{}(), 0)...};
+ (void)ls;
+}
+
+#endif // SUPPORT_CHARCONV_TEST_HELPERS_H
diff --git a/test/support/test_macros.h b/test/support/test_macros.h
index dbbfd53094e6..ac6ec79b9235 100644
--- a/test/support/test_macros.h
+++ b/test/support/test_macros.h
@@ -94,16 +94,6 @@
#define TEST_GLIBC_PREREQ(major, minor) __GLIBC_PREREQ(major, minor)
#endif
-/* Features that were introduced in C++14 */
-#if TEST_STD_VER >= 14
-#define TEST_HAS_EXTENDED_CONSTEXPR
-#define TEST_HAS_VARIABLE_TEMPLATES
-#endif
-
-/* Features that were introduced after C++14 */
-#if TEST_STD_VER > 14
-#endif
-
#if TEST_STD_VER >= 11
#define TEST_ALIGNOF(...) alignof(__VA_ARGS__)
#define TEST_ALIGNAS(...) alignas(__VA_ARGS__)
@@ -132,6 +122,43 @@
#define TEST_THROW_SPEC(...) throw(__VA_ARGS__)
#endif
+// Sniff out to see if the underling C library has C11 features
+// Note that at this time (July 2018), MacOS X and iOS do NOT.
+#if __ISO_C_VISIBLE >= 2011
+# if defined(__FreeBSD__)
+# define TEST_HAS_C11_FEATURES
+# elif defined(__Fuchsia__)
+# define TEST_HAS_C11_FEATURES
+# elif defined(__linux__)
+# if !defined(_LIBCPP_HAS_MUSL_LIBC)
+# if _LIBCPP_GLIBC_PREREQ(2, 17)
+# define TEST_HAS_C11_FEATURES
+# endif
+# else // defined(_LIBCPP_HAS_MUSL_LIBC)
+# define TEST_HAS_C11_FEATURES
+# endif
+# elif defined(_WIN32)
+# if defined(_MSC_VER) && !defined(__MINGW32__)
+# define TEST_HAS_C11_FEATURES // Using Microsoft's C Runtime library
+# endif
+# endif
+#endif
+
+/* Features that were introduced in C++14 */
+#if TEST_STD_VER >= 14
+#define TEST_HAS_EXTENDED_CONSTEXPR
+#define TEST_HAS_VARIABLE_TEMPLATES
+#endif
+
+/* Features that were introduced in C++17 */
+#if TEST_STD_VER >= 17
+#endif
+
+/* Features that were introduced after C++17 */
+#if TEST_STD_VER > 17
+#endif
+
+
#define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__))
#if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \
diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html
index dc35283739b3..5f713ede981e 100644
--- a/www/cxx1z_status.html
+++ b/www/cxx1z_status.html
@@ -99,9 +99,9 @@
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/p0032r3">p0032r3</a></td><td>LWG</td><td>Homogeneous interface for variant, any and optional</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/p0040r3">p0040r3</a></td><td>LWG</td><td>Extending memory management tools</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
- <tr><td><a href="https://wg21.link/p0063r3">p0063r3</a></td><td>LWG</td><td>C++17 should refer to C11 instead of C99</td><td>Oulu</td><td><i>Nothing to do</i></td><td>n/a</td></tr>
- <tr><td><a href="https://wg21.link/p0067r3">p0067r3</a></td><td>LWG</td><td>Elementary string conversions</td><td>Oulu</td><td>Now <a href="https://wg21.link/P0067R5">P0067R5</a></td><td></td></tr>
- <tr><td><a href="https://wg21.link/p0083r3">p0083r3</a></td><td>LWG</td><td>Splicing Maps and Sets</td><td>Oulu</td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/p0063r3">p0063r3</a></td><td>LWG</td><td>C++17 should refer to C11 instead of C99</td><td>Oulu</td><td>Complete</td><td>7.0</td></tr>
+ <tr><td><a href="https://wg21.link/p0067r3">p0067r3</a></td><td>LWG</td><td>Elementary string conversions</td><td>Oulu</td><td>Now <a href="https://wg21.link/P0067R5">P0067R5</a></td><td>n/a</td></tr>
+ <tr><td><a href="https://wg21.link/p0083r3">p0083r3</a></td><td>LWG</td><td>Splicing Maps and Sets</td><td>Oulu</td><td><i>Partially Done</i></td><td></td></tr>
<tr><td><a href="https://wg21.link/p0084r2">p0084r2</a></td><td>LWG</td><td>Emplace Return Type</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/p0088r3">p0088r3</a></td><td>LWG</td><td>Variant: a type-safe union for C++17</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/p0137r1">p0137r1</a></td><td>CWG</td><td>Core Issue 1776: Replacement of class objects containing reference members</td><td>Oulu</td><td>Complete</td><td>6.0</td></tr>
@@ -127,7 +127,7 @@
<tr><td><a href="https://wg21.link/P0394r4">P0394r4</a></td><td>LWG</td><td>Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling</td><td>Oulu</td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0003R5">P0003R5</a></td><td>LWG</td><td>Removing Deprecated Exception Specifications from C++17</td><td>Issaquah</td><td>Complete</td><td>5.0</td></tr>
- <tr><td><a href="https://wg21.link/P0067R5">P0067R5</a></td><td>LWG</td><td>Elementary string conversions, revision 5</td><td>Issaquah</td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0067R5">P0067R5</a></td><td>LWG</td><td>Elementary string conversions, revision 5</td><td>Issaquah</td><td><i>Partially done</i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0403R1">P0403R1</a></td><td>LWG</td><td>Literal suffixes for <tt>basic_string_view</tt></td><td>Issaquah</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/P0414R2">P0414R2</a></td><td>LWG</td><td>Merging shared_ptr changes from Library Fundamentals to C++17</td><td>Issaquah</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0418R2">P0418R2</a></td><td>LWG</td><td>Fail or succeed: there is no atomic lattice</td><td>Issaquah</td><td></td><td></td></tr>