summaryrefslogtreecommitdiff
path: root/kernel/lib/libcxx/include/span
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lib/libcxx/include/span')
-rw-r--r--kernel/lib/libcxx/include/span216
1 files changed, 216 insertions, 0 deletions
diff --git a/kernel/lib/libcxx/include/span b/kernel/lib/libcxx/include/span
new file mode 100644
index 0000000..3e4c3ee
--- /dev/null
+++ b/kernel/lib/libcxx/include/span
@@ -0,0 +1,216 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the BastionOS freestanding C++ standard library.
+//
+// std::span — non-owning contiguous view.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBBASTION_SPAN
+#define _LIBBASTION_SPAN
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/type_modifications.h>
+#include <__type_traits/type_relationships.h>
+#include <array>
+#include <cstddef>
+
+_LIBBASTION_BEGIN_NAMESPACE_STD
+
+inline constexpr size_t dynamic_extent = static_cast<size_t>(-1);
+
+// ── span — dynamic extent ───────────────────────────────────────────────────
+
+template<class _Tp, size_t _Extent = dynamic_extent>
+class span;
+
+template<class _Tp>
+class span<_Tp, dynamic_extent> {
+public:
+ using element_type = _Tp;
+ using value_type = remove_cv_t<_Tp>;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using pointer = _Tp*;
+ using const_pointer = const _Tp*;
+ using reference = _Tp&;
+ using const_reference = const _Tp&;
+ using iterator = _Tp*;
+ using const_iterator = const _Tp*;
+
+ static constexpr size_type extent = dynamic_extent;
+
+ // Constructors
+ constexpr span() noexcept : __data_(nullptr), __size_(0) {}
+ constexpr span(_Tp* __ptr, size_type __count) noexcept : __data_(__ptr), __size_(__count) {}
+ constexpr span(_Tp* __first, _Tp* __last) noexcept : __data_(__first), __size_(static_cast<size_type>(__last - __first)) {}
+
+ template<size_t _Np>
+ constexpr span(_Tp (&__arr)[_Np]) noexcept : __data_(__arr), __size_(_Np) {}
+
+ template<class _Up, size_t _Np>
+ requires is_convertible_v<_Up(*)[], _Tp(*)[]>
+ constexpr span(array<_Up, _Np>& __arr) noexcept : __data_(__arr.data()), __size_(_Np) {}
+
+ template<class _Up, size_t _Np>
+ requires is_convertible_v<const _Up(*)[], _Tp(*)[]>
+ constexpr span(const array<_Up, _Np>& __arr) noexcept : __data_(__arr.data()), __size_(_Np) {}
+
+ // From other span
+ template<class _Up, size_t _OtherExtent>
+ requires is_convertible_v<_Up(*)[], _Tp(*)[]>
+ constexpr span(const span<_Up, _OtherExtent>& __other) noexcept
+ : __data_(__other.data()), __size_(__other.size()) {}
+
+ constexpr span(const span&) noexcept = default;
+ constexpr span& operator=(const span&) noexcept = default;
+
+ // Element access
+ _LIBBASTION_NODISCARD constexpr reference operator[](size_type __idx) const { return __data_[__idx]; }
+ _LIBBASTION_NODISCARD constexpr reference front() const { return __data_[0]; }
+ _LIBBASTION_NODISCARD constexpr reference back() const { return __data_[__size_ - 1]; }
+ _LIBBASTION_NODISCARD constexpr pointer data() const noexcept { return __data_; }
+
+ // Iterators
+ _LIBBASTION_NODISCARD constexpr iterator begin() const noexcept { return __data_; }
+ _LIBBASTION_NODISCARD constexpr iterator end() const noexcept { return __data_ + __size_; }
+ _LIBBASTION_NODISCARD constexpr const_iterator cbegin() const noexcept { return __data_; }
+ _LIBBASTION_NODISCARD constexpr const_iterator cend() const noexcept { return __data_ + __size_; }
+
+ // Capacity
+ _LIBBASTION_NODISCARD constexpr size_type size() const noexcept { return __size_; }
+ _LIBBASTION_NODISCARD constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(_Tp); }
+ _LIBBASTION_NODISCARD constexpr bool empty() const noexcept { return __size_ == 0; }
+
+ // Subviews
+ constexpr span first(size_type __count) const { return span(__data_, __count); }
+ constexpr span last(size_type __count) const { return span(__data_ + __size_ - __count, __count); }
+
+ constexpr span subspan(size_type __offset, size_type __count = dynamic_extent) const {
+ return span(__data_ + __offset, __count == dynamic_extent ? __size_ - __offset : __count);
+ }
+
+ template<size_t _Count>
+ constexpr span<_Tp, _Count> first() const { return span<_Tp, _Count>(__data_, _Count); }
+
+ template<size_t _Count>
+ constexpr span<_Tp, _Count> last() const { return span<_Tp, _Count>(__data_ + __size_ - _Count, _Count); }
+
+private:
+ pointer __data_;
+ size_type __size_;
+};
+
+// ── span — static extent ────────────────────────────────────────────────────
+
+template<class _Tp, size_t _Extent>
+class span {
+public:
+ using element_type = _Tp;
+ using value_type = remove_cv_t<_Tp>;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using pointer = _Tp*;
+ using const_pointer = const _Tp*;
+ using reference = _Tp&;
+ using const_reference = const _Tp&;
+ using iterator = _Tp*;
+ using const_iterator = const _Tp*;
+
+ static constexpr size_type extent = _Extent;
+
+ // Constructors
+ constexpr span() noexcept requires (_Extent == 0) : __data_(nullptr) {}
+ constexpr span(_Tp* __ptr, size_type) noexcept : __data_(__ptr) {}
+ constexpr span(_Tp* __first, _Tp*) noexcept : __data_(__first) {}
+
+ constexpr span(_Tp (&__arr)[_Extent]) noexcept : __data_(__arr) {}
+
+ template<class _Up>
+ requires is_convertible_v<_Up(*)[], _Tp(*)[]>
+ constexpr span(array<_Up, _Extent>& __arr) noexcept : __data_(__arr.data()) {}
+
+ template<class _Up>
+ requires is_convertible_v<const _Up(*)[], _Tp(*)[]>
+ constexpr span(const array<_Up, _Extent>& __arr) noexcept : __data_(__arr.data()) {}
+
+ // From dynamic span
+ template<class _Up>
+ requires is_convertible_v<_Up(*)[], _Tp(*)[]>
+ constexpr span(const span<_Up, dynamic_extent>& __other) noexcept : __data_(__other.data()) {}
+
+ // From other static span
+ template<class _Up, size_t _OtherExtent>
+ requires (_OtherExtent == _Extent) && is_convertible_v<_Up(*)[], _Tp(*)[]>
+ constexpr span(const span<_Up, _OtherExtent>& __other) noexcept : __data_(__other.data()) {}
+
+ constexpr span(const span&) noexcept = default;
+ constexpr span& operator=(const span&) noexcept = default;
+
+ // Element access
+ _LIBBASTION_NODISCARD constexpr reference operator[](size_type __idx) const { return __data_[__idx]; }
+ _LIBBASTION_NODISCARD constexpr reference front() const { return __data_[0]; }
+ _LIBBASTION_NODISCARD constexpr reference back() const { return __data_[_Extent - 1]; }
+ _LIBBASTION_NODISCARD constexpr pointer data() const noexcept { return __data_; }
+
+ // Iterators
+ _LIBBASTION_NODISCARD constexpr iterator begin() const noexcept { return __data_; }
+ _LIBBASTION_NODISCARD constexpr iterator end() const noexcept { return __data_ + _Extent; }
+ _LIBBASTION_NODISCARD constexpr const_iterator cbegin() const noexcept { return __data_; }
+ _LIBBASTION_NODISCARD constexpr const_iterator cend() const noexcept { return __data_ + _Extent; }
+
+ // Capacity
+ _LIBBASTION_NODISCARD constexpr size_type size() const noexcept { return _Extent; }
+ _LIBBASTION_NODISCARD constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(_Tp); }
+ _LIBBASTION_NODISCARD constexpr bool empty() const noexcept { return _Extent == 0; }
+
+ // Subviews
+ constexpr span<_Tp, dynamic_extent> first(size_type __count) const {
+ return span<_Tp, dynamic_extent>(__data_, __count);
+ }
+ constexpr span<_Tp, dynamic_extent> last(size_type __count) const {
+ return span<_Tp, dynamic_extent>(__data_ + _Extent - __count, __count);
+ }
+ constexpr span<_Tp, dynamic_extent> subspan(size_type __offset, size_type __count = dynamic_extent) const {
+ return span<_Tp, dynamic_extent>(__data_ + __offset, __count == dynamic_extent ? _Extent - __offset : __count);
+ }
+
+ template<size_t _Count>
+ constexpr span<_Tp, _Count> first() const { return span<_Tp, _Count>(__data_, _Count); }
+
+ template<size_t _Count>
+ constexpr span<_Tp, _Count> last() const { return span<_Tp, _Count>(__data_ + _Extent - _Count, _Count); }
+
+private:
+ pointer __data_;
+};
+
+// Deduction guides
+template<class _Tp, size_t _Np>
+span(_Tp (&)[_Np]) -> span<_Tp, _Np>;
+
+template<class _Tp, size_t _Np>
+span(array<_Tp, _Np>&) -> span<_Tp, _Np>;
+
+template<class _Tp, size_t _Np>
+span(const array<_Tp, _Np>&) -> span<const _Tp, _Np>;
+
+// as_bytes / as_writable_bytes
+template<class _Tp, size_t _Extent>
+span<const byte, _Extent == dynamic_extent ? dynamic_extent : sizeof(_Tp) * _Extent>
+as_bytes(span<_Tp, _Extent> __sp) noexcept {
+ return {reinterpret_cast<const byte*>(__sp.data()), __sp.size_bytes()};
+}
+
+template<class _Tp, size_t _Extent>
+ requires (!__is_const(_Tp))
+span<byte, _Extent == dynamic_extent ? dynamic_extent : sizeof(_Tp) * _Extent>
+as_writable_bytes(span<_Tp, _Extent> __sp) noexcept {
+ return {reinterpret_cast<byte*>(__sp.data()), __sp.size_bytes()};
+}
+
+_LIBBASTION_END_NAMESPACE_STD
+
+#endif // _LIBBASTION_SPAN