Merge libc++ trunk r338150 (just before the 7.0.0 branch point), and
resolve conflicts.
This commit is contained in:
commit
ce657679ca
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
212
contrib/libc++/include/__node_handle
Normal file
212
contrib/libc++/include/__node_handle
Normal file
@ -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
|
@ -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>
|
||||
@ -2345,19 +2382,140 @@ __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
|
||||
return iterator(__nd);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Compare, class _Allocator>
|
||||
typename __tree<_Tp, _Compare, _Allocator>::iterator
|
||||
__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr)
|
||||
{
|
||||
iterator __r(__ptr);
|
||||
++__r;
|
||||
if (__begin_node() == __ptr)
|
||||
__begin_node() = __r.__ptr_;
|
||||
--size();
|
||||
__tree_remove(__end_node()->__left_,
|
||||
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(__p.__ptr_);
|
||||
++__r;
|
||||
if (__begin_node() == __p.__ptr_)
|
||||
__begin_node() = __r.__ptr_;
|
||||
--size();
|
||||
iterator __r = __remove_node_pointer(__np);
|
||||
__node_allocator& __na = __node_alloc();
|
||||
__tree_remove(__end_node()->__left_,
|
||||
static_cast<__node_base_pointer>(__np));
|
||||
__node_traits::destroy(__na, _NodeTypes::__get_ptr(
|
||||
const_cast<__node_value_type&>(*__p)));
|
||||
__node_traits::deallocate(__na, __np, 1);
|
||||
|
@ -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>
|
||||
|
610
contrib/libc++/include/charconv
Normal file
610
contrib/libc++/include/charconv
Normal file
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -651,6 +651,7 @@ public:
|
||||
*/
|
||||
|
||||
#include <experimental/__config>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@ -661,26 +662,246 @@ public:
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
|
||||
enum class _StorageKind {
|
||||
_Scalar,
|
||||
_Array,
|
||||
_VecExt,
|
||||
};
|
||||
|
||||
template <_StorageKind __kind, int _Np>
|
||||
struct __simd_abi {};
|
||||
|
||||
template <class _Tp, class _Abi>
|
||||
struct __simd_storage_traits {};
|
||||
class __simd_storage {};
|
||||
|
||||
template <class _Tp, int __num_element>
|
||||
struct __simd_storage_traits<_Tp,
|
||||
__simd_abi<_StorageKind::_Array, __num_element>> {
|
||||
using type = std::array<_Tp, __num_element>;
|
||||
class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
|
||||
std::array<_Tp, __num_element> __storage_;
|
||||
|
||||
template <class, class>
|
||||
friend struct simd;
|
||||
|
||||
template <class, class>
|
||||
friend struct simd_mask;
|
||||
|
||||
public:
|
||||
_Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
|
||||
void __set(size_t __index, _Tp __val) noexcept {
|
||||
__storage_[__index] = __val;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __simd_storage_traits<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
|
||||
using type = _Tp;
|
||||
class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
|
||||
_Tp __storage_;
|
||||
|
||||
template <class, class>
|
||||
friend struct simd;
|
||||
|
||||
template <class, class>
|
||||
friend struct simd_mask;
|
||||
|
||||
public:
|
||||
_Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; };
|
||||
void __set(size_t __index, _Tp __val) noexcept {
|
||||
(&__storage_)[__index] = __val;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
|
||||
|
||||
constexpr size_t __floor_pow_of_2(size_t __val) {
|
||||
return ((__val - 1) & __val) == 0 ? __val
|
||||
: __floor_pow_of_2((__val - 1) & __val);
|
||||
}
|
||||
|
||||
constexpr size_t __ceil_pow_of_2(size_t __val) {
|
||||
return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1;
|
||||
}
|
||||
|
||||
template <class _Tp, size_t __bytes>
|
||||
struct __vec_ext_traits {
|
||||
#if !defined(_LIBCPP_COMPILER_CLANG)
|
||||
typedef _Tp type __attribute__((vector_size(__ceil_pow_of_2(__bytes))));
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(_LIBCPP_COMPILER_CLANG)
|
||||
#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT) \
|
||||
template <> \
|
||||
struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> { \
|
||||
using type = \
|
||||
_TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT))); \
|
||||
}
|
||||
|
||||
#define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE) \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 1); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 2); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 3); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 4); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 5); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 6); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 7); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 8); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 9); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 10); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 11); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 12); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 13); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 14); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 15); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 16); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 17); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 18); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 19); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 20); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 21); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 22); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 23); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 24); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 25); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 26); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 27); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 28); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 29); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 30); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 31); \
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32);
|
||||
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(char);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(char16_t);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(char32_t);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(wchar_t);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed char);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed short);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed int);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long long);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned char);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned short);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned int);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long long);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(float);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(double);
|
||||
_LIBCPP_SPECIALIZE_VEC_EXT_32(long double);
|
||||
|
||||
#undef _LIBCPP_SPECIALIZE_VEC_EXT_32
|
||||
#undef _LIBCPP_SPECIALIZE_VEC_EXT
|
||||
#endif
|
||||
|
||||
template <class _Tp, int __num_element>
|
||||
class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
|
||||
using _StorageType =
|
||||
typename __vec_ext_traits<_Tp, sizeof(_Tp) * __num_element>::type;
|
||||
|
||||
_StorageType __storage_;
|
||||
|
||||
template <class, class>
|
||||
friend struct simd;
|
||||
|
||||
template <class, class>
|
||||
friend struct simd_mask;
|
||||
|
||||
public:
|
||||
_Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
|
||||
void __set(size_t __index, _Tp __val) noexcept {
|
||||
__storage_[__index] = __val;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
|
||||
|
||||
template <class _Vp, class _Tp, class _Abi>
|
||||
class __simd_reference {
|
||||
static_assert(std::is_same<_Vp, _Tp>::value, "");
|
||||
|
||||
template <class, class>
|
||||
friend struct simd;
|
||||
|
||||
template <class, class>
|
||||
friend struct simd_mask;
|
||||
|
||||
__simd_storage<_Tp, _Abi>* __ptr_;
|
||||
size_t __index_;
|
||||
|
||||
__simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
|
||||
: __ptr_(__ptr), __index_(__index) {}
|
||||
|
||||
__simd_reference(const __simd_reference&) = default;
|
||||
|
||||
public:
|
||||
__simd_reference() = delete;
|
||||
__simd_reference& operator=(const __simd_reference&) = delete;
|
||||
|
||||
operator _Vp() const { return __ptr_->__get(__index_); }
|
||||
|
||||
__simd_reference operator=(_Vp __value) && {
|
||||
__ptr_->__set(__index_, __value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
__simd_reference operator++() && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) + 1;
|
||||
}
|
||||
|
||||
_Vp operator++(int) && {
|
||||
auto __val = __ptr_->__get(__index_);
|
||||
__ptr_->__set(__index_, __val + 1);
|
||||
return __val;
|
||||
}
|
||||
|
||||
__simd_reference operator--() && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) - 1;
|
||||
}
|
||||
|
||||
_Vp operator--(int) && {
|
||||
auto __val = __ptr_->__get(__index_);
|
||||
__ptr_->__set(__index_, __val - 1);
|
||||
return __val;
|
||||
}
|
||||
|
||||
__simd_reference operator+=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) + __value;
|
||||
}
|
||||
|
||||
__simd_reference operator-=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) - __value;
|
||||
}
|
||||
|
||||
__simd_reference operator*=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) * __value;
|
||||
}
|
||||
|
||||
__simd_reference operator/=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) / __value;
|
||||
}
|
||||
|
||||
__simd_reference operator%=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) % __value;
|
||||
}
|
||||
|
||||
__simd_reference operator>>=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) >> __value;
|
||||
}
|
||||
|
||||
__simd_reference operator<<=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) << __value;
|
||||
}
|
||||
|
||||
__simd_reference operator&=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) & __value;
|
||||
}
|
||||
|
||||
__simd_reference operator|=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) | __value;
|
||||
}
|
||||
|
||||
__simd_reference operator^=(_Vp __value) && {
|
||||
return std::move(*this) = __ptr_->__get(__index_) ^ __value;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _To, class _From>
|
||||
@ -720,6 +941,17 @@ constexpr _Tp __variadic_sum(_Up __first, _Args... __rest) {
|
||||
return static_cast<_Tp>(__first) + __variadic_sum<_Tp>(__rest...);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
struct __nodeduce {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
constexpr bool __vectorizable() {
|
||||
return std::is_arithmetic<_Tp>::value && !std::is_const<_Tp>::value &&
|
||||
!std::is_volatile<_Tp>::value && !std::is_same<_Tp, bool>::value;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD_ABI
|
||||
|
||||
@ -728,14 +960,21 @@ using scalar = __simd_abi<_StorageKind::_Scalar, 1>;
|
||||
template <int _Np>
|
||||
using fixed_size = __simd_abi<_StorageKind::_Array, _Np>;
|
||||
|
||||
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VAR constexpr int max_fixed_size = 32;
|
||||
#endif
|
||||
_LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 32;
|
||||
|
||||
template <class _Tp>
|
||||
using compatible = fixed_size<16 / sizeof(_Tp)>;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
|
||||
template <class _Tp>
|
||||
using native = compatible<_Tp>;
|
||||
using native = __simd_abi<_StorageKind::_VecExt,
|
||||
_LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
|
||||
#else
|
||||
template <class _Tp>
|
||||
using native =
|
||||
fixed_size<_Tp, _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
|
||||
#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
|
||||
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
|
||||
@ -749,14 +988,10 @@ struct element_aligned_tag {};
|
||||
struct vector_aligned_tag {};
|
||||
template <size_t>
|
||||
struct overaligned_tag {};
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
_LIBCPP_INLINE_VAR constexpr element_aligned_tag element_aligned{};
|
||||
_LIBCPP_INLINE_VAR constexpr vector_aligned_tag vector_aligned{};
|
||||
#if !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
|
||||
template <size_t _Np>
|
||||
_LIBCPP_INLINE_VAR constexpr overaligned_tag<_Np> overaligned{};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// traits [simd.traits]
|
||||
template <class _Tp>
|
||||
@ -794,7 +1029,6 @@ template <size_t _Align>
|
||||
struct is_simd_flag_type<overaligned_tag<_Align>>
|
||||
: std::integral_constant<bool, true> {};
|
||||
|
||||
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VAR constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value;
|
||||
template <class _Tp>
|
||||
@ -804,7 +1038,6 @@ _LIBCPP_INLINE_VAR constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value;
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VAR constexpr bool is_simd_flag_type_v =
|
||||
is_simd_flag_type<_Tp>::value;
|
||||
#endif
|
||||
template <class _Tp, size_t _Np>
|
||||
struct abi_for_size {
|
||||
using type = simd_abi::fixed_size<_Np>;
|
||||
@ -824,17 +1057,16 @@ struct simd_size<_Tp, __simd_abi<__kind, _Np>>
|
||||
"Element type should be vectorizable");
|
||||
};
|
||||
|
||||
// TODO: implement it.
|
||||
template <class _Tp, class _Up = typename _Tp::value_type>
|
||||
struct memory_alignment;
|
||||
|
||||
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
|
||||
template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
|
||||
_LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
|
||||
|
||||
template <class _Tp, class _Up = typename _Tp::value_type>
|
||||
_LIBCPP_INLINE_VAR constexpr size_t memory_alignment_v =
|
||||
memory_alignment<_Tp, _Up>::value;
|
||||
#endif
|
||||
|
||||
// class template simd [simd.class]
|
||||
template <class _Tp>
|
||||
@ -972,11 +1204,6 @@ template <class _MaskType, class _Tp>
|
||||
class where_expression;
|
||||
|
||||
// masked assignment [simd.mask.where]
|
||||
template <class _Tp>
|
||||
struct __nodeduce {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <class _Tp, class _Abi>
|
||||
where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>>
|
||||
where(const typename simd<_Tp, _Abi>::mask_type&, simd<_Tp, _Abi>&) noexcept;
|
||||
@ -1113,7 +1340,23 @@ public:
|
||||
// TODO: implement simd
|
||||
template <class _Tp, class _Abi>
|
||||
class simd {
|
||||
public:
|
||||
using value_type = _Tp;
|
||||
using reference = __simd_reference<_Tp, _Tp, _Abi>;
|
||||
using mask_type = simd_mask<_Tp, _Abi>;
|
||||
using abi_type = _Abi;
|
||||
|
||||
simd() = default;
|
||||
simd(const simd&) = default;
|
||||
simd& operator=(const simd&) = default;
|
||||
|
||||
static constexpr size_t size() noexcept {
|
||||
return simd_size<_Tp, _Abi>::value;
|
||||
}
|
||||
|
||||
private:
|
||||
__simd_storage<_Tp, _Abi> __s_;
|
||||
|
||||
template <class _Up>
|
||||
static constexpr bool __can_broadcast() {
|
||||
return (std::is_arithmetic<_Up>::value &&
|
||||
@ -1126,57 +1369,97 @@ private:
|
||||
std::is_unsigned<_Tp>::value);
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = _Tp;
|
||||
// TODO: this is strawman implementation. Turn it into a proxy type.
|
||||
using reference = _Tp&;
|
||||
using mask_type = simd_mask<_Tp, _Abi>;
|
||||
|
||||
using abi_type = _Abi;
|
||||
|
||||
static constexpr size_t size() noexcept {
|
||||
return simd_size<_Tp, _Abi>::value;
|
||||
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>()))>()...);
|
||||
}
|
||||
|
||||
simd() = default;
|
||||
template <class _Generator>
|
||||
static bool __can_generate(...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -7,7 +7,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define _LIBCPP_BUILDING_BIND
|
||||
#include "functional"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
233
contrib/libc++/src/charconv.cpp
Normal file
233
contrib/libc++/src/charconv.cpp
Normal file
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define _LIBCPP_BUILDING_MEMORY
|
||||
#include "memory"
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
#include "mutex"
|
||||
|
@ -7,7 +7,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define _LIBCPP_BUILDING_MUTEX
|
||||
#include "mutex"
|
||||
#include "limits"
|
||||
#include "system_error"
|
||||
|
@ -7,8 +7,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define _LIBCPP_BUILDING_NEW
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "new"
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "__config"
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
#define _LIBCPP_BUILDING_SHARED_MUTEX
|
||||
#include "shared_mutex"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "__config"
|
||||
|
||||
#define _LIBCPP_BUILDING_SYSTEM_ERROR
|
||||
#include "system_error"
|
||||
|
||||
#include "include/config_elast.h"
|
||||
|
@ -7,7 +7,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define _LIBCPP_BUILDING_UTILITY
|
||||
#include "utility"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
Loading…
x
Reference in New Issue
Block a user