2010-05-12 03:42:16 +08:00
|
|
|
// -*- C++ -*-
|
|
|
|
//===-------------------------- utility -----------------------------------===//
|
|
|
|
//
|
2019-01-19 18:56:40 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-05-12 03:42:16 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_UTILITY
|
|
|
|
#define _LIBCPP_UTILITY
|
|
|
|
|
|
|
|
/*
|
|
|
|
utility synopsis
|
|
|
|
|
2018-07-06 00:16:03 +08:00
|
|
|
#include <initializer_list>
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
namespace std
|
|
|
|
{
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
void
|
|
|
|
swap(T& a, T& b);
|
|
|
|
|
|
|
|
namespace rel_ops
|
|
|
|
{
|
|
|
|
template<class T> bool operator!=(const T&, const T&);
|
|
|
|
template<class T> bool operator> (const T&, const T&);
|
|
|
|
template<class T> bool operator<=(const T&, const T&);
|
|
|
|
template<class T> bool operator>=(const T&, const T&);
|
|
|
|
}
|
|
|
|
|
2011-05-27 23:04:19 +08:00
|
|
|
template<class T>
|
|
|
|
void
|
|
|
|
swap(T& a, T& b) noexcept(is_nothrow_move_constructible<T>::value &&
|
|
|
|
is_nothrow_move_assignable<T>::value);
|
|
|
|
|
|
|
|
template <class T, size_t N>
|
|
|
|
void
|
|
|
|
swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2013-07-16 04:46:11 +08:00
|
|
|
template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept; // constexpr in C++14
|
|
|
|
template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept; // constexpr in C++14
|
2011-05-27 23:04:19 +08:00
|
|
|
|
2013-07-16 04:46:11 +08:00
|
|
|
template <class T> typename remove_reference<T>::type&& move(T&&) noexcept; // constexpr in C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class T>
|
|
|
|
typename conditional
|
|
|
|
<
|
2010-11-20 06:17:28 +08:00
|
|
|
!is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
const T&,
|
|
|
|
T&&
|
|
|
|
>::type
|
2013-07-16 04:46:11 +08:00
|
|
|
move_if_noexcept(T& x) noexcept; // constexpr in C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2018-02-12 05:51:49 +08:00
|
|
|
template <class T> constexpr add_const_t<T>& as_const(T& t) noexcept; // C++17
|
2015-11-17 08:08:08 +08:00
|
|
|
template <class T> void as_const(const T&&) = delete; // C++17
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class T> typename add_rvalue_reference<T>::type declval() noexcept;
|
|
|
|
|
|
|
|
template <class T1, class T2>
|
|
|
|
struct pair
|
|
|
|
{
|
|
|
|
typedef T1 first_type;
|
|
|
|
typedef T2 second_type;
|
|
|
|
|
|
|
|
T1 first;
|
|
|
|
T2 second;
|
|
|
|
|
|
|
|
pair(const pair&) = default;
|
2011-05-27 23:04:19 +08:00
|
|
|
pair(pair&&) = default;
|
2019-09-26 22:51:10 +08:00
|
|
|
explicit(see-below) constexpr pair();
|
2019-07-23 04:45:23 +08:00
|
|
|
explicit(see-below) pair(const T1& x, const T2& y); // constexpr in C++14
|
|
|
|
template <class U, class V> explicit(see-below) pair(U&& x, V&& y); // constexpr in C++14
|
|
|
|
template <class U, class V> explicit(see-below) pair(const pair<U, V>& p); // constexpr in C++14
|
|
|
|
template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class... Args1, class... Args2>
|
|
|
|
pair(piecewise_construct_t, tuple<Args1...> first_args,
|
|
|
|
tuple<Args2...> second_args);
|
|
|
|
|
|
|
|
template <class U, class V> pair& operator=(const pair<U, V>& p);
|
2011-05-27 23:04:19 +08:00
|
|
|
pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
|
|
|
|
is_nothrow_move_assignable<T2>::value);
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class U, class V> pair& operator=(pair<U, V>&& p);
|
|
|
|
|
2016-04-22 07:38:59 +08:00
|
|
|
void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
|
|
|
|
is_nothrow_swappable_v<T2>);
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
2013-07-17 01:45:44 +08:00
|
|
|
template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
|
|
|
|
template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
|
|
|
|
template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
|
|
|
|
template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
|
|
|
|
template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
|
|
|
|
template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2013-07-17 01:45:44 +08:00
|
|
|
template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); // constexpr in C++14
|
2011-05-27 23:04:19 +08:00
|
|
|
template <class T1, class T2>
|
|
|
|
void
|
|
|
|
swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2019-09-26 22:51:10 +08:00
|
|
|
struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
|
2018-01-03 01:17:01 +08:00
|
|
|
inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2019-01-12 05:57:12 +08:00
|
|
|
template <class T> struct tuple_size;
|
2019-04-02 00:39:34 +08:00
|
|
|
template <size_t I, class T> struct tuple_element;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2014-03-03 14:18:11 +08:00
|
|
|
template <class T1, class T2> struct tuple_size<pair<T1, T2> >;
|
|
|
|
template <class T1, class T2> struct tuple_element<0, pair<T1, T2> >;
|
|
|
|
template <class T1, class T2> struct tuple_element<1, pair<T1, T2> >;
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<size_t I, class T1, class T2>
|
2014-03-03 14:18:11 +08:00
|
|
|
typename tuple_element<I, pair<T1, T2> >::type&
|
|
|
|
get(pair<T1, T2>&) noexcept; // constexpr in C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template<size_t I, class T1, class T2>
|
2015-11-20 03:45:29 +08:00
|
|
|
const typename tuple_element<I, pair<T1, T2> >::type&
|
2014-03-03 14:18:11 +08:00
|
|
|
get(const pair<T1, T2>&) noexcept; // constexpr in C++14
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2010-11-18 03:52:17 +08:00
|
|
|
template<size_t I, class T1, class T2>
|
2014-03-03 14:18:11 +08:00
|
|
|
typename tuple_element<I, pair<T1, T2> >::type&&
|
|
|
|
get(pair<T1, T2>&&) noexcept; // constexpr in C++14
|
2010-11-18 03:52:17 +08:00
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template<size_t I, class T1, class T2>
|
|
|
|
const typename tuple_element<I, pair<T1, T2> >::type&&
|
|
|
|
get(const pair<T1, T2>&&) noexcept; // constexpr in C++14
|
|
|
|
|
2013-07-13 10:54:05 +08:00
|
|
|
template<class T1, class T2>
|
2014-03-03 14:18:11 +08:00
|
|
|
constexpr T1& get(pair<T1, T2>&) noexcept; // C++14
|
2013-07-13 10:54:05 +08:00
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template<class T1, class T2>
|
2015-11-20 03:45:29 +08:00
|
|
|
constexpr const T1& get(const pair<T1, T2>&) noexcept; // C++14
|
2013-07-13 10:54:05 +08:00
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template<class T1, class T2>
|
2014-03-03 14:18:11 +08:00
|
|
|
constexpr T1&& get(pair<T1, T2>&&) noexcept; // C++14
|
2013-07-13 10:54:05 +08:00
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template<class T1, class T2>
|
|
|
|
constexpr const T1&& get(const pair<T1, T2>&&) noexcept; // C++14
|
|
|
|
|
|
|
|
template<class T1, class T2>
|
|
|
|
constexpr T1& get(pair<T2, T1>&) noexcept; // C++14
|
|
|
|
|
|
|
|
template<class T1, class T2>
|
|
|
|
constexpr const T1& get(const pair<T2, T1>&) noexcept; // C++14
|
|
|
|
|
|
|
|
template<class T1, class T2>
|
|
|
|
constexpr T1&& get(pair<T2, T1>&&) noexcept; // C++14
|
|
|
|
|
|
|
|
template<class T1, class T2>
|
|
|
|
constexpr const T1&& get(const pair<T2, T1>&&) noexcept; // C++14
|
|
|
|
|
2013-07-02 00:26:55 +08:00
|
|
|
// C++14
|
|
|
|
|
|
|
|
template<class T, T... I>
|
|
|
|
struct integer_sequence
|
|
|
|
{
|
|
|
|
typedef T value_type;
|
|
|
|
|
|
|
|
static constexpr size_t size() noexcept;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<size_t... I>
|
|
|
|
using index_sequence = integer_sequence<size_t, I...>;
|
|
|
|
|
|
|
|
template<class T, T N>
|
|
|
|
using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;
|
|
|
|
template<size_t N>
|
|
|
|
using make_index_sequence = make_integer_sequence<size_t, N>;
|
|
|
|
|
|
|
|
template<class... T>
|
|
|
|
using index_sequence_for = make_index_sequence<sizeof...(T)>;
|
|
|
|
|
2016-06-20 03:29:52 +08:00
|
|
|
template<class T, class U=T>
|
2013-07-09 04:54:40 +08:00
|
|
|
T exchange(T& obj, U&& new_value);
|
2016-07-24 06:19:19 +08:00
|
|
|
|
|
|
|
// 20.2.7, in-place construction // C++17
|
2016-11-18 03:24:04 +08:00
|
|
|
struct in_place_t {
|
|
|
|
explicit in_place_t() = default;
|
|
|
|
};
|
|
|
|
inline constexpr in_place_t in_place{};
|
2016-07-24 06:19:19 +08:00
|
|
|
template <class T>
|
2016-11-18 03:24:04 +08:00
|
|
|
struct in_place_type_t {
|
|
|
|
explicit in_place_type_t() = default;
|
|
|
|
};
|
2016-07-24 06:19:19 +08:00
|
|
|
template <class T>
|
2016-11-18 03:24:04 +08:00
|
|
|
inline constexpr in_place_type_t<T> in_place_type{};
|
2016-07-24 06:19:19 +08:00
|
|
|
template <size_t I>
|
2016-11-18 03:24:04 +08:00
|
|
|
struct in_place_index_t {
|
|
|
|
explicit in_place_index_t() = default;
|
|
|
|
};
|
|
|
|
template <size_t I>
|
|
|
|
inline constexpr in_place_index_t<I> in_place_index{};
|
2016-07-24 06:19:19 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
} // std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <__config>
|
|
|
|
#include <__tuple>
|
|
|
|
#include <type_traits>
|
2016-04-20 04:13:55 +08:00
|
|
|
#include <initializer_list>
|
2017-01-21 08:02:12 +08:00
|
|
|
#include <cstddef>
|
|
|
|
#include <cstring>
|
|
|
|
#include <cstdint>
|
2018-09-13 03:41:40 +08:00
|
|
|
#include <version>
|
2016-07-24 06:19:19 +08:00
|
|
|
#include <__debug>
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2011-10-18 04:05:10 +08:00
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
2010-05-12 03:42:16 +08:00
|
|
|
#pragma GCC system_header
|
2011-10-18 04:05:10 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
|
|
|
namespace rel_ops
|
|
|
|
{
|
|
|
|
|
|
|
|
template<class _Tp>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool
|
|
|
|
operator!=(const _Tp& __x, const _Tp& __y)
|
|
|
|
{
|
|
|
|
return !(__x == __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Tp>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool
|
|
|
|
operator> (const _Tp& __x, const _Tp& __y)
|
|
|
|
{
|
|
|
|
return __y < __x;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Tp>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool
|
|
|
|
operator<=(const _Tp& __x, const _Tp& __y)
|
|
|
|
{
|
|
|
|
return !(__y < __x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Tp>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
bool
|
|
|
|
operator>=(const _Tp& __x, const _Tp& __y)
|
|
|
|
{
|
|
|
|
return !(__x < __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // rel_ops
|
|
|
|
|
2019-09-12 01:39:24 +08:00
|
|
|
// swap_ranges is defined in <type_traits>`
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2019-09-12 01:39:24 +08:00
|
|
|
// swap is defined in <type_traits>
|
2015-01-07 03:20:49 +08:00
|
|
|
|
2019-09-12 01:39:24 +08:00
|
|
|
// move_if_noexcept
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
2013-07-16 04:46:11 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2017-04-19 09:23:39 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
typename conditional
|
|
|
|
<
|
2010-11-20 06:17:28 +08:00
|
|
|
!is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value,
|
2010-05-12 03:42:16 +08:00
|
|
|
const _Tp&,
|
|
|
|
_Tp&&
|
|
|
|
>::type
|
2017-04-19 09:23:39 +08:00
|
|
|
#else // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
const _Tp&
|
|
|
|
#endif
|
2011-05-27 23:04:19 +08:00
|
|
|
move_if_noexcept(_Tp& __x) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return _VSTD::move(__x);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2015-11-17 08:08:08 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
template <class _Tp> constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; }
|
|
|
|
template <class _Tp> void as_const(const _Tp&&) = delete;
|
|
|
|
#endif
|
|
|
|
|
2019-09-26 22:51:10 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; };
|
2018-08-01 10:08:59 +08:00
|
|
|
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
2018-10-25 20:13:43 +08:00
|
|
|
extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
|
2012-04-04 05:09:48 +08:00
|
|
|
#else
|
2018-01-03 02:57:47 +08:00
|
|
|
/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
2012-04-04 05:09:48 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2016-10-12 05:22:21 +08:00
|
|
|
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
|
Fix PR40230 - std::pair may have padding on FreeBSD.
Summary:
FreeBSD ships a very old and deprecated ABI for std::pair where the copy and move constructors are not allowed to be trivial. D25389 change how this was implemented by introducing a non-trivial base class. This patch, introduced in October 2016, introduced an ABI bug that caused nested `std::pair` instantiations to have padding. For example:
```
using PairT = std::pair< std::pair<char, char>, char >;
static_assert(offsetof(PairT, first) == 0, "First member should exist at offset zero"); // Fails on FreeBSD!
```
The bug occurs because the base class for the first element (the nested pair) cannot be put at offset zero because the top-level pair already has the same base class laid out there.
This patch fixes that ABI bug by templating the dummy base class on the same parameters as the pair.
Technically this fix is an ABI break for users who depend on the "broken" ABI introduced in 2016. I'm putting this up for review so that the FreeBSD maintainers can sign off on fixing the ABI by breaking the ABI.
Another option, since we have to "break" the ABI to fix it, would be to move FreeBSD off the deprecated non-trivial pair ABI instead.
Also see:
* https://llvm.org/PR40230
* https://reviews.llvm.org/D21329
Reviewers: rsmith, dim, emaste
Reviewed By: rsmith
Subscribers: mclow.lists, krytarowski, christof, ldionne, libcxx-commits
Differential Revision: https://reviews.llvm.org/D56357
llvm-svn: 351290
2019-01-16 09:54:34 +08:00
|
|
|
template <class, class>
|
2016-10-12 05:22:21 +08:00
|
|
|
struct __non_trivially_copyable_base {
|
|
|
|
_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
|
|
|
|
__non_trivially_copyable_base() _NOEXCEPT {}
|
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
|
|
|
|
__non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
|
|
|
|
};
|
|
|
|
#endif
|
2016-07-25 12:32:07 +08:00
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _T1, class _T2>
|
2017-01-05 07:56:00 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS pair
|
2016-10-12 05:22:21 +08:00
|
|
|
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
|
Fix PR40230 - std::pair may have padding on FreeBSD.
Summary:
FreeBSD ships a very old and deprecated ABI for std::pair where the copy and move constructors are not allowed to be trivial. D25389 change how this was implemented by introducing a non-trivial base class. This patch, introduced in October 2016, introduced an ABI bug that caused nested `std::pair` instantiations to have padding. For example:
```
using PairT = std::pair< std::pair<char, char>, char >;
static_assert(offsetof(PairT, first) == 0, "First member should exist at offset zero"); // Fails on FreeBSD!
```
The bug occurs because the base class for the first element (the nested pair) cannot be put at offset zero because the top-level pair already has the same base class laid out there.
This patch fixes that ABI bug by templating the dummy base class on the same parameters as the pair.
Technically this fix is an ABI break for users who depend on the "broken" ABI introduced in 2016. I'm putting this up for review so that the FreeBSD maintainers can sign off on fixing the ABI by breaking the ABI.
Another option, since we have to "break" the ABI to fix it, would be to move FreeBSD off the deprecated non-trivial pair ABI instead.
Also see:
* https://llvm.org/PR40230
* https://reviews.llvm.org/D21329
Reviewers: rsmith, dim, emaste
Reviewed By: rsmith
Subscribers: mclow.lists, krytarowski, christof, ldionne, libcxx-commits
Differential Revision: https://reviews.llvm.org/D56357
llvm-svn: 351290
2019-01-16 09:54:34 +08:00
|
|
|
: private __non_trivially_copyable_base<_T1, _T2>
|
2016-10-12 05:22:21 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
typedef _T1 first_type;
|
|
|
|
typedef _T2 second_type;
|
|
|
|
|
|
|
|
_T1 first;
|
|
|
|
_T2 second;
|
|
|
|
|
2016-10-12 05:22:21 +08:00
|
|
|
#if !defined(_LIBCPP_CXX03_LANG)
|
2016-07-18 09:58:37 +08:00
|
|
|
pair(pair const&) = default;
|
|
|
|
pair(pair&&) = default;
|
|
|
|
#else
|
|
|
|
// Use the implicitly declared copy constructor in C++03
|
2013-07-17 01:45:44 +08:00
|
|
|
#endif
|
2011-07-02 03:24:36 +08:00
|
|
|
|
2016-07-25 12:32:07 +08:00
|
|
|
#ifdef _LIBCPP_CXX03_LANG
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pair() : first(), second() {}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
|
|
|
|
|
|
|
|
template <class _U1, class _U2>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
pair& operator=(pair const& __p) {
|
|
|
|
first = __p.first;
|
|
|
|
second = __p.second;
|
|
|
|
return *this;
|
|
|
|
}
|
2016-07-25 10:36:42 +08:00
|
|
|
#else
|
2016-07-25 12:32:07 +08:00
|
|
|
template <bool _Val>
|
2019-06-12 10:03:31 +08:00
|
|
|
using _EnableB _LIBCPP_NODEBUG_TYPE = typename enable_if<_Val, bool>::type;
|
2016-07-25 12:32:07 +08:00
|
|
|
|
|
|
|
struct _CheckArgs {
|
2019-10-01 04:55:30 +08:00
|
|
|
template <int&...>
|
2019-09-26 22:51:10 +08:00
|
|
|
static constexpr bool __enable_explicit_default() {
|
2019-10-01 04:55:30 +08:00
|
|
|
return is_default_constructible<_T1>::value
|
|
|
|
&& is_default_constructible<_T2>::value
|
|
|
|
&& !__enable_implicit_default<>();
|
2019-09-26 22:51:10 +08:00
|
|
|
}
|
|
|
|
|
2019-10-01 04:55:30 +08:00
|
|
|
template <int&...>
|
2019-09-26 22:51:10 +08:00
|
|
|
static constexpr bool __enable_implicit_default() {
|
2019-10-01 04:55:30 +08:00
|
|
|
return __is_implicitly_default_constructible<_T1>::value
|
|
|
|
&& __is_implicitly_default_constructible<_T2>::value;
|
2016-07-25 12:32:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _U1, class _U2>
|
|
|
|
static constexpr bool __enable_explicit() {
|
|
|
|
return is_constructible<first_type, _U1>::value
|
|
|
|
&& is_constructible<second_type, _U2>::value
|
|
|
|
&& (!is_convertible<_U1, first_type>::value
|
|
|
|
|| !is_convertible<_U2, second_type>::value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _U1, class _U2>
|
|
|
|
static constexpr bool __enable_implicit() {
|
|
|
|
return is_constructible<first_type, _U1>::value
|
|
|
|
&& is_constructible<second_type, _U2>::value
|
|
|
|
&& is_convertible<_U1, first_type>::value
|
|
|
|
&& is_convertible<_U2, second_type>::value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <bool _MaybeEnable>
|
2019-06-12 10:03:31 +08:00
|
|
|
using _CheckArgsDep _LIBCPP_NODEBUG_TYPE = typename conditional<
|
2016-07-25 12:32:07 +08:00
|
|
|
_MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
|
|
|
|
|
|
|
|
struct _CheckTupleLikeConstructor {
|
|
|
|
template <class _Tuple>
|
|
|
|
static constexpr bool __enable_implicit() {
|
|
|
|
return __tuple_convertible<_Tuple, pair>::value;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tuple>
|
|
|
|
static constexpr bool __enable_explicit() {
|
|
|
|
return __tuple_constructible<_Tuple, pair>::value
|
|
|
|
&& !__tuple_convertible<_Tuple, pair>::value;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tuple>
|
|
|
|
static constexpr bool __enable_assign() {
|
|
|
|
return __tuple_assignable<_Tuple, pair>::value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tuple>
|
2019-06-12 10:03:31 +08:00
|
|
|
using _CheckTLC _LIBCPP_NODEBUG_TYPE = typename conditional<
|
2016-07-25 12:32:07 +08:00
|
|
|
__tuple_like_with_size<_Tuple, 2>::value
|
|
|
|
&& !is_same<typename decay<_Tuple>::type, pair>::value,
|
|
|
|
_CheckTupleLikeConstructor,
|
|
|
|
__check_tuple_constructor_fail
|
|
|
|
>::type;
|
|
|
|
|
|
|
|
template<bool _Dummy = true, _EnableB<
|
2019-10-01 04:55:30 +08:00
|
|
|
_CheckArgsDep<_Dummy>::__enable_explicit_default()
|
2019-09-26 22:51:10 +08:00
|
|
|
> = false>
|
|
|
|
explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
|
|
|
pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
|
|
|
|
is_nothrow_default_constructible<second_type>::value)
|
|
|
|
: first(), second() {}
|
|
|
|
|
|
|
|
template<bool _Dummy = true, _EnableB<
|
2019-10-01 04:55:30 +08:00
|
|
|
_CheckArgsDep<_Dummy>::__enable_implicit_default()
|
2016-07-25 12:32:07 +08:00
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
2018-12-11 22:22:28 +08:00
|
|
|
pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
|
|
|
|
is_nothrow_default_constructible<second_type>::value)
|
|
|
|
: first(), second() {}
|
2016-07-25 12:32:07 +08:00
|
|
|
|
|
|
|
template <bool _Dummy = true, _EnableB<
|
|
|
|
_CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
explicit pair(_T1 const& __t1, _T2 const& __t2)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
|
|
|
|
is_nothrow_copy_constructible<second_type>::value)
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(__t1), second(__t2) {}
|
|
|
|
|
|
|
|
template<bool _Dummy = true, _EnableB<
|
|
|
|
_CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
pair(_T1 const& __t1, _T2 const& __t2)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
|
|
|
|
is_nothrow_copy_constructible<second_type>::value)
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(__t1), second(__t2) {}
|
|
|
|
|
|
|
|
template<class _U1, class _U2, _EnableB<
|
|
|
|
_CheckArgs::template __enable_explicit<_U1, _U2>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
explicit pair(_U1&& __u1, _U2&& __u2)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
|
|
|
|
is_nothrow_constructible<second_type, _U2>::value))
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
|
|
|
|
|
|
|
|
template<class _U1, class _U2, _EnableB<
|
|
|
|
_CheckArgs::template __enable_implicit<_U1, _U2>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
pair(_U1&& __u1, _U2&& __u2)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
|
|
|
|
is_nothrow_constructible<second_type, _U2>::value))
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
|
|
|
|
|
|
|
|
template<class _U1, class _U2, _EnableB<
|
|
|
|
_CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
explicit pair(pair<_U1, _U2> const& __p)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
|
|
|
|
is_nothrow_constructible<second_type, _U2 const&>::value))
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(__p.first), second(__p.second) {}
|
|
|
|
|
|
|
|
template<class _U1, class _U2, _EnableB<
|
|
|
|
_CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
pair(pair<_U1, _U2> const& __p)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
|
|
|
|
is_nothrow_constructible<second_type, _U2 const&>::value))
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(__p.first), second(__p.second) {}
|
2016-07-25 10:36:42 +08:00
|
|
|
|
2016-07-25 12:32:07 +08:00
|
|
|
template<class _U1, class _U2, _EnableB<
|
|
|
|
_CheckArgs::template __enable_explicit<_U1, _U2>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
explicit pair(pair<_U1, _U2>&&__p)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
|
|
|
|
is_nothrow_constructible<second_type, _U2&&>::value))
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
|
|
|
|
|
|
|
|
template<class _U1, class _U2, _EnableB<
|
|
|
|
_CheckArgs::template __enable_implicit<_U1, _U2>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
pair(pair<_U1, _U2>&& __p)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
|
|
|
|
is_nothrow_constructible<second_type, _U2&&>::value))
|
2016-07-25 12:32:07 +08:00
|
|
|
: first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
|
|
|
|
|
|
|
|
template<class _Tuple, _EnableB<
|
|
|
|
_CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
explicit pair(_Tuple&& __p)
|
|
|
|
: first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
|
|
|
|
second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
|
|
|
|
|
|
|
|
template<class _Tuple, _EnableB<
|
|
|
|
_CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
|
|
|
|
> = false>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
pair(_Tuple&& __p)
|
|
|
|
: first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))),
|
|
|
|
second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {}
|
|
|
|
|
|
|
|
template <class... _Args1, class... _Args2>
|
2020-09-03 03:20:33 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
2016-07-25 12:32:07 +08:00
|
|
|
pair(piecewise_construct_t __pc,
|
|
|
|
tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
|
2018-12-11 22:22:28 +08:00
|
|
|
_NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
|
|
|
|
is_nothrow_constructible<second_type, _Args2...>::value))
|
2016-07-25 12:32:07 +08:00
|
|
|
: pair(__pc, __first_args, __second_args,
|
|
|
|
typename __make_tuple_indices<sizeof...(_Args1)>::type(),
|
|
|
|
typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
|
|
|
|
|
2020-09-03 03:20:33 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
2016-07-25 12:32:07 +08:00
|
|
|
pair& operator=(typename conditional<
|
|
|
|
is_copy_assignable<first_type>::value &&
|
|
|
|
is_copy_assignable<second_type>::value,
|
|
|
|
pair, __nat>::type const& __p)
|
2011-07-02 03:24:36 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
|
|
|
|
is_nothrow_copy_assignable<second_type>::value)
|
2011-05-27 23:04:19 +08:00
|
|
|
{
|
|
|
|
first = __p.first;
|
|
|
|
second = __p.second;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2020-09-03 03:20:33 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
2016-07-25 12:32:07 +08:00
|
|
|
pair& operator=(typename conditional<
|
|
|
|
is_move_assignable<first_type>::value &&
|
|
|
|
is_move_assignable<second_type>::value,
|
|
|
|
pair, __nat>::type&& __p)
|
2016-07-25 10:36:42 +08:00
|
|
|
_NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
|
|
|
|
is_nothrow_move_assignable<second_type>::value)
|
|
|
|
{
|
|
|
|
first = _VSTD::forward<first_type>(__p.first);
|
|
|
|
second = _VSTD::forward<second_type>(__p.second);
|
|
|
|
return *this;
|
|
|
|
}
|
2011-04-30 02:10:55 +08:00
|
|
|
|
2016-07-25 12:32:07 +08:00
|
|
|
template <class _Tuple, _EnableB<
|
2016-08-29 09:43:41 +08:00
|
|
|
_CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
|
2016-07-25 12:32:07 +08:00
|
|
|
> = false>
|
2020-09-03 03:20:33 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
2016-07-25 12:32:07 +08:00
|
|
|
pair& operator=(_Tuple&& __p) {
|
|
|
|
first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p));
|
|
|
|
second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
#endif
|
2011-05-27 23:04:19 +08:00
|
|
|
|
2020-09-03 03:20:33 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
2011-05-27 23:04:19 +08:00
|
|
|
void
|
2011-05-28 03:08:18 +08:00
|
|
|
swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
|
|
|
|
__is_nothrow_swappable<second_type>::value)
|
2011-05-27 23:04:19 +08:00
|
|
|
{
|
2015-09-23 01:50:11 +08:00
|
|
|
using _VSTD::swap;
|
|
|
|
swap(first, __p.first);
|
|
|
|
swap(second, __p.second);
|
2011-05-27 23:04:19 +08:00
|
|
|
}
|
2010-05-12 03:42:16 +08:00
|
|
|
private:
|
2010-08-22 08:02:43 +08:00
|
|
|
|
2016-07-25 12:32:07 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
|
2020-09-03 03:20:33 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
|
|
|
pair(piecewise_construct_t,
|
|
|
|
tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
|
|
|
|
__tuple_indices<_I1...>, __tuple_indices<_I2...>);
|
2016-07-25 12:32:07 +08:00
|
|
|
#endif
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
2017-10-04 08:04:26 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
|
|
|
template<class _T1, class _T2>
|
|
|
|
pair(_T1, _T2) -> pair<_T1, _T2>;
|
|
|
|
#endif // _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _T1, class _T2>
|
2013-07-17 01:45:44 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
|
|
|
|
{
|
|
|
|
return __x.first == __y.first && __x.second == __y.second;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-07-17 01:45:44 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
|
|
|
|
{
|
|
|
|
return !(__x == __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-07-17 01:45:44 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
|
|
|
|
{
|
|
|
|
return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-07-17 01:45:44 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
|
|
|
|
{
|
|
|
|
return __y < __x;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-07-17 01:45:44 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
|
|
|
|
{
|
|
|
|
return !(__x < __y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-07-17 01:45:44 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
bool
|
|
|
|
operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
|
|
|
|
{
|
|
|
|
return !(__y < __x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2020-09-03 03:20:33 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
2011-06-02 03:59:32 +08:00
|
|
|
typename enable_if
|
|
|
|
<
|
|
|
|
__is_swappable<_T1>::value &&
|
|
|
|
__is_swappable<_T2>::value,
|
|
|
|
void
|
|
|
|
>::type
|
2010-05-12 03:42:16 +08:00
|
|
|
swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
|
2011-05-28 03:08:18 +08:00
|
|
|
_NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
|
|
|
|
__is_nothrow_swappable<_T2>::value))
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2011-05-27 23:04:19 +08:00
|
|
|
__x.swap(__y);
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2018-12-03 22:03:27 +08:00
|
|
|
template <class _Tp>
|
2019-06-12 10:03:31 +08:00
|
|
|
struct __unwrap_reference { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
2019-06-12 10:03:31 +08:00
|
|
|
struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; };
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2018-12-03 22:03:27 +08:00
|
|
|
#if _LIBCPP_STD_VER > 17
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _Tp>
|
2018-12-03 22:03:27 +08:00
|
|
|
struct unwrap_reference : __unwrap_reference<_Tp> { };
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
2018-12-03 22:03:27 +08:00
|
|
|
struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { };
|
|
|
|
#endif // > C++17
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __unwrap_ref_decay
|
|
|
|
#if _LIBCPP_STD_VER > 17
|
|
|
|
: unwrap_ref_decay<_Tp>
|
|
|
|
#else
|
|
|
|
: __unwrap_reference<typename decay<_Tp>::type>
|
|
|
|
#endif
|
|
|
|
{ };
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-07-17 01:45:44 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2018-12-03 22:03:27 +08:00
|
|
|
pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
|
2010-05-12 03:42:16 +08:00
|
|
|
make_pair(_T1&& __t1, _T2&& __t2)
|
|
|
|
{
|
2018-12-03 22:03:27 +08:00
|
|
|
return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
|
2011-07-01 05:18:19 +08:00
|
|
|
(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
|
2010-05-12 03:42:16 +08:00
|
|
|
}
|
|
|
|
|
2017-04-19 09:23:39 +08:00
|
|
|
#else // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
pair<_T1,_T2>
|
|
|
|
make_pair(_T1 __x, _T2 __y)
|
|
|
|
{
|
|
|
|
return pair<_T1, _T2>(__x, __y);
|
|
|
|
}
|
|
|
|
|
2017-04-19 09:23:39 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2019-01-12 05:57:12 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
|
2010-09-24 02:58:28 +08:00
|
|
|
: public integral_constant<size_t, 2> {};
|
2010-05-12 03:42:16 +08:00
|
|
|
|
2017-06-13 00:13:17 +08:00
|
|
|
template <size_t _Ip, class _T1, class _T2>
|
2019-04-02 00:39:34 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
|
2017-06-13 00:13:17 +08:00
|
|
|
{
|
|
|
|
static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
|
|
|
|
};
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
template <class _T1, class _T2>
|
2019-04-02 00:39:34 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2019-06-12 10:03:31 +08:00
|
|
|
typedef _LIBCPP_NODEBUG_TYPE _T1 type;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2019-04-02 00:39:34 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
2019-06-12 10:03:31 +08:00
|
|
|
typedef _LIBCPP_NODEBUG_TYPE _T2 type;
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <size_t _Ip> struct __get_pair;
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct __get_pair<0>
|
|
|
|
{
|
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
2013-07-18 02:25:36 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
_T1&
|
2011-05-28 03:08:18 +08:00
|
|
|
get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
2013-07-18 02:25:36 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
const _T1&
|
2011-05-28 03:08:18 +08:00
|
|
|
get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
|
2010-11-18 03:52:17 +08:00
|
|
|
|
2017-04-19 09:23:39 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-11-18 03:52:17 +08:00
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
2013-07-18 02:25:36 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-11-18 03:52:17 +08:00
|
|
|
_T1&&
|
2011-07-01 05:18:19 +08:00
|
|
|
get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
|
2010-11-18 03:52:17 +08:00
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
const _T1&&
|
|
|
|
get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);}
|
2017-04-19 09:23:39 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct __get_pair<1>
|
|
|
|
{
|
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
2013-07-18 02:25:36 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
_T2&
|
2011-05-28 03:08:18 +08:00
|
|
|
get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
|
2010-05-12 03:42:16 +08:00
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
2013-07-18 02:25:36 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
const _T2&
|
2011-05-28 03:08:18 +08:00
|
|
|
get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
|
2010-11-18 03:52:17 +08:00
|
|
|
|
2017-04-19 09:23:39 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-11-18 03:52:17 +08:00
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
2013-07-18 02:25:36 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-11-18 03:52:17 +08:00
|
|
|
_T2&&
|
2011-07-01 05:18:19 +08:00
|
|
|
get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
|
2010-11-18 03:52:17 +08:00
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template <class _T1, class _T2>
|
|
|
|
static
|
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
const _T2&&
|
|
|
|
get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);}
|
2017-04-19 09:23:39 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-05-12 03:42:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <size_t _Ip, class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
typename tuple_element<_Ip, pair<_T1, _T2> >::type&
|
2011-05-28 03:08:18 +08:00
|
|
|
get(pair<_T1, _T2>& __p) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __get_pair<_Ip>::get(__p);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <size_t _Ip, class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-05-12 03:42:16 +08:00
|
|
|
const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
|
2011-05-28 03:08:18 +08:00
|
|
|
get(const pair<_T1, _T2>& __p) _NOEXCEPT
|
2010-05-12 03:42:16 +08:00
|
|
|
{
|
|
|
|
return __get_pair<_Ip>::get(__p);
|
|
|
|
}
|
|
|
|
|
2017-04-19 09:23:39 +08:00
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2010-11-18 03:52:17 +08:00
|
|
|
template <size_t _Ip, class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
2010-11-18 03:52:17 +08:00
|
|
|
typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
|
2011-05-28 03:08:18 +08:00
|
|
|
get(pair<_T1, _T2>&& __p) _NOEXCEPT
|
2010-11-18 03:52:17 +08:00
|
|
|
{
|
2011-07-01 05:18:19 +08:00
|
|
|
return __get_pair<_Ip>::get(_VSTD::move(__p));
|
2010-11-18 03:52:17 +08:00
|
|
|
}
|
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template <size_t _Ip, class _T1, class _T2>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
|
const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
|
|
|
|
get(const pair<_T1, _T2>&& __p) _NOEXCEPT
|
|
|
|
{
|
|
|
|
return __get_pair<_Ip>::get(_VSTD::move(__p));
|
|
|
|
}
|
2017-04-19 09:23:39 +08:00
|
|
|
#endif // _LIBCPP_CXX03_LANG
|
2010-11-18 03:52:17 +08:00
|
|
|
|
2013-07-13 10:54:05 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template <class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2013-07-13 10:54:05 +08:00
|
|
|
constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
|
|
|
|
{
|
2013-07-17 01:45:44 +08:00
|
|
|
return __get_pair<0>::get(__p);
|
2013-07-13 10:54:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2013-07-13 10:54:05 +08:00
|
|
|
constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
|
|
|
|
{
|
2013-07-17 01:45:44 +08:00
|
|
|
return __get_pair<0>::get(__p);
|
2013-07-13 10:54:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2013-07-13 10:54:05 +08:00
|
|
|
constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
|
|
|
|
{
|
2013-07-17 01:45:44 +08:00
|
|
|
return __get_pair<0>::get(_VSTD::move(__p));
|
2013-07-13 10:54:05 +08:00
|
|
|
}
|
|
|
|
|
2015-12-18 08:36:55 +08:00
|
|
|
template <class _T1, class _T2>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
|
|
|
|
{
|
|
|
|
return __get_pair<0>::get(_VSTD::move(__p));
|
|
|
|
}
|
|
|
|
|
2013-07-13 10:54:05 +08:00
|
|
|
template <class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2013-07-13 10:54:05 +08:00
|
|
|
constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
|
|
|
|
{
|
2013-07-17 01:45:44 +08:00
|
|
|
return __get_pair<1>::get(__p);
|
2013-07-13 10:54:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2013-07-13 10:54:05 +08:00
|
|
|
constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
|
|
|
|
{
|
2013-07-17 01:45:44 +08:00
|
|
|
return __get_pair<1>::get(__p);
|
2013-07-13 10:54:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
2013-10-05 06:09:00 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2013-07-13 10:54:05 +08:00
|
|
|
constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
|
|
|
|
{
|
2013-07-17 01:45:44 +08:00
|
|
|
return __get_pair<1>::get(_VSTD::move(__p));
|
2015-12-18 08:36:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _T1, class _T2>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
|
|
|
|
{
|
|
|
|
return __get_pair<1>::get(_VSTD::move(__p));
|
2013-07-13 10:54:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2013-07-02 00:26:55 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
|
|
|
|
template<class _Tp, _Tp... _Ip>
|
2017-01-05 07:56:00 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS integer_sequence
|
2013-07-02 00:26:55 +08:00
|
|
|
{
|
|
|
|
typedef _Tp value_type;
|
|
|
|
static_assert( is_integral<_Tp>::value,
|
|
|
|
"std::integer_sequence can only be instantiated with an integral type" );
|
|
|
|
static
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr
|
|
|
|
size_t
|
|
|
|
size() noexcept { return sizeof...(_Ip); }
|
|
|
|
};
|
|
|
|
|
|
|
|
template<size_t... _Ip>
|
|
|
|
using index_sequence = integer_sequence<size_t, _Ip...>;
|
|
|
|
|
2015-12-10 06:03:06 +08:00
|
|
|
#if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
|
|
|
|
|
|
|
|
template <class _Tp, _Tp _Ep>
|
2019-06-12 10:03:31 +08:00
|
|
|
using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = __make_integer_seq<integer_sequence, _Tp, _Ep>;
|
2015-12-10 06:03:06 +08:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2019-06-12 10:03:31 +08:00
|
|
|
template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked _LIBCPP_NODEBUG_TYPE =
|
2016-07-01 06:34:43 +08:00
|
|
|
typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
|
2013-07-02 00:26:55 +08:00
|
|
|
|
|
|
|
template <class _Tp, _Tp _Ep>
|
2016-07-01 06:34:43 +08:00
|
|
|
struct __make_integer_sequence_checked
|
2013-07-02 00:26:55 +08:00
|
|
|
{
|
|
|
|
static_assert(is_integral<_Tp>::value,
|
|
|
|
"std::make_integer_sequence can only be instantiated with an integral type" );
|
2015-12-10 06:03:06 +08:00
|
|
|
static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length");
|
2015-12-16 08:35:45 +08:00
|
|
|
// Workaround GCC bug by preventing bad installations when 0 <= _Ep
|
|
|
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
|
2019-06-12 10:03:31 +08:00
|
|
|
typedef _LIBCPP_NODEBUG_TYPE __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
|
2013-07-02 00:26:55 +08:00
|
|
|
};
|
|
|
|
|
2016-07-01 06:34:43 +08:00
|
|
|
template <class _Tp, _Tp _Ep>
|
2019-06-12 10:03:31 +08:00
|
|
|
using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
|
2016-07-01 06:34:43 +08:00
|
|
|
|
2015-12-10 06:03:06 +08:00
|
|
|
#endif
|
|
|
|
|
2013-07-02 00:26:55 +08:00
|
|
|
template<class _Tp, _Tp _Np>
|
2016-07-01 06:34:43 +08:00
|
|
|
using make_integer_sequence = __make_integer_sequence<_Tp, _Np>;
|
2013-07-02 00:26:55 +08:00
|
|
|
|
|
|
|
template<size_t _Np>
|
|
|
|
using make_index_sequence = make_integer_sequence<size_t, _Np>;
|
|
|
|
|
|
|
|
template<class... _Tp>
|
|
|
|
using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
|
2016-06-20 03:29:52 +08:00
|
|
|
|
2013-07-02 00:26:55 +08:00
|
|
|
#endif // _LIBCPP_STD_VER > 11
|
|
|
|
|
2013-07-09 04:54:40 +08:00
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
template<class _T1, class _T2 = _T1>
|
2018-01-23 07:10:40 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
2013-07-09 04:54:40 +08:00
|
|
|
_T1 exchange(_T1& __obj, _T2 && __new_value)
|
|
|
|
{
|
2013-07-09 05:06:38 +08:00
|
|
|
_T1 __old_value = _VSTD::move(__obj);
|
|
|
|
__obj = _VSTD::forward<_T2>(__new_value);
|
|
|
|
return __old_value;
|
2016-06-20 03:29:52 +08:00
|
|
|
}
|
2013-07-09 04:54:40 +08:00
|
|
|
#endif // _LIBCPP_STD_VER > 11
|
|
|
|
|
2016-07-24 06:19:19 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
|
2016-11-18 03:24:04 +08:00
|
|
|
struct _LIBCPP_TYPE_VIS in_place_t {
|
|
|
|
explicit in_place_t() = default;
|
|
|
|
};
|
2018-01-03 01:17:01 +08:00
|
|
|
_LIBCPP_INLINE_VAR constexpr in_place_t in_place{};
|
2016-07-24 06:19:19 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
2017-04-20 09:45:15 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
|
2016-11-18 03:24:04 +08:00
|
|
|
explicit in_place_type_t() = default;
|
2016-07-24 06:19:19 +08:00
|
|
|
};
|
|
|
|
template <class _Tp>
|
2018-01-03 01:17:01 +08:00
|
|
|
_LIBCPP_INLINE_VAR constexpr in_place_type_t<_Tp> in_place_type{};
|
2016-07-24 06:19:19 +08:00
|
|
|
|
2016-11-18 03:24:04 +08:00
|
|
|
template <size_t _Idx>
|
|
|
|
struct _LIBCPP_TYPE_VIS in_place_index_t {
|
|
|
|
explicit in_place_index_t() = default;
|
|
|
|
};
|
|
|
|
template <size_t _Idx>
|
2018-01-03 01:17:01 +08:00
|
|
|
_LIBCPP_INLINE_VAR constexpr in_place_index_t<_Idx> in_place_index{};
|
2016-10-16 10:51:50 +08:00
|
|
|
|
2016-11-18 03:24:04 +08:00
|
|
|
template <class _Tp> struct __is_inplace_type_imp : false_type {};
|
|
|
|
template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_type {};
|
2016-10-16 10:51:50 +08:00
|
|
|
|
|
|
|
template <class _Tp>
|
2016-11-18 03:24:04 +08:00
|
|
|
using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>;
|
2016-07-24 15:42:13 +08:00
|
|
|
|
2017-06-14 13:51:18 +08:00
|
|
|
template <class _Tp> struct __is_inplace_index_imp : false_type {};
|
|
|
|
template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : true_type {};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
using __is_inplace_index = __is_inplace_index_imp<__uncvref_t<_Tp>>;
|
|
|
|
|
2016-07-24 06:19:19 +08:00
|
|
|
#endif // _LIBCPP_STD_VER > 14
|
|
|
|
|
2017-01-21 08:02:12 +08:00
|
|
|
template <class _Arg, class _Result>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS unary_function
|
|
|
|
{
|
|
|
|
typedef _Arg argument_type;
|
|
|
|
typedef _Result result_type;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Size>
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
|
|
_Size
|
|
|
|
__loadword(const void* __p)
|
|
|
|
{
|
|
|
|
_Size __r;
|
[libc++] Consistently replace `std::` qualification with `_VSTD::` or nothing. NFCI.
I used a lot of `git grep` to find places where `std::` was being used
outside of comments and assert-messages. There were three outcomes:
- Qualified function calls, e.g. `std::move` becomes `_VSTD::move`.
This is the most common case.
- Typenames that don't need qualification, e.g. `std::allocator` becomes `allocator`.
Leaving these as `_VSTD::allocator` would also be fine, but I decided
that removing the qualification is more consistent with existing practice.
- Names that specifically need un-versioned `std::` qualification,
or that I wasn't sure about. For example, I didn't touch any code in
<atomic>, <math.h>, <new>, or any ext/ or experimental/ headers;
and I didn't touch any instances of `std::type_info`.
In some deduction guides, we were accidentally using `class Alloc = typename std::allocator<T>`,
despite `std::allocator<T>`'s type-ness not being template-dependent.
Because `std::allocator` is a qualified name, this did parse as we intended;
but what we meant was simply `class Alloc = allocator<T>`.
Differential Revision: https://reviews.llvm.org/D92250
2020-11-28 00:02:06 +08:00
|
|
|
_VSTD::memcpy(&__r, __p, sizeof(__r));
|
2017-01-21 08:02:12 +08:00
|
|
|
return __r;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
|
|
|
|
// is 64 bits. This is because cityhash64 uses 64bit x 64bit
|
|
|
|
// multiplication, which can be very slow on 32-bit systems.
|
|
|
|
template <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__>
|
|
|
|
struct __murmur2_or_cityhash;
|
|
|
|
|
|
|
|
template <class _Size>
|
|
|
|
struct __murmur2_or_cityhash<_Size, 32>
|
|
|
|
{
|
2017-02-08 08:10:10 +08:00
|
|
|
inline _Size operator()(const void* __key, _Size __len)
|
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
|
2017-01-21 08:02:12 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// murmur2
|
|
|
|
template <class _Size>
|
|
|
|
_Size
|
2017-02-08 08:10:10 +08:00
|
|
|
__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
|
2017-01-21 08:02:12 +08:00
|
|
|
{
|
|
|
|
const _Size __m = 0x5bd1e995;
|
|
|
|
const _Size __r = 24;
|
|
|
|
_Size __h = __len;
|
|
|
|
const unsigned char* __data = static_cast<const unsigned char*>(__key);
|
|
|
|
for (; __len >= 4; __data += 4, __len -= 4)
|
|
|
|
{
|
|
|
|
_Size __k = __loadword<_Size>(__data);
|
|
|
|
__k *= __m;
|
|
|
|
__k ^= __k >> __r;
|
|
|
|
__k *= __m;
|
|
|
|
__h *= __m;
|
|
|
|
__h ^= __k;
|
|
|
|
}
|
|
|
|
switch (__len)
|
|
|
|
{
|
|
|
|
case 3:
|
|
|
|
__h ^= __data[2] << 16;
|
2018-11-08 07:51:13 +08:00
|
|
|
_LIBCPP_FALLTHROUGH();
|
2017-01-21 08:02:12 +08:00
|
|
|
case 2:
|
|
|
|
__h ^= __data[1] << 8;
|
2018-11-08 07:51:13 +08:00
|
|
|
_LIBCPP_FALLTHROUGH();
|
2017-01-21 08:02:12 +08:00
|
|
|
case 1:
|
|
|
|
__h ^= __data[0];
|
|
|
|
__h *= __m;
|
|
|
|
}
|
|
|
|
__h ^= __h >> 13;
|
|
|
|
__h *= __m;
|
|
|
|
__h ^= __h >> 15;
|
|
|
|
return __h;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Size>
|
|
|
|
struct __murmur2_or_cityhash<_Size, 64>
|
|
|
|
{
|
2017-02-08 08:10:10 +08:00
|
|
|
inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK;
|
2017-01-21 08:02:12 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Some primes between 2^63 and 2^64.
|
|
|
|
static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
|
|
|
|
static const _Size __k1 = 0xb492b66fbe98f273ULL;
|
|
|
|
static const _Size __k2 = 0x9ae16a3b2f90404fULL;
|
|
|
|
static const _Size __k3 = 0xc949d7c7509e6557ULL;
|
|
|
|
|
|
|
|
static _Size __rotate(_Size __val, int __shift) {
|
|
|
|
return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static _Size __rotate_by_at_least_1(_Size __val, int __shift) {
|
|
|
|
return (__val >> __shift) | (__val << (64 - __shift));
|
|
|
|
}
|
|
|
|
|
|
|
|
static _Size __shift_mix(_Size __val) {
|
|
|
|
return __val ^ (__val >> 47);
|
|
|
|
}
|
|
|
|
|
2017-02-08 08:10:10 +08:00
|
|
|
static _Size __hash_len_16(_Size __u, _Size __v)
|
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
|
|
|
{
|
2017-01-21 08:02:12 +08:00
|
|
|
const _Size __mul = 0x9ddfea08eb382d69ULL;
|
|
|
|
_Size __a = (__u ^ __v) * __mul;
|
|
|
|
__a ^= (__a >> 47);
|
|
|
|
_Size __b = (__v ^ __a) * __mul;
|
|
|
|
__b ^= (__b >> 47);
|
|
|
|
__b *= __mul;
|
|
|
|
return __b;
|
|
|
|
}
|
|
|
|
|
2017-02-08 08:10:10 +08:00
|
|
|
static _Size __hash_len_0_to_16(const char* __s, _Size __len)
|
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
|
|
|
{
|
2017-01-21 08:02:12 +08:00
|
|
|
if (__len > 8) {
|
|
|
|
const _Size __a = __loadword<_Size>(__s);
|
|
|
|
const _Size __b = __loadword<_Size>(__s + __len - 8);
|
|
|
|
return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;
|
|
|
|
}
|
|
|
|
if (__len >= 4) {
|
|
|
|
const uint32_t __a = __loadword<uint32_t>(__s);
|
|
|
|
const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);
|
|
|
|
return __hash_len_16(__len + (__a << 3), __b);
|
|
|
|
}
|
|
|
|
if (__len > 0) {
|
|
|
|
const unsigned char __a = __s[0];
|
|
|
|
const unsigned char __b = __s[__len >> 1];
|
|
|
|
const unsigned char __c = __s[__len - 1];
|
|
|
|
const uint32_t __y = static_cast<uint32_t>(__a) +
|
|
|
|
(static_cast<uint32_t>(__b) << 8);
|
|
|
|
const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2);
|
|
|
|
return __shift_mix(__y * __k2 ^ __z * __k3) * __k2;
|
|
|
|
}
|
|
|
|
return __k2;
|
|
|
|
}
|
|
|
|
|
2017-02-08 08:10:10 +08:00
|
|
|
static _Size __hash_len_17_to_32(const char *__s, _Size __len)
|
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
|
|
|
{
|
2017-01-21 08:02:12 +08:00
|
|
|
const _Size __a = __loadword<_Size>(__s) * __k1;
|
|
|
|
const _Size __b = __loadword<_Size>(__s + 8);
|
|
|
|
const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;
|
|
|
|
const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;
|
|
|
|
return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,
|
|
|
|
__a + __rotate(__b ^ __k3, 20) - __c + __len);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return a 16-byte hash for 48 bytes. Quick and dirty.
|
|
|
|
// Callers do best to use "random-looking" values for a and b.
|
|
|
|
static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
|
2017-02-08 08:10:10 +08:00
|
|
|
_Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b)
|
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
|
|
|
{
|
2017-01-21 08:02:12 +08:00
|
|
|
__a += __w;
|
|
|
|
__b = __rotate(__b + __a + __z, 21);
|
|
|
|
const _Size __c = __a;
|
|
|
|
__a += __x;
|
|
|
|
__a += __y;
|
|
|
|
__b += __rotate(__a, 44);
|
|
|
|
return pair<_Size, _Size>(__a + __z, __b + __c);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
|
|
|
|
static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
|
2017-02-08 08:10:10 +08:00
|
|
|
const char* __s, _Size __a, _Size __b)
|
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
|
|
|
{
|
2017-01-21 08:02:12 +08:00
|
|
|
return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),
|
|
|
|
__loadword<_Size>(__s + 8),
|
|
|
|
__loadword<_Size>(__s + 16),
|
|
|
|
__loadword<_Size>(__s + 24),
|
|
|
|
__a,
|
|
|
|
__b);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return an 8-byte hash for 33 to 64 bytes.
|
2017-02-08 08:10:10 +08:00
|
|
|
static _Size __hash_len_33_to_64(const char *__s, size_t __len)
|
|
|
|
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
|
|
|
|
{
|
2017-01-21 08:02:12 +08:00
|
|
|
_Size __z = __loadword<_Size>(__s + 24);
|
|
|
|
_Size __a = __loadword<_Size>(__s) +
|
|
|
|
(__len + __loadword<_Size>(__s + __len - 16)) * __k0;
|
|
|
|
_Size __b = __rotate(__a + __z, 52);
|
|
|
|
_Size __c = __rotate(__a, 37);
|
|
|
|
__a += __loadword<_Size>(__s + 8);
|
|
|
|
__c += __rotate(__a, 7);
|
|
|
|
__a += __loadword<_Size>(__s + 16);
|
|
|
|
_Size __vf = __a + __z;
|
|
|
|
_Size __vs = __b + __rotate(__a, 31) + __c;
|
|
|
|
__a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);
|
|
|
|
__z += __loadword<_Size>(__s + __len - 8);
|
|
|
|
__b = __rotate(__a + __z, 52);
|
|
|
|
__c = __rotate(__a, 37);
|
|
|
|
__a += __loadword<_Size>(__s + __len - 24);
|
|
|
|
__c += __rotate(__a, 7);
|
|
|
|
__a += __loadword<_Size>(__s + __len - 16);
|
|
|
|
_Size __wf = __a + __z;
|
|
|
|
_Size __ws = __b + __rotate(__a, 31) + __c;
|
|
|
|
_Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);
|
|
|
|
return __shift_mix(__r * __k0 + __vs) * __k2;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// cityhash64
|
|
|
|
template <class _Size>
|
|
|
|
_Size
|
2017-02-08 08:10:10 +08:00
|
|
|
__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
|
2017-01-21 08:02:12 +08:00
|
|
|
{
|
|
|
|
const char* __s = static_cast<const char*>(__key);
|
|
|
|
if (__len <= 32) {
|
|
|
|
if (__len <= 16) {
|
|
|
|
return __hash_len_0_to_16(__s, __len);
|
|
|
|
} else {
|
|
|
|
return __hash_len_17_to_32(__s, __len);
|
|
|
|
}
|
|
|
|
} else if (__len <= 64) {
|
|
|
|
return __hash_len_33_to_64(__s, __len);
|
|
|
|
}
|
|
|
|
|
|
|
|
// For strings over 64 bytes we hash the end first, and then as we
|
|
|
|
// loop we keep 56 bytes of state: v, w, x, y, and z.
|
|
|
|
_Size __x = __loadword<_Size>(__s + __len - 40);
|
|
|
|
_Size __y = __loadword<_Size>(__s + __len - 16) +
|
|
|
|
__loadword<_Size>(__s + __len - 56);
|
|
|
|
_Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,
|
|
|
|
__loadword<_Size>(__s + __len - 24));
|
|
|
|
pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
|
|
|
|
pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
|
|
|
|
__x = __x * __k1 + __loadword<_Size>(__s);
|
|
|
|
|
|
|
|
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
|
|
|
|
__len = (__len - 1) & ~static_cast<_Size>(63);
|
|
|
|
do {
|
|
|
|
__x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;
|
|
|
|
__y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;
|
|
|
|
__x ^= __w.second;
|
|
|
|
__y += __v.first + __loadword<_Size>(__s + 40);
|
|
|
|
__z = __rotate(__z + __w.first, 33) * __k1;
|
|
|
|
__v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
|
|
|
|
__w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
|
|
|
|
__y + __loadword<_Size>(__s + 16));
|
[libc++] Consistently replace `std::` qualification with `_VSTD::` or nothing. NFCI.
I used a lot of `git grep` to find places where `std::` was being used
outside of comments and assert-messages. There were three outcomes:
- Qualified function calls, e.g. `std::move` becomes `_VSTD::move`.
This is the most common case.
- Typenames that don't need qualification, e.g. `std::allocator` becomes `allocator`.
Leaving these as `_VSTD::allocator` would also be fine, but I decided
that removing the qualification is more consistent with existing practice.
- Names that specifically need un-versioned `std::` qualification,
or that I wasn't sure about. For example, I didn't touch any code in
<atomic>, <math.h>, <new>, or any ext/ or experimental/ headers;
and I didn't touch any instances of `std::type_info`.
In some deduction guides, we were accidentally using `class Alloc = typename std::allocator<T>`,
despite `std::allocator<T>`'s type-ness not being template-dependent.
Because `std::allocator` is a qualified name, this did parse as we intended;
but what we meant was simply `class Alloc = allocator<T>`.
Differential Revision: https://reviews.llvm.org/D92250
2020-11-28 00:02:06 +08:00
|
|
|
_VSTD::swap(__z, __x);
|
2017-01-21 08:02:12 +08:00
|
|
|
__s += 64;
|
|
|
|
__len -= 64;
|
|
|
|
} while (__len != 0);
|
|
|
|
return __hash_len_16(
|
|
|
|
__hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
|
|
|
|
__hash_len_16(__v.second, __w.second) + __x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
|
|
|
|
struct __scalar_hash;
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __scalar_hash<_Tp, 0>
|
|
|
|
: public unary_function<_Tp, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(_Tp __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
_Tp __t;
|
|
|
|
size_t __a;
|
|
|
|
} __u;
|
|
|
|
__u.__a = 0;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __u.__a;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __scalar_hash<_Tp, 1>
|
|
|
|
: public unary_function<_Tp, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(_Tp __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
_Tp __t;
|
|
|
|
size_t __a;
|
|
|
|
} __u;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __u.__a;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __scalar_hash<_Tp, 2>
|
|
|
|
: public unary_function<_Tp, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(_Tp __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
_Tp __t;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
size_t __a;
|
|
|
|
size_t __b;
|
|
|
|
} __s;
|
|
|
|
} __u;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __scalar_hash<_Tp, 3>
|
|
|
|
: public unary_function<_Tp, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(_Tp __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
_Tp __t;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
size_t __a;
|
|
|
|
size_t __b;
|
|
|
|
size_t __c;
|
|
|
|
} __s;
|
|
|
|
} __u;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __scalar_hash<_Tp, 4>
|
|
|
|
: public unary_function<_Tp, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(_Tp __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
_Tp __t;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
size_t __a;
|
|
|
|
size_t __b;
|
|
|
|
size_t __c;
|
|
|
|
size_t __d;
|
|
|
|
} __s;
|
|
|
|
} __u;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _PairT {
|
|
|
|
size_t first;
|
|
|
|
size_t second;
|
|
|
|
};
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
|
|
|
|
typedef __scalar_hash<_PairT> _HashT;
|
|
|
|
const _PairT __p = {__lhs, __rhs};
|
|
|
|
return _HashT()(__p);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Tp>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
|
|
|
|
: public unary_function<_Tp*, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(_Tp* __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
_Tp* __t;
|
|
|
|
size_t __a;
|
|
|
|
} __u;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<bool>
|
|
|
|
: public unary_function<bool, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<char>
|
|
|
|
: public unary_function<char, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<signed char>
|
|
|
|
: public unary_function<signed char, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
|
|
|
|
: public unary_function<unsigned char, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
2020-12-09 02:39:56 +08:00
|
|
|
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
|
|
|
|
: public unary_function<char8_t, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
#endif // !_LIBCPP_NO_HAS_CHAR8_T
|
|
|
|
|
2017-01-21 08:02:12 +08:00
|
|
|
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
|
|
|
|
: public unary_function<char16_t, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
|
|
|
|
: public unary_function<char32_t, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
|
|
|
|
: public unary_function<wchar_t, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<short>
|
|
|
|
: public unary_function<short, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
|
|
|
|
: public unary_function<unsigned short, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<int>
|
|
|
|
: public unary_function<int, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
|
|
|
|
: public unary_function<unsigned int, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<long>
|
|
|
|
: public unary_function<long, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
|
|
|
|
: public unary_function<unsigned long, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<long long>
|
|
|
|
: public __scalar_hash<long long>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<unsigned long long>
|
|
|
|
: public __scalar_hash<unsigned long long>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_HAS_NO_INT128
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<__int128_t>
|
|
|
|
: public __scalar_hash<__int128_t>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t>
|
|
|
|
: public __scalar_hash<__uint128_t>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<float>
|
|
|
|
: public __scalar_hash<float>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(float __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
// -0.0 and 0.0 should return same hash
|
2019-07-02 00:13:31 +08:00
|
|
|
if (__v == 0.0f)
|
2017-01-21 08:02:12 +08:00
|
|
|
return 0;
|
|
|
|
return __scalar_hash<float>::operator()(__v);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<double>
|
|
|
|
: public __scalar_hash<double>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(double __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
// -0.0 and 0.0 should return same hash
|
2018-10-01 09:59:37 +08:00
|
|
|
if (__v == 0.0)
|
2017-01-21 08:02:12 +08:00
|
|
|
return 0;
|
|
|
|
return __scalar_hash<double>::operator()(__v);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<long double>
|
|
|
|
: public __scalar_hash<long double>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(long double __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
// -0.0 and 0.0 should return same hash
|
2019-07-02 00:13:31 +08:00
|
|
|
if (__v == 0.0L)
|
2017-01-21 08:02:12 +08:00
|
|
|
return 0;
|
2020-11-29 21:52:28 +08:00
|
|
|
#if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__))
|
2017-01-21 08:02:12 +08:00
|
|
|
// Zero out padding bits
|
|
|
|
union
|
|
|
|
{
|
|
|
|
long double __t;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
size_t __a;
|
|
|
|
size_t __b;
|
|
|
|
size_t __c;
|
|
|
|
size_t __d;
|
|
|
|
} __s;
|
|
|
|
} __u;
|
|
|
|
__u.__s.__a = 0;
|
|
|
|
__u.__s.__b = 0;
|
|
|
|
__u.__s.__c = 0;
|
|
|
|
__u.__s.__d = 0;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d;
|
|
|
|
#elif defined(__x86_64__)
|
|
|
|
// Zero out padding bits
|
|
|
|
union
|
|
|
|
{
|
|
|
|
long double __t;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
size_t __a;
|
|
|
|
size_t __b;
|
|
|
|
} __s;
|
|
|
|
} __u;
|
|
|
|
__u.__s.__a = 0;
|
|
|
|
__u.__s.__b = 0;
|
|
|
|
__u.__t = __v;
|
|
|
|
return __u.__s.__a ^ __u.__s.__b;
|
|
|
|
#else
|
|
|
|
return __scalar_hash<long double>::operator()(__v);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#if _LIBCPP_STD_VER > 11
|
|
|
|
|
|
|
|
template <class _Tp, bool = is_enum<_Tp>::value>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS __enum_hash
|
|
|
|
: public unary_function<_Tp, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(_Tp __v) const _NOEXCEPT
|
|
|
|
{
|
|
|
|
typedef typename underlying_type<_Tp>::type type;
|
|
|
|
return hash<type>{}(static_cast<type>(__v));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
template <class _Tp>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> {
|
|
|
|
__enum_hash() = delete;
|
|
|
|
__enum_hash(__enum_hash const&) = delete;
|
|
|
|
__enum_hash& operator=(__enum_hash const&) = delete;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
|
|
|
|
: public unary_function<nullptr_t, size_t>
|
|
|
|
{
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
size_t operator()(nullptr_t) const _NOEXCEPT {
|
|
|
|
return 662607004ull;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
2017-03-04 06:35:58 +08:00
|
|
|
template <class _Key, class _Hash>
|
2019-06-12 10:03:31 +08:00
|
|
|
using __check_hash_requirements _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
|
2017-01-21 08:02:12 +08:00
|
|
|
is_copy_constructible<_Hash>::value &&
|
|
|
|
is_move_constructible<_Hash>::value &&
|
|
|
|
__invokable_r<size_t, _Hash, _Key const&>::value
|
|
|
|
>;
|
|
|
|
|
[libc++] Consistently replace `std::` qualification with `_VSTD::` or nothing. NFCI.
I used a lot of `git grep` to find places where `std::` was being used
outside of comments and assert-messages. There were three outcomes:
- Qualified function calls, e.g. `std::move` becomes `_VSTD::move`.
This is the most common case.
- Typenames that don't need qualification, e.g. `std::allocator` becomes `allocator`.
Leaving these as `_VSTD::allocator` would also be fine, but I decided
that removing the qualification is more consistent with existing practice.
- Names that specifically need un-versioned `std::` qualification,
or that I wasn't sure about. For example, I didn't touch any code in
<atomic>, <math.h>, <new>, or any ext/ or experimental/ headers;
and I didn't touch any instances of `std::type_info`.
In some deduction guides, we were accidentally using `class Alloc = typename std::allocator<T>`,
despite `std::allocator<T>`'s type-ness not being template-dependent.
Because `std::allocator` is a qualified name, this did parse as we intended;
but what we meant was simply `class Alloc = allocator<T>`.
Differential Revision: https://reviews.llvm.org/D92250
2020-11-28 00:02:06 +08:00
|
|
|
template <class _Key, class _Hash = hash<_Key> >
|
2019-06-12 10:03:31 +08:00
|
|
|
using __has_enabled_hash _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
|
2017-03-04 06:35:58 +08:00
|
|
|
__check_hash_requirements<_Key, _Hash>::value &&
|
|
|
|
is_default_constructible<_Hash>::value
|
|
|
|
>;
|
|
|
|
|
2017-01-21 08:02:12 +08:00
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
template <class _Type, class>
|
2019-06-12 10:03:31 +08:00
|
|
|
using __enable_hash_helper_imp _LIBCPP_NODEBUG_TYPE = _Type;
|
2017-01-21 08:02:12 +08:00
|
|
|
|
|
|
|
template <class _Type, class ..._Keys>
|
2019-06-12 10:03:31 +08:00
|
|
|
using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = __enable_hash_helper_imp<_Type,
|
2017-01-21 08:02:12 +08:00
|
|
|
typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type
|
|
|
|
>;
|
|
|
|
#else
|
|
|
|
template <class _Type, class ...>
|
2019-06-12 10:03:31 +08:00
|
|
|
using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = _Type;
|
2017-01-21 08:02:12 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif // !_LIBCPP_CXX03_LANG
|
|
|
|
|
2010-05-12 03:42:16 +08:00
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
|
|
|
#endif // _LIBCPP_UTILITY
|