v8 12.4.254 (node 22.4.1)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
v8-memory-span.h
Go to the documentation of this file.
1// Copyright 2021 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef INCLUDE_V8_MEMORY_SPAN_H_
6#define INCLUDE_V8_MEMORY_SPAN_H_
7
8#include <stddef.h>
9
10#include <array>
11#include <iterator>
12#include <type_traits>
13
14#include "v8config.h" // NOLINT(build/include_directory)
15
16namespace v8 {
17
28template <typename T>
30 private:
32 template <typename From, typename To>
33 using is_array_convertible = std::is_convertible<From (*)[], To (*)[]>;
34 template <typename From, typename To>
35 static constexpr bool is_array_convertible_v =
36 is_array_convertible<From, To>::value;
37
38 template <typename It>
39 using iter_reference_t = decltype(*std::declval<It&>());
40
41 template <typename It, typename = void>
42 struct is_compatible_iterator : std::false_type {};
43 template <typename It>
44 struct is_compatible_iterator<
45 It,
46 std::void_t<
47 std::is_base_of<std::random_access_iterator_tag,
48 typename std::iterator_traits<It>::iterator_category>,
49 is_array_convertible<std::remove_reference_t<iter_reference_t<It>>,
50 T>>> : std::true_type {};
51 template <typename It>
52 static constexpr bool is_compatible_iterator_v =
53 is_compatible_iterator<It>::value;
54
55 template <typename U>
56 static constexpr U* to_address(U* p) noexcept {
57 return p;
58 }
59
60 template <typename It,
61 typename = std::void_t<decltype(std::declval<It&>().operator->())>>
62 static constexpr auto to_address(It it) noexcept {
63 return it.operator->();
64 }
65
66 public:
68 constexpr MemorySpan() = default;
69
73 constexpr MemorySpan(std::nullptr_t, size_t) {}
74
76 template <typename Iterator,
77 std::enable_if_t<is_compatible_iterator_v<Iterator>, bool> = true>
78 constexpr MemorySpan(Iterator first,
79 size_t count) // NOLINT(runtime/explicit)
80 : data_(to_address(first)), size_(count) {}
81
83 template <typename Iterator,
84 std::enable_if_t<is_compatible_iterator_v<Iterator> &&
85 !std::is_convertible_v<Iterator, size_t>,
86 bool> = true>
87 constexpr MemorySpan(Iterator first,
88 Iterator last) // NOLINT(runtime/explicit)
89 : data_(to_address(first)), size_(last - first) {}
90
92 template <size_t N>
93 constexpr MemorySpan(T (&a)[N]) noexcept // NOLINT(runtime/explicit)
94 : data_(a), size_(N) {}
95
97 template <typename U, size_t N,
98 std::enable_if_t<is_array_convertible_v<U, T>, bool> = true>
99 constexpr MemorySpan(
100 std::array<U, N>& a) noexcept // NOLINT(runtime/explicit)
101 : data_(a.data()), size_{N} {}
102
104 template <typename U, size_t N,
105 std::enable_if_t<is_array_convertible_v<const U, T>, bool> = true>
106 constexpr MemorySpan(
107 const std::array<U, N>& a) noexcept // NOLINT(runtime/explicit)
108 : data_(a.data()), size_{N} {}
109
111 constexpr T* data() const { return data_; }
113 constexpr size_t size() const { return size_; }
114
115 constexpr T& operator[](size_t i) const { return data_[i]; }
116
118 constexpr bool empty() const { return size() == 0; }
119
120 class Iterator {
121 public:
122 using iterator_category = std::forward_iterator_tag;
123 using value_type = T;
124 using difference_type = std::ptrdiff_t;
127
128 T& operator*() const { return *ptr_; }
129 T* operator->() const { return ptr_; }
130
131 bool operator==(Iterator other) const { return ptr_ == other.ptr_; }
132 bool operator!=(Iterator other) const { return !(*this == other); }
133
135 ++ptr_;
136 return *this;
137 }
138
139 Iterator operator++(int) {
140 Iterator temp(*this);
141 ++(*this);
142 return temp;
143 }
144
145 private:
146 friend class MemorySpan<T>;
147
148 explicit Iterator(T* ptr) : ptr_(ptr) {}
149
150 T* ptr_ = nullptr;
151 };
152
153 Iterator begin() const { return Iterator(data_); }
154 Iterator end() const { return Iterator(data_ + size_); }
155
156 private:
157 T* data_ = nullptr;
158 size_t size_ = 0;
159};
160
172namespace detail {
173template <class T, std::size_t N, std::size_t... I>
174constexpr std::array<std::remove_cv_t<T>, N> to_array_lvalue_impl(
175 T (&a)[N], std::index_sequence<I...>) {
176 return {{a[I]...}};
177}
178
179template <class T, std::size_t N, std::size_t... I>
180constexpr std::array<std::remove_cv_t<T>, N> to_array_rvalue_impl(
181 T (&&a)[N], std::index_sequence<I...>) {
182 return {{std::move(a[I])...}};
183}
184} // namespace detail
185
186template <class T, std::size_t N>
187constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&a)[N]) {
188 return detail::to_array_lvalue_impl(a, std::make_index_sequence<N>{});
189}
190
191template <class T, std::size_t N>
192constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&&a)[N]) {
193 return detail::to_array_rvalue_impl(std::move(a),
194 std::make_index_sequence<N>{});
195}
196
197} // namespace v8
198#endif // INCLUDE_V8_MEMORY_SPAN_H_
std::forward_iterator_tag iterator_category
bool operator==(Iterator other) const
bool operator!=(Iterator other) const
std::ptrdiff_t difference_type
Iterator begin() const
constexpr T * data() const
constexpr T & operator[](size_t i) const
constexpr MemorySpan(std::array< U, N > &a) noexcept
Iterator end() const
constexpr MemorySpan(std::nullptr_t, size_t)
constexpr MemorySpan(const std::array< U, N > &a) noexcept
constexpr MemorySpan()=default
constexpr MemorySpan(T(&a)[N]) noexcept
constexpr size_t size() const
constexpr MemorySpan(Iterator first, size_t count)
constexpr MemorySpan(Iterator first, Iterator last)
constexpr bool empty() const
constexpr std::array< std::remove_cv_t< T >, N > to_array_rvalue_impl(T(&&a)[N], std::index_sequence< I... >)
constexpr std::array< std::remove_cv_t< T >, N > to_array_lvalue_impl(T(&a)[N], std::index_sequence< I... >)
constexpr std::array< std::remove_cv_t< T >, N > to_array(T(&a)[N])
#define V8_EXPORT
Definition v8config.h:753