2010-05-11 11:42:16 -08:00
|
|
|
// -*- C++ -*-
|
2021-11-17 12:25:01 -09:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-05-11 11:42:16 -08:00
|
|
|
//
|
2019-01-19 01:56:40 -09: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-11 11:42:16 -08:00
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_ARRAY
|
|
|
|
|
#define _LIBCPP_ARRAY
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
array synopsis
|
|
|
|
|
|
|
|
|
|
namespace std
|
|
|
|
|
{
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class T, size_t N >
|
2010-05-11 11:42:16 -08:00
|
|
|
struct array
|
2010-08-21 16:02:43 -08:00
|
|
|
{
|
|
|
|
|
// types:
|
2024-07-30 10:24:11 -08:00
|
|
|
using value_type = T;
|
|
|
|
|
using pointer = T*;
|
|
|
|
|
using const_pointer = const T*;
|
|
|
|
|
using reference = T&;
|
|
|
|
|
using const_reference = const T&;
|
|
|
|
|
using size_type = size_t;
|
|
|
|
|
using difference_type = ptrdiff_t;
|
|
|
|
|
using iterator = implementation-defined;
|
|
|
|
|
using const_iterator = implementation-defined;
|
|
|
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
|
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
2010-05-11 11:42:16 -08:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
// No explicit construct/copy/destroy for aggregate type
|
2020-05-22 05:59:48 -08:00
|
|
|
void fill(const T& u); // constexpr in C++20
|
|
|
|
|
void swap(array& a) noexcept(is_nothrow_swappable_v<T>); // constexpr in C++20
|
2010-05-11 11:42:16 -08:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
// iterators:
|
2020-05-22 05:59:48 -08:00
|
|
|
iterator begin() noexcept; // constexpr in C++17
|
|
|
|
|
const_iterator begin() const noexcept; // constexpr in C++17
|
|
|
|
|
iterator end() noexcept; // constexpr in C++17
|
|
|
|
|
const_iterator end() const noexcept; // constexpr in C++17
|
2010-05-11 11:42:16 -08:00
|
|
|
|
2020-05-22 05:59:48 -08:00
|
|
|
reverse_iterator rbegin() noexcept; // constexpr in C++17
|
|
|
|
|
const_reverse_iterator rbegin() const noexcept; // constexpr in C++17
|
|
|
|
|
reverse_iterator rend() noexcept; // constexpr in C++17
|
|
|
|
|
const_reverse_iterator rend() const noexcept; // constexpr in C++17
|
2010-05-11 11:42:16 -08:00
|
|
|
|
2020-05-22 05:59:48 -08:00
|
|
|
const_iterator cbegin() const noexcept; // constexpr in C++17
|
|
|
|
|
const_iterator cend() const noexcept; // constexpr in C++17
|
|
|
|
|
const_reverse_iterator crbegin() const noexcept; // constexpr in C++17
|
|
|
|
|
const_reverse_iterator crend() const noexcept; // constexpr in C++17
|
2010-08-21 16:02:43 -08:00
|
|
|
|
|
|
|
|
// capacity:
|
2011-05-31 13:06:33 -08:00
|
|
|
constexpr size_type size() const noexcept;
|
|
|
|
|
constexpr size_type max_size() const noexcept;
|
2012-07-20 11:20:49 -08:00
|
|
|
constexpr bool empty() const noexcept;
|
2010-08-21 16:02:43 -08:00
|
|
|
|
|
|
|
|
// element access:
|
2020-05-22 05:59:48 -08:00
|
|
|
reference operator[](size_type n); // constexpr in C++17
|
|
|
|
|
const_reference operator[](size_type n) const; // constexpr in C++14
|
|
|
|
|
reference at(size_type n); // constexpr in C++17
|
|
|
|
|
const_reference at(size_type n) const; // constexpr in C++14
|
|
|
|
|
|
|
|
|
|
reference front(); // constexpr in C++17
|
|
|
|
|
const_reference front() const; // constexpr in C++14
|
|
|
|
|
reference back(); // constexpr in C++17
|
|
|
|
|
const_reference back() const; // constexpr in C++14
|
|
|
|
|
|
|
|
|
|
T* data() noexcept; // constexpr in C++17
|
|
|
|
|
const T* data() const noexcept; // constexpr in C++17
|
2010-05-11 11:42:16 -08:00
|
|
|
};
|
|
|
|
|
|
2020-05-22 05:59:48 -08:00
|
|
|
template <class T, class... U>
|
|
|
|
|
array(T, U...) -> array<T, 1 + sizeof...(U)>; // C++17
|
2018-05-18 13:01:04 -08:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class T, size_t N>
|
2020-05-22 05:59:48 -08:00
|
|
|
bool operator==(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class T, size_t N>
|
2023-05-06 04:41:41 -08:00
|
|
|
bool operator!=(const array<T,N>& x, const array<T,N>& y); // removed in C++20
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class T, size_t N>
|
2023-05-06 04:41:41 -08:00
|
|
|
bool operator<(const array<T,N>& x, const array<T,N>& y); // removed in C++20
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class T, size_t N>
|
2023-05-06 04:41:41 -08:00
|
|
|
bool operator>(const array<T,N>& x, const array<T,N>& y); // removed in C++20
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class T, size_t N>
|
2023-05-06 04:41:41 -08:00
|
|
|
bool operator<=(const array<T,N>& x, const array<T,N>& y); // removed in C++20
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class T, size_t N>
|
2023-05-06 04:41:41 -08:00
|
|
|
bool operator>=(const array<T,N>& x, const array<T,N>& y); // removed in C++20
|
|
|
|
|
template<class T, size_t N>
|
|
|
|
|
constexpr synth-three-way-result<T>
|
|
|
|
|
operator<=>(const array<T, N>& x, const array<T, N>& y); // since C++20
|
2010-08-21 16:02:43 -08:00
|
|
|
|
|
|
|
|
template <class T, size_t N >
|
2020-05-22 05:59:48 -08:00
|
|
|
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
|
|
|
|
|
|
|
|
|
|
template <class T, size_t N>
|
|
|
|
|
constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]); // C++20
|
|
|
|
|
template <class T, size_t N>
|
|
|
|
|
constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // C++20
|
2010-08-21 16:02:43 -08:00
|
|
|
|
2019-01-11 12:57:12 -09:00
|
|
|
template <class T> struct tuple_size;
|
2019-04-01 08:39:34 -08:00
|
|
|
template <size_t I, class T> struct tuple_element;
|
2010-05-11 11:42:16 -08:00
|
|
|
template <class T, size_t N> struct tuple_size<array<T, N>>;
|
2015-11-19 10:41:04 -09:00
|
|
|
template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
|
2020-05-22 05:59:48 -08:00
|
|
|
template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
|
|
|
|
|
template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
|
|
|
|
|
template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
|
2015-12-17 15:36:55 -09:00
|
|
|
template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14
|
2010-05-11 11:42:16 -08:00
|
|
|
|
|
|
|
|
} // std
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
2024-12-21 03:01:48 -09:00
|
|
|
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
|
|
|
|
# include <__cxx03/array>
|
|
|
|
|
#else
|
2024-12-10 06:02:12 -09:00
|
|
|
# include <__algorithm/equal.h>
|
|
|
|
|
# include <__algorithm/fill_n.h>
|
|
|
|
|
# include <__algorithm/lexicographical_compare.h>
|
|
|
|
|
# include <__algorithm/lexicographical_compare_three_way.h>
|
|
|
|
|
# include <__algorithm/swap_ranges.h>
|
|
|
|
|
# include <__assert>
|
|
|
|
|
# include <__config>
|
|
|
|
|
# include <__cstddef/ptrdiff_t.h>
|
|
|
|
|
# include <__fwd/array.h>
|
|
|
|
|
# include <__iterator/reverse_iterator.h>
|
|
|
|
|
# include <__iterator/static_bounded_iter.h>
|
|
|
|
|
# include <__iterator/wrap_iter.h>
|
|
|
|
|
# include <__tuple/sfinae_helpers.h>
|
|
|
|
|
# include <__type_traits/conditional.h>
|
|
|
|
|
# include <__type_traits/conjunction.h>
|
|
|
|
|
# include <__type_traits/enable_if.h>
|
|
|
|
|
# include <__type_traits/is_array.h>
|
|
|
|
|
# include <__type_traits/is_const.h>
|
|
|
|
|
# include <__type_traits/is_constructible.h>
|
|
|
|
|
# include <__type_traits/is_nothrow_constructible.h>
|
|
|
|
|
# include <__type_traits/is_same.h>
|
|
|
|
|
# include <__type_traits/is_swappable.h>
|
|
|
|
|
# include <__type_traits/is_trivially_relocatable.h>
|
|
|
|
|
# include <__type_traits/remove_cv.h>
|
|
|
|
|
# include <__utility/empty.h>
|
|
|
|
|
# include <__utility/integer_sequence.h>
|
|
|
|
|
# include <__utility/move.h>
|
|
|
|
|
# include <__utility/unreachable.h>
|
|
|
|
|
# include <stdexcept>
|
|
|
|
|
# include <version>
|
2010-05-11 11:42:16 -08:00
|
|
|
|
2022-06-16 12:43:46 -08:00
|
|
|
// standard-mandated includes
|
|
|
|
|
|
|
|
|
|
// [iterator.range]
|
2024-12-10 06:02:12 -09:00
|
|
|
# include <__iterator/access.h>
|
|
|
|
|
# include <__iterator/data.h>
|
|
|
|
|
# include <__iterator/empty.h>
|
|
|
|
|
# include <__iterator/reverse_access.h>
|
|
|
|
|
# include <__iterator/size.h>
|
2022-06-16 12:43:46 -08:00
|
|
|
|
|
|
|
|
// [array.syn]
|
2024-12-10 06:02:12 -09:00
|
|
|
# include <compare>
|
|
|
|
|
# include <initializer_list>
|
2022-06-16 12:43:46 -08:00
|
|
|
|
2022-09-05 04:38:24 -08:00
|
|
|
// [tuple.helper]
|
2024-12-10 06:02:12 -09:00
|
|
|
# include <__tuple/tuple_element.h>
|
|
|
|
|
# include <__tuple/tuple_size.h>
|
2022-09-05 04:38:24 -08:00
|
|
|
|
2024-12-10 06:02:12 -09:00
|
|
|
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
|
|
|
# pragma GCC system_header
|
|
|
|
|
# endif
|
2010-05-11 11:42:16 -08:00
|
|
|
|
[libc++] Fix missing and incorrect push/pop macros (#79204)
We recently noticed that the unwrap_iter.h file was pushing macros, but
it was pushing them again instead of popping them at the end of the
file. This led to libc++ basically swallowing any custom definition of
these macros in user code:
#define min HELLO
#include <algorithm>
// min is not HELLO anymore, it's not defined
While investigating this issue, I noticed that our push/pop pragmas were
actually entirely wrong too. Indeed, instead of pushing macros like
`move`, we'd push `move(int, int)` in the pragma, which is not a valid
macro name. As a result, we would not actually push macros like `move`
-- instead we'd simply undefine them. This led to the following code not
working:
#define move HELLO
#include <algorithm>
// move is not HELLO anymore
Fixing the pragma push/pop incantations led to a cascade of issues
because we use identifiers like `move` in a large number of places, and
all of these headers would now need to do the push/pop dance.
This patch fixes all these issues. First, it adds a check that we don't
swallow important names like min, max, move or refresh as explained
above. This is done by augmenting the existing
system_reserved_names.gen.py test to also check that the macros are what
we expect after including each header.
Second, it fixes the push/pop pragmas to work properly and adds missing
pragmas to all the files I could detect a failure in via the newly added
test.
rdar://121365472
2024-01-25 11:48:46 -09:00
|
|
|
_LIBCPP_PUSH_MACROS
|
2024-12-10 06:02:12 -09:00
|
|
|
# include <__undef_macros>
|
[libc++] Fix missing and incorrect push/pop macros (#79204)
We recently noticed that the unwrap_iter.h file was pushing macros, but
it was pushing them again instead of popping them at the end of the
file. This led to libc++ basically swallowing any custom definition of
these macros in user code:
#define min HELLO
#include <algorithm>
// min is not HELLO anymore, it's not defined
While investigating this issue, I noticed that our push/pop pragmas were
actually entirely wrong too. Indeed, instead of pushing macros like
`move`, we'd push `move(int, int)` in the pragma, which is not a valid
macro name. As a result, we would not actually push macros like `move`
-- instead we'd simply undefine them. This led to the following code not
working:
#define move HELLO
#include <algorithm>
// move is not HELLO anymore
Fixing the pragma push/pop incantations led to a cascade of issues
because we use identifiers like `move` in a large number of places, and
all of these headers would now need to do the push/pop dance.
This patch fixes all these issues. First, it adds a check that we don't
swallow important names like min, max, move or refresh as explained
above. This is done by augmenting the existing
system_reserved_names.gen.py test to also check that the macros are what
we expect after including each header.
Second, it fixes the push/pop pragmas to work properly and adds missing
pragmas to all the files I could detect a failure in via the newly added
test.
rdar://121365472
2024-01-25 11:48:46 -09:00
|
|
|
|
2010-05-11 11:42:16 -08:00
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class _Tp, size_t _Size>
|
2025-04-09 13:47:57 -08:00
|
|
|
struct array {
|
2025-01-08 07:12:59 -09:00
|
|
|
using __trivially_relocatable _LIBCPP_NODEBUG =
|
|
|
|
|
__conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>;
|
2024-06-17 03:09:04 -08:00
|
|
|
|
2010-05-11 11:42:16 -08:00
|
|
|
// types:
|
2025-01-08 07:12:59 -09:00
|
|
|
using __self _LIBCPP_NODEBUG = array;
|
|
|
|
|
using value_type = _Tp;
|
|
|
|
|
using reference = value_type&;
|
|
|
|
|
using const_reference = const value_type&;
|
|
|
|
|
using pointer = value_type*;
|
|
|
|
|
using const_pointer = const value_type*;
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
using iterator = __static_bounded_iter<pointer, _Size>;
|
|
|
|
|
using const_iterator = __static_bounded_iter<const_pointer, _Size>;
|
2024-12-10 06:02:12 -09:00
|
|
|
# elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY)
|
2024-03-04 14:23:53 -09:00
|
|
|
using iterator = __wrap_iter<pointer>;
|
|
|
|
|
using const_iterator = __wrap_iter<const_pointer>;
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2024-03-04 14:23:53 -09:00
|
|
|
using iterator = pointer;
|
|
|
|
|
using const_iterator = const_pointer;
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2023-12-05 07:21:06 -09:00
|
|
|
using size_type = size_t;
|
|
|
|
|
using difference_type = ptrdiff_t;
|
|
|
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
|
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2018-02-07 12:06:13 -09:00
|
|
|
_Tp __elems_[_Size];
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
// No explicit construct/copy/destroy for aggregate type
|
2022-08-19 03:08:01 -08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type& __u) {
|
2020-06-01 12:28:44 -08:00
|
|
|
std::fill_n(data(), _Size, __u);
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2024-06-18 01:01:43 -08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable_v<_Tp>) {
|
[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-27 07:02:06 -09:00
|
|
|
std::swap_ranges(data(), data() + _Size, __a.data());
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
// iterators:
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<_Size>(data(), data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2024-11-07 05:23:21 -09:00
|
|
|
return iterator(data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2024-11-07 05:23:21 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<_Size>(data(), data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2018-02-07 12:06:13 -09:00
|
|
|
return const_iterator(data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2024-11-07 05:23:21 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<_Size>(data() + _Size, data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2024-11-07 05:23:21 -09:00
|
|
|
return iterator(data() + _Size);
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<_Size>(data() + _Size, data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2018-02-07 12:06:13 -09:00
|
|
|
return const_iterator(data() + _Size);
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
|
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
|
2011-05-31 13:06:33 -08:00
|
|
|
return reverse_iterator(end());
|
|
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
|
|
|
|
|
rbegin() const _NOEXCEPT {
|
2011-05-31 13:06:33 -08:00
|
|
|
return const_reverse_iterator(end());
|
|
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
|
2011-05-31 13:06:33 -08:00
|
|
|
return reverse_iterator(begin());
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
|
2011-05-31 13:06:33 -08:00
|
|
|
return const_reverse_iterator(begin());
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
|
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT {
|
|
|
|
|
return begin();
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT {
|
|
|
|
|
return end();
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
|
|
|
|
|
crbegin() const _NOEXCEPT {
|
2018-02-07 12:06:13 -09:00
|
|
|
return rbegin();
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT {
|
|
|
|
|
return rend();
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
// capacity:
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; }
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; }
|
2024-09-12 11:18:43 -08:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return _Size == 0; }
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
// element access:
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
|
2020-06-01 12:35:42 -08:00
|
|
|
return __elems_[__n];
|
|
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference
|
|
|
|
|
operator[](size_type __n) const _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
|
2020-06-01 12:35:42 -08:00
|
|
|
return __elems_[__n];
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) {
|
2020-05-22 05:23:32 -08:00
|
|
|
if (__n >= _Size)
|
2025-02-21 03:59:46 -09:00
|
|
|
std::__throw_out_of_range("array::at");
|
2020-05-22 05:23:32 -08:00
|
|
|
return __elems_[__n];
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const {
|
2020-05-22 05:23:32 -08:00
|
|
|
if (__n >= _Size)
|
2025-02-21 03:59:46 -09:00
|
|
|
std::__throw_out_of_range("array::at");
|
2020-05-22 05:23:32 -08:00
|
|
|
return __elems_[__n];
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
|
|
|
|
|
return (*this)[0];
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
|
|
|
|
|
return (*this)[0];
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
|
|
|
|
|
return (*this)[_Size - 1];
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
|
2022-08-19 03:08:01 -08:00
|
|
|
return (*this)[_Size - 1];
|
2018-02-05 18:03:37 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT {
|
|
|
|
|
return __elems_;
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT {
|
|
|
|
|
return __elems_;
|
|
|
|
|
}
|
2010-05-11 11:42:16 -08:00
|
|
|
};
|
|
|
|
|
|
2018-02-07 12:06:13 -09:00
|
|
|
template <class _Tp>
|
2025-04-09 13:47:57 -08:00
|
|
|
struct array<_Tp, 0> {
|
2018-02-07 12:06:13 -09:00
|
|
|
// types:
|
2025-01-08 07:12:59 -09:00
|
|
|
using __self _LIBCPP_NODEBUG = array;
|
|
|
|
|
using value_type = _Tp;
|
|
|
|
|
using reference = value_type&;
|
|
|
|
|
using const_reference = const value_type&;
|
|
|
|
|
using pointer = value_type*;
|
|
|
|
|
using const_pointer = const value_type*;
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
using iterator = __static_bounded_iter<pointer, 0>;
|
|
|
|
|
using const_iterator = __static_bounded_iter<const_pointer, 0>;
|
2024-12-10 06:02:12 -09:00
|
|
|
# elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY)
|
2024-07-30 10:24:11 -08:00
|
|
|
using iterator = __wrap_iter<pointer>;
|
|
|
|
|
using const_iterator = __wrap_iter<const_pointer>;
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2024-07-30 10:24:11 -08:00
|
|
|
using iterator = pointer;
|
|
|
|
|
using const_iterator = const_pointer;
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2024-07-30 10:24:11 -08:00
|
|
|
using size_type = size_t;
|
|
|
|
|
using difference_type = ptrdiff_t;
|
|
|
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
|
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
|
|
|
|
2025-01-08 07:12:59 -09:00
|
|
|
using _EmptyType _LIBCPP_NODEBUG = __conditional_t<is_const<_Tp>::value, const __empty, __empty>;
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2018-02-07 14:50:25 -09:00
|
|
|
struct _ArrayInStructT {
|
|
|
|
|
_Tp __data_[1];
|
|
|
|
|
};
|
2023-12-15 12:06:12 -09:00
|
|
|
_ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)];
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; }
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2018-02-07 12:06:13 -09:00
|
|
|
// No explicit construct/copy/destroy for aggregate type
|
2022-08-19 03:08:01 -08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type&) {
|
2018-02-07 12:06:13 -09:00
|
|
|
static_assert(!is_const<_Tp>::value, "cannot fill zero-sized array of type 'const T'");
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2022-08-19 03:08:01 -08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array&) _NOEXCEPT {
|
2018-02-07 12:06:13 -09:00
|
|
|
static_assert(!is_const<_Tp>::value, "cannot swap zero-sized array of type 'const T'");
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2018-02-07 12:06:13 -09:00
|
|
|
// iterators:
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<0>(data(), data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2024-11-07 05:23:21 -09:00
|
|
|
return iterator(data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2024-11-07 05:23:21 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<0>(data(), data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2018-02-07 12:06:13 -09:00
|
|
|
return const_iterator(data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2024-11-07 05:23:21 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<0>(data(), data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2024-11-07 05:23:21 -09:00
|
|
|
return iterator(data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
|
2024-12-10 06:02:12 -09:00
|
|
|
# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
|
2024-11-07 05:23:21 -09:00
|
|
|
return std::__make_static_bounded_iter<0>(data(), data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# else
|
2018-02-07 12:06:13 -09:00
|
|
|
return const_iterator(data());
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
|
2018-02-07 12:06:13 -09:00
|
|
|
return reverse_iterator(end());
|
|
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
|
|
|
|
|
rbegin() const _NOEXCEPT {
|
2018-02-07 12:06:13 -09:00
|
|
|
return const_reverse_iterator(end());
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
|
2011-05-31 13:06:33 -08:00
|
|
|
return reverse_iterator(begin());
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
|
2018-02-07 12:06:13 -09:00
|
|
|
return const_reverse_iterator(begin());
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT {
|
|
|
|
|
return begin();
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT {
|
|
|
|
|
return end();
|
|
|
|
|
}
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
|
|
|
|
|
crbegin() const _NOEXCEPT {
|
2018-02-07 12:06:13 -09:00
|
|
|
return rbegin();
|
2023-12-18 10:01:33 -09:00
|
|
|
}
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT {
|
|
|
|
|
return rend();
|
|
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2018-02-07 12:06:13 -09:00
|
|
|
// capacity:
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; }
|
|
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; }
|
2024-09-12 11:18:43 -08:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return true; }
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2018-02-07 12:06:13 -09:00
|
|
|
// element access:
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference
|
|
|
|
|
operator[](size_type) const _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) {
|
2025-02-21 03:59:46 -09:00
|
|
|
std::__throw_out_of_range("array<T, 0>::at");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const {
|
2025-02-21 03:59:46 -09:00
|
|
|
std::__throw_out_of_range("array<T, 0>::at");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
2023-12-18 10:01:33 -09:00
|
|
|
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
|
2023-07-20 09:13:54 -08:00
|
|
|
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
|
2022-02-14 08:26:02 -09:00
|
|
|
__libcpp_unreachable();
|
2018-02-07 12:06:13 -09:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-12-10 06:02:12 -09:00
|
|
|
# if _LIBCPP_STD_VER >= 17
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-17 08:26:09 -08:00
|
|
|
template <class _Tp, class... _Args, class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value> >
|
2018-05-18 13:01:04 -08:00
|
|
|
array(_Tp, _Args...) -> array<_Tp, 1 + sizeof...(_Args)>;
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif
|
2018-05-18 13:01:04 -08:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class _Tp, size_t _Size>
|
2022-08-19 03:08:01 -08:00
|
|
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
2010-05-11 11:42:16 -08:00
|
|
|
operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
|
2018-02-07 12:06:13 -09:00
|
|
|
return std::equal(__x.begin(), __x.end(), __y.begin());
|
2010-05-11 11:42:16 -08:00
|
|
|
}
|
|
|
|
|
|
2024-12-10 06:02:12 -09:00
|
|
|
# if _LIBCPP_STD_VER <= 17
|
2023-05-06 04:41:41 -08:00
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class _Tp, size_t _Size>
|
2023-05-06 04:41:41 -08:00
|
|
|
inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
|
2010-05-11 11:42:16 -08:00
|
|
|
return !(__x == __y);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class _Tp, size_t _Size>
|
2023-05-06 04:41:41 -08:00
|
|
|
inline _LIBCPP_HIDE_FROM_ABI bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
|
|
|
|
|
return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
|
2010-05-11 11:42:16 -08:00
|
|
|
}
|
|
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class _Tp, size_t _Size>
|
2023-05-06 04:41:41 -08:00
|
|
|
inline _LIBCPP_HIDE_FROM_ABI bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
|
2010-05-11 11:42:16 -08:00
|
|
|
return __y < __x;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class _Tp, size_t _Size>
|
2023-05-06 04:41:41 -08:00
|
|
|
inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
|
2010-05-11 11:42:16 -08:00
|
|
|
return !(__y < __x);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-21 16:02:43 -08:00
|
|
|
template <class _Tp, size_t _Size>
|
2023-05-06 04:41:41 -08:00
|
|
|
inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
|
2010-05-11 11:42:16 -08:00
|
|
|
return !(__x < __y);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-10 06:02:12 -09:00
|
|
|
# else // _LIBCPP_STD_VER <= 17
|
2023-05-06 04:41:41 -08:00
|
|
|
|
|
|
|
|
template <class _Tp, size_t _Size>
|
|
|
|
|
_LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp>
|
|
|
|
|
operator<=>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
|
2024-08-30 08:07:07 -08:00
|
|
|
return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
|
2023-05-06 04:41:41 -08:00
|
|
|
}
|
|
|
|
|
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif // _LIBCPP_STD_VER <= 17
|
2023-05-06 04:41:41 -08:00
|
|
|
|
2024-06-18 01:01:43 -08:00
|
|
|
template <class _Tp, size_t _Size, __enable_if_t<_Size == 0 || __is_swappable_v<_Tp>, int> = 0>
|
2022-08-19 03:08:01 -08:00
|
|
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
|
2016-04-21 15:38:59 -08:00
|
|
|
_NOEXCEPT_(noexcept(__x.swap(__y))) {
|
2010-05-11 11:42:16 -08:00
|
|
|
__x.swap(__y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class _Tp, size_t _Size>
|
2025-04-09 13:47:57 -08:00
|
|
|
struct tuple_size<array<_Tp, _Size> > : public integral_constant<size_t, _Size> {};
|
2010-05-11 11:42:16 -08:00
|
|
|
|
|
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
2025-04-09 13:47:57 -08:00
|
|
|
struct tuple_element<_Ip, array<_Tp, _Size> > {
|
2017-06-12 06:41:37 -08:00
|
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)");
|
2025-03-23 12:01:25 -08:00
|
|
|
using type _LIBCPP_NODEBUG = _Tp;
|
2010-05-11 11:42:16 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&
|
|
|
|
|
get(array<_Tp, _Size>& __a) _NOEXCEPT {
|
2012-12-18 07:46:30 -09:00
|
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
|
2013-07-17 10:25:36 -08:00
|
|
|
return __a.__elems_[_Ip];
|
2010-05-11 11:42:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
|
|
|
|
|
get(const array<_Tp, _Size>& __a) _NOEXCEPT {
|
2012-12-18 07:46:30 -09:00
|
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
|
2013-07-17 10:25:36 -08:00
|
|
|
return __a.__elems_[_Ip];
|
2010-05-11 11:42:16 -08:00
|
|
|
}
|
|
|
|
|
|
2010-11-17 10:52:17 -09:00
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&&
|
|
|
|
|
get(array<_Tp, _Size>&& __a) _NOEXCEPT {
|
2012-12-18 07:46:30 -09:00
|
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
|
2013-07-17 10:25:36 -08:00
|
|
|
return std::move(__a.__elems_[_Ip]);
|
2010-11-17 10:52:17 -09:00
|
|
|
}
|
|
|
|
|
|
2015-12-17 15:36:55 -09:00
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
2025-11-24 01:32:29 -09:00
|
|
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&&
|
|
|
|
|
get(const array<_Tp, _Size>&& __a) _NOEXCEPT {
|
2015-12-17 15:36:55 -09:00
|
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)");
|
|
|
|
|
return std::move(__a.__elems_[_Ip]);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-10 06:02:12 -09:00
|
|
|
# if _LIBCPP_STD_VER >= 20
|
2020-01-30 03:27:35 -09:00
|
|
|
|
|
|
|
|
template <typename _Tp, size_t _Size, size_t... _Index>
|
|
|
|
|
_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
|
|
|
|
|
__to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) {
|
|
|
|
|
return {{__arr[_Index]...}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename _Tp, size_t _Size, size_t... _Index>
|
|
|
|
|
_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
|
|
|
|
|
__to_array_rvalue_impl(_Tp (&&__arr)[_Size], index_sequence<_Index...>) {
|
|
|
|
|
return {{std::move(__arr[_Index])...}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename _Tp, size_t _Size>
|
2025-11-24 01:32:29 -09:00
|
|
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
|
2020-01-30 03:27:35 -09:00
|
|
|
to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
|
|
|
|
|
static_assert(!is_array_v<_Tp>, "[array.creation]/1: to_array does not accept multidimensional arrays.");
|
|
|
|
|
static_assert(is_constructible_v<_Tp, _Tp&>, "[array.creation]/1: to_array requires copy constructible elements.");
|
2020-12-15 15:32:29 -09:00
|
|
|
return std::__to_array_lvalue_impl(__arr, make_index_sequence<_Size>());
|
2020-01-30 03:27:35 -09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename _Tp, size_t _Size>
|
2025-11-24 01:32:29 -09:00
|
|
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
|
2020-01-30 03:27:35 -09:00
|
|
|
to_array(_Tp (&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
|
|
|
|
|
static_assert(!is_array_v<_Tp>, "[array.creation]/4: to_array does not accept multidimensional arrays.");
|
|
|
|
|
static_assert(is_move_constructible_v<_Tp>, "[array.creation]/4: to_array requires move constructible elements.");
|
2020-12-15 15:32:29 -09:00
|
|
|
return std::__to_array_rvalue_impl(std::move(__arr), make_index_sequence<_Size>());
|
2020-01-30 03:27:35 -09:00
|
|
|
}
|
|
|
|
|
|
2024-12-10 06:02:12 -09:00
|
|
|
# endif // _LIBCPP_STD_VER >= 20
|
2020-01-30 03:27:35 -09:00
|
|
|
|
2010-05-11 11:42:16 -08:00
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
|
[libc++] Fix missing and incorrect push/pop macros (#79204)
We recently noticed that the unwrap_iter.h file was pushing macros, but
it was pushing them again instead of popping them at the end of the
file. This led to libc++ basically swallowing any custom definition of
these macros in user code:
#define min HELLO
#include <algorithm>
// min is not HELLO anymore, it's not defined
While investigating this issue, I noticed that our push/pop pragmas were
actually entirely wrong too. Indeed, instead of pushing macros like
`move`, we'd push `move(int, int)` in the pragma, which is not a valid
macro name. As a result, we would not actually push macros like `move`
-- instead we'd simply undefine them. This led to the following code not
working:
#define move HELLO
#include <algorithm>
// move is not HELLO anymore
Fixing the pragma push/pop incantations led to a cascade of issues
because we use identifiers like `move` in a large number of places, and
all of these headers would now need to do the push/pop dance.
This patch fixes all these issues. First, it adds a check that we don't
swallow important names like min, max, move or refresh as explained
above. This is done by augmenting the existing
system_reserved_names.gen.py test to also check that the macros are what
we expect after including each header.
Second, it fixes the push/pop pragmas to work properly and adds missing
pragmas to all the files I could detect a failure in via the newly added
test.
rdar://121365472
2024-01-25 11:48:46 -09:00
|
|
|
_LIBCPP_POP_MACROS
|
|
|
|
|
|
2026-06-04 23:45:49 -08:00
|
|
|
# if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 20
|
2024-12-10 06:02:12 -09:00
|
|
|
# include <algorithm>
|
|
|
|
|
# include <concepts>
|
|
|
|
|
# include <cstdlib>
|
|
|
|
|
# include <iterator>
|
2024-12-13 10:17:56 -09:00
|
|
|
# include <new>
|
2025-04-19 03:12:43 -08:00
|
|
|
# include <optional>
|
2024-12-10 06:02:12 -09:00
|
|
|
# include <type_traits>
|
|
|
|
|
# include <utility>
|
|
|
|
|
# endif
|
2024-12-21 03:01:48 -09:00
|
|
|
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
2022-09-02 07:53:28 -08:00
|
|
|
|
2021-04-20 08:03:32 -08:00
|
|
|
#endif // _LIBCPP_ARRAY
|