aboutsummaryrefslogtreecommitdiff
path: root/contrib/libc++
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-08-02 18:04:37 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-08-02 18:04:37 +0000
commit001571757a996eb123a8568a0c53eee4108efda6 (patch)
treef9da6c0059a7085385e65f1ab69d097c35763fbb /contrib/libc++
parent862c6211d194e5d218eccae84eab0bd9140cf5e9 (diff)
parent315d10f09ee888005b1da55e7bbb57d8a79b8447 (diff)
Notes
Diffstat (limited to 'contrib/libc++')
-rw-r--r--contrib/libc++/include/__config6
-rw-r--r--contrib/libc++/include/__functional_base2
-rw-r--r--contrib/libc++/include/__hash_table120
-rw-r--r--contrib/libc++/include/__mutex_base2
-rw-r--r--contrib/libc++/include/__node_handle212
-rw-r--r--contrib/libc++/include/__tree170
-rw-r--r--contrib/libc++/include/cfloat10
-rw-r--r--contrib/libc++/include/charconv610
-rw-r--r--contrib/libc++/include/ctime14
-rw-r--r--contrib/libc++/include/experimental/__config7
-rw-r--r--contrib/libc++/include/experimental/simd381
-rw-r--r--contrib/libc++/include/float.h11
-rw-r--r--contrib/libc++/include/functional4
-rw-r--r--contrib/libc++/include/map83
-rw-r--r--contrib/libc++/include/memory6
-rw-r--r--contrib/libc++/include/module.modulemap5
-rw-r--r--contrib/libc++/include/new6
-rw-r--r--contrib/libc++/include/set81
-rw-r--r--contrib/libc++/include/shared_mutex2
-rw-r--r--contrib/libc++/include/system_error2
-rw-r--r--contrib/libc++/include/unordered_map87
-rw-r--r--contrib/libc++/include/unordered_set84
-rw-r--r--contrib/libc++/include/utility2
-rw-r--r--contrib/libc++/src/bind.cpp1
-rw-r--r--contrib/libc++/src/charconv.cpp233
-rw-r--r--contrib/libc++/src/future.cpp44
-rw-r--r--contrib/libc++/src/memory.cpp1
-rw-r--r--contrib/libc++/src/mutex.cpp1
-rw-r--r--contrib/libc++/src/new.cpp2
-rw-r--r--contrib/libc++/src/shared_mutex.cpp1
-rw-r--r--contrib/libc++/src/system_error.cpp1
-rw-r--r--contrib/libc++/src/utility.cpp1
32 files changed, 2079 insertions, 113 deletions
diff --git a/contrib/libc++/include/__config b/contrib/libc++/include/__config
index c01ac12be4b8..639d06c9f5d7 100644
--- a/contrib/libc++/include/__config
+++ b/contrib/libc++/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/contrib/libc++/include/__functional_base b/contrib/libc++/include/__functional_base
index 1a90bd6280f6..57fdf2b9f663 100644
--- a/contrib/libc++/include/__functional_base
+++ b/contrib/libc++/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/contrib/libc++/include/__hash_table b/contrib/libc++/include/__hash_table
index 44ba268a0ec8..c77de961be6b 100644
--- a/contrib/libc++/include/__hash_table
+++ b/contrib/libc++/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/contrib/libc++/include/__mutex_base b/contrib/libc++/include/__mutex_base
index 402a52d945e1..4659ca9298c9 100644
--- a/contrib/libc++/include/__mutex_base
+++ b/contrib/libc++/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/contrib/libc++/include/__node_handle b/contrib/libc++/include/__node_handle
new file mode 100644
index 000000000000..fe09f3c1e51c
--- /dev/null
+++ b/contrib/libc++/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/contrib/libc++/include/__tree b/contrib/libc++/include/__tree
index 30c32f163935..af9b9616df8a 100644
--- a/contrib/libc++/include/__tree
+++ b/contrib/libc++/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/contrib/libc++/include/cfloat b/contrib/libc++/include/cfloat
index 176fa9de3cec..0abe84bf175d 100644
--- a/contrib/libc++/include/cfloat
+++ b/contrib/libc++/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/contrib/libc++/include/charconv b/contrib/libc++/include/charconv
new file mode 100644
index 000000000000..7cb790e1beec
--- /dev/null
+++ b/contrib/libc++/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/contrib/libc++/include/ctime b/contrib/libc++/include/ctime
index da9e3290bbb2..81cf11a466c2 100644
--- a/contrib/libc++/include/ctime
+++ b/contrib/libc++/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/contrib/libc++/include/experimental/__config b/contrib/libc++/include/experimental/__config
index 55ae31b8aea3..c6f177620224 100644
--- a/contrib/libc++/include/experimental/__config
+++ b/contrib/libc++/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/contrib/libc++/include/experimental/simd b/contrib/libc++/include/experimental/simd
index 4876ccb82d20..6580443f7b03 100644
--- a/contrib/libc++/include/experimental/simd
+++ b/contrib/libc++/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 = __simd_abi<_StorageKind::_VecExt,
+ _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
+#else
template <class _Tp>
-using native = compatible<_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/contrib/libc++/include/float.h b/contrib/libc++/include/float.h
index 1acfdc6188f2..759ac8e79543 100644
--- a/contrib/libc++/include/float.h
+++ b/contrib/libc++/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/contrib/libc++/include/functional b/contrib/libc++/include/functional
index 80261895e6e5..6b70f731e1cc 100644
--- a/contrib/libc++/include/functional
+++ b/contrib/libc++/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/contrib/libc++/include/map b/contrib/libc++/include/map
index 97ce4d0b18c7..559ec484aca0 100644
--- a/contrib/libc++/include/map
+++ b/contrib/libc++/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/contrib/libc++/include/memory b/contrib/libc++/include/memory
index fd830d7ed2cc..a4bf89b495ad 100644
--- a/contrib/libc++/include/memory
+++ b/contrib/libc++/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/contrib/libc++/include/module.modulemap b/contrib/libc++/include/module.modulemap
index 127a42b0633d..089505586fb3 100644
--- a/contrib/libc++/include/module.modulemap
+++ b/contrib/libc++/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/contrib/libc++/include/new b/contrib/libc++/include/new
index b5dc05542b59..e70b9c621570 100644
--- a/contrib/libc++/include/new
+++ b/contrib/libc++/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/contrib/libc++/include/set b/contrib/libc++/include/set
index 94db8c79d107..108a9e97f88d 100644
--- a/contrib/libc++/include/set
+++ b/contrib/libc++/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/contrib/libc++/include/shared_mutex b/contrib/libc++/include/shared_mutex
index 9cb81528cd9d..a7735d6732c5 100644
--- a/contrib/libc++/include/shared_mutex
+++ b/contrib/libc++/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/contrib/libc++/include/system_error b/contrib/libc++/include/system_error
index 917c710290ac..6e2c8388f17e 100644
--- a/contrib/libc++/include/system_error
+++ b/contrib/libc++/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/contrib/libc++/include/unordered_map b/contrib/libc++/include/unordered_map
index f34d82efdc33..348f57923b52 100644
--- a/contrib/libc++/include/unordered_map
+++ b/contrib/libc++/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/contrib/libc++/include/unordered_set b/contrib/libc++/include/unordered_set
index 3ae024a45eed..9b8560da494a 100644
--- a/contrib/libc++/include/unordered_set
+++ b/contrib/libc++/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/contrib/libc++/include/utility b/contrib/libc++/include/utility
index 8fdaf65db6a6..ed9bf030d499 100644
--- a/contrib/libc++/include/utility
+++ b/contrib/libc++/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/contrib/libc++/src/bind.cpp b/contrib/libc++/src/bind.cpp
index b318fc16979e..b4c76ffe6a4d 100644
--- a/contrib/libc++/src/bind.cpp
+++ b/contrib/libc++/src/bind.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_BIND
#include "functional"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/contrib/libc++/src/charconv.cpp b/contrib/libc++/src/charconv.cpp
new file mode 100644
index 000000000000..ec241db74471
--- /dev/null
+++ b/contrib/libc++/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/contrib/libc++/src/future.cpp b/contrib/libc++/src/future.cpp
index e1758f39df3a..07e4602f567f 100644
--- a/contrib/libc++/src/future.cpp
+++ b/contrib/libc++/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/contrib/libc++/src/memory.cpp b/contrib/libc++/src/memory.cpp
index 4e0d3af9167e..77ebe837c73c 100644
--- a/contrib/libc++/src/memory.cpp
+++ b/contrib/libc++/src/memory.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_MEMORY
#include "memory"
#ifndef _LIBCPP_HAS_NO_THREADS
#include "mutex"
diff --git a/contrib/libc++/src/mutex.cpp b/contrib/libc++/src/mutex.cpp
index c36bd5549da8..c61d34bb885b 100644
--- a/contrib/libc++/src/mutex.cpp
+++ b/contrib/libc++/src/mutex.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_MUTEX
#include "mutex"
#include "limits"
#include "system_error"
diff --git a/contrib/libc++/src/new.cpp b/contrib/libc++/src/new.cpp
index e228a0d83d8e..8013d89ae3c2 100644
--- a/contrib/libc++/src/new.cpp
+++ b/contrib/libc++/src/new.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_NEW
-
#include <stdlib.h>
#include "new"
diff --git a/contrib/libc++/src/shared_mutex.cpp b/contrib/libc++/src/shared_mutex.cpp
index 874aceb1b03a..6185f15deabd 100644
--- a/contrib/libc++/src/shared_mutex.cpp
+++ b/contrib/libc++/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/contrib/libc++/src/system_error.cpp b/contrib/libc++/src/system_error.cpp
index 72623ea6bc81..06caa6fecd9f 100644
--- a/contrib/libc++/src/system_error.cpp
+++ b/contrib/libc++/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/contrib/libc++/src/utility.cpp b/contrib/libc++/src/utility.cpp
index e9830e7c24f0..7dccffb73e5a 100644
--- a/contrib/libc++/src/utility.cpp
+++ b/contrib/libc++/src/utility.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_BUILDING_UTILITY
#include "utility"
_LIBCPP_BEGIN_NAMESPACE_STD