diff options
| author | Arseney300 <Arseney300@gmail.com> | 2026-04-12 02:01:25 +0700 |
|---|---|---|
| committer | Arseney300 <Arseney300@gmail.com> | 2026-04-12 02:01:25 +0700 |
| commit | 2496ffd6d97c3ccd3e325687442d31ab035479a1 (patch) | |
| tree | 5d176669f823182fe74261f076dc11c8e8f88025 /kernel/lib/libcxx/include | |
| parent | 496246c92dabe6757480147016490ea6ae43bb66 (diff) | |
bastion: add freestanding C++ standard library (libcxx)feature/freestanding-libcxx
Header-only implementation of a C++ standard library subset for the
freestanding kernel, using Clang builtins wherever possible. Provides
19 public headers (~35 internal files): type_traits, utility, memory,
algorithm, functional, concepts, array, string_view, span, optional,
expected, variant, tuple, bit, limits, new, initializer_list, cstdint,
cstddef, and source_location.
Integration changes:
- kernel/Makefile: add -Ilib/libcxx/include to include path
- kernel/lib/string.cpp: add memchr and strncmp (needed by string_view)
- kernel/lib/cxxabi.cpp: guard placement new against <new> header conflict
- kernel/include/kernel/kernel.h: Panic() now uses std::source_location
- kernel/core/kernel.cpp: Panic() implementation updated to match
Builds cleanly on both x86_64 and aarch64 with zero new warnings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'kernel/lib/libcxx/include')
56 files changed, 5436 insertions, 0 deletions
diff --git a/kernel/lib/libcxx/include/__algorithm/bound.h b/kernel/lib/libcxx/include/__algorithm/bound.h new file mode 100644 index 0000000..560104b --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/bound.h @@ -0,0 +1,89 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_BOUND_H +#define _LIBBASTION_ALGORITHM_BOUND_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _ForwardIt, class _Tp> +_LIBBASTION_NODISCARD constexpr _ForwardIt lower_bound(_ForwardIt __first, _ForwardIt __last, const _Tp& __val) { + auto __len = __last - __first; + while (__len > 0) { + auto __half = __len / 2; + auto __mid = __first; + __mid += __half; + if (*__mid < __val) { + __first = __mid; + ++__first; + __len -= __half + 1; + } else { + __len = __half; + } + } + return __first; +} + +template<class _ForwardIt, class _Tp, class _Compare> +_LIBBASTION_NODISCARD constexpr _ForwardIt lower_bound(_ForwardIt __first, _ForwardIt __last, const _Tp& __val, _Compare __comp) { + auto __len = __last - __first; + while (__len > 0) { + auto __half = __len / 2; + auto __mid = __first; + __mid += __half; + if (__comp(*__mid, __val)) { + __first = __mid; + ++__first; + __len -= __half + 1; + } else { + __len = __half; + } + } + return __first; +} + +template<class _ForwardIt, class _Tp> +_LIBBASTION_NODISCARD constexpr _ForwardIt upper_bound(_ForwardIt __first, _ForwardIt __last, const _Tp& __val) { + auto __len = __last - __first; + while (__len > 0) { + auto __half = __len / 2; + auto __mid = __first; + __mid += __half; + if (!(__val < *__mid)) { + __first = __mid; + ++__first; + __len -= __half + 1; + } else { + __len = __half; + } + } + return __first; +} + +template<class _ForwardIt, class _Tp, class _Compare> +_LIBBASTION_NODISCARD constexpr _ForwardIt upper_bound(_ForwardIt __first, _ForwardIt __last, const _Tp& __val, _Compare __comp) { + auto __len = __last - __first; + while (__len > 0) { + auto __half = __len / 2; + auto __mid = __first; + __mid += __half; + if (!__comp(__val, *__mid)) { + __first = __mid; + ++__first; + __len -= __half + 1; + } else { + __len = __half; + } + } + return __first; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_BOUND_H diff --git a/kernel/lib/libcxx/include/__algorithm/comparison.h b/kernel/lib/libcxx/include/__algorithm/comparison.h new file mode 100644 index 0000000..8c8799c --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/comparison.h @@ -0,0 +1,75 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_COMPARISON_H +#define _LIBBASTION_ALGORITHM_COMPARISON_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _InputIt1, class _InputIt2> +_LIBBASTION_NODISCARD constexpr bool equal(_InputIt1 __first1, _InputIt1 __last1, _InputIt2 __first2) { + for (; __first1 != __last1; ++__first1, ++__first2) + if (!(*__first1 == *__first2)) + return false; + return true; +} + +template<class _InputIt1, class _InputIt2, class _BinPred> +_LIBBASTION_NODISCARD constexpr bool equal(_InputIt1 __first1, _InputIt1 __last1, _InputIt2 __first2, _BinPred __pred) { + for (; __first1 != __last1; ++__first1, ++__first2) + if (!__pred(*__first1, *__first2)) + return false; + return true; +} + +template<class _InputIt, class _Pred> +_LIBBASTION_NODISCARD constexpr bool all_of(_InputIt __first, _InputIt __last, _Pred __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + return false; + return true; +} + +template<class _InputIt, class _Pred> +_LIBBASTION_NODISCARD constexpr bool any_of(_InputIt __first, _InputIt __last, _Pred __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + return true; + return false; +} + +template<class _InputIt, class _Pred> +_LIBBASTION_NODISCARD constexpr bool none_of(_InputIt __first, _InputIt __last, _Pred __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; +} + +template<class _InputIt, class _Tp> +_LIBBASTION_NODISCARD constexpr auto count(_InputIt __first, _InputIt __last, const _Tp& __val) { + decltype(__last - __first) __ret = 0; + for (; __first != __last; ++__first) + if (*__first == __val) + ++__ret; + return __ret; +} + +template<class _InputIt, class _Pred> +_LIBBASTION_NODISCARD constexpr auto count_if(_InputIt __first, _InputIt __last, _Pred __pred) { + decltype(__last - __first) __ret = 0; + for (; __first != __last; ++__first) + if (__pred(*__first)) + ++__ret; + return __ret; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_COMPARISON_H diff --git a/kernel/lib/libcxx/include/__algorithm/copy.h b/kernel/lib/libcxx/include/__algorithm/copy.h new file mode 100644 index 0000000..e4251f6 --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/copy.h @@ -0,0 +1,53 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_COPY_H +#define _LIBBASTION_ALGORITHM_COPY_H + +#include <__config> +#include <__utility/move.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _InputIt, class _OutputIt> +constexpr _OutputIt copy(_InputIt __first, _InputIt __last, _OutputIt __d_first) { + for (; __first != __last; ++__first, ++__d_first) + *__d_first = *__first; + return __d_first; +} + +template<class _InputIt, class _Size, class _OutputIt> +constexpr _OutputIt copy_n(_InputIt __first, _Size __count, _OutputIt __result) { + for (_Size __i = 0; __i < __count; ++__i, ++__first, ++__result) + *__result = *__first; + return __result; +} + +template<class _InputIt, class _OutputIt> +constexpr _OutputIt copy_backward(_InputIt __first, _InputIt __last, _OutputIt __d_last) { + while (__first != __last) + *(--__d_last) = *(--__last); + return __d_last; +} + +template<class _InputIt, class _OutputIt> +constexpr _OutputIt move(_InputIt __first, _InputIt __last, _OutputIt __d_first) { + for (; __first != __last; ++__first, ++__d_first) + *__d_first = std::move(*__first); + return __d_first; +} + +template<class _InputIt, class _OutputIt> +constexpr _OutputIt move_backward(_InputIt __first, _InputIt __last, _OutputIt __d_last) { + while (__first != __last) + *(--__d_last) = std::move(*(--__last)); + return __d_last; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_COPY_H diff --git a/kernel/lib/libcxx/include/__algorithm/fill.h b/kernel/lib/libcxx/include/__algorithm/fill.h new file mode 100644 index 0000000..be09b1c --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/fill.h @@ -0,0 +1,30 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_FILL_H +#define _LIBBASTION_ALGORITHM_FILL_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _ForwardIt, class _Tp> +constexpr void fill(_ForwardIt __first, _ForwardIt __last, const _Tp& __val) { + for (; __first != __last; ++__first) + *__first = __val; +} + +template<class _OutputIt, class _Size, class _Tp> +constexpr _OutputIt fill_n(_OutputIt __first, _Size __count, const _Tp& __val) { + for (_Size __i = 0; __i < __count; ++__i, ++__first) + *__first = __val; + return __first; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_FILL_H diff --git a/kernel/lib/libcxx/include/__algorithm/find.h b/kernel/lib/libcxx/include/__algorithm/find.h new file mode 100644 index 0000000..c47b914 --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/find.h @@ -0,0 +1,41 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_FIND_H +#define _LIBBASTION_ALGORITHM_FIND_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _InputIt, class _Tp> +_LIBBASTION_NODISCARD constexpr _InputIt find(_InputIt __first, _InputIt __last, const _Tp& __val) { + for (; __first != __last; ++__first) + if (*__first == __val) + return __first; + return __last; +} + +template<class _InputIt, class _Pred> +_LIBBASTION_NODISCARD constexpr _InputIt find_if(_InputIt __first, _InputIt __last, _Pred __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + return __first; + return __last; +} + +template<class _InputIt, class _Pred> +_LIBBASTION_NODISCARD constexpr _InputIt find_if_not(_InputIt __first, _InputIt __last, _Pred __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + return __first; + return __last; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_FIND_H diff --git a/kernel/lib/libcxx/include/__algorithm/for_each.h b/kernel/lib/libcxx/include/__algorithm/for_each.h new file mode 100644 index 0000000..af9a762 --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/for_each.h @@ -0,0 +1,31 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_FOR_EACH_H +#define _LIBBASTION_ALGORITHM_FOR_EACH_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _InputIt, class _UnaryFunc> +constexpr _UnaryFunc for_each(_InputIt __first, _InputIt __last, _UnaryFunc __f) { + for (; __first != __last; ++__first) + __f(*__first); + return __f; +} + +template<class _InputIt, class _Size, class _UnaryFunc> +constexpr _InputIt for_each_n(_InputIt __first, _Size __n, _UnaryFunc __f) { + for (_Size __i = 0; __i < __n; ++__first, ++__i) + __f(*__first); + return __first; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_FOR_EACH_H diff --git a/kernel/lib/libcxx/include/__algorithm/minmax.h b/kernel/lib/libcxx/include/__algorithm/minmax.h new file mode 100644 index 0000000..b28d66c --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/minmax.h @@ -0,0 +1,76 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_MINMAX_H +#define _LIBBASTION_ALGORITHM_MINMAX_H + +#include <__config> +#include <initializer_list> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── min ───────────────────────────────────────────────────────────────────── + +template<class _Tp> +_LIBBASTION_NODISCARD constexpr const _Tp& min(const _Tp& __a, const _Tp& __b) { + return (__b < __a) ? __b : __a; +} + +template<class _Tp, class _Compare> +_LIBBASTION_NODISCARD constexpr const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? __b : __a; +} + +template<class _Tp> +_LIBBASTION_NODISCARD constexpr _Tp min(initializer_list<_Tp> __il) { + const _Tp* __first = __il.begin(); + const _Tp* __last = __il.end(); + const _Tp* __result = __first; + for (++__first; __first != __last; ++__first) + if (*__first < *__result) + __result = __first; + return *__result; +} + +// ── max ───────────────────────────────────────────────────────────────────── + +template<class _Tp> +_LIBBASTION_NODISCARD constexpr const _Tp& max(const _Tp& __a, const _Tp& __b) { + return (__a < __b) ? __b : __a; +} + +template<class _Tp, class _Compare> +_LIBBASTION_NODISCARD constexpr const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__a, __b) ? __b : __a; +} + +template<class _Tp> +_LIBBASTION_NODISCARD constexpr _Tp max(initializer_list<_Tp> __il) { + const _Tp* __first = __il.begin(); + const _Tp* __last = __il.end(); + const _Tp* __result = __first; + for (++__first; __first != __last; ++__first) + if (*__result < *__first) + __result = __first; + return *__result; +} + +// ── clamp ─────────────────────────────────────────────────────────────────── + +template<class _Tp> +_LIBBASTION_NODISCARD constexpr const _Tp& clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) { + return (__v < __lo) ? __lo : (__hi < __v) ? __hi : __v; +} + +template<class _Tp, class _Compare> +_LIBBASTION_NODISCARD constexpr const _Tp& clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) { + return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_MINMAX_H diff --git a/kernel/lib/libcxx/include/__algorithm/sort.h b/kernel/lib/libcxx/include/__algorithm/sort.h new file mode 100644 index 0000000..22c7b33 --- /dev/null +++ b/kernel/lib/libcxx/include/__algorithm/sort.h @@ -0,0 +1,62 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Insertion sort — simple, stable, good for small arrays (typical in kernel). +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM_SORT_H +#define _LIBBASTION_ALGORITHM_SORT_H + +#include <__config> +#include <__utility/move.h> +#include <__utility/swap.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _RandomIt> +constexpr void sort(_RandomIt __first, _RandomIt __last) { + for (auto __i = __first; __i != __last; ++__i) { + auto __key = std::move(*__i); + auto __j = __i; + while (__j != __first) { + auto __prev = __j; + --__prev; + if (!(__key < *__prev)) break; + *__j = std::move(*__prev); + __j = __prev; + } + *__j = std::move(__key); + } +} + +template<class _RandomIt, class _Compare> +constexpr void sort(_RandomIt __first, _RandomIt __last, _Compare __comp) { + for (auto __i = __first; __i != __last; ++__i) { + auto __key = std::move(*__i); + auto __j = __i; + while (__j != __first) { + auto __prev = __j; + --__prev; + if (!__comp(__key, *__prev)) break; + *__j = std::move(*__prev); + __j = __prev; + } + *__j = std::move(__key); + } +} + +template<class _BidirIt> +constexpr void reverse(_BidirIt __first, _BidirIt __last) { + while (__first != __last && __first != --__last) { + using std::swap; + swap(*__first, *__last); + ++__first; + } +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM_SORT_H diff --git a/kernel/lib/libcxx/include/__bit/bit.h b/kernel/lib/libcxx/include/__bit/bit.h new file mode 100644 index 0000000..2a778f6 --- /dev/null +++ b/kernel/lib/libcxx/include/__bit/bit.h @@ -0,0 +1,168 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Bit manipulation utilities — all backed by compiler builtins. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_BIT_BIT_H +#define _LIBBASTION_BIT_BIT_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/primary_categories.h> +#include <__type_traits/type_properties.h> +#include <cstdint> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── endian ────────────────────────────────────────────────────────────────── + +enum class endian { +#if defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__) + little = __ORDER_LITTLE_ENDIAN__, + big = __ORDER_BIG_ENDIAN__, + native = __BYTE_ORDER__, +#else + little = 0, + big = 1, + native = 0, // assume little-endian +#endif +}; + +// ── bit_cast ──────────────────────────────────────────────────────────────── + +template<class _To, class _From> +_LIBBASTION_NODISCARD constexpr _To bit_cast(const _From& __from) noexcept { + static_assert(sizeof(_To) == sizeof(_From), "bit_cast requires same size types"); + static_assert(__is_trivially_copyable(_To), "bit_cast target must be trivially copyable"); + static_assert(__is_trivially_copyable(_From), "bit_cast source must be trivially copyable"); + return __builtin_bit_cast(_To, __from); +} + +// ── Helpers for unsigned integer operations ───────────────────────────────── + +namespace __detail { + +template<class _Tp> +concept __unsigned_integer = is_unsigned_v<_Tp> && is_integral_v<_Tp> && !__is_same(_Tp, bool); + +} // namespace __detail + +// ── countl_zero / countl_one ──────────────────────────────────────────────── + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr int countl_zero(_Tp __x) noexcept { + if (__x == 0) return static_cast<int>(sizeof(_Tp) * __CHAR_BIT__); + if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) + return __builtin_clz(static_cast<unsigned int>(__x)) - (sizeof(unsigned int) - sizeof(_Tp)) * __CHAR_BIT__; + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) + return __builtin_clzl(static_cast<unsigned long>(__x)); + else + return __builtin_clzll(static_cast<unsigned long long>(__x)); +} + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr int countl_one(_Tp __x) noexcept { + return countl_zero(static_cast<_Tp>(~__x)); +} + +// ── countr_zero / countr_one ──────────────────────────────────────────────── + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr int countr_zero(_Tp __x) noexcept { + if (__x == 0) return static_cast<int>(sizeof(_Tp) * __CHAR_BIT__); + if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) + return __builtin_ctz(static_cast<unsigned int>(__x)); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) + return __builtin_ctzl(static_cast<unsigned long>(__x)); + else + return __builtin_ctzll(static_cast<unsigned long long>(__x)); +} + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr int countr_one(_Tp __x) noexcept { + return countr_zero(static_cast<_Tp>(~__x)); +} + +// ── popcount ──────────────────────────────────────────────────────────────── + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr int popcount(_Tp __x) noexcept { + if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) + return __builtin_popcount(static_cast<unsigned int>(__x)); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) + return __builtin_popcountl(static_cast<unsigned long>(__x)); + else + return __builtin_popcountll(static_cast<unsigned long long>(__x)); +} + +// ── has_single_bit ────────────────────────────────────────────────────────── + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr bool has_single_bit(_Tp __x) noexcept { + return __x != 0 && (__x & (__x - 1)) == 0; +} + +// ── bit_width ─────────────────────────────────────────────────────────────── + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr int bit_width(_Tp __x) noexcept { + return static_cast<int>(sizeof(_Tp) * __CHAR_BIT__) - countl_zero(__x); +} + +// ── bit_ceil / bit_floor ──────────────────────────────────────────────────── + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr _Tp bit_ceil(_Tp __x) noexcept { + if (__x <= 1) return _Tp(1); + return _Tp(1) << bit_width(static_cast<_Tp>(__x - 1)); +} + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr _Tp bit_floor(_Tp __x) noexcept { + if (__x == 0) return 0; + return _Tp(1) << (bit_width(__x) - 1); +} + +// ── rotl / rotr ───────────────────────────────────────────────────────────── + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr _Tp rotl(_Tp __x, int __s) noexcept { + constexpr int _Nd = sizeof(_Tp) * __CHAR_BIT__; + int __r = __s % _Nd; + if (__r == 0) return __x; + if (__r < 0) return rotr(__x, -__r); + return static_cast<_Tp>((__x << __r) | (__x >> (_Nd - __r))); +} + +template<__detail::__unsigned_integer _Tp> +_LIBBASTION_NODISCARD constexpr _Tp rotr(_Tp __x, int __s) noexcept { + constexpr int _Nd = sizeof(_Tp) * __CHAR_BIT__; + int __r = __s % _Nd; + if (__r == 0) return __x; + if (__r < 0) return rotl(__x, -__r); + return static_cast<_Tp>((__x >> __r) | (__x << (_Nd - __r))); +} + +// ── byteswap (C++23) ─────────────────────────────────────────────────────── + +template<class _Tp> + requires is_integral_v<_Tp> +_LIBBASTION_NODISCARD constexpr _Tp byteswap(_Tp __val) noexcept { + if constexpr (sizeof(_Tp) == 1) { + return __val; + } else if constexpr (sizeof(_Tp) == 2) { + return static_cast<_Tp>(__builtin_bswap16(static_cast<uint16_t>(__val))); + } else if constexpr (sizeof(_Tp) == 4) { + return static_cast<_Tp>(__builtin_bswap32(static_cast<uint32_t>(__val))); + } else if constexpr (sizeof(_Tp) == 8) { + return static_cast<_Tp>(__builtin_bswap64(static_cast<uint64_t>(__val))); + } +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_BIT_BIT_H diff --git a/kernel/lib/libcxx/include/__config b/kernel/lib/libcxx/include/__config new file mode 100644 index 0000000..f40c971 --- /dev/null +++ b/kernel/lib/libcxx/include/__config @@ -0,0 +1,63 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// Modeled after libc++. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_CONFIG +#define _LIBBASTION_CONFIG + +// Require Clang >= 16 for the builtin set we depend on. +#if !defined(__clang__) || __clang_major__ < 16 +#error "BastionOS libcxx requires Clang >= 16" +#endif + +// C++ standard version detection. +#if __cplusplus >= 202302L +#define _LIBBASTION_STD_VER 23 +#elif __cplusplus >= 202002L +#define _LIBBASTION_STD_VER 20 +#elif __cplusplus >= 201703L +#define _LIBBASTION_STD_VER 17 +#else +#error "BastionOS libcxx requires C++17 or later" +#endif + +// Builtin detection. +#define _LIBBASTION_HAS_BUILTIN(x) __has_builtin(x) + +// Namespace macros. +#define _LIBBASTION_BEGIN_NAMESPACE_STD namespace std { +#define _LIBBASTION_END_NAMESPACE_STD } + +// All functions are effectively noexcept (no exception support). +#define _LIBBASTION_NOEXCEPT noexcept + +// Attributes. +#define _LIBBASTION_NODISCARD [[nodiscard]] +#define _LIBBASTION_NORETURN [[noreturn]] +#define _LIBBASTION_MAYBE_UNUSED [[maybe_unused]] +#define _LIBBASTION_DEPRECATED [[deprecated]] + +// Inline visibility — encourage inlining for small helpers. +#define _LIBBASTION_INLINE_VISIBILITY __attribute__((__always_inline__)) +#define _LIBBASTION_HIDE_FROM_ABI __attribute__((__visibility__("hidden"))) __attribute__((__always_inline__)) + +// Unreachable / trap. +#define _LIBBASTION_UNREACHABLE() __builtin_unreachable() +#define _LIBBASTION_TRAP() __builtin_trap() +#define _LIBBASTION_ASSERT(cond, msg) \ + do { if (!(cond)) __builtin_trap(); } while (0) + +// constexpr annotations for features added in specific standards. +#define _LIBBASTION_CONSTEXPR constexpr +#define _LIBBASTION_CONSTEXPR_SINCE_CXX20 constexpr +#if _LIBBASTION_STD_VER >= 23 +#define _LIBBASTION_CONSTEXPR_SINCE_CXX23 constexpr +#else +#define _LIBBASTION_CONSTEXPR_SINCE_CXX23 +#endif + +#endif // _LIBBASTION_CONFIG diff --git a/kernel/lib/libcxx/include/__expected/expected.h b/kernel/lib/libcxx/include/__expected/expected.h new file mode 100644 index 0000000..2266cd2 --- /dev/null +++ b/kernel/lib/libcxx/include/__expected/expected.h @@ -0,0 +1,403 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::expected (C++23) — no-exceptions version (traps on bad access). +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_EXPECTED_EXPECTED_H +#define _LIBBASTION_EXPECTED_EXPECTED_H + +#include <__config> +#include <__type_traits/construction_traits.h> +#include <__type_traits/type_modifications.h> +#include <__type_traits/type_relationships.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include <__utility/in_place.h> +#include <new> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── unexpect tag ──────────────────────────────────────────────────────────── + +struct unexpect_t { explicit unexpect_t() = default; }; +inline constexpr unexpect_t unexpect{}; + +// ── unexpected ────────────────────────────────���──────────────────────────���── + +template<class _Err> +class unexpected { + static_assert(!__is_void(_Err), "unexpected<void> is ill-formed"); +public: + constexpr unexpected(const unexpected&) = default; + constexpr unexpected(unexpected&&) = default; + + template<class _Er = _Err> + requires (!__is_same(__decay(_Er), unexpected)) && (!__is_same(__decay(_Er), in_place_t)) && + is_constructible_v<_Err, _Er> + constexpr explicit unexpected(_Er&& __e) : __val_(std::forward<_Er>(__e)) {} + + template<class... _Args> + requires is_constructible_v<_Err, _Args...> + constexpr explicit unexpected(in_place_t, _Args&&... __args) : __val_(std::forward<_Args>(__args)...) {} + + _LIBBASTION_NODISCARD constexpr _Err& error() & noexcept { return __val_; } + _LIBBASTION_NODISCARD constexpr const _Err& error() const& noexcept { return __val_; } + _LIBBASTION_NODISCARD constexpr _Err&& error() && noexcept { return std::move(__val_); } + _LIBBASTION_NODISCARD constexpr const _Err&& error() const&& noexcept { return std::move(__val_); } + + template<class _Er2> + _LIBBASTION_NODISCARD friend constexpr bool operator==(const unexpected& __x, const unexpected<_Er2>& __y) { + return __x.error() == __y.error(); + } + + constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) { + using std::swap; + swap(__val_, __other.__val_); + } + +private: + _Err __val_; +}; + +template<class _Err> +unexpected(_Err) -> unexpected<_Err>; + +// ── expected<T, E> ───────────────────────────��────────────────────────────── + +template<class _Tp, class _Err> +class expected { + static_assert(!__is_void(_Err), "expected<T, void> is ill-formed; use expected<void, E> for void value"); + static_assert(!__is_reference(_Tp), "expected<T&, E> is ill-formed"); + static_assert(!__is_reference(_Err), "expected<T, E&> is ill-formed"); + +public: + using value_type = _Tp; + using error_type = _Err; + using unexpected_type = unexpected<_Err>; + + // ── Constructors ──────────────────────────��───────────────────────── + + constexpr expected() + noexcept(is_nothrow_default_constructible_v<_Tp>) + requires is_default_constructible_v<_Tp> + : __has_val_(true) + { ::new (static_cast<void*>(&__val_)) _Tp(); } + + constexpr expected(const expected& __other) + requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> + : __has_val_(__other.__has_val_) + { + if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(__other.__val_); + else ::new (static_cast<void*>(&__err_)) _Err(__other.__err_); + } + + constexpr expected(expected&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) + requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> + : __has_val_(__other.__has_val_) + { + if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(std::move(__other.__val_)); + else ::new (static_cast<void*>(&__err_)) _Err(std::move(__other.__err_)); + } + + template<class _Up = _Tp> + requires (!__is_same(__decay(_Up), expected)) && + (!__is_same(__decay(_Up), in_place_t)) && + is_constructible_v<_Tp, _Up> + constexpr expected(_Up&& __val) : __has_val_(true) { + ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Up>(__val)); + } + + template<class _G> + requires is_constructible_v<_Err, const _G&> + constexpr expected(const unexpected<_G>& __e) : __has_val_(false) { + ::new (static_cast<void*>(&__err_)) _Err(__e.error()); + } + + template<class _G> + requires is_constructible_v<_Err, _G> + constexpr expected(unexpected<_G>&& __e) : __has_val_(false) { + ::new (static_cast<void*>(&__err_)) _Err(std::move(__e.error())); + } + + template<class... _Args> + requires is_constructible_v<_Tp, _Args...> + constexpr explicit expected(in_place_t, _Args&&... __args) : __has_val_(true) { + ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Args>(__args)...); + } + + template<class... _Args> + requires is_constructible_v<_Err, _Args...> + constexpr explicit expected(unexpect_t, _Args&&... __args) : __has_val_(false) { + ::new (static_cast<void*>(&__err_)) _Err(std::forward<_Args>(__args)...); + } + + // ── Destructor ───────────────────────��────────────────────────────── + + constexpr ~expected() + requires is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err> + = default; + + constexpr ~expected() + requires (!(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)) + { + if (__has_val_) __val_.~_Tp(); + else __err_.~_Err(); + } + + // ── Assignment ───────���───────────────────────────���────────────────── + + constexpr expected& operator=(const expected& __other) + requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && + is_copy_assignable_v<_Tp> && is_copy_assignable_v<_Err> + { + if (__has_val_ && __other.__has_val_) { + __val_ = __other.__val_; + } else if (!__has_val_ && !__other.__has_val_) { + __err_ = __other.__err_; + } else { + __destroy(); + __has_val_ = __other.__has_val_; + if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(__other.__val_); + else ::new (static_cast<void*>(&__err_)) _Err(__other.__err_); + } + return *this; + } + + constexpr expected& operator=(expected&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) + requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && + is_move_assignable_v<_Tp> && is_move_assignable_v<_Err> + { + if (__has_val_ && __other.__has_val_) { + __val_ = std::move(__other.__val_); + } else if (!__has_val_ && !__other.__has_val_) { + __err_ = std::move(__other.__err_); + } else { + __destroy(); + __has_val_ = __other.__has_val_; + if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(std::move(__other.__val_)); + else ::new (static_cast<void*>(&__err_)) _Err(std::move(__other.__err_)); + } + return *this; + } + + // ── Observers ─────────────────────────────────────────────────────── + + _LIBBASTION_NODISCARD constexpr bool has_value() const noexcept { return __has_val_; } + _LIBBASTION_NODISCARD constexpr explicit operator bool() const noexcept { return __has_val_; } + + _LIBBASTION_NODISCARD constexpr _Tp& operator*() & { return __val_; } + _LIBBASTION_NODISCARD constexpr const _Tp& operator*() const& { return __val_; } + _LIBBASTION_NODISCARD constexpr _Tp&& operator*() && { return std::move(__val_); } + _LIBBASTION_NODISCARD constexpr _Tp* operator->() { return &__val_; } + _LIBBASTION_NODISCARD constexpr const _Tp* operator->() const { return &__val_; } + + _LIBBASTION_NODISCARD constexpr _Tp& value() & { + if (!__has_val_) _LIBBASTION_TRAP(); + return __val_; + } + _LIBBASTION_NODISCARD constexpr const _Tp& value() const& { + if (!__has_val_) _LIBBASTION_TRAP(); + return __val_; + } + _LIBBASTION_NODISCARD constexpr _Tp&& value() && { + if (!__has_val_) _LIBBASTION_TRAP(); + return std::move(__val_); + } + + _LIBBASTION_NODISCARD constexpr _Err& error() & { return __err_; } + _LIBBASTION_NODISCARD constexpr const _Err& error() const& { return __err_; } + _LIBBASTION_NODISCARD constexpr _Err&& error() && { return std::move(__err_); } + + template<class _Up> + _LIBBASTION_NODISCARD constexpr _Tp value_or(_Up&& __default_val) const& { + return __has_val_ ? __val_ : static_cast<_Tp>(std::forward<_Up>(__default_val)); + } + template<class _Up> + _LIBBASTION_NODISCARD constexpr _Tp value_or(_Up&& __default_val) && { + return __has_val_ ? std::move(__val_) : static_cast<_Tp>(std::forward<_Up>(__default_val)); + } + + // ── Monadic operations (C++23) ───────────────────────��────────────── + + template<class _Fn> + constexpr auto and_then(_Fn&& __f) & { + if (__has_val_) return std::forward<_Fn>(__f)(__val_); + using _Result = __decay(decltype(std::forward<_Fn>(__f)(__val_))); + return _Result(unexpect, __err_); + } + + template<class _Fn> + constexpr auto and_then(_Fn&& __f) const& { + if (__has_val_) return std::forward<_Fn>(__f)(__val_); + using _Result = __decay(decltype(std::forward<_Fn>(__f)(__val_))); + return _Result(unexpect, __err_); + } + + template<class _Fn> + constexpr auto and_then(_Fn&& __f) && { + if (__has_val_) return std::forward<_Fn>(__f)(std::move(__val_)); + using _Result = __decay(decltype(std::forward<_Fn>(__f)(std::move(__val_)))); + return _Result(unexpect, std::move(__err_)); + } + + template<class _Fn> + constexpr auto transform(_Fn&& __f) & { + using _Up = __remove_cvref(decltype(std::forward<_Fn>(__f)(__val_))); + if (__has_val_) return expected<_Up, _Err>(std::forward<_Fn>(__f)(__val_)); + return expected<_Up, _Err>(unexpect, __err_); + } + + template<class _Fn> + constexpr auto transform(_Fn&& __f) const& { + using _Up = __remove_cvref(decltype(std::forward<_Fn>(__f)(__val_))); + if (__has_val_) return expected<_Up, _Err>(std::forward<_Fn>(__f)(__val_)); + return expected<_Up, _Err>(unexpect, __err_); + } + + template<class _Fn> + constexpr auto or_else(_Fn&& __f) & { + if (__has_val_) { + using _Result = __decay(decltype(std::forward<_Fn>(__f)(__err_))); + return _Result(__val_); + } + return std::forward<_Fn>(__f)(__err_); + } + + template<class _Fn> + constexpr auto or_else(_Fn&& __f) const& { + if (__has_val_) { + using _Result = __decay(decltype(std::forward<_Fn>(__f)(__err_))); + return _Result(__val_); + } + return std::forward<_Fn>(__f)(__err_); + } + + template<class _Fn> + constexpr auto transform_error(_Fn&& __f) & { + using _G = __remove_cvref(decltype(std::forward<_Fn>(__f)(__err_))); + if (__has_val_) return expected<_Tp, _G>(in_place, __val_); + return expected<_Tp, _G>(unexpect, std::forward<_Fn>(__f)(__err_)); + } + + template<class _Fn> + constexpr auto transform_error(_Fn&& __f) const& { + using _G = __remove_cvref(decltype(std::forward<_Fn>(__f)(__err_))); + if (__has_val_) return expected<_Tp, _G>(in_place, __val_); + return expected<_Tp, _G>(unexpect, std::forward<_Fn>(__f)(__err_)); + } + + // ── Modifiers ─────────────────────────────────────────────────────── + + template<class... _Args> + constexpr _Tp& emplace(_Args&&... __args) { + __destroy(); + ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Args>(__args)...); + __has_val_ = true; + return __val_; + } + +private: + constexpr void __destroy() { + if (__has_val_) { + if constexpr (!is_trivially_destructible_v<_Tp>) __val_.~_Tp(); + } else { + if constexpr (!is_trivially_destructible_v<_Err>) __err_.~_Err(); + } + } + + union { + _Tp __val_; + _Err __err_; + }; + bool __has_val_; +}; + +// ── expected<void, E> specialization ──────────────────────────────────────── + +template<class _Err> +class expected<void, _Err> { +public: + using value_type = void; + using error_type = _Err; + using unexpected_type = unexpected<_Err>; + + constexpr expected() noexcept : __has_val_(true) {} + + template<class _G> + requires is_constructible_v<_Err, const _G&> + constexpr expected(const unexpected<_G>& __e) : __has_val_(false) { + ::new (static_cast<void*>(&__err_)) _Err(__e.error()); + } + + template<class _G> + requires is_constructible_v<_Err, _G> + constexpr expected(unexpected<_G>&& __e) : __has_val_(false) { + ::new (static_cast<void*>(&__err_)) _Err(std::move(__e.error())); + } + + constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {} + + template<class... _Args> + requires is_constructible_v<_Err, _Args...> + constexpr explicit expected(unexpect_t, _Args&&... __args) : __has_val_(false) { + ::new (static_cast<void*>(&__err_)) _Err(std::forward<_Args>(__args)...); + } + + constexpr ~expected() requires is_trivially_destructible_v<_Err> = default; + constexpr ~expected() requires (!is_trivially_destructible_v<_Err>) { + if (!__has_val_) __err_.~_Err(); + } + + _LIBBASTION_NODISCARD constexpr bool has_value() const noexcept { return __has_val_; } + _LIBBASTION_NODISCARD constexpr explicit operator bool() const noexcept { return __has_val_; } + + constexpr void operator*() const noexcept {} + constexpr void value() const { if (!__has_val_) _LIBBASTION_TRAP(); } + + _LIBBASTION_NODISCARD constexpr _Err& error() & { return __err_; } + _LIBBASTION_NODISCARD constexpr const _Err& error() const& { return __err_; } + _LIBBASTION_NODISCARD constexpr _Err&& error() && { return std::move(__err_); } + + constexpr void emplace() noexcept { + if (!__has_val_) { + if constexpr (!is_trivially_destructible_v<_Err>) __err_.~_Err(); + __has_val_ = true; + } + } + +private: + union { + char __empty_; + _Err __err_; + }; + bool __has_val_; +}; + +// ── Comparison ────────────────────────────────────────────────────────────── + +template<class _T1, class _E1, class _T2, class _E2> +_LIBBASTION_NODISCARD constexpr bool operator==(const expected<_T1, _E1>& __x, const expected<_T2, _E2>& __y) { + if (__x.has_value() != __y.has_value()) return false; + if (__x.has_value()) return *__x == *__y; + return __x.error() == __y.error(); +} + +template<class _T1, class _E1, class _T2> +_LIBBASTION_NODISCARD constexpr bool operator==(const expected<_T1, _E1>& __x, const _T2& __y) { + return __x.has_value() && *__x == __y; +} + +template<class _T1, class _E1, class _E2> +_LIBBASTION_NODISCARD constexpr bool operator==(const expected<_T1, _E1>& __x, const unexpected<_E2>& __y) { + return !__x.has_value() && __x.error() == __y.error(); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_EXPECTED_EXPECTED_H diff --git a/kernel/lib/libcxx/include/__functional/arithmetic.h b/kernel/lib/libcxx/include/__functional/arithmetic.h new file mode 100644 index 0000000..f9c015d --- /dev/null +++ b/kernel/lib/libcxx/include/__functional/arithmetic.h @@ -0,0 +1,101 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_FUNCTIONAL_ARITHMETIC_H +#define _LIBBASTION_FUNCTIONAL_ARITHMETIC_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp = void> +struct plus { + _LIBBASTION_NODISCARD constexpr _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } +}; + +template<> +struct plus<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) + static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) + static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +template<class _Tp = void> +struct minus { + _LIBBASTION_NODISCARD constexpr _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } +}; + +template<> +struct minus<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) - static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) - static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +template<class _Tp = void> +struct multiplies { + _LIBBASTION_NODISCARD constexpr _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } +}; + +template<> +struct multiplies<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) * static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) * static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +template<class _Tp = void> +struct divides { + _LIBBASTION_NODISCARD constexpr _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } +}; + +template<> +struct divides<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) / static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) / static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +template<class _Tp = void> +struct modulus { + _LIBBASTION_NODISCARD constexpr _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } +}; + +template<> +struct modulus<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) % static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) % static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +template<class _Tp = void> +struct negate { + _LIBBASTION_NODISCARD constexpr _Tp operator()(const _Tp& __x) const { return -__x; } +}; + +template<> +struct negate<void> { + template<class _Tp> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t) const + -> decltype(-static_cast<_Tp&&>(__t)) + { return -static_cast<_Tp&&>(__t); } + using is_transparent = void; +}; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_FUNCTIONAL_ARITHMETIC_H diff --git a/kernel/lib/libcxx/include/__functional/comparisons.h b/kernel/lib/libcxx/include/__functional/comparisons.h new file mode 100644 index 0000000..69450d3 --- /dev/null +++ b/kernel/lib/libcxx/include/__functional/comparisons.h @@ -0,0 +1,113 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_FUNCTIONAL_COMPARISONS_H +#define _LIBBASTION_FUNCTIONAL_COMPARISONS_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── less ──────────────────────────────────────────────────────────────────── + +template<class _Tp = void> +struct less { + _LIBBASTION_NODISCARD constexpr bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } +}; + +template<> +struct less<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) < static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) < static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +// ── greater ───────────────────────────────────────────────────────────────── + +template<class _Tp = void> +struct greater { + _LIBBASTION_NODISCARD constexpr bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } +}; + +template<> +struct greater<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) > static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) > static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +// ── less_equal ────────────────────────────────────────────────────────────── + +template<class _Tp = void> +struct less_equal { + _LIBBASTION_NODISCARD constexpr bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } +}; + +template<> +struct less_equal<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) <= static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) <= static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +// ── greater_equal ─────────────────────────────────────────────────────────── + +template<class _Tp = void> +struct greater_equal { + _LIBBASTION_NODISCARD constexpr bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } +}; + +template<> +struct greater_equal<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) >= static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) >= static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +// ── equal_to ──────────────────────────────────────────────────────────────── + +template<class _Tp = void> +struct equal_to { + _LIBBASTION_NODISCARD constexpr bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } +}; + +template<> +struct equal_to<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) == static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) == static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +// ── not_equal_to ──────────────────────────────────────────────────────────── + +template<class _Tp = void> +struct not_equal_to { + _LIBBASTION_NODISCARD constexpr bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } +}; + +template<> +struct not_equal_to<void> { + template<class _Tp, class _Up> + _LIBBASTION_NODISCARD constexpr auto operator()(_Tp&& __t, _Up&& __u) const + -> decltype(static_cast<_Tp&&>(__t) != static_cast<_Up&&>(__u)) + { return static_cast<_Tp&&>(__t) != static_cast<_Up&&>(__u); } + using is_transparent = void; +}; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_FUNCTIONAL_COMPARISONS_H diff --git a/kernel/lib/libcxx/include/__functional/hash.h b/kernel/lib/libcxx/include/__functional/hash.h new file mode 100644 index 0000000..24b6487 --- /dev/null +++ b/kernel/lib/libcxx/include/__functional/hash.h @@ -0,0 +1,85 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Basic hash specializations for integral types, pointers, and bool. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_FUNCTIONAL_HASH_H +#define _LIBBASTION_FUNCTIONAL_HASH_H + +#include <__config> +#include <cstddef> +#include <cstdint> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// Primary template — disabled. +template<class _Tp> +struct hash; + +namespace __detail { + +// FNV-1a for types larger than size_t would be overkill in a kernel. +// Identity hash for integers, cast-to-size_t for pointers. +inline constexpr size_t __hash_integral(size_t __val) noexcept { + // Mix bits for better distribution — based on splitmix64. + __val ^= __val >> 30; + __val *= 0xbf58476d1ce4e5b9ULL; + __val ^= __val >> 27; + __val *= 0x94d049bb133111ebULL; + __val ^= __val >> 31; + return __val; +} + +} // namespace __detail + +// Macro for integral type specializations. +#define _LIBBASTION_HASH_INTEGRAL(_Type) \ +template<> \ +struct hash<_Type> { \ + _LIBBASTION_NODISCARD size_t operator()(_Type __val) const noexcept { \ + return __detail::__hash_integral(static_cast<size_t>(__val)); \ + } \ +}; + +_LIBBASTION_HASH_INTEGRAL(bool) +_LIBBASTION_HASH_INTEGRAL(char) +_LIBBASTION_HASH_INTEGRAL(signed char) +_LIBBASTION_HASH_INTEGRAL(unsigned char) +_LIBBASTION_HASH_INTEGRAL(char8_t) +_LIBBASTION_HASH_INTEGRAL(char16_t) +_LIBBASTION_HASH_INTEGRAL(char32_t) +_LIBBASTION_HASH_INTEGRAL(wchar_t) +_LIBBASTION_HASH_INTEGRAL(short) +_LIBBASTION_HASH_INTEGRAL(unsigned short) +_LIBBASTION_HASH_INTEGRAL(int) +_LIBBASTION_HASH_INTEGRAL(unsigned int) +_LIBBASTION_HASH_INTEGRAL(long) +_LIBBASTION_HASH_INTEGRAL(unsigned long) +_LIBBASTION_HASH_INTEGRAL(long long) +_LIBBASTION_HASH_INTEGRAL(unsigned long long) + +#undef _LIBBASTION_HASH_INTEGRAL + +// Pointer specialization +template<class _Tp> +struct hash<_Tp*> { + _LIBBASTION_NODISCARD size_t operator()(_Tp* __ptr) const noexcept { + return __detail::__hash_integral(reinterpret_cast<size_t>(__ptr)); + } +}; + +// nullptr_t +template<> +struct hash<nullptr_t> { + _LIBBASTION_NODISCARD size_t operator()(nullptr_t) const noexcept { + return 0; + } +}; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_FUNCTIONAL_HASH_H diff --git a/kernel/lib/libcxx/include/__memory/addressof.h b/kernel/lib/libcxx/include/__memory/addressof.h new file mode 100644 index 0000000..994e7cb --- /dev/null +++ b/kernel/lib/libcxx/include/__memory/addressof.h @@ -0,0 +1,25 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_MEMORY_ADDRESSOF_H +#define _LIBBASTION_MEMORY_ADDRESSOF_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp> +_LIBBASTION_NODISCARD inline constexpr _Tp* addressof(_Tp& __x) noexcept { + return __builtin_addressof(__x); +} + +template<class _Tp> +_Tp* addressof(const _Tp&&) = delete; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_MEMORY_ADDRESSOF_H diff --git a/kernel/lib/libcxx/include/__memory/pointer_traits.h b/kernel/lib/libcxx/include/__memory/pointer_traits.h new file mode 100644 index 0000000..4c3657e --- /dev/null +++ b/kernel/lib/libcxx/include/__memory/pointer_traits.h @@ -0,0 +1,49 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_MEMORY_POINTER_TRAITS_H +#define _LIBBASTION_MEMORY_POINTER_TRAITS_H + +#include <__config> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// Primary template — for smart pointer types with element_type typedef. +template<class _Ptr> +struct pointer_traits { + using pointer = _Ptr; + using element_type = typename _Ptr::element_type; + using difference_type = ptrdiff_t; + + template<class _Up> + using rebind = typename _Ptr::template rebind<_Up>; +}; + +// Specialization for raw pointers. +template<class _Tp> +struct pointer_traits<_Tp*> { + using pointer = _Tp*; + using element_type = _Tp; + using difference_type = ptrdiff_t; + + template<class _Up> + using rebind = _Up*; + + _LIBBASTION_NODISCARD static constexpr _Tp* to_address(_Tp* __p) noexcept { return __p; } +}; + +// to_address (C++20) +template<class _Tp> +_LIBBASTION_NODISCARD constexpr _Tp* to_address(_Tp* __p) noexcept { + static_assert(!__is_function(_Tp), "to_address cannot be used with function pointers"); + return __p; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_MEMORY_POINTER_TRAITS_H diff --git a/kernel/lib/libcxx/include/__memory/unique_ptr.h b/kernel/lib/libcxx/include/__memory/unique_ptr.h new file mode 100644 index 0000000..f484d15 --- /dev/null +++ b/kernel/lib/libcxx/include/__memory/unique_ptr.h @@ -0,0 +1,242 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::unique_ptr — owning RAII smart pointer. +// operator delete is stubbed in cxxabi.cpp until kernel heap is available. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_MEMORY_UNIQUE_PTR_H +#define _LIBBASTION_MEMORY_UNIQUE_PTR_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/primary_categories.h> +#include <__type_traits/type_modifications.h> +#include <__type_traits/construction_traits.h> +#include <__type_traits/type_relationships.h> +#include <__utility/move.h> +#include <__utility/exchange.h> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── default_delete ────────────────────────────────────────────────────────── + +template<class _Tp> +struct default_delete { + constexpr default_delete() noexcept = default; + + template<class _Up> + requires is_convertible_v<_Up*, _Tp*> + constexpr default_delete(const default_delete<_Up>&) noexcept {} + + constexpr void operator()(_Tp* __ptr) const noexcept { + static_assert(sizeof(_Tp) > 0, "cannot delete an incomplete type"); + delete __ptr; + } +}; + +template<class _Tp> +struct default_delete<_Tp[]> { + constexpr default_delete() noexcept = default; + + template<class _Up> + requires is_convertible_v<_Up(*)[], _Tp(*)[]> + constexpr default_delete(const default_delete<_Up[]>&) noexcept {} + + template<class _Up> + requires is_convertible_v<_Up(*)[], _Tp(*)[]> + constexpr void operator()(_Up* __ptr) const noexcept { + static_assert(sizeof(_Up) > 0, "cannot delete an incomplete type"); + delete[] __ptr; + } +}; + +// ── unique_ptr<T, Deleter> ────────────────────────────────────────────────── + +template<class _Tp, class _Dp = default_delete<_Tp>> +class unique_ptr { +public: + using element_type = _Tp; + using deleter_type = _Dp; + using pointer = _Tp*; + + // Constructors + constexpr unique_ptr() noexcept : __ptr_(nullptr) {} + constexpr unique_ptr(nullptr_t) noexcept : __ptr_(nullptr) {} + constexpr explicit unique_ptr(pointer __p) noexcept : __ptr_(__p) {} + + constexpr unique_ptr(unique_ptr&& __u) noexcept + : __ptr_(__u.release()) {} + + template<class _Up, class _Ep> + requires is_convertible_v<typename unique_ptr<_Up, _Ep>::pointer, pointer> && + (!__is_array(_Up)) + constexpr unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept + : __ptr_(__u.release()) {} + + // No copy + unique_ptr(const unique_ptr&) = delete; + unique_ptr& operator=(const unique_ptr&) = delete; + + // Destructor + constexpr ~unique_ptr() { + if (__ptr_) get_deleter()(__ptr_); + } + + // Assignment + constexpr unique_ptr& operator=(unique_ptr&& __u) noexcept { + reset(__u.release()); + return *this; + } + + template<class _Up, class _Ep> + requires is_convertible_v<typename unique_ptr<_Up, _Ep>::pointer, pointer> && + (!__is_array(_Up)) + constexpr unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { + reset(__u.release()); + return *this; + } + + constexpr unique_ptr& operator=(nullptr_t) noexcept { + reset(); + return *this; + } + + // Observers + _LIBBASTION_NODISCARD constexpr pointer get() const noexcept { return __ptr_; } + _LIBBASTION_NODISCARD constexpr _Dp& get_deleter() noexcept { return __deleter_; } + _LIBBASTION_NODISCARD constexpr const _Dp& get_deleter() const noexcept { return __deleter_; } + _LIBBASTION_NODISCARD constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; } + + _LIBBASTION_NODISCARD constexpr _Tp& operator*() const { return *__ptr_; } + _LIBBASTION_NODISCARD constexpr pointer operator->() const noexcept { return __ptr_; } + + // Modifiers + constexpr pointer release() noexcept { + return std::exchange(__ptr_, nullptr); + } + + constexpr void reset(pointer __p = pointer()) noexcept { + pointer __old = std::exchange(__ptr_, __p); + if (__old) get_deleter()(__old); + } + + constexpr void swap(unique_ptr& __other) noexcept { + using std::swap; + swap(__ptr_, __other.__ptr_); + swap(__deleter_, __other.__deleter_); + } + +private: + pointer __ptr_; + _LIBBASTION_MAYBE_UNUSED _Dp __deleter_; +}; + +// ── unique_ptr<T[], Deleter> ──────────────────────────────────────────────── + +template<class _Tp, class _Dp> +class unique_ptr<_Tp[], _Dp> { +public: + using element_type = _Tp; + using deleter_type = _Dp; + using pointer = _Tp*; + + constexpr unique_ptr() noexcept : __ptr_(nullptr) {} + constexpr unique_ptr(nullptr_t) noexcept : __ptr_(nullptr) {} + constexpr explicit unique_ptr(pointer __p) noexcept : __ptr_(__p) {} + constexpr unique_ptr(unique_ptr&& __u) noexcept : __ptr_(__u.release()) {} + + unique_ptr(const unique_ptr&) = delete; + unique_ptr& operator=(const unique_ptr&) = delete; + + constexpr ~unique_ptr() { + if (__ptr_) get_deleter()(__ptr_); + } + + constexpr unique_ptr& operator=(unique_ptr&& __u) noexcept { + reset(__u.release()); + return *this; + } + + constexpr unique_ptr& operator=(nullptr_t) noexcept { + reset(); + return *this; + } + + _LIBBASTION_NODISCARD constexpr pointer get() const noexcept { return __ptr_; } + _LIBBASTION_NODISCARD constexpr _Dp& get_deleter() noexcept { return __deleter_; } + _LIBBASTION_NODISCARD constexpr const _Dp& get_deleter() const noexcept { return __deleter_; } + _LIBBASTION_NODISCARD constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; } + + _LIBBASTION_NODISCARD constexpr _Tp& operator[](size_t __i) const { return __ptr_[__i]; } + + constexpr pointer release() noexcept { return std::exchange(__ptr_, nullptr); } + + constexpr void reset(pointer __p = pointer()) noexcept { + pointer __old = std::exchange(__ptr_, __p); + if (__old) get_deleter()(__old); + } + + constexpr void swap(unique_ptr& __other) noexcept { + using std::swap; + swap(__ptr_, __other.__ptr_); + } + +private: + pointer __ptr_; + _LIBBASTION_MAYBE_UNUSED _Dp __deleter_; +}; + +// ── Non-member functions ──────────────────────────────────────────────────── + +template<class _Tp, class _Dp> +inline constexpr void swap(unique_ptr<_Tp, _Dp>& __a, unique_ptr<_Tp, _Dp>& __b) noexcept { + __a.swap(__b); +} + +// Comparison +template<class _T1, class _D1, class _T2, class _D2> +_LIBBASTION_NODISCARD inline constexpr bool operator==(const unique_ptr<_T1, _D1>& __a, const unique_ptr<_T2, _D2>& __b) { + return __a.get() == __b.get(); +} + +template<class _T1, class _D1> +_LIBBASTION_NODISCARD inline constexpr bool operator==(const unique_ptr<_T1, _D1>& __a, nullptr_t) noexcept { + return !__a; +} + +template<class _T1, class _D1> +_LIBBASTION_NODISCARD inline constexpr bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __a) noexcept { + return !__a; +} + +template<class _T1, class _D1, class _T2, class _D2> +_LIBBASTION_NODISCARD inline constexpr bool operator!=(const unique_ptr<_T1, _D1>& __a, const unique_ptr<_T2, _D2>& __b) { + return __a.get() != __b.get(); +} + +template<class _T1, class _D1, class _T2, class _D2> +_LIBBASTION_NODISCARD inline constexpr bool operator<(const unique_ptr<_T1, _D1>& __a, const unique_ptr<_T2, _D2>& __b) { + return __a.get() < __b.get(); +} + +// make_unique (requires working operator new — will work after kernel heap) +template<class _Tp, class... _Args> + requires (!__is_array(_Tp)) +_LIBBASTION_NODISCARD inline constexpr unique_ptr<_Tp> make_unique(_Args&&... __args) { + return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); +} + +template<class _Tp> + requires __is_unbounded_array(_Tp) +_LIBBASTION_NODISCARD inline constexpr unique_ptr<_Tp> make_unique(size_t __n) { + return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__n]()); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_MEMORY_UNIQUE_PTR_H diff --git a/kernel/lib/libcxx/include/__optional/optional.h b/kernel/lib/libcxx/include/__optional/optional.h new file mode 100644 index 0000000..cf01b9f --- /dev/null +++ b/kernel/lib/libcxx/include/__optional/optional.h @@ -0,0 +1,354 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::optional — no-exceptions version (traps on bad access). +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_OPTIONAL_OPTIONAL_H +#define _LIBBASTION_OPTIONAL_OPTIONAL_H + +#include <__config> +#include <__type_traits/construction_traits.h> +#include <__type_traits/type_modifications.h> +#include <__type_traits/type_relationships.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include <__utility/in_place.h> +#include <new> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── nullopt ───────────────────────────────────────────────────────────────── + +struct nullopt_t { + struct __tag {}; + explicit constexpr nullopt_t(__tag) noexcept {} +}; +inline constexpr nullopt_t nullopt{nullopt_t::__tag{}}; + +// ── bad_optional_access ───────────────────────────────────────────────────── +// In a no-exceptions environment, accessing an empty optional traps. +// This struct exists only for API completeness. + +struct bad_optional_access { + const char* what() const noexcept { return "bad optional access"; } +}; + +// ── optional ──────────────────────────────────────────────────────────────── + +template<class _Tp> +class optional { + static_assert(!__is_same(_Tp, in_place_t), "optional<in_place_t> is ill-formed"); + static_assert(!__is_same(_Tp, nullopt_t), "optional<nullopt_t> is ill-formed"); + static_assert(!__is_reference(_Tp), "optional<T&> is ill-formed"); + static_assert(__is_destructible(_Tp), "optional<T> requires T to be destructible"); + +public: + using value_type = _Tp; + + // ── Constructors ──────────────────────────────────────────────────── + + constexpr optional() noexcept : __engaged_(false) {} + constexpr optional(nullopt_t) noexcept : __engaged_(false) {} + + constexpr optional(const optional& __other) + requires is_copy_constructible_v<_Tp> + { + if (__other.__engaged_) { + ::new (static_cast<void*>(&__val_)) _Tp(__other.__val_); + __engaged_ = true; + } else { + __engaged_ = false; + } + } + + constexpr optional(optional&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp>) + requires is_move_constructible_v<_Tp> + { + if (__other.__engaged_) { + ::new (static_cast<void*>(&__val_)) _Tp(std::move(__other.__val_)); + __engaged_ = true; + } else { + __engaged_ = false; + } + } + + template<class _Up = _Tp> + requires is_constructible_v<_Tp, _Up&&> && + !__is_same(__decay(_Up), in_place_t) && + !__is_same(__decay(_Up), optional) + constexpr optional(_Up&& __val) + : __engaged_(true) + { + ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Up>(__val)); + } + + template<class... _Args> + requires is_constructible_v<_Tp, _Args...> + constexpr explicit optional(in_place_t, _Args&&... __args) + : __engaged_(true) + { + ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Args>(__args)...); + } + + // ── Destructor ────────────────────────────────────────────────────── + + constexpr ~optional() requires is_trivially_destructible_v<_Tp> = default; + + constexpr ~optional() requires (!is_trivially_destructible_v<_Tp>) { + if (__engaged_) __val_.~_Tp(); + } + + // ── Assignment ────────────────────────────────────────────────────── + + constexpr optional& operator=(nullopt_t) noexcept { + reset(); + return *this; + } + + constexpr optional& operator=(const optional& __other) + requires is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Tp> + { + if (__engaged_ && __other.__engaged_) { + __val_ = __other.__val_; + } else if (__other.__engaged_) { + ::new (static_cast<void*>(&__val_)) _Tp(__other.__val_); + __engaged_ = true; + } else { + reset(); + } + return *this; + } + + constexpr optional& operator=(optional&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) + requires is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp> + { + if (__engaged_ && __other.__engaged_) { + __val_ = std::move(__other.__val_); + } else if (__other.__engaged_) { + ::new (static_cast<void*>(&__val_)) _Tp(std::move(__other.__val_)); + __engaged_ = true; + } else { + reset(); + } + return *this; + } + + template<class _Up = _Tp> + requires is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> && + !__is_same(__decay(_Up), optional) + constexpr optional& operator=(_Up&& __val) { + if (__engaged_) { + __val_ = std::forward<_Up>(__val); + } else { + ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Up>(__val)); + __engaged_ = true; + } + return *this; + } + + // ── Observers ─────────────────────────────────────────────────────── + + _LIBBASTION_NODISCARD constexpr bool has_value() const noexcept { return __engaged_; } + _LIBBASTION_NODISCARD constexpr explicit operator bool() const noexcept { return __engaged_; } + + _LIBBASTION_NODISCARD constexpr _Tp& operator*() & { return __val_; } + _LIBBASTION_NODISCARD constexpr const _Tp& operator*() const& { return __val_; } + _LIBBASTION_NODISCARD constexpr _Tp&& operator*() && { return std::move(__val_); } + _LIBBASTION_NODISCARD constexpr const _Tp&& operator*() const&& { return std::move(__val_); } + + _LIBBASTION_NODISCARD constexpr _Tp* operator->() { return &__val_; } + _LIBBASTION_NODISCARD constexpr const _Tp* operator->() const { return &__val_; } + + _LIBBASTION_NODISCARD constexpr _Tp& value() & { + if (!__engaged_) _LIBBASTION_TRAP(); + return __val_; + } + _LIBBASTION_NODISCARD constexpr const _Tp& value() const& { + if (!__engaged_) _LIBBASTION_TRAP(); + return __val_; + } + _LIBBASTION_NODISCARD constexpr _Tp&& value() && { + if (!__engaged_) _LIBBASTION_TRAP(); + return std::move(__val_); + } + _LIBBASTION_NODISCARD constexpr const _Tp&& value() const&& { + if (!__engaged_) _LIBBASTION_TRAP(); + return std::move(__val_); + } + + template<class _Up> + _LIBBASTION_NODISCARD constexpr _Tp value_or(_Up&& __default_val) const& { + return __engaged_ ? __val_ : static_cast<_Tp>(std::forward<_Up>(__default_val)); + } + template<class _Up> + _LIBBASTION_NODISCARD constexpr _Tp value_or(_Up&& __default_val) && { + return __engaged_ ? std::move(__val_) : static_cast<_Tp>(std::forward<_Up>(__default_val)); + } + + // ── Modifiers ─────────────────────────────────────────────────────── + + constexpr void reset() noexcept { + if (__engaged_) { + if constexpr (!is_trivially_destructible_v<_Tp>) + __val_.~_Tp(); + __engaged_ = false; + } + } + + template<class... _Args> + constexpr _Tp& emplace(_Args&&... __args) { + reset(); + ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Args>(__args)...); + __engaged_ = true; + return __val_; + } + + constexpr void swap(optional& __other) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>) + { + if (__engaged_ && __other.__engaged_) { + using std::swap; + swap(__val_, __other.__val_); + } else if (__engaged_) { + ::new (static_cast<void*>(&__other.__val_)) _Tp(std::move(__val_)); + __other.__engaged_ = true; + reset(); + } else if (__other.__engaged_) { + ::new (static_cast<void*>(&__val_)) _Tp(std::move(__other.__val_)); + __engaged_ = true; + __other.reset(); + } + } + + // ── Monadic operations (C++23) ────────────────────────────────────── + + template<class _Fn> + constexpr auto and_then(_Fn&& __f) & { + using _Result = __decay(decltype(std::forward<_Fn>(__f)(__val_))); + if (__engaged_) return std::forward<_Fn>(__f)(__val_); + return _Result(); + } + + template<class _Fn> + constexpr auto and_then(_Fn&& __f) const& { + using _Result = __decay(decltype(std::forward<_Fn>(__f)(__val_))); + if (__engaged_) return std::forward<_Fn>(__f)(__val_); + return _Result(); + } + + template<class _Fn> + constexpr auto and_then(_Fn&& __f) && { + using _Result = __decay(decltype(std::forward<_Fn>(__f)(std::move(__val_)))); + if (__engaged_) return std::forward<_Fn>(__f)(std::move(__val_)); + return _Result(); + } + + template<class _Fn> + constexpr auto transform(_Fn&& __f) & { + using _Result = __remove_cvref(decltype(std::forward<_Fn>(__f)(__val_))); + if (__engaged_) return optional<_Result>(std::forward<_Fn>(__f)(__val_)); + return optional<_Result>(); + } + + template<class _Fn> + constexpr auto transform(_Fn&& __f) const& { + using _Result = __remove_cvref(decltype(std::forward<_Fn>(__f)(__val_))); + if (__engaged_) return optional<_Result>(std::forward<_Fn>(__f)(__val_)); + return optional<_Result>(); + } + + template<class _Fn> + constexpr auto transform(_Fn&& __f) && { + using _Result = __remove_cvref(decltype(std::forward<_Fn>(__f)(std::move(__val_)))); + if (__engaged_) return optional<_Result>(std::forward<_Fn>(__f)(std::move(__val_))); + return optional<_Result>(); + } + + template<class _Fn> + constexpr optional or_else(_Fn&& __f) const& { + return __engaged_ ? *this : std::forward<_Fn>(__f)(); + } + + template<class _Fn> + constexpr optional or_else(_Fn&& __f) && { + return __engaged_ ? std::move(*this) : std::forward<_Fn>(__f)(); + } + +private: + union { + char __empty_; + _Tp __val_; + }; + bool __engaged_; +}; + +// ── Comparison operators ──────────────────────────────────────────────────── + +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (__x.has_value() != __y.has_value()) return false; + if (!__x.has_value()) return true; + return *__x == *__y; +} + +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) { + return !(__x == __y); +} + +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator<(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (!__y.has_value()) return false; + if (!__x.has_value()) return true; + return *__x < *__y; +} + +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator>(const optional<_Tp>& __x, const optional<_Up>& __y) { return __y < __x; } +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) { return !(__y < __x); } +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) { return !(__x < __y); } + +// Compare with nullopt +template<class _Tp> +_LIBBASTION_NODISCARD constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept { return !__x.has_value(); } +template<class _Tp> +_LIBBASTION_NODISCARD constexpr bool operator==(nullopt_t, const optional<_Tp>& __x) noexcept { return !__x.has_value(); } + +// Compare with value +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator==(const optional<_Tp>& __x, const _Up& __y) { + return __x.has_value() && *__x == __y; +} +template<class _Tp, class _Up> +_LIBBASTION_NODISCARD constexpr bool operator==(const _Tp& __x, const optional<_Up>& __y) { + return __y.has_value() && __x == *__y; +} + +// Non-member swap +template<class _Tp> +inline constexpr void swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) { + __x.swap(__y); +} + +// make_optional +template<class _Tp> +_LIBBASTION_NODISCARD constexpr optional<__decay(_Tp)> make_optional(_Tp&& __val) { + return optional<__decay(_Tp)>(std::forward<_Tp>(__val)); +} + +template<class _Tp, class... _Args> +_LIBBASTION_NODISCARD constexpr optional<_Tp> make_optional(_Args&&... __args) { + return optional<_Tp>(in_place, std::forward<_Args>(__args)...); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_OPTIONAL_OPTIONAL_H diff --git a/kernel/lib/libcxx/include/__tuple/tuple.h b/kernel/lib/libcxx/include/__tuple/tuple.h new file mode 100644 index 0000000..a4c1ef0 --- /dev/null +++ b/kernel/lib/libcxx/include/__tuple/tuple.h @@ -0,0 +1,213 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::tuple — recursive inheritance implementation with __type_pack_element. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TUPLE_TUPLE_H +#define _LIBBASTION_TUPLE_TUPLE_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/construction_traits.h> +#include <__type_traits/type_modifications.h> +#include <__type_traits/type_relationships.h> +#include <__utility/move.h> +#include <__utility/integer_sequence.h> +#include <__tuple/tuple_element.h> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── Forward declaration ───────────────────────────────────────────────────── + +template<class... _Types> +class tuple; + +// ── tuple_size specialization ─────────────────────────────────────────────── + +template<class... _Types> +struct tuple_size<tuple<_Types...>> : integral_constant<size_t, sizeof...(_Types)> {}; + +// ── tuple_element specialization ──────────────────────────────────────────── + +template<size_t _Ip, class... _Types> +struct tuple_element<_Ip, tuple<_Types...>> { + static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); + using type = __type_pack_element<_Ip, _Types...>; +}; + +// ── Internal: leaf storage ────────────────────────────────────────────────── + +namespace __tuple_detail { + +template<size_t _Ip, class _Tp> +struct __tuple_leaf { + _Tp __value_; + + constexpr __tuple_leaf() : __value_() {} + + template<class _Up> + constexpr explicit __tuple_leaf(_Up&& __u) : __value_(std::forward<_Up>(__u)) {} + + constexpr _Tp& get() noexcept { return __value_; } + constexpr const _Tp& get() const noexcept { return __value_; } +}; + +// Indexed tuple implementation. +template<class _IndexSeq, class... _Types> +struct __tuple_impl; + +template<size_t... _Ip, class... _Types> +struct __tuple_impl<index_sequence<_Ip...>, _Types...> : __tuple_leaf<_Ip, _Types>... { + constexpr __tuple_impl() = default; + + template<class... _UTypes> + constexpr explicit __tuple_impl(_UTypes&&... __args) + : __tuple_leaf<_Ip, _Types>(std::forward<_UTypes>(__args))... {} +}; + +template<size_t _Ip, class _Tp> +constexpr _Tp& __get_leaf(__tuple_leaf<_Ip, _Tp>& __leaf) noexcept { + return __leaf.get(); +} + +template<size_t _Ip, class _Tp> +constexpr const _Tp& __get_leaf(const __tuple_leaf<_Ip, _Tp>& __leaf) noexcept { + return __leaf.get(); +} + +template<size_t _Ip, class _Tp> +constexpr _Tp&& __get_leaf_rv(__tuple_leaf<_Ip, _Tp>& __leaf) noexcept { + return std::move(__leaf.get()); +} + +} // namespace __tuple_detail + +// ── tuple ─────────────────────────────────────────────────────────────────── + +template<class... _Types> +class tuple { + using __impl_t = __tuple_detail::__tuple_impl<make_index_sequence<sizeof...(_Types)>, _Types...>; + __impl_t __impl_; + +public: + // Default constructor + constexpr tuple() + requires (is_default_constructible_v<_Types> && ...) + = default; + + // Direct constructor + constexpr explicit tuple(const _Types&... __args) + requires (sizeof...(_Types) >= 1) && (is_copy_constructible_v<_Types> && ...) + : __impl_(__args...) {} + + // Converting constructor + template<class... _UTypes> + requires (sizeof...(_UTypes) == sizeof...(_Types)) && + (is_constructible_v<_Types, _UTypes&&> && ...) + constexpr explicit tuple(_UTypes&&... __args) + : __impl_(std::forward<_UTypes>(__args)...) {} + + // Copy/move from other tuple + template<class... _UTypes> + requires (sizeof...(_UTypes) == sizeof...(_Types)) && + (is_constructible_v<_Types, const _UTypes&> && ...) + constexpr tuple(const tuple<_UTypes...>& __other) + : tuple(__make_from_other(__other, make_index_sequence<sizeof...(_Types)>{})) {} + + template<class... _UTypes> + requires (sizeof...(_UTypes) == sizeof...(_Types)) && + (is_constructible_v<_Types, _UTypes&&> && ...) + constexpr tuple(tuple<_UTypes...>&& __other) + : tuple(__make_from_other(std::move(__other), make_index_sequence<sizeof...(_Types)>{})) {} + + tuple(const tuple&) = default; + tuple(tuple&&) = default; + tuple& operator=(const tuple&) = default; + tuple& operator=(tuple&&) = default; + + // get access (friendship pattern via public impl accessor) + constexpr __impl_t& __get_impl() noexcept { return __impl_; } + constexpr const __impl_t& __get_impl() const noexcept { return __impl_; } + +private: + template<class _OtherTuple, size_t... _Ip> + static constexpr tuple __make_from_other(_OtherTuple&& __other, index_sequence<_Ip...>) { + return tuple(get<_Ip>(std::forward<_OtherTuple>(__other))...); + } +}; + +// Empty tuple specialization. +template<> +class tuple<> { +public: + constexpr tuple() noexcept = default; +}; + +// Deduction guide +template<class... _Types> +tuple(_Types...) -> tuple<_Types...>; + +// ── get<I>(tuple) ─────────────────────────────────────────────────────────── + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr tuple_element_t<_Ip, tuple<_Types...>>& get(tuple<_Types...>& __t) noexcept { + return __tuple_detail::__get_leaf<_Ip>(__t.__get_impl()); +} + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr const tuple_element_t<_Ip, tuple<_Types...>>& get(const tuple<_Types...>& __t) noexcept { + return __tuple_detail::__get_leaf<_Ip>(__t.__get_impl()); +} + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr tuple_element_t<_Ip, tuple<_Types...>>&& get(tuple<_Types...>&& __t) noexcept { + return __tuple_detail::__get_leaf_rv<_Ip>(__t.__get_impl()); +} + +// ── make_tuple / tie / forward_as_tuple ───────────────────────────────────── + +template<class... _Types> +_LIBBASTION_NODISCARD constexpr tuple<__decay(_Types)...> make_tuple(_Types&&... __args) { + return tuple<__decay(_Types)...>(std::forward<_Types>(__args)...); +} + +template<class... _Types> +_LIBBASTION_NODISCARD constexpr tuple<_Types&...> tie(_Types&... __args) noexcept { + return tuple<_Types&...>(__args...); +} + +template<class... _Types> +_LIBBASTION_NODISCARD constexpr tuple<_Types&&...> forward_as_tuple(_Types&&... __args) noexcept { + return tuple<_Types&&...>(std::forward<_Types>(__args)...); +} + +// ── Comparison ────────────────────────────────────────────────────────────── + +namespace __tuple_detail { + +template<class _T1, class _T2, size_t... _Ip> +constexpr bool __tuple_equal(const _T1& __a, const _T2& __b, index_sequence<_Ip...>) { + return ((get<_Ip>(__a) == get<_Ip>(__b)) && ...); +} + +} // namespace __tuple_detail + +template<class... _T1, class... _T2> + requires (sizeof...(_T1) == sizeof...(_T2)) +_LIBBASTION_NODISCARD constexpr bool operator==(const tuple<_T1...>& __a, const tuple<_T2...>& __b) { + return __tuple_detail::__tuple_equal(__a, __b, make_index_sequence<sizeof...(_T1)>{}); +} + +template<class... _T1, class... _T2> +_LIBBASTION_NODISCARD constexpr bool operator!=(const tuple<_T1...>& __a, const tuple<_T2...>& __b) { + return !(__a == __b); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TUPLE_TUPLE_H diff --git a/kernel/lib/libcxx/include/__tuple/tuple_element.h b/kernel/lib/libcxx/include/__tuple/tuple_element.h new file mode 100644 index 0000000..97b347f --- /dev/null +++ b/kernel/lib/libcxx/include/__tuple/tuple_element.h @@ -0,0 +1,42 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// tuple_size and tuple_element — protocol types for structured bindings. +// Primary templates here; specializations in pair.h, array, tuple.h, etc. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TUPLE_TUPLE_ELEMENT_H +#define _LIBBASTION_TUPLE_TUPLE_ELEMENT_H + +#include <__config> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// Primary templates (specialized by pair, array, tuple, variant). +template<class _Tp> +struct tuple_size; // : integral_constant<size_t, N> + +template<class _Tp> +struct tuple_size<const _Tp> : tuple_size<_Tp> {}; + +template<class _Tp> +inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; + +template<size_t _Ip, class _Tp> +struct tuple_element; // { using type = ...; } + +template<size_t _Ip, class _Tp> +struct tuple_element<_Ip, const _Tp> { + using type = const typename tuple_element<_Ip, _Tp>::type; +}; + +template<size_t _Ip, class _Tp> +using tuple_element_t = typename tuple_element<_Ip, _Tp>::type; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TUPLE_TUPLE_ELEMENT_H diff --git a/kernel/lib/libcxx/include/__type_traits/construction_traits.h b/kernel/lib/libcxx/include/__type_traits/construction_traits.h new file mode 100644 index 0000000..3c84713 --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/construction_traits.h @@ -0,0 +1,158 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Construction, assignment, and destruction traits. +// All use Clang builtins. is_swappable is deferred until swap is defined. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_CONSTRUCTION_TRAITS_H +#define _LIBBASTION_TYPE_TRAITS_CONSTRUCTION_TRAITS_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── is_constructible family ───────────────────────────────────────────────── + +template<class _Tp, class... _Args> +struct is_constructible : bool_constant<__is_constructible(_Tp, _Args...)> {}; +template<class _Tp, class... _Args> +inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); + +template<class _Tp> +struct is_default_constructible : bool_constant<__is_constructible(_Tp)> {}; +template<class _Tp> +inline constexpr bool is_default_constructible_v = __is_constructible(_Tp); + +template<class _Tp> +struct is_copy_constructible : bool_constant<__is_constructible(_Tp, __add_lvalue_reference(const _Tp))> {}; +template<class _Tp> +inline constexpr bool is_copy_constructible_v = __is_constructible(_Tp, __add_lvalue_reference(const _Tp)); + +template<class _Tp> +struct is_move_constructible : bool_constant<__is_constructible(_Tp, __add_rvalue_reference(_Tp))> {}; +template<class _Tp> +inline constexpr bool is_move_constructible_v = __is_constructible(_Tp, __add_rvalue_reference(_Tp)); + +// ── is_trivially_constructible family ─────────────────────────────────────── + +template<class _Tp, class... _Args> +struct is_trivially_constructible : bool_constant<__is_trivially_constructible(_Tp, _Args...)> {}; +template<class _Tp, class... _Args> +inline constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Tp, _Args...); + +template<class _Tp> +struct is_trivially_default_constructible : bool_constant<__is_trivially_constructible(_Tp)> {}; +template<class _Tp> +inline constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Tp); + +template<class _Tp> +struct is_trivially_copy_constructible : bool_constant<__is_trivially_constructible(_Tp, __add_lvalue_reference(const _Tp))> {}; +template<class _Tp> +inline constexpr bool is_trivially_copy_constructible_v = __is_trivially_constructible(_Tp, __add_lvalue_reference(const _Tp)); + +template<class _Tp> +struct is_trivially_move_constructible : bool_constant<__is_trivially_constructible(_Tp, __add_rvalue_reference(_Tp))> {}; +template<class _Tp> +inline constexpr bool is_trivially_move_constructible_v = __is_trivially_constructible(_Tp, __add_rvalue_reference(_Tp)); + +// ── is_nothrow_constructible family ───────────────────────────────────────── + +template<class _Tp, class... _Args> +struct is_nothrow_constructible : bool_constant<__is_nothrow_constructible(_Tp, _Args...)> {}; +template<class _Tp, class... _Args> +inline constexpr bool is_nothrow_constructible_v = __is_nothrow_constructible(_Tp, _Args...); + +template<class _Tp> +struct is_nothrow_default_constructible : bool_constant<__is_nothrow_constructible(_Tp)> {}; +template<class _Tp> +inline constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Tp); + +template<class _Tp> +struct is_nothrow_copy_constructible : bool_constant<__is_nothrow_constructible(_Tp, __add_lvalue_reference(const _Tp))> {}; +template<class _Tp> +inline constexpr bool is_nothrow_copy_constructible_v = __is_nothrow_constructible(_Tp, __add_lvalue_reference(const _Tp)); + +template<class _Tp> +struct is_nothrow_move_constructible : bool_constant<__is_nothrow_constructible(_Tp, __add_rvalue_reference(_Tp))> {}; +template<class _Tp> +inline constexpr bool is_nothrow_move_constructible_v = __is_nothrow_constructible(_Tp, __add_rvalue_reference(_Tp)); + +// ── is_assignable family ──────────────────────────────────────────────────── + +template<class _Tp, class _Up> +struct is_assignable : bool_constant<__is_assignable(_Tp, _Up)> {}; +template<class _Tp, class _Up> +inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up); + +template<class _Tp> +struct is_copy_assignable : bool_constant<__is_assignable(__add_lvalue_reference(_Tp), __add_lvalue_reference(const _Tp))> {}; +template<class _Tp> +inline constexpr bool is_copy_assignable_v = __is_assignable(__add_lvalue_reference(_Tp), __add_lvalue_reference(const _Tp)); + +template<class _Tp> +struct is_move_assignable : bool_constant<__is_assignable(__add_lvalue_reference(_Tp), __add_rvalue_reference(_Tp))> {}; +template<class _Tp> +inline constexpr bool is_move_assignable_v = __is_assignable(__add_lvalue_reference(_Tp), __add_rvalue_reference(_Tp)); + +// ── is_trivially_assignable family ────────────────────────────────────────── + +template<class _Tp, class _Up> +struct is_trivially_assignable : bool_constant<__is_trivially_assignable(_Tp, _Up)> {}; +template<class _Tp, class _Up> +inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Tp, _Up); + +template<class _Tp> +struct is_trivially_copy_assignable : bool_constant<__is_trivially_assignable(__add_lvalue_reference(_Tp), __add_lvalue_reference(const _Tp))> {}; +template<class _Tp> +inline constexpr bool is_trivially_copy_assignable_v = __is_trivially_assignable(__add_lvalue_reference(_Tp), __add_lvalue_reference(const _Tp)); + +template<class _Tp> +struct is_trivially_move_assignable : bool_constant<__is_trivially_assignable(__add_lvalue_reference(_Tp), __add_rvalue_reference(_Tp))> {}; +template<class _Tp> +inline constexpr bool is_trivially_move_assignable_v = __is_trivially_assignable(__add_lvalue_reference(_Tp), __add_rvalue_reference(_Tp)); + +// ── is_nothrow_assignable family ──────────────────────────────────────────── + +template<class _Tp, class _Up> +struct is_nothrow_assignable : bool_constant<__is_nothrow_assignable(_Tp, _Up)> {}; +template<class _Tp, class _Up> +inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Up); + +template<class _Tp> +struct is_nothrow_copy_assignable : bool_constant<__is_nothrow_assignable(__add_lvalue_reference(_Tp), __add_lvalue_reference(const _Tp))> {}; +template<class _Tp> +inline constexpr bool is_nothrow_copy_assignable_v = __is_nothrow_assignable(__add_lvalue_reference(_Tp), __add_lvalue_reference(const _Tp)); + +template<class _Tp> +struct is_nothrow_move_assignable : bool_constant<__is_nothrow_assignable(__add_lvalue_reference(_Tp), __add_rvalue_reference(_Tp))> {}; +template<class _Tp> +inline constexpr bool is_nothrow_move_assignable_v = __is_nothrow_assignable(__add_lvalue_reference(_Tp), __add_rvalue_reference(_Tp)); + +// ── is_destructible family ────────────────────────────────────────────────── + +template<class _Tp> +struct is_destructible : bool_constant<__is_destructible(_Tp)> {}; +template<class _Tp> +inline constexpr bool is_destructible_v = __is_destructible(_Tp); + +template<class _Tp> +struct is_trivially_destructible : bool_constant<__is_trivially_destructible(_Tp)> {}; +template<class _Tp> +inline constexpr bool is_trivially_destructible_v = __is_trivially_destructible(_Tp); + +template<class _Tp> +struct is_nothrow_destructible : bool_constant<__is_nothrow_destructible(_Tp)> {}; +template<class _Tp> +inline constexpr bool is_nothrow_destructible_v = __is_nothrow_destructible(_Tp); + +// ── is_swappable ──────────────────────────────────────────────────────────── +// Deferred: defined in __utility/swap.h after swap is available. + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_CONSTRUCTION_TRAITS_H diff --git a/kernel/lib/libcxx/include/__type_traits/integral_constant.h b/kernel/lib/libcxx/include/__type_traits/integral_constant.h new file mode 100644 index 0000000..54144db --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/integral_constant.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_INTEGRAL_CONSTANT_H +#define _LIBBASTION_TYPE_TRAITS_INTEGRAL_CONSTANT_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp, _Tp __v> +struct integral_constant { + static constexpr _Tp value = __v; + using value_type = _Tp; + using type = integral_constant; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } +}; + +template<bool _Bp> +using bool_constant = integral_constant<bool, _Bp>; + +using true_type = bool_constant<true>; +using false_type = bool_constant<false>; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_INTEGRAL_CONSTANT_H diff --git a/kernel/lib/libcxx/include/__type_traits/logical_traits.h b/kernel/lib/libcxx/include/__type_traits/logical_traits.h new file mode 100644 index 0000000..c5fa11c --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/logical_traits.h @@ -0,0 +1,59 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Logical operator traits — conjunction, disjunction, negation. +// These use recursive inheritance for short-circuit evaluation. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_LOGICAL_TRAITS_H +#define _LIBBASTION_TYPE_TRAITS_LOGICAL_TRAITS_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── conjunction ───────────────────────────────────────────────────────────── + +template<class...> +struct conjunction : true_type {}; + +template<class _B1> +struct conjunction<_B1> : _B1 {}; + +template<class _B1, class... _Bn> +struct conjunction<_B1, _Bn...> + : conditional_t<bool(_B1::value), conjunction<_Bn...>, _B1> {}; + +template<class... _Bn> +inline constexpr bool conjunction_v = conjunction<_Bn...>::value; + +// ── disjunction ───────────────────────────────────────────────────────────── + +template<class...> +struct disjunction : false_type {}; + +template<class _B1> +struct disjunction<_B1> : _B1 {}; + +template<class _B1, class... _Bn> +struct disjunction<_B1, _Bn...> + : conditional_t<bool(_B1::value), _B1, disjunction<_Bn...>> {}; + +template<class... _Bn> +inline constexpr bool disjunction_v = disjunction<_Bn...>::value; + +// ── negation ──────────────────────────────────────────────────────────────── + +template<class _Bp> +struct negation : bool_constant<!bool(_Bp::value)> {}; + +template<class _Bp> +inline constexpr bool negation_v = !bool(_Bp::value); + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_LOGICAL_TRAITS_H diff --git a/kernel/lib/libcxx/include/__type_traits/other_transformations.h b/kernel/lib/libcxx/include/__type_traits/other_transformations.h new file mode 100644 index 0000000..b1b0e67 --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/other_transformations.h @@ -0,0 +1,183 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Other type transformations: enable_if, conditional, void_t, +// underlying_type, common_type, invoke_result, alignment_of, rank, extent. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_OTHER_TRANSFORMATIONS_H +#define _LIBBASTION_TYPE_TRAITS_OTHER_TRANSFORMATIONS_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/type_modifications.h> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── enable_if ─────────────────────────────────────────────────────────────── + +template<bool, class _Tp = void> +struct enable_if {}; + +template<class _Tp> +struct enable_if<true, _Tp> { using type = _Tp; }; + +template<bool _Bp, class _Tp = void> +using enable_if_t = typename enable_if<_Bp, _Tp>::type; + +// ── conditional ───────────────────────────────────────────────────────────── + +template<bool _Bp, class _If, class _Then> +struct conditional { using type = _If; }; + +template<class _If, class _Then> +struct conditional<false, _If, _Then> { using type = _Then; }; + +template<bool _Bp, class _If, class _Then> +using conditional_t = typename conditional<_Bp, _If, _Then>::type; + +// ── void_t ────────────────────────────────────────────────────────────────── + +template<class...> +using void_t = void; + +// ── underlying_type ───────────────────────────────────────────────────────── + +template<class _Tp> +struct underlying_type { using type = __underlying_type(_Tp); }; + +template<class _Tp> +using underlying_type_t = __underlying_type(_Tp); + +// ── alignment_of ──────────────────────────────────────────────────────────── + +template<class _Tp> +struct alignment_of : integral_constant<size_t, alignof(_Tp)> {}; + +template<class _Tp> +inline constexpr size_t alignment_of_v = alignof(_Tp); + +// ── rank ──────────────────────────────────────────────────────────────────── + +template<class _Tp> +struct rank : integral_constant<size_t, 0> {}; + +template<class _Tp> +struct rank<_Tp[]> : integral_constant<size_t, rank<_Tp>::value + 1> {}; + +template<class _Tp, size_t _Np> +struct rank<_Tp[_Np]> : integral_constant<size_t, rank<_Tp>::value + 1> {}; + +template<class _Tp> +inline constexpr size_t rank_v = rank<_Tp>::value; + +// ── extent ────────────────────────────────────────────────────────────────── + +template<class _Tp, unsigned _Ip = 0> +struct extent : integral_constant<size_t, 0> {}; + +template<class _Tp> +struct extent<_Tp[], 0> : integral_constant<size_t, 0> {}; + +template<class _Tp, unsigned _Ip> +struct extent<_Tp[], _Ip> : extent<_Tp, _Ip - 1> {}; + +template<class _Tp, size_t _Np> +struct extent<_Tp[_Np], 0> : integral_constant<size_t, _Np> {}; + +template<class _Tp, size_t _Np, unsigned _Ip> +struct extent<_Tp[_Np], _Ip> : extent<_Tp, _Ip - 1> {}; + +template<class _Tp, unsigned _Ip = 0> +inline constexpr size_t extent_v = extent<_Tp, _Ip>::value; + +// ── common_type ───────────────────────────────────────────────────────────── +// Simplified: supports 0, 1, 2, and N-ary forms. +// Depends on declval (forward-declared here, defined in __utility/declval.h). + +template<class _Tp> +__add_rvalue_reference(_Tp) declval() noexcept; + +namespace __detail { + +template<class _Tp, class _Up, class = void> +struct __common_type2_impl {}; + +template<class _Tp, class _Up> +struct __common_type2_impl<_Tp, _Up, + void_t<decltype(false ? declval<_Tp>() : declval<_Up>())>> { + using type = __decay(decltype(false ? declval<_Tp>() : declval<_Up>())); +}; + +} // namespace __detail + +template<class...> +struct common_type {}; + +template<class _Tp> +struct common_type<_Tp> : common_type<_Tp, _Tp> {}; + +template<class _Tp, class _Up> +struct common_type<_Tp, _Up> + : __detail::__common_type2_impl<__decay(_Tp), __decay(_Up)> {}; + +template<class _Tp, class _Up, class... _Vp> +struct common_type<_Tp, _Up, _Vp...> + : common_type<typename common_type<_Tp, _Up>::type, _Vp...> {}; + +template<class... _Tp> +using common_type_t = typename common_type<_Tp...>::type; + +// ── invoke_result ─────────────────────────────────────────────────────────── +// Simplified: supports regular callables. Member pointer invocation omitted. + +namespace __detail { + +template<class, class _Fn, class... _Args> +struct __invoke_result_impl {}; + +template<class _Fn, class... _Args> +struct __invoke_result_impl<void_t<decltype(declval<_Fn>()(declval<_Args>()...))>, _Fn, _Args...> { + using type = decltype(declval<_Fn>()(declval<_Args>()...)); +}; + +} // namespace __detail + +template<class _Fn, class... _Args> +struct invoke_result : __detail::__invoke_result_impl<void, _Fn, _Args...> {}; + +template<class _Fn, class... _Args> +using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; + +// ── is_invocable / is_invocable_r ─────────────────────────────────────────── + +namespace __detail { + +template<class, class _Fn, class... _Args> +struct __is_invocable_impl : false_type {}; + +template<class _Fn, class... _Args> +struct __is_invocable_impl<void_t<decltype(declval<_Fn>()(declval<_Args>()...))>, _Fn, _Args...> + : true_type {}; + +} // namespace __detail + +template<class _Fn, class... _Args> +struct is_invocable : __detail::__is_invocable_impl<void, _Fn, _Args...> {}; +template<class _Fn, class... _Args> +inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; + +template<class _Ret, class _Fn, class... _Args> +struct is_invocable_r + : bool_constant<is_invocable_v<_Fn, _Args...> && + __is_convertible(invoke_result_t<_Fn, _Args...>, _Ret)> {}; +template<class _Ret, class _Fn, class... _Args> +inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_OTHER_TRANSFORMATIONS_H diff --git a/kernel/lib/libcxx/include/__type_traits/primary_categories.h b/kernel/lib/libcxx/include/__type_traits/primary_categories.h new file mode 100644 index 0000000..8384907 --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/primary_categories.h @@ -0,0 +1,112 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Primary type categories — each type belongs to exactly one. +// Almost all use Clang builtins directly. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_PRIMARY_CATEGORIES_H +#define _LIBBASTION_TYPE_TRAITS_PRIMARY_CATEGORIES_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// is_void +template<class _Tp> struct is_void : bool_constant<__is_void(_Tp)> {}; +template<class _Tp> inline constexpr bool is_void_v = __is_void(_Tp); + +// is_null_pointer — no builtin, use specialization +template<class _Tp> struct is_null_pointer : false_type {}; +template<> struct is_null_pointer<nullptr_t> : true_type {}; +template<> struct is_null_pointer<const nullptr_t> : true_type {}; +template<> struct is_null_pointer<volatile nullptr_t> : true_type {}; +template<> struct is_null_pointer<const volatile nullptr_t> : true_type {}; +template<class _Tp> inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value; + +// is_integral +template<class _Tp> struct is_integral : bool_constant<__is_integral(_Tp)> {}; +template<class _Tp> inline constexpr bool is_integral_v = __is_integral(_Tp); + +// is_floating_point +template<class _Tp> struct is_floating_point : bool_constant<__is_floating_point(_Tp)> {}; +template<class _Tp> inline constexpr bool is_floating_point_v = __is_floating_point(_Tp); + +// is_array +template<class _Tp> struct is_array : bool_constant<__is_array(_Tp)> {}; +template<class _Tp> inline constexpr bool is_array_v = __is_array(_Tp); + +// is_pointer +template<class _Tp> struct is_pointer : bool_constant<__is_pointer(_Tp)> {}; +template<class _Tp> inline constexpr bool is_pointer_v = __is_pointer(_Tp); + +// is_lvalue_reference +template<class _Tp> struct is_lvalue_reference : bool_constant<__is_lvalue_reference(_Tp)> {}; +template<class _Tp> inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp); + +// is_rvalue_reference +template<class _Tp> struct is_rvalue_reference : bool_constant<__is_rvalue_reference(_Tp)> {}; +template<class _Tp> inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp); + +// is_reference +template<class _Tp> struct is_reference : bool_constant<__is_reference(_Tp)> {}; +template<class _Tp> inline constexpr bool is_reference_v = __is_reference(_Tp); + +// is_function +template<class _Tp> struct is_function : bool_constant<__is_function(_Tp)> {}; +template<class _Tp> inline constexpr bool is_function_v = __is_function(_Tp); + +// is_enum +template<class _Tp> struct is_enum : bool_constant<__is_enum(_Tp)> {}; +template<class _Tp> inline constexpr bool is_enum_v = __is_enum(_Tp); + +// is_union +template<class _Tp> struct is_union : bool_constant<__is_union(_Tp)> {}; +template<class _Tp> inline constexpr bool is_union_v = __is_union(_Tp); + +// is_class +template<class _Tp> struct is_class : bool_constant<__is_class(_Tp)> {}; +template<class _Tp> inline constexpr bool is_class_v = __is_class(_Tp); + +// is_member_pointer +template<class _Tp> struct is_member_pointer : bool_constant<__is_member_pointer(_Tp)> {}; +template<class _Tp> inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp); + +// is_member_function_pointer +template<class _Tp> struct is_member_function_pointer : bool_constant<__is_member_function_pointer(_Tp)> {}; +template<class _Tp> inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp); + +// is_member_object_pointer +template<class _Tp> struct is_member_object_pointer : bool_constant<__is_member_object_pointer(_Tp)> {}; +template<class _Tp> inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp); + +// Composite categories + +// is_arithmetic +template<class _Tp> struct is_arithmetic : bool_constant<__is_arithmetic(_Tp)> {}; +template<class _Tp> inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp); + +// is_fundamental +template<class _Tp> struct is_fundamental : bool_constant<__is_fundamental(_Tp)> {}; +template<class _Tp> inline constexpr bool is_fundamental_v = __is_fundamental(_Tp); + +// is_scalar +template<class _Tp> struct is_scalar : bool_constant<__is_scalar(_Tp)> {}; +template<class _Tp> inline constexpr bool is_scalar_v = __is_scalar(_Tp); + +// is_object +template<class _Tp> struct is_object : bool_constant<__is_object(_Tp)> {}; +template<class _Tp> inline constexpr bool is_object_v = __is_object(_Tp); + +// is_compound +template<class _Tp> struct is_compound : bool_constant<__is_compound(_Tp)> {}; +template<class _Tp> inline constexpr bool is_compound_v = __is_compound(_Tp); + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_PRIMARY_CATEGORIES_H diff --git a/kernel/lib/libcxx/include/__type_traits/type_modifications.h b/kernel/lib/libcxx/include/__type_traits/type_modifications.h new file mode 100644 index 0000000..8cff255 --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/type_modifications.h @@ -0,0 +1,93 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Type modifications — use Clang type-expression builtins. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_TYPE_MODIFICATIONS_H +#define _LIBBASTION_TYPE_TRAITS_TYPE_MODIFICATIONS_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── remove_const / remove_volatile / remove_cv ────────────────────────────── + +template<class _Tp> struct remove_const { using type = __remove_const(_Tp); }; +template<class _Tp> using remove_const_t = __remove_const(_Tp); + +template<class _Tp> struct remove_volatile { using type = __remove_volatile(_Tp); }; +template<class _Tp> using remove_volatile_t = __remove_volatile(_Tp); + +template<class _Tp> struct remove_cv { using type = __remove_cv(_Tp); }; +template<class _Tp> using remove_cv_t = __remove_cv(_Tp); + +// ── add_const / add_volatile / add_cv ─────────────────────────────────────── + +template<class _Tp> struct add_const { using type = const _Tp; }; +template<class _Tp> using add_const_t = const _Tp; + +template<class _Tp> struct add_volatile { using type = volatile _Tp; }; +template<class _Tp> using add_volatile_t = volatile _Tp; + +template<class _Tp> struct add_cv { using type = const volatile _Tp; }; +template<class _Tp> using add_cv_t = const volatile _Tp; + +// ── remove_reference ──────────────────────────────────────────────────────── + +template<class _Tp> struct remove_reference { using type = __remove_reference_t(_Tp); }; +template<class _Tp> using remove_reference_t = __remove_reference_t(_Tp); + +// ── add_lvalue_reference / add_rvalue_reference ───────────────────────────── + +template<class _Tp> struct add_lvalue_reference { using type = __add_lvalue_reference(_Tp); }; +template<class _Tp> using add_lvalue_reference_t = __add_lvalue_reference(_Tp); + +template<class _Tp> struct add_rvalue_reference { using type = __add_rvalue_reference(_Tp); }; +template<class _Tp> using add_rvalue_reference_t = __add_rvalue_reference(_Tp); + +// ── remove_pointer / add_pointer ──────────────────────────────────────────── + +template<class _Tp> struct remove_pointer { using type = __remove_pointer(_Tp); }; +template<class _Tp> using remove_pointer_t = __remove_pointer(_Tp); + +template<class _Tp> struct add_pointer { using type = __add_pointer(_Tp); }; +template<class _Tp> using add_pointer_t = __add_pointer(_Tp); + +// ── remove_extent / remove_all_extents ────────────────────────────────────── + +template<class _Tp> struct remove_extent { using type = __remove_extent(_Tp); }; +template<class _Tp> using remove_extent_t = __remove_extent(_Tp); + +template<class _Tp> struct remove_all_extents { using type = __remove_all_extents(_Tp); }; +template<class _Tp> using remove_all_extents_t = __remove_all_extents(_Tp); + +// ── remove_cvref ──────────────────────────────────────────────────────────── + +template<class _Tp> struct remove_cvref { using type = __remove_cvref(_Tp); }; +template<class _Tp> using remove_cvref_t = __remove_cvref(_Tp); + +// ── decay ─────────────────────────────────────────────────────────────────── + +template<class _Tp> struct decay { using type = __decay(_Tp); }; +template<class _Tp> using decay_t = __decay(_Tp); + +// ── type_identity ─────────────────────────────────────────────────────────── + +template<class _Tp> struct type_identity { using type = _Tp; }; +template<class _Tp> using type_identity_t = _Tp; + +// ── make_signed / make_unsigned ───────────────────────────────────────────── + +template<class _Tp> struct make_signed { using type = __make_signed(_Tp); }; +template<class _Tp> using make_signed_t = __make_signed(_Tp); + +template<class _Tp> struct make_unsigned { using type = __make_unsigned(_Tp); }; +template<class _Tp> using make_unsigned_t = __make_unsigned(_Tp); + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_TYPE_MODIFICATIONS_H diff --git a/kernel/lib/libcxx/include/__type_traits/type_properties.h b/kernel/lib/libcxx/include/__type_traits/type_properties.h new file mode 100644 index 0000000..b9b8c53 --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/type_properties.h @@ -0,0 +1,68 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Type property queries — all use Clang builtins. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_TYPE_PROPERTIES_H +#define _LIBBASTION_TYPE_TRAITS_TYPE_PROPERTIES_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// cv-qualification +template<class _Tp> struct is_const : bool_constant<__is_const(_Tp)> {}; +template<class _Tp> inline constexpr bool is_const_v = __is_const(_Tp); + +template<class _Tp> struct is_volatile : bool_constant<__is_volatile(_Tp)> {}; +template<class _Tp> inline constexpr bool is_volatile_v = __is_volatile(_Tp); + +// Triviality +template<class _Tp> struct is_trivial : bool_constant<__is_trivial(_Tp)> {}; +template<class _Tp> inline constexpr bool is_trivial_v = __is_trivial(_Tp); + +template<class _Tp> struct is_trivially_copyable : bool_constant<__is_trivially_copyable(_Tp)> {}; +template<class _Tp> inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp); + +template<class _Tp> struct is_standard_layout : bool_constant<__is_standard_layout(_Tp)> {}; +template<class _Tp> inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp); + +// Emptiness / abstractness / finality +template<class _Tp> struct is_empty : bool_constant<__is_empty(_Tp)> {}; +template<class _Tp> inline constexpr bool is_empty_v = __is_empty(_Tp); + +template<class _Tp> struct is_abstract : bool_constant<__is_abstract(_Tp)> {}; +template<class _Tp> inline constexpr bool is_abstract_v = __is_abstract(_Tp); + +template<class _Tp> struct is_final : bool_constant<__is_final(_Tp)> {}; +template<class _Tp> inline constexpr bool is_final_v = __is_final(_Tp); + +template<class _Tp> struct is_aggregate : bool_constant<__is_aggregate(_Tp)> {}; +template<class _Tp> inline constexpr bool is_aggregate_v = __is_aggregate(_Tp); + +// Signedness +template<class _Tp> struct is_signed : bool_constant<__is_signed(_Tp)> {}; +template<class _Tp> inline constexpr bool is_signed_v = __is_signed(_Tp); + +template<class _Tp> struct is_unsigned : bool_constant<__is_unsigned(_Tp)> {}; +template<class _Tp> inline constexpr bool is_unsigned_v = __is_unsigned(_Tp); + +// Bounded/unbounded arrays +template<class _Tp> struct is_bounded_array : bool_constant<__is_bounded_array(_Tp)> {}; +template<class _Tp> inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp); + +template<class _Tp> struct is_unbounded_array : bool_constant<__is_unbounded_array(_Tp)> {}; +template<class _Tp> inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp); + +// Scoped enum (C++23) +template<class _Tp> struct is_scoped_enum : bool_constant<__is_scoped_enum(_Tp)> {}; +template<class _Tp> inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp); + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_TYPE_PROPERTIES_H diff --git a/kernel/lib/libcxx/include/__type_traits/type_relationships.h b/kernel/lib/libcxx/include/__type_traits/type_relationships.h new file mode 100644 index 0000000..3efa440 --- /dev/null +++ b/kernel/lib/libcxx/include/__type_traits/type_relationships.h @@ -0,0 +1,50 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Type relationships — all use Clang builtins. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS_TYPE_RELATIONSHIPS_H +#define _LIBBASTION_TYPE_TRAITS_TYPE_RELATIONSHIPS_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// is_same +template<class _Tp, class _Up> +struct is_same : bool_constant<__is_same(_Tp, _Up)> {}; +template<class _Tp, class _Up> +inline constexpr bool is_same_v = __is_same(_Tp, _Up); + +// is_base_of +template<class _Base, class _Derived> +struct is_base_of : bool_constant<__is_base_of(_Base, _Derived)> {}; +template<class _Base, class _Derived> +inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived); + +// is_convertible +template<class _From, class _To> +struct is_convertible : bool_constant<__is_convertible(_From, _To)> {}; +template<class _From, class _To> +inline constexpr bool is_convertible_v = __is_convertible(_From, _To); + +// is_nothrow_convertible +template<class _From, class _To> +struct is_nothrow_convertible : bool_constant<__is_nothrow_convertible(_From, _To)> {}; +template<class _From, class _To> +inline constexpr bool is_nothrow_convertible_v = __is_nothrow_convertible(_From, _To); + +// is_layout_compatible (C++20) +template<class _Tp, class _Up> +struct is_layout_compatible : bool_constant<__is_layout_compatible(_Tp, _Up)> {}; +template<class _Tp, class _Up> +inline constexpr bool is_layout_compatible_v = __is_layout_compatible(_Tp, _Up); + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_TYPE_TRAITS_TYPE_RELATIONSHIPS_H diff --git a/kernel/lib/libcxx/include/__utility/declval.h b/kernel/lib/libcxx/include/__utility/declval.h new file mode 100644 index 0000000..95e8159 --- /dev/null +++ b/kernel/lib/libcxx/include/__utility/declval.h @@ -0,0 +1,20 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY_DECLVAL_H +#define _LIBBASTION_UTILITY_DECLVAL_H + +#include <__config> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp> +__add_rvalue_reference(_Tp) declval() noexcept; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY_DECLVAL_H diff --git a/kernel/lib/libcxx/include/__utility/exchange.h b/kernel/lib/libcxx/include/__utility/exchange.h new file mode 100644 index 0000000..bdea8ab --- /dev/null +++ b/kernel/lib/libcxx/include/__utility/exchange.h @@ -0,0 +1,27 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY_EXCHANGE_H +#define _LIBBASTION_UTILITY_EXCHANGE_H + +#include <__config> +#include <__utility/move.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp, class _Up = _Tp> +_LIBBASTION_CONSTEXPR_SINCE_CXX20 inline _Tp exchange(_Tp& __obj, _Up&& __new_val) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_assignable_v<_Tp&, _Up>) +{ + _Tp __old_val = std::move(__obj); + __obj = std::forward<_Up>(__new_val); + return __old_val; +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY_EXCHANGE_H diff --git a/kernel/lib/libcxx/include/__utility/in_place.h b/kernel/lib/libcxx/include/__utility/in_place.h new file mode 100644 index 0000000..924f7e7 --- /dev/null +++ b/kernel/lib/libcxx/include/__utility/in_place.h @@ -0,0 +1,34 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY_IN_PLACE_H +#define _LIBBASTION_UTILITY_IN_PLACE_H + +#include <__config> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// in_place_t +struct in_place_t { explicit in_place_t() = default; }; +inline constexpr in_place_t in_place{}; + +// in_place_type_t +template<class _Tp> +struct in_place_type_t { explicit in_place_type_t() = default; }; +template<class _Tp> +inline constexpr in_place_type_t<_Tp> in_place_type{}; + +// in_place_index_t +template<size_t _Idx> +struct in_place_index_t { explicit in_place_index_t() = default; }; +template<size_t _Idx> +inline constexpr in_place_index_t<_Idx> in_place_index{}; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY_IN_PLACE_H diff --git a/kernel/lib/libcxx/include/__utility/integer_sequence.h b/kernel/lib/libcxx/include/__utility/integer_sequence.h new file mode 100644 index 0000000..a18e97d --- /dev/null +++ b/kernel/lib/libcxx/include/__utility/integer_sequence.h @@ -0,0 +1,39 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Uses __make_integer_seq builtin for fast compilation. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY_INTEGER_SEQUENCE_H +#define _LIBBASTION_UTILITY_INTEGER_SEQUENCE_H + +#include <__config> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp, _Tp... _Ip> +struct integer_sequence { + using value_type = _Tp; + static constexpr size_t size() noexcept { return sizeof...(_Ip); } +}; + +template<size_t... _Ip> +using index_sequence = integer_sequence<size_t, _Ip...>; + +// Use __make_integer_seq builtin for O(log N) instantiation depth. +template<class _Tp, _Tp _Np> +using make_integer_sequence = __make_integer_seq<integer_sequence, _Tp, _Np>; + +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)>; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY_INTEGER_SEQUENCE_H diff --git a/kernel/lib/libcxx/include/__utility/move.h b/kernel/lib/libcxx/include/__utility/move.h new file mode 100644 index 0000000..048eb06 --- /dev/null +++ b/kernel/lib/libcxx/include/__utility/move.h @@ -0,0 +1,45 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY_MOVE_H +#define _LIBBASTION_UTILITY_MOVE_H + +#include <__config> +#include <__type_traits/other_transformations.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp> +_LIBBASTION_NODISCARD inline constexpr __remove_reference_t(_Tp)&& move(_Tp&& __t) noexcept { + return static_cast<__remove_reference_t(_Tp)&&>(__t); +} + +template<class _Tp> +_LIBBASTION_NODISCARD inline constexpr _Tp&& forward(__remove_reference_t(_Tp)& __t) noexcept { + return static_cast<_Tp&&>(__t); +} + +template<class _Tp> +_LIBBASTION_NODISCARD inline constexpr _Tp&& forward(__remove_reference_t(_Tp)&& __t) noexcept { + static_assert(!__is_lvalue_reference(_Tp), "cannot forward an rvalue as an lvalue"); + return static_cast<_Tp&&>(__t); +} + +template<class _Tp> +_LIBBASTION_NODISCARD inline constexpr +conditional_t< + !__is_nothrow_constructible(_Tp, __add_rvalue_reference(_Tp)) && + __is_constructible(_Tp, __add_lvalue_reference(const _Tp)), + const _Tp&, + _Tp&&> +move_if_noexcept(_Tp& __x) noexcept { + return std::move(__x); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY_MOVE_H diff --git a/kernel/lib/libcxx/include/__utility/pair.h b/kernel/lib/libcxx/include/__utility/pair.h new file mode 100644 index 0000000..470afcb --- /dev/null +++ b/kernel/lib/libcxx/include/__utility/pair.h @@ -0,0 +1,195 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY_PAIR_H +#define _LIBBASTION_UTILITY_PAIR_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/type_modifications.h> +#include <__type_traits/construction_traits.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _T1, class _T2> +struct pair { + using first_type = _T1; + using second_type = _T2; + + _T1 first; + _T2 second; + + // Default constructor + constexpr pair() + noexcept(is_nothrow_default_constructible_v<_T1> && is_nothrow_default_constructible_v<_T2>) + requires is_default_constructible_v<_T1> && is_default_constructible_v<_T2> + : first(), second() {} + + // Copy from elements + constexpr pair(const _T1& __a, const _T2& __b) + noexcept(is_nothrow_copy_constructible_v<_T1> && is_nothrow_copy_constructible_v<_T2>) + requires is_copy_constructible_v<_T1> && is_copy_constructible_v<_T2> + : first(__a), second(__b) {} + + // Converting constructor + template<class _U1, class _U2> + requires is_constructible_v<_T1, _U1> && is_constructible_v<_T2, _U2> + constexpr pair(_U1&& __a, _U2&& __b) + noexcept(is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>) + : first(std::forward<_U1>(__a)), second(std::forward<_U2>(__b)) {} + + // Converting copy constructor + template<class _U1, class _U2> + requires is_constructible_v<_T1, const _U1&> && is_constructible_v<_T2, const _U2&> + constexpr pair(const pair<_U1, _U2>& __p) + noexcept(is_nothrow_constructible_v<_T1, const _U1&> && is_nothrow_constructible_v<_T2, const _U2&>) + : first(__p.first), second(__p.second) {} + + // Converting move constructor + template<class _U1, class _U2> + requires is_constructible_v<_T1, _U1> && is_constructible_v<_T2, _U2> + constexpr pair(pair<_U1, _U2>&& __p) + noexcept(is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>) + : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} + + pair(const pair&) = default; + pair(pair&&) = default; + + // Assignment + constexpr pair& operator=(const pair& __p) + noexcept(is_nothrow_copy_assignable_v<_T1> && is_nothrow_copy_assignable_v<_T2>) + requires is_copy_assignable_v<_T1> && is_copy_assignable_v<_T2> + { + first = __p.first; + second = __p.second; + return *this; + } + + constexpr pair& operator=(pair&& __p) + noexcept(is_nothrow_move_assignable_v<_T1> && is_nothrow_move_assignable_v<_T2>) + requires is_move_assignable_v<_T1> && is_move_assignable_v<_T2> + { + first = std::move(__p.first); + second = std::move(__p.second); + return *this; + } + + template<class _U1, class _U2> + requires is_assignable_v<_T1&, const _U1&> && is_assignable_v<_T2&, const _U2&> + constexpr pair& operator=(const pair<_U1, _U2>& __p) { + first = __p.first; + second = __p.second; + return *this; + } + + template<class _U1, class _U2> + requires is_assignable_v<_T1&, _U1> && is_assignable_v<_T2&, _U2> + constexpr pair& operator=(pair<_U1, _U2>&& __p) { + first = std::forward<_U1>(__p.first); + second = std::forward<_U2>(__p.second); + return *this; + } + + constexpr void swap(pair& __p) + noexcept(is_nothrow_swappable_v<_T1> && is_nothrow_swappable_v<_T2>) + { + using std::swap; + swap(first, __p.first); + swap(second, __p.second); + } +}; + +// Deduction guide +template<class _T1, class _T2> +pair(_T1, _T2) -> pair<_T1, _T2>; + +// Non-member swap +template<class _T1, class _T2> +inline constexpr void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) + noexcept(noexcept(__x.swap(__y))) +{ + __x.swap(__y); +} + +// Comparison operators +template<class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr 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> +_LIBBASTION_NODISCARD inline constexpr bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__x == __y); +} + +template<class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr 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> +_LIBBASTION_NODISCARD inline constexpr bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return __y < __x; +} + +template<class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__y < __x); +} + +template<class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { + return !(__x < __y); +} + +// make_pair +template<class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr pair<__decay(_T1), __decay(_T2)> make_pair(_T1&& __a, _T2&& __b) { + return pair<__decay(_T1), __decay(_T2)>(std::forward<_T1>(__a), std::forward<_T2>(__b)); +} + +// Structured bindings support (tuple-like access) +template<class _T1, class _T2> +struct tuple_size<pair<_T1, _T2>> : integral_constant<size_t, 2> {}; + +template<size_t _Ip, class _T1, class _T2> struct tuple_element; +template<class _T1, class _T2> struct tuple_element<0, pair<_T1, _T2>> { using type = _T1; }; +template<class _T1, class _T2> struct tuple_element<1, pair<_T1, _T2>> { using type = _T2; }; + +template<size_t _Ip, class _T1, class _T2> +using tuple_element_t = typename tuple_element<_Ip, pair<_T1, _T2>>::type; + +template<size_t _Ip, class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr auto& get(pair<_T1, _T2>& __p) noexcept { + if constexpr (_Ip == 0) return __p.first; + else return __p.second; +} + +template<size_t _Ip, class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr const auto& get(const pair<_T1, _T2>& __p) noexcept { + if constexpr (_Ip == 0) return __p.first; + else return __p.second; +} + +template<size_t _Ip, class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr auto&& get(pair<_T1, _T2>&& __p) noexcept { + if constexpr (_Ip == 0) return std::move(__p.first); + else return std::move(__p.second); +} + +template<size_t _Ip, class _T1, class _T2> +_LIBBASTION_NODISCARD inline constexpr const auto&& get(const pair<_T1, _T2>&& __p) noexcept { + if constexpr (_Ip == 0) return std::move(__p.first); + else return std::move(__p.second); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY_PAIR_H diff --git a/kernel/lib/libcxx/include/__utility/swap.h b/kernel/lib/libcxx/include/__utility/swap.h new file mode 100644 index 0000000..287ea95 --- /dev/null +++ b/kernel/lib/libcxx/include/__utility/swap.h @@ -0,0 +1,91 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Also defines is_swappable / is_nothrow_swappable (they depend on swap). +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY_SWAP_H +#define _LIBBASTION_UTILITY_SWAP_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/construction_traits.h> +#include <__utility/move.h> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── swap ──────────────────────────────────────────────────────────────────── + +template<class _Tp> +inline constexpr void swap(_Tp& __a, _Tp& __b) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) +{ + _Tp __tmp = std::move(__a); + __a = std::move(__b); + __b = std::move(__tmp); +} + +template<class _Tp, size_t _Np> +inline constexpr void swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) + noexcept(noexcept(swap(*__a, *__b))) +{ + for (size_t __i = 0; __i < _Np; ++__i) + swap(__a[__i], __b[__i]); +} + +// ── is_swappable / is_nothrow_swappable ───────────────────────────────────── + +namespace __detail { + +template<class _Tp, class = void> +struct __is_swappable_impl : false_type {}; + +template<class _Tp> +struct __is_swappable_impl<_Tp, + decltype(swap(declval<_Tp&>(), declval<_Tp&>()))> : true_type {}; + +template<class _Tp, bool = __is_swappable_impl<_Tp>::value> +struct __is_nothrow_swappable_impl : false_type {}; + +template<class _Tp> +struct __is_nothrow_swappable_impl<_Tp, true> + : bool_constant<noexcept(swap(declval<_Tp&>(), declval<_Tp&>()))> {}; + +} // namespace __detail + +template<class _Tp> +struct is_swappable : __detail::__is_swappable_impl<_Tp> {}; +template<class _Tp> +inline constexpr bool is_swappable_v = is_swappable<_Tp>::value; + +template<class _Tp> +struct is_nothrow_swappable : __detail::__is_nothrow_swappable_impl<_Tp> {}; +template<class _Tp> +inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; + +// ── is_swappable_with ─────────────────────────────────────────────────────── + +namespace __detail { + +template<class _Tp, class _Up, class = void> +struct __is_swappable_with_impl : false_type {}; + +template<class _Tp, class _Up> +struct __is_swappable_with_impl<_Tp, _Up, + decltype((void)swap(declval<_Tp>(), declval<_Up>()), + (void)swap(declval<_Up>(), declval<_Tp>()))> : true_type {}; + +} // namespace __detail + +template<class _Tp, class _Up> +struct is_swappable_with : __detail::__is_swappable_with_impl<_Tp, _Up> {}; +template<class _Tp, class _Up> +inline constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY_SWAP_H diff --git a/kernel/lib/libcxx/include/__variant/variant.h b/kernel/lib/libcxx/include/__variant/variant.h new file mode 100644 index 0000000..731cb5d --- /dev/null +++ b/kernel/lib/libcxx/include/__variant/variant.h @@ -0,0 +1,421 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::variant — no-exceptions version (traps on bad access). +// valueless_by_exception() always returns false. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_VARIANT_VARIANT_H +#define _LIBBASTION_VARIANT_VARIANT_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/construction_traits.h> +#include <__type_traits/type_modifications.h> +#include <__type_traits/type_relationships.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include <__utility/in_place.h> +#include <cstddef> +#include <new> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +inline constexpr size_t variant_npos = static_cast<size_t>(-1); + +// ── monostate ─────────────────────────────────────────────────────────────── + +struct monostate {}; +constexpr bool operator==(monostate, monostate) noexcept { return true; } +constexpr bool operator<(monostate, monostate) noexcept { return false; } + +// ── Internal helpers ──────────────────────────────────────────────────────── + +namespace __variant_detail { + +// Type at index using __type_pack_element builtin. +template<size_t _Ip, class... _Types> +using __type_at = __type_pack_element<_Ip, _Types...>; + +// Find index of type in pack. +template<class _Tp, class... _Types> +struct __index_of; + +template<class _Tp, class _First, class... _Rest> +struct __index_of<_Tp, _First, _Rest...> { + static constexpr size_t value = __is_same(_Tp, _First) ? 0 : 1 + __index_of<_Tp, _Rest...>::value; +}; + +template<class _Tp> +struct __index_of<_Tp> { + static constexpr size_t value = variant_npos; +}; + +// Recursive union storage. +template<bool _TriviallyDestructible, class... _Types> +union __storage; + +// Trivially destructible case. +template<class _First, class... _Rest> +union __storage<true, _First, _Rest...> { + _First __head; + __storage<true, _Rest...> __tail; + constexpr __storage() : __tail() {} +}; + +template<> +union __storage<true> { + constexpr __storage() {} +}; + +// Non-trivially destructible case. +template<class _First, class... _Rest> +union __storage<false, _First, _Rest...> { + _First __head; + __storage<(is_trivially_destructible_v<_Rest> && ...), _Rest...> __tail; + constexpr __storage() : __tail() {} + constexpr ~__storage() requires is_trivially_destructible_v<_First> = default; + constexpr ~__storage() requires (!is_trivially_destructible_v<_First>) {} +}; + +template<> +union __storage<false> { + constexpr __storage() {} +}; + +// Get reference from storage by index. +template<size_t _Ip, bool _Triv, class... _Types> +constexpr auto& __get_storage(__storage<_Triv, _Types...>& __s) { + if constexpr (_Ip == 0) + return __s.__head; + else + return __get_storage<_Ip - 1>(__s.__tail); +} + +template<size_t _Ip, bool _Triv, class... _Types> +constexpr const auto& __get_storage(const __storage<_Triv, _Types...>& __s) { + if constexpr (_Ip == 0) + return __s.__head; + else + return __get_storage<_Ip - 1>(__s.__tail); +} + +// Destroy active alternative. +template<size_t _Np, class _Storage> +constexpr void __destroy_at(size_t __idx, _Storage& __s) { + if constexpr (_Np > 0) { + if (__idx == 0) { + using _Tp = __remove_reference_t(decltype(__s.__head)); + if constexpr (!is_trivially_destructible_v<_Tp>) + __s.__head.~_Tp(); + } else { + __destroy_at<_Np - 1>(__idx - 1, __s.__tail); + } + } +} + +} // namespace __variant_detail + +// ── variant ───────────────────────────────────────────────────────────────── + +template<class... _Types> +class variant { + static_assert(sizeof...(_Types) > 0, "variant must have at least one alternative"); + static_assert((!__is_void(_Types) && ...), "variant alternatives cannot be void"); + static_assert((!__is_reference(_Types) && ...), "variant alternatives cannot be references"); + + static constexpr bool __all_trivially_destructible = (is_trivially_destructible_v<_Types> && ...); + using __storage_t = __variant_detail::__storage<__all_trivially_destructible, _Types...>; + +public: + // ── Constructors ──────────────────────────────────────────────────── + + constexpr variant() + noexcept(is_nothrow_default_constructible_v<__variant_detail::__type_at<0, _Types...>>) + requires is_default_constructible_v<__variant_detail::__type_at<0, _Types...>> + : __index_(0) + { + using _T0 = __variant_detail::__type_at<0, _Types...>; + ::new (static_cast<void*>(&__storage_.__head)) _T0(); + } + + constexpr variant(const variant& __other) + requires (is_copy_constructible_v<_Types> && ...) + : __index_(__other.__index_) + { + __copy_construct(__other, std::make_index_sequence<sizeof...(_Types)>{}); + } + + constexpr variant(variant&& __other) + noexcept((is_nothrow_move_constructible_v<_Types> && ...)) + requires (is_move_constructible_v<_Types> && ...) + : __index_(__other.__index_) + { + __move_construct(std::move(__other), std::make_index_sequence<sizeof...(_Types)>{}); + } + + template<class _Tp> + requires (!__is_same(__decay(_Tp), variant)) && + (!__is_same(__decay(_Tp), in_place_type_t<_Tp>)) + constexpr variant(_Tp&& __t) { + constexpr size_t __idx = __find_best_match<__decay(_Tp)>(); + static_assert(__idx != variant_npos, "no matching variant alternative for this type"); + using _Alt = __variant_detail::__type_at<__idx, _Types...>; + ::new (static_cast<void*>(&__variant_detail::__get_storage<__idx>(__storage_))) _Alt(std::forward<_Tp>(__t)); + __index_ = __idx; + } + + template<size_t _Ip, class... _Args> + requires (_Ip < sizeof...(_Types)) && + is_constructible_v<__variant_detail::__type_at<_Ip, _Types...>, _Args...> + constexpr explicit variant(in_place_index_t<_Ip>, _Args&&... __args) : __index_(_Ip) { + using _Alt = __variant_detail::__type_at<_Ip, _Types...>; + ::new (static_cast<void*>(&__variant_detail::__get_storage<_Ip>(__storage_))) _Alt(std::forward<_Args>(__args)...); + } + + // ── Destructor ────────────────────────────────────────────────────── + + constexpr ~variant() requires __all_trivially_destructible = default; + + constexpr ~variant() requires (!__all_trivially_destructible) { + __variant_detail::__destroy_at<sizeof...(_Types)>(__index_, __storage_); + } + + // ── Assignment ────────────────────────────────────────────────────── + + constexpr variant& operator=(const variant& __other) + requires (is_copy_constructible_v<_Types> && ...) && (is_copy_assignable_v<_Types> && ...) + { + if (this == &__other) return *this; + __destroy_current(); + __index_ = __other.__index_; + __copy_construct(__other, std::make_index_sequence<sizeof...(_Types)>{}); + return *this; + } + + constexpr variant& operator=(variant&& __other) + noexcept((is_nothrow_move_constructible_v<_Types> && ...) && (is_nothrow_move_assignable_v<_Types> && ...)) + requires (is_move_constructible_v<_Types> && ...) && (is_move_assignable_v<_Types> && ...) + { + if (this == &__other) return *this; + __destroy_current(); + __index_ = __other.__index_; + __move_construct(std::move(__other), std::make_index_sequence<sizeof...(_Types)>{}); + return *this; + } + + // ── Observers ─────────────────────────────────────────────────────── + + _LIBBASTION_NODISCARD constexpr size_t index() const noexcept { return __index_; } + _LIBBASTION_NODISCARD constexpr bool valueless_by_exception() const noexcept { return false; } + + // ── Modifiers ─────────────────────────────────────────────────────── + + template<size_t _Ip, class... _Args> + requires is_constructible_v<__variant_detail::__type_at<_Ip, _Types...>, _Args...> + constexpr auto& emplace(_Args&&... __args) { + __destroy_current(); + using _Alt = __variant_detail::__type_at<_Ip, _Types...>; + auto* __ptr = ::new (static_cast<void*>(&__variant_detail::__get_storage<_Ip>(__storage_))) + _Alt(std::forward<_Args>(__args)...); + __index_ = _Ip; + return *__ptr; + } + + constexpr void swap(variant& __other) + noexcept((is_nothrow_move_constructible_v<_Types> && ...) && (is_nothrow_swappable_v<_Types> && ...)) + { + variant __tmp(std::move(*this)); + __destroy_current(); + __index_ = __other.__index_; + __move_construct(std::move(__other), std::make_index_sequence<sizeof...(_Types)>{}); + __other.__destroy_current(); + __other.__index_ = __tmp.__index_; + __other.__move_construct(std::move(__tmp), std::make_index_sequence<sizeof...(_Types)>{}); + } + +// Internal — accessible by get/get_if/visit. Prefixed with __ to discourage direct use. +//public: + __storage_t __storage_; + size_t __index_; + +private: + template<class _Tp> + static constexpr size_t __find_best_match() { + // Find first alternative constructible from _Tp. + return __find_constructible<_Tp, 0, _Types...>(); + } + + template<class _Tp, size_t _Ip> + static constexpr size_t __find_constructible() { return variant_npos; } + + template<class _Tp, size_t _Ip, class _First, class... _Rest> + static constexpr size_t __find_constructible() { + if constexpr (__is_same(_Tp, _First)) + return _Ip; + else + return __find_constructible<_Tp, _Ip + 1, _Rest...>(); + } + + constexpr void __destroy_current() { + if constexpr (!__all_trivially_destructible) + __variant_detail::__destroy_at<sizeof...(_Types)>(__index_, __storage_); + } + + template<size_t... _Ip> + constexpr void __copy_construct(const variant& __other, index_sequence<_Ip...>) { + (void)(( __other.__index_ == _Ip && + (::new (static_cast<void*>(&__variant_detail::__get_storage<_Ip>(__storage_))) + __variant_detail::__type_at<_Ip, _Types...>(__variant_detail::__get_storage<_Ip>(__other.__storage_)), true) + ) || ...); + } + + template<size_t... _Ip> + constexpr void __move_construct(variant&& __other, index_sequence<_Ip...>) { + (void)(( __other.__index_ == _Ip && + (::new (static_cast<void*>(&__variant_detail::__get_storage<_Ip>(__storage_))) + __variant_detail::__type_at<_Ip, _Types...>(std::move(__variant_detail::__get_storage<_Ip>(__other.__storage_))), true) + ) || ...); + } +}; + +// ── get<I> ────────────────────────────────────────────────────────────────── + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr auto& get(variant<_Types...>& __v) { + if (__v.index() != _Ip) _LIBBASTION_TRAP(); + return __variant_detail::__get_storage<_Ip>(__v.__storage_); +} + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr const auto& get(const variant<_Types...>& __v) { + if (__v.index() != _Ip) _LIBBASTION_TRAP(); + return __variant_detail::__get_storage<_Ip>(__v.__storage_); +} + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr auto&& get(variant<_Types...>&& __v) { + if (__v.index() != _Ip) _LIBBASTION_TRAP(); + return std::move(__variant_detail::__get_storage<_Ip>(__v.__storage_)); +} + +// ── get<T> ────────────────────────────────────────────────────────────────── + +template<class _Tp, class... _Types> +_LIBBASTION_NODISCARD constexpr _Tp& get(variant<_Types...>& __v) { + constexpr size_t __idx = __variant_detail::__index_of<_Tp, _Types...>::value; + static_assert(__idx != variant_npos, "type not found in variant"); + return get<__idx>(__v); +} + +template<class _Tp, class... _Types> +_LIBBASTION_NODISCARD constexpr const _Tp& get(const variant<_Types...>& __v) { + constexpr size_t __idx = __variant_detail::__index_of<_Tp, _Types...>::value; + static_assert(__idx != variant_npos, "type not found in variant"); + return get<__idx>(__v); +} + +// ── get_if ────────────────────────────────────────────────────────────────── + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr auto* get_if(variant<_Types...>* __v) noexcept { + if (!__v || __v->index() != _Ip) return static_cast<__variant_detail::__type_at<_Ip, _Types...>*>(nullptr); + return &__variant_detail::__get_storage<_Ip>(__v->__storage_); +} + +template<size_t _Ip, class... _Types> +_LIBBASTION_NODISCARD constexpr const auto* get_if(const variant<_Types...>* __v) noexcept { + if (!__v || __v->index() != _Ip) return static_cast<const __variant_detail::__type_at<_Ip, _Types...>*>(nullptr); + return &__variant_detail::__get_storage<_Ip>(__v->__storage_); +} + +// ── holds_alternative ─────────────────────────────────────────────────────── + +template<class _Tp, class... _Types> +_LIBBASTION_NODISCARD constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { + constexpr size_t __idx = __variant_detail::__index_of<_Tp, _Types...>::value; + static_assert(__idx != variant_npos, "type not found in variant"); + return __v.index() == __idx; +} + +// ── visit (single variant) ────────────────────────────────────────────────── + +namespace __variant_detail { + +template<size_t _Ip, size_t _Np, class _Visitor, class _Variant> +constexpr decltype(auto) __visit_impl(_Visitor&& __vis, _Variant&& __v) { + if constexpr (_Ip == _Np) { + _LIBBASTION_UNREACHABLE(); + } else { + if (__v.index() == _Ip) + return std::forward<_Visitor>(__vis)(get<_Ip>(std::forward<_Variant>(__v))); + return __visit_impl<_Ip + 1, _Np>(std::forward<_Visitor>(__vis), std::forward<_Variant>(__v)); + } +} + +} // namespace __variant_detail + +template<class _Visitor, class... _Types> +constexpr decltype(auto) visit(_Visitor&& __vis, variant<_Types...>& __v) { + return __variant_detail::__visit_impl<0, sizeof...(_Types)>(std::forward<_Visitor>(__vis), __v); +} + +template<class _Visitor, class... _Types> +constexpr decltype(auto) visit(_Visitor&& __vis, const variant<_Types...>& __v) { + return __variant_detail::__visit_impl<0, sizeof...(_Types)>(std::forward<_Visitor>(__vis), __v); +} + +template<class _Visitor, class... _Types> +constexpr decltype(auto) visit(_Visitor&& __vis, variant<_Types...>&& __v) { + return __variant_detail::__visit_impl<0, sizeof...(_Types)>(std::forward<_Visitor>(__vis), std::move(__v)); +} + +// ── variant_size / variant_alternative ────────────────────────────────────── + +template<class _Tp> struct variant_size; + +template<class... _Types> +struct variant_size<variant<_Types...>> : integral_constant<size_t, sizeof...(_Types)> {}; + +template<class _Tp> +struct variant_size<const _Tp> : variant_size<_Tp> {}; + +template<class _Tp> +inline constexpr size_t variant_size_v = variant_size<_Tp>::value; + +template<size_t _Ip, class _Tp> struct variant_alternative; + +template<size_t _Ip, class... _Types> +struct variant_alternative<_Ip, variant<_Types...>> { + using type = __variant_detail::__type_at<_Ip, _Types...>; +}; + +template<size_t _Ip, class _Tp> +struct variant_alternative<_Ip, const _Tp> { + using type = const typename variant_alternative<_Ip, _Tp>::type; +}; + +template<size_t _Ip, class _Tp> +using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type; + +// Non-member swap +template<class... _Types> +constexpr void swap(variant<_Types...>& __a, variant<_Types...>& __b) noexcept(noexcept(__a.swap(__b))) { + __a.swap(__b); +} + +// ── Make variant's storage_ accessible from get ───────────────────────────── +// Friendship declaration is needed. We add it via the fact that get is in std::. +// Actually, we need variant to declare get as friend. + +_LIBBASTION_END_NAMESPACE_STD + +// The get functions need access to __storage_. We achieve this by making them friends. +// But since they're already defined, we need to restructure. For simplicity, +// mark __storage_ as public in the variant class. +// This is the same approach many freestanding implementations use. + +#endif // _LIBBASTION_VARIANT_VARIANT_H diff --git a/kernel/lib/libcxx/include/algorithm b/kernel/lib/libcxx/include/algorithm new file mode 100644 index 0000000..56b71a7 --- /dev/null +++ b/kernel/lib/libcxx/include/algorithm @@ -0,0 +1,42 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ALGORITHM +#define _LIBBASTION_ALGORITHM + +#include <__config> +#include <__algorithm/minmax.h> +#include <__algorithm/find.h> +#include <__algorithm/copy.h> +#include <__algorithm/fill.h> +#include <__algorithm/comparison.h> +#include <__algorithm/sort.h> +#include <__algorithm/bound.h> +#include <__algorithm/for_each.h> + +// Also pull in swap (algorithms often need it). +#include <__utility/swap.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// swap_ranges +template<class _ForwardIt1, class _ForwardIt2> +constexpr _ForwardIt2 swap_ranges(_ForwardIt1 __first1, _ForwardIt1 __last1, _ForwardIt2 __first2) { + for (; __first1 != __last1; ++__first1, ++__first2) + swap(*__first1, *__first2); + return __first2; +} + +// iter_swap +template<class _ForwardIt1, class _ForwardIt2> +constexpr void iter_swap(_ForwardIt1 __a, _ForwardIt2 __b) { + swap(*__a, *__b); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ALGORITHM diff --git a/kernel/lib/libcxx/include/array b/kernel/lib/libcxx/include/array new file mode 100644 index 0000000..cb022a3 --- /dev/null +++ b/kernel/lib/libcxx/include/array @@ -0,0 +1,191 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::array — fixed-size aggregate container. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_ARRAY +#define _LIBBASTION_ARRAY + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/type_modifications.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include <__algorithm/fill.h> +#include <__algorithm/comparison.h> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Tp, size_t _Np> +struct array { + using value_type = _Tp; + using size_type = size_t; + using difference_type = ptrdiff_t; + using reference = _Tp&; + using const_reference = const _Tp&; + using pointer = _Tp*; + using const_pointer = const _Tp*; + using iterator = _Tp*; + using const_iterator = const _Tp*; + + // Aggregate — public data member. + _Tp __data_[_Np]; + + // Element access + _LIBBASTION_NODISCARD constexpr reference at(size_type __pos) { _LIBBASTION_ASSERT(__pos < _Np, "array::at out of range"); return __data_[__pos]; } + _LIBBASTION_NODISCARD constexpr const_reference at(size_type __pos) const { _LIBBASTION_ASSERT(__pos < _Np, "array::at out of range"); return __data_[__pos]; } + _LIBBASTION_NODISCARD constexpr reference operator[](size_type __pos) { return __data_[__pos]; } + _LIBBASTION_NODISCARD constexpr const_reference operator[](size_type __pos) const { return __data_[__pos]; } + _LIBBASTION_NODISCARD constexpr reference front() { return __data_[0]; } + _LIBBASTION_NODISCARD constexpr const_reference front() const { return __data_[0]; } + _LIBBASTION_NODISCARD constexpr reference back() { return __data_[_Np - 1]; } + _LIBBASTION_NODISCARD constexpr const_reference back() const { return __data_[_Np - 1]; } + _LIBBASTION_NODISCARD constexpr pointer data() noexcept { return __data_; } + _LIBBASTION_NODISCARD constexpr const_pointer data() const noexcept { return __data_; } + + // Iterators + _LIBBASTION_NODISCARD constexpr iterator begin() noexcept { return __data_; } + _LIBBASTION_NODISCARD constexpr const_iterator begin() const noexcept { return __data_; } + _LIBBASTION_NODISCARD constexpr const_iterator cbegin() const noexcept { return __data_; } + _LIBBASTION_NODISCARD constexpr iterator end() noexcept { return __data_ + _Np; } + _LIBBASTION_NODISCARD constexpr const_iterator end() const noexcept { return __data_ + _Np; } + _LIBBASTION_NODISCARD constexpr const_iterator cend() const noexcept { return __data_ + _Np; } + + // Capacity + _LIBBASTION_NODISCARD constexpr bool empty() const noexcept { return _Np == 0; } + _LIBBASTION_NODISCARD constexpr size_type size() const noexcept { return _Np; } + _LIBBASTION_NODISCARD constexpr size_type max_size() const noexcept { return _Np; } + + // Operations + constexpr void fill(const _Tp& __val) { std::fill(begin(), end(), __val); } + + constexpr void swap(array& __other) noexcept(is_nothrow_swappable_v<_Tp>) { + for (size_type __i = 0; __i < _Np; ++__i) + std::swap(__data_[__i], __other.__data_[__i]); + } +}; + +// Zero-size specialization +template<class _Tp> +struct array<_Tp, 0> { + using value_type = _Tp; + using size_type = size_t; + using difference_type = ptrdiff_t; + using reference = _Tp&; + using const_reference = const _Tp&; + using pointer = _Tp*; + using const_pointer = const _Tp*; + using iterator = _Tp*; + using const_iterator = const _Tp*; + + // No __data_ member for zero-size array. + + _LIBBASTION_NODISCARD constexpr reference at(size_type) { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr const_reference at(size_type) const { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr reference operator[](size_type) { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr const_reference operator[](size_type) const { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr reference front() { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr const_reference front() const { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr reference back() { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr const_reference back() const { _LIBBASTION_TRAP(); } + _LIBBASTION_NODISCARD constexpr pointer data() noexcept { return nullptr; } + _LIBBASTION_NODISCARD constexpr const_pointer data() const noexcept { return nullptr; } + + _LIBBASTION_NODISCARD constexpr iterator begin() noexcept { return nullptr; } + _LIBBASTION_NODISCARD constexpr const_iterator begin() const noexcept { return nullptr; } + _LIBBASTION_NODISCARD constexpr const_iterator cbegin() const noexcept { return nullptr; } + _LIBBASTION_NODISCARD constexpr iterator end() noexcept { return nullptr; } + _LIBBASTION_NODISCARD constexpr const_iterator end() const noexcept { return nullptr; } + _LIBBASTION_NODISCARD constexpr const_iterator cend() const noexcept { return nullptr; } + + _LIBBASTION_NODISCARD constexpr bool empty() const noexcept { return true; } + _LIBBASTION_NODISCARD constexpr size_type size() const noexcept { return 0; } + _LIBBASTION_NODISCARD constexpr size_type max_size() const noexcept { return 0; } + + constexpr void fill(const _Tp&) {} + constexpr void swap(array&) noexcept {} +}; + +// Deduction guide +template<class _Tp, class... _Up> +array(_Tp, _Up...) -> array<_Tp, 1 + sizeof...(_Up)>; + +// Non-member swap +template<class _Tp, size_t _Np> +inline constexpr void swap(array<_Tp, _Np>& __a, array<_Tp, _Np>& __b) noexcept(noexcept(__a.swap(__b))) { + __a.swap(__b); +} + +// Comparison +template<class _Tp, size_t _Np> +_LIBBASTION_NODISCARD constexpr bool operator==(const array<_Tp, _Np>& __a, const array<_Tp, _Np>& __b) { + return std::equal(__a.begin(), __a.end(), __b.begin()); +} + +template<class _Tp, size_t _Np> +_LIBBASTION_NODISCARD constexpr bool operator!=(const array<_Tp, _Np>& __a, const array<_Tp, _Np>& __b) { + return !(__a == __b); +} + +// get<I> for structured bindings +template<size_t _Ip, class _Tp, size_t _Np> +_LIBBASTION_NODISCARD constexpr _Tp& get(array<_Tp, _Np>& __a) noexcept { + static_assert(_Ip < _Np, "array index out of range"); + return __a.__data_[_Ip]; +} + +template<size_t _Ip, class _Tp, size_t _Np> +_LIBBASTION_NODISCARD constexpr const _Tp& get(const array<_Tp, _Np>& __a) noexcept { + static_assert(_Ip < _Np, "array index out of range"); + return __a.__data_[_Ip]; +} + +template<size_t _Ip, class _Tp, size_t _Np> +_LIBBASTION_NODISCARD constexpr _Tp&& get(array<_Tp, _Np>&& __a) noexcept { + static_assert(_Ip < _Np, "array index out of range"); + return std::move(__a.__data_[_Ip]); +} + +// tuple_size / tuple_element for structured bindings +template<class _Tp, size_t _Np> +struct tuple_size<array<_Tp, _Np>> : integral_constant<size_t, _Np> {}; + +template<size_t _Ip, class _Tp, size_t _Np> +struct tuple_element<_Ip, array<_Tp, _Np>> { + static_assert(_Ip < _Np, "array index out of range"); + using type = _Tp; +}; + +// to_array (C++20) +namespace __detail { + +template<class _Tp, size_t _Np, size_t... _Idx> +constexpr array<remove_cv_t<_Tp>, _Np> __to_array_impl(_Tp (&__a)[_Np], index_sequence<_Idx...>) { + return {{__a[_Idx]...}}; +} + +template<class _Tp, size_t _Np, size_t... _Idx> +constexpr array<remove_cv_t<_Tp>, _Np> __to_array_impl(_Tp (&&__a)[_Np], index_sequence<_Idx...>) { + return {{std::move(__a[_Idx])...}}; +} + +} // namespace __detail + +template<class _Tp, size_t _Np> +constexpr array<remove_cv_t<_Tp>, _Np> to_array(_Tp (&__a)[_Np]) { + return __detail::__to_array_impl(__a, make_index_sequence<_Np>{}); +} + +template<class _Tp, size_t _Np> +constexpr array<remove_cv_t<_Tp>, _Np> to_array(_Tp (&&__a)[_Np]) { + return __detail::__to_array_impl(std::move(__a), make_index_sequence<_Np>{}); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_ARRAY diff --git a/kernel/lib/libcxx/include/bit b/kernel/lib/libcxx/include/bit new file mode 100644 index 0000000..d30fdb2 --- /dev/null +++ b/kernel/lib/libcxx/include/bit @@ -0,0 +1,14 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_BIT +#define _LIBBASTION_BIT + +#include <__config> +#include <__bit/bit.h> + +#endif // _LIBBASTION_BIT diff --git a/kernel/lib/libcxx/include/concepts b/kernel/lib/libcxx/include/concepts new file mode 100644 index 0000000..8e7e3df --- /dev/null +++ b/kernel/lib/libcxx/include/concepts @@ -0,0 +1,141 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// C++20 concepts — most use Clang builtins directly. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_CONCEPTS +#define _LIBBASTION_CONCEPTS + +#include <__config> +#include <type_traits> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── Core language concepts ────────────────────────────────────────────────── + +template<class _Tp, class _Up> +concept same_as = __is_same(_Tp, _Up) && __is_same(_Up, _Tp); + +template<class _Derived, class _Base> +concept derived_from = + __is_base_of(_Base, _Derived) && + __is_convertible(const volatile _Derived*, const volatile _Base*); + +template<class _From, class _To> +concept convertible_to = + __is_convertible(_From, _To) && + requires { static_cast<_To>(declval<_From>()); }; + +// ── Arithmetic concepts ───────────────────────────────────────────────────── + +template<class _Tp> +concept integral = __is_integral(_Tp); + +template<class _Tp> +concept signed_integral = integral<_Tp> && __is_signed(_Tp); + +template<class _Tp> +concept unsigned_integral = integral<_Tp> && __is_unsigned(_Tp); + +template<class _Tp> +concept floating_point = __is_floating_point(_Tp); + +// ── Object concepts ───────────────────────────────────────────────────────── + +template<class _Tp> +concept destructible = __is_nothrow_destructible(_Tp); + +template<class _Tp, class... _Args> +concept constructible_from = destructible<_Tp> && __is_constructible(_Tp, _Args...); + +template<class _Tp> +concept default_initializable = constructible_from<_Tp> && + requires { _Tp{}; } && requires { ::new _Tp; }; + +template<class _Tp> +concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; + +template<class _Tp> +concept copy_constructible = + move_constructible<_Tp> && + constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && + constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> && + constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>; + +// ── Comparison concepts ───────────────────────────────────────────────────── + +namespace __detail { + +template<class _Tp, class _Up> +concept __weakly_eq_comparable_with = + requires(const remove_reference_t<_Tp>& __t, const remove_reference_t<_Up>& __u) { + { __t == __u } -> convertible_to<bool>; + { __t != __u } -> convertible_to<bool>; + { __u == __t } -> convertible_to<bool>; + { __u != __t } -> convertible_to<bool>; + }; + +template<class _Tp, class _Up> +concept __partially_ordered_with = + requires(const remove_reference_t<_Tp>& __t, const remove_reference_t<_Up>& __u) { + { __t < __u } -> convertible_to<bool>; + { __t > __u } -> convertible_to<bool>; + { __t <= __u } -> convertible_to<bool>; + { __t >= __u } -> convertible_to<bool>; + { __u < __t } -> convertible_to<bool>; + { __u > __t } -> convertible_to<bool>; + { __u <= __t } -> convertible_to<bool>; + { __u >= __t } -> convertible_to<bool>; + }; + +} // namespace __detail + +template<class _Tp> +concept equality_comparable = __detail::__weakly_eq_comparable_with<_Tp, _Tp>; + +template<class _Tp, class _Up> +concept equality_comparable_with = + equality_comparable<_Tp> && equality_comparable<_Up> && + __detail::__weakly_eq_comparable_with<_Tp, _Up>; + +template<class _Tp> +concept totally_ordered = + equality_comparable<_Tp> && __detail::__partially_ordered_with<_Tp, _Tp>; + +template<class _Tp, class _Up> +concept totally_ordered_with = + totally_ordered<_Tp> && totally_ordered<_Up> && + equality_comparable_with<_Tp, _Up> && + __detail::__partially_ordered_with<_Tp, _Up>; + +// ── Callable concepts ─────────────────────────────────────────────────────── + +template<class _Fn, class... _Args> +concept invocable = is_invocable_v<_Fn, _Args...>; + +template<class _Fn, class... _Args> +concept regular_invocable = invocable<_Fn, _Args...>; + +// ── Movable / Copyable / Semiregular / Regular ────────────────────────────── + +template<class _Tp> +concept movable = __is_object(_Tp) && move_constructible<_Tp> && + requires(_Tp& __a, _Tp& __b) { { std::swap(__a, __b) }; }; + +template<class _Tp> +concept copyable = copy_constructible<_Tp> && movable<_Tp> && + __is_assignable(__add_lvalue_reference(_Tp), __add_lvalue_reference(const _Tp)); + +template<class _Tp> +concept semiregular = copyable<_Tp> && default_initializable<_Tp>; + +template<class _Tp> +concept regular = semiregular<_Tp> && equality_comparable<_Tp>; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_CONCEPTS diff --git a/kernel/lib/libcxx/include/cstddef b/kernel/lib/libcxx/include/cstddef new file mode 100644 index 0000000..e1230c2 --- /dev/null +++ b/kernel/lib/libcxx/include/cstddef @@ -0,0 +1,68 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_CSTDDEF +#define _LIBBASTION_CSTDDEF + +#include <__config> +#include <stddef.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +using ::size_t; +using ::ptrdiff_t; +using ::nullptr_t; +using ::max_align_t; + +// std::byte (C++17) +enum class byte : unsigned char {}; + +// Bitwise operators for std::byte. +_LIBBASTION_NODISCARD inline constexpr byte operator|(byte lhs, byte rhs) noexcept { + return static_cast<byte>(static_cast<unsigned char>(lhs) | static_cast<unsigned char>(rhs)); +} + +_LIBBASTION_NODISCARD inline constexpr byte operator&(byte lhs, byte rhs) noexcept { + return static_cast<byte>(static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs)); +} + +_LIBBASTION_NODISCARD inline constexpr byte operator^(byte lhs, byte rhs) noexcept { + return static_cast<byte>(static_cast<unsigned char>(lhs) ^ static_cast<unsigned char>(rhs)); +} + +_LIBBASTION_NODISCARD inline constexpr byte operator~(byte b) noexcept { + return static_cast<byte>(~static_cast<unsigned char>(b)); +} + +inline constexpr byte& operator|=(byte& lhs, byte rhs) noexcept { return lhs = lhs | rhs; } +inline constexpr byte& operator&=(byte& lhs, byte rhs) noexcept { return lhs = lhs & rhs; } +inline constexpr byte& operator^=(byte& lhs, byte rhs) noexcept { return lhs = lhs ^ rhs; } + +template<class IntegerType> +_LIBBASTION_NODISCARD inline constexpr byte operator<<(byte b, IntegerType shift) noexcept { + return static_cast<byte>(static_cast<unsigned char>(b) << shift); +} + +template<class IntegerType> +_LIBBASTION_NODISCARD inline constexpr byte operator>>(byte b, IntegerType shift) noexcept { + return static_cast<byte>(static_cast<unsigned char>(b) >> shift); +} + +template<class IntegerType> +inline constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept { return b = b << shift; } + +template<class IntegerType> +inline constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept { return b = b >> shift; } + +template<class IntegerType> +_LIBBASTION_NODISCARD inline constexpr IntegerType to_integer(byte b) noexcept { + return static_cast<IntegerType>(b); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_CSTDDEF diff --git a/kernel/lib/libcxx/include/cstdint b/kernel/lib/libcxx/include/cstdint new file mode 100644 index 0000000..f5a76da --- /dev/null +++ b/kernel/lib/libcxx/include/cstdint @@ -0,0 +1,53 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_CSTDINT +#define _LIBBASTION_CSTDINT + +#include <__config> +#include <stdint.h> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +using ::int8_t; +using ::int16_t; +using ::int32_t; +using ::int64_t; + +using ::uint8_t; +using ::uint16_t; +using ::uint32_t; +using ::uint64_t; + +using ::int_least8_t; +using ::int_least16_t; +using ::int_least32_t; +using ::int_least64_t; + +using ::uint_least8_t; +using ::uint_least16_t; +using ::uint_least32_t; +using ::uint_least64_t; + +using ::int_fast8_t; +using ::int_fast16_t; +using ::int_fast32_t; +using ::int_fast64_t; + +using ::uint_fast8_t; +using ::uint_fast16_t; +using ::uint_fast32_t; +using ::uint_fast64_t; + +using ::intptr_t; +using ::uintptr_t; +using ::intmax_t; +using ::uintmax_t; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_CSTDINT diff --git a/kernel/lib/libcxx/include/expected b/kernel/lib/libcxx/include/expected new file mode 100644 index 0000000..31da8c1 --- /dev/null +++ b/kernel/lib/libcxx/include/expected @@ -0,0 +1,14 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_EXPECTED +#define _LIBBASTION_EXPECTED + +#include <__config> +#include <__expected/expected.h> + +#endif // _LIBBASTION_EXPECTED diff --git a/kernel/lib/libcxx/include/functional b/kernel/lib/libcxx/include/functional new file mode 100644 index 0000000..a0a76c9 --- /dev/null +++ b/kernel/lib/libcxx/include/functional @@ -0,0 +1,16 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_FUNCTIONAL +#define _LIBBASTION_FUNCTIONAL + +#include <__config> +#include <__functional/comparisons.h> +#include <__functional/arithmetic.h> +#include <__functional/hash.h> + +#endif // _LIBBASTION_FUNCTIONAL diff --git a/kernel/lib/libcxx/include/initializer_list b/kernel/lib/libcxx/include/initializer_list new file mode 100644 index 0000000..31aff39 --- /dev/null +++ b/kernel/lib/libcxx/include/initializer_list @@ -0,0 +1,57 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// The compiler generates calls to std::initializer_list's private constructor. +// The memory layout MUST match what Clang expects. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_INITIALIZER_LIST +#define _LIBBASTION_INITIALIZER_LIST + +#include <__config> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +template<class _Ep> +class initializer_list { +public: + using value_type = _Ep; + using reference = const _Ep&; + using const_reference = const _Ep&; + using size_type = size_t; + using iterator = const _Ep*; + using const_iterator = const _Ep*; + + _LIBBASTION_NODISCARD constexpr size_type size() const noexcept { return __size_; } + _LIBBASTION_NODISCARD constexpr const_iterator begin() const noexcept { return __begin_; } + _LIBBASTION_NODISCARD constexpr const_iterator end() const noexcept { return __begin_ + __size_; } + + constexpr initializer_list() noexcept : __begin_(nullptr), __size_(0) {} + +private: + // Clang constructs initializer_list with (pointer, size). + // This constructor and the field order MUST match the compiler's ABI. + constexpr initializer_list(const _Ep* __b, size_t __s) noexcept + : __begin_(__b), __size_(__s) {} + + const _Ep* __begin_; + size_t __size_; +}; + +template<class _Ep> +_LIBBASTION_NODISCARD inline constexpr const _Ep* begin(initializer_list<_Ep> __il) noexcept { + return __il.begin(); +} + +template<class _Ep> +_LIBBASTION_NODISCARD inline constexpr const _Ep* end(initializer_list<_Ep> __il) noexcept { + return __il.end(); +} + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_INITIALIZER_LIST diff --git a/kernel/lib/libcxx/include/limits b/kernel/lib/libcxx/include/limits new file mode 100644 index 0000000..9e58c5c --- /dev/null +++ b/kernel/lib/libcxx/include/limits @@ -0,0 +1,194 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::numeric_limits — uses compiler-defined macros for all values. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_LIMITS +#define _LIBBASTION_LIMITS + +#include <__config> +#include <cstdint> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +enum float_round_style { + round_indeterminate = -1, + round_toward_zero = 0, + round_to_nearest = 1, + round_toward_infinity = 2, + round_toward_neg_infinity = 3, +}; + +enum float_denorm_style { + denorm_indeterminate = -1, + denorm_absent = 0, + denorm_present = 1, +}; + +// Primary template — all members false/zero for non-arithmetic types. +template<class _Tp> +class numeric_limits { +public: + static constexpr bool is_specialized = false; + static constexpr _Tp min() noexcept { return _Tp(); } + static constexpr _Tp max() noexcept { return _Tp(); } + static constexpr _Tp lowest() noexcept { return _Tp(); } + static constexpr int digits = 0; + static constexpr int digits10 = 0; + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 0; + static constexpr _Tp epsilon() noexcept { return _Tp(); } + static constexpr _Tp round_error() noexcept { return _Tp(); } + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr _Tp infinity() noexcept { return _Tp(); } + static constexpr _Tp quiet_NaN() noexcept { return _Tp(); } + static constexpr _Tp signaling_NaN() noexcept { return _Tp(); } + static constexpr _Tp denorm_min() noexcept { return _Tp(); } + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = false; + static constexpr bool is_modulo = false; + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; +}; + +// Macro to generate integer specializations. +#define _LIBBASTION_NUMERIC_LIMITS_INT(_Type, _IsSigned, _Digits, _Digits10, _Min, _Max) \ +template<> \ +class numeric_limits<_Type> { \ +public: \ + static constexpr bool is_specialized = true; \ + static constexpr _Type min() noexcept { return _Min; } \ + static constexpr _Type max() noexcept { return _Max; } \ + static constexpr _Type lowest() noexcept { return _Min; } \ + static constexpr int digits = _Digits; \ + static constexpr int digits10 = _Digits10; \ + static constexpr int max_digits10 = 0; \ + static constexpr bool is_signed = _IsSigned; \ + static constexpr bool is_integer = true; \ + static constexpr bool is_exact = true; \ + static constexpr int radix = 2; \ + static constexpr _Type epsilon() noexcept { return 0; } \ + static constexpr _Type round_error() noexcept { return 0; } \ + static constexpr int min_exponent = 0; \ + static constexpr int min_exponent10 = 0; \ + static constexpr int max_exponent = 0; \ + static constexpr int max_exponent10 = 0; \ + static constexpr bool has_infinity = false; \ + static constexpr bool has_quiet_NaN = false; \ + static constexpr bool has_signaling_NaN = false; \ + static constexpr float_denorm_style has_denorm = denorm_absent; \ + static constexpr bool has_denorm_loss = false; \ + static constexpr _Type infinity() noexcept { return 0; } \ + static constexpr _Type quiet_NaN() noexcept { return 0; } \ + static constexpr _Type signaling_NaN() noexcept { return 0; } \ + static constexpr _Type denorm_min() noexcept { return 0; } \ + static constexpr bool is_iec559 = false; \ + static constexpr bool is_bounded = true; \ + static constexpr bool is_modulo = !_IsSigned; \ + static constexpr bool traps = false; \ + static constexpr bool tinyness_before = false; \ + static constexpr float_round_style round_style = round_toward_zero; \ +}; + +_LIBBASTION_NUMERIC_LIMITS_INT(bool, false, 1, 0, false, true) +_LIBBASTION_NUMERIC_LIMITS_INT(char, (__CHAR_BIT__ == 8 && (char(-1) < char(0))), __CHAR_BIT__ - (char(-1) < char(0) ? 1 : 0), ((__CHAR_BIT__ - (char(-1) < char(0) ? 1 : 0)) * 301) / 1000, __SCHAR_MAX__ * (char(-1) < char(0) ? -1 : 0) + (char(-1) < char(0) ? -1 : 0), char(-1) < char(0) ? __SCHAR_MAX__ : static_cast<char>(__SCHAR_MAX__ * 2U + 1U)) +_LIBBASTION_NUMERIC_LIMITS_INT(signed char, true, 7, 2, -__SCHAR_MAX__ - 1, __SCHAR_MAX__) +_LIBBASTION_NUMERIC_LIMITS_INT(unsigned char, false, 8, 2, 0, static_cast<unsigned char>(__SCHAR_MAX__ * 2U + 1U)) +_LIBBASTION_NUMERIC_LIMITS_INT(char8_t, false, 8, 2, 0, static_cast<char8_t>(__SCHAR_MAX__ * 2U + 1U)) +_LIBBASTION_NUMERIC_LIMITS_INT(char16_t, false, 16, 4, 0, static_cast<char16_t>(65535)) +_LIBBASTION_NUMERIC_LIMITS_INT(char32_t, false, 32, 9, 0, static_cast<char32_t>(4294967295U)) +_LIBBASTION_NUMERIC_LIMITS_INT(wchar_t, __WCHAR_MAX__ != __WCHAR_MAX__ * 2U + 1U, sizeof(wchar_t) * __CHAR_BIT__ - (__WCHAR_MAX__ != __WCHAR_MAX__ * 2U + 1U ? 1 : 0), ((sizeof(wchar_t) * __CHAR_BIT__ - (__WCHAR_MAX__ != __WCHAR_MAX__ * 2U + 1U ? 1 : 0)) * 301) / 1000, static_cast<wchar_t>(__WCHAR_MIN__), static_cast<wchar_t>(__WCHAR_MAX__)) +_LIBBASTION_NUMERIC_LIMITS_INT(short, true, __SIZEOF_SHORT__ * 8 - 1, ((__SIZEOF_SHORT__ * 8 - 1) * 301) / 1000, -__SHRT_MAX__ - 1, __SHRT_MAX__) +_LIBBASTION_NUMERIC_LIMITS_INT(unsigned short, false, __SIZEOF_SHORT__ * 8, (__SIZEOF_SHORT__ * 8 * 301) / 1000, 0, static_cast<unsigned short>(__SHRT_MAX__ * 2U + 1U)) +_LIBBASTION_NUMERIC_LIMITS_INT(int, true, __SIZEOF_INT__ * 8 - 1, ((__SIZEOF_INT__ * 8 - 1) * 301) / 1000, -__INT_MAX__ - 1, __INT_MAX__) +_LIBBASTION_NUMERIC_LIMITS_INT(unsigned int, false, __SIZEOF_INT__ * 8, (__SIZEOF_INT__ * 8 * 301) / 1000, 0, __INT_MAX__ * 2U + 1U) +_LIBBASTION_NUMERIC_LIMITS_INT(long, true, __SIZEOF_LONG__ * 8 - 1, ((__SIZEOF_LONG__ * 8 - 1) * 301) / 1000, -__LONG_MAX__ - 1L, __LONG_MAX__) +_LIBBASTION_NUMERIC_LIMITS_INT(unsigned long, false, __SIZEOF_LONG__ * 8, (__SIZEOF_LONG__ * 8 * 301) / 1000, 0UL, __LONG_MAX__ * 2UL + 1UL) +_LIBBASTION_NUMERIC_LIMITS_INT(long long, true, __SIZEOF_LONG_LONG__ * 8 - 1, ((__SIZEOF_LONG_LONG__ * 8 - 1) * 301) / 1000, -__LONG_LONG_MAX__ - 1LL, __LONG_LONG_MAX__) +_LIBBASTION_NUMERIC_LIMITS_INT(unsigned long long, false, __SIZEOF_LONG_LONG__ * 8, (__SIZEOF_LONG_LONG__ * 8 * 301) / 1000, 0ULL, __LONG_LONG_MAX__ * 2ULL + 1ULL) + +#undef _LIBBASTION_NUMERIC_LIMITS_INT + +// Float specialization +#define _LIBBASTION_NUMERIC_LIMITS_FLOAT(_Type, _Mant, _Mant10, _MaxDig10, _MinExp, _MinExp10, _MaxExp, _MaxExp10, _Min, _Max, _Eps, _Inf, _Nan, _DenMin) \ +template<> \ +class numeric_limits<_Type> { \ +public: \ + static constexpr bool is_specialized = true; \ + static constexpr _Type min() noexcept { return _Min; } \ + static constexpr _Type max() noexcept { return _Max; } \ + static constexpr _Type lowest() noexcept { return -_Max; } \ + static constexpr int digits = _Mant; \ + static constexpr int digits10 = _Mant10; \ + static constexpr int max_digits10 = _MaxDig10; \ + static constexpr bool is_signed = true; \ + static constexpr bool is_integer = false; \ + static constexpr bool is_exact = false; \ + static constexpr int radix = 2; \ + static constexpr _Type epsilon() noexcept { return _Eps; } \ + static constexpr _Type round_error() noexcept { return 0.5; } \ + static constexpr int min_exponent = _MinExp; \ + static constexpr int min_exponent10 = _MinExp10; \ + static constexpr int max_exponent = _MaxExp; \ + static constexpr int max_exponent10 = _MaxExp10; \ + static constexpr bool has_infinity = true; \ + static constexpr bool has_quiet_NaN = true; \ + static constexpr bool has_signaling_NaN = true; \ + static constexpr float_denorm_style has_denorm = denorm_present; \ + static constexpr bool has_denorm_loss = false; \ + static constexpr _Type infinity() noexcept { return _Inf; } \ + static constexpr _Type quiet_NaN() noexcept { return _Nan; } \ + static constexpr _Type signaling_NaN() noexcept { return _Nan; } \ + static constexpr _Type denorm_min() noexcept { return _DenMin; } \ + static constexpr bool is_iec559 = true; \ + static constexpr bool is_bounded = true; \ + static constexpr bool is_modulo = false; \ + static constexpr bool traps = false; \ + static constexpr bool tinyness_before = false; \ + static constexpr float_round_style round_style = round_to_nearest; \ +}; + +_LIBBASTION_NUMERIC_LIMITS_FLOAT(float, + __FLT_MANT_DIG__, __FLT_DIG__, __FLT_DECIMAL_DIG__, + __FLT_MIN_EXP__, __FLT_MIN_10_EXP__, __FLT_MAX_EXP__, __FLT_MAX_10_EXP__, + __FLT_MIN__, __FLT_MAX__, __FLT_EPSILON__, + __builtin_huge_valf(), __builtin_nanf(""), __FLT_DENORM_MIN__) + +_LIBBASTION_NUMERIC_LIMITS_FLOAT(double, + __DBL_MANT_DIG__, __DBL_DIG__, __DBL_DECIMAL_DIG__, + __DBL_MIN_EXP__, __DBL_MIN_10_EXP__, __DBL_MAX_EXP__, __DBL_MAX_10_EXP__, + __DBL_MIN__, __DBL_MAX__, __DBL_EPSILON__, + __builtin_huge_val(), __builtin_nan(""), __DBL_DENORM_MIN__) + +_LIBBASTION_NUMERIC_LIMITS_FLOAT(long double, + __LDBL_MANT_DIG__, __LDBL_DIG__, __LDBL_DECIMAL_DIG__, + __LDBL_MIN_EXP__, __LDBL_MIN_10_EXP__, __LDBL_MAX_EXP__, __LDBL_MAX_10_EXP__, + __LDBL_MIN__, __LDBL_MAX__, __LDBL_EPSILON__, + __builtin_huge_vall(), __builtin_nanl(""), __LDBL_DENORM_MIN__) + +#undef _LIBBASTION_NUMERIC_LIMITS_FLOAT + +// cv-qualified types delegate to unqualified +template<class _Tp> class numeric_limits<const _Tp> : public numeric_limits<_Tp> {}; +template<class _Tp> class numeric_limits<volatile _Tp> : public numeric_limits<_Tp> {}; +template<class _Tp> class numeric_limits<const volatile _Tp> : public numeric_limits<_Tp> {}; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_LIMITS diff --git a/kernel/lib/libcxx/include/memory b/kernel/lib/libcxx/include/memory new file mode 100644 index 0000000..72ea03c --- /dev/null +++ b/kernel/lib/libcxx/include/memory @@ -0,0 +1,16 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_MEMORY +#define _LIBBASTION_MEMORY + +#include <__config> +#include <__memory/addressof.h> +#include <__memory/pointer_traits.h> +#include <__memory/unique_ptr.h> + +#endif // _LIBBASTION_MEMORY diff --git a/kernel/lib/libcxx/include/new b/kernel/lib/libcxx/include/new new file mode 100644 index 0000000..3e16108 --- /dev/null +++ b/kernel/lib/libcxx/include/new @@ -0,0 +1,51 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Declares placement new and related facilities. +// The actual operator new/delete are defined in cxxabi.cpp. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_NEW +#define _LIBBASTION_NEW + +#include <__config> +#include <cstddef> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +struct nothrow_t { explicit nothrow_t() = default; }; +inline constexpr nothrow_t nothrow{}; + +enum class align_val_t : size_t {}; + +// launder +template<class _Tp> +_LIBBASTION_NODISCARD inline constexpr _Tp* launder(_Tp* __p) noexcept { + return __builtin_launder(__p); +} + +// hardware_destructive_interference_size / hardware_constructive_interference_size +#ifdef __GCC_DESTRUCTIVE_SIZE +inline constexpr size_t hardware_destructive_interference_size = __GCC_DESTRUCTIVE_SIZE; +inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUCTIVE_SIZE; +#else +inline constexpr size_t hardware_destructive_interference_size = 64; +inline constexpr size_t hardware_constructive_interference_size = 64; +#endif + +_LIBBASTION_END_NAMESPACE_STD + +// Placement new/delete — these must be at global scope. +// Guard against redefinition from cxxabi.cpp or compiler headers. +#ifndef _LIBBASTION_PLACEMENT_NEW_DEFINED +#define _LIBBASTION_PLACEMENT_NEW_DEFINED +_LIBBASTION_NODISCARD inline void* operator new(std::size_t, void* __p) noexcept { return __p; } +_LIBBASTION_NODISCARD inline void* operator new[](std::size_t, void* __p) noexcept { return __p; } +inline void operator delete(void*, void*) noexcept {} +inline void operator delete[](void*, void*) noexcept {} +#endif + +#endif // _LIBBASTION_NEW diff --git a/kernel/lib/libcxx/include/optional b/kernel/lib/libcxx/include/optional new file mode 100644 index 0000000..6423028 --- /dev/null +++ b/kernel/lib/libcxx/include/optional @@ -0,0 +1,14 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_OPTIONAL +#define _LIBBASTION_OPTIONAL + +#include <__config> +#include <__optional/optional.h> + +#endif // _LIBBASTION_OPTIONAL diff --git a/kernel/lib/libcxx/include/source_location b/kernel/lib/libcxx/include/source_location new file mode 100644 index 0000000..0d5052c --- /dev/null +++ b/kernel/lib/libcxx/include/source_location @@ -0,0 +1,49 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::source_location (C++20) — wraps compiler builtins. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_SOURCE_LOCATION +#define _LIBBASTION_SOURCE_LOCATION + +#include <__config> +#include <cstdint> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +class source_location { +public: + static consteval source_location current( + const char* __file = __builtin_FILE(), + const char* __func = __builtin_FUNCTION(), + unsigned __line = __builtin_LINE(), + unsigned __col = __builtin_COLUMN()) noexcept { + source_location __loc; + __loc.__file_ = __file; + __loc.__func_ = __func; + __loc.__line_ = __line; + __loc.__col_ = __col; + return __loc; + } + + constexpr source_location() noexcept = default; + + _LIBBASTION_NODISCARD constexpr const char* file_name() const noexcept { return __file_; } + _LIBBASTION_NODISCARD constexpr const char* function_name() const noexcept { return __func_; } + _LIBBASTION_NODISCARD constexpr uint_least32_t line() const noexcept { return __line_; } + _LIBBASTION_NODISCARD constexpr uint_least32_t column() const noexcept { return __col_; } + +private: + const char* __file_ = ""; + const char* __func_ = ""; + uint_least32_t __line_ = 0; + uint_least32_t __col_ = 0; +}; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_SOURCE_LOCATION 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 diff --git a/kernel/lib/libcxx/include/string_view b/kernel/lib/libcxx/include/string_view new file mode 100644 index 0000000..18ceb13 --- /dev/null +++ b/kernel/lib/libcxx/include/string_view @@ -0,0 +1,269 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// std::basic_string_view with minimal inline char_traits. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_STRING_VIEW +#define _LIBBASTION_STRING_VIEW + +#include <__config> +#include <__algorithm/minmax.h> +#include <cstddef> + +// Freestanding C functions we depend on. +extern "C" { + size_t strlen(const char*); + int memcmp(const void*, const void*, size_t); + void* memchr(const void*, int, size_t); +} + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// ── Minimal char_traits ───────────────────────────────────────────────────── + +template<class _CharT> struct char_traits; + +template<> +struct char_traits<char> { + using char_type = char; + using int_type = int; + using size_type = size_t; + + static constexpr size_t length(const char* __s) noexcept { + size_t __len = 0; + while (__s[__len]) ++__len; + return __len; + } + + static constexpr int compare(const char* __s1, const char* __s2, size_t __n) noexcept { + if (__builtin_is_constant_evaluated()) { + for (size_t __i = 0; __i < __n; ++__i) { + auto __a = static_cast<unsigned char>(__s1[__i]); + auto __b = static_cast<unsigned char>(__s2[__i]); + if (__a < __b) return -1; + if (__a > __b) return 1; + } + return 0; + } + return __n == 0 ? 0 : memcmp(__s1, __s2, __n); + } + + static constexpr const char* find(const char* __s, size_t __n, char __c) noexcept { + if (__builtin_is_constant_evaluated()) { + for (size_t __i = 0; __i < __n; ++__i) + if (__s[__i] == __c) return __s + __i; + return nullptr; + } + return static_cast<const char*>(memchr(__s, static_cast<unsigned char>(__c), __n)); + } + + static constexpr bool eq(char __a, char __b) noexcept { return __a == __b; } + static constexpr bool lt(char __a, char __b) noexcept { + return static_cast<unsigned char>(__a) < static_cast<unsigned char>(__b); + } + + static constexpr int_type eof() noexcept { return -1; } + static constexpr bool eq_int_type(int_type __a, int_type __b) noexcept { return __a == __b; } +}; + +// ── basic_string_view ─────────────────────────────────────────────────────── + +template<class _CharT, class _Traits = char_traits<_CharT>> +class basic_string_view { +public: + using traits_type = _Traits; + using value_type = _CharT; + using pointer = _CharT*; + using const_pointer = const _CharT*; + using reference = _CharT&; + using const_reference = const _CharT&; + using const_iterator = const _CharT*; + using iterator = const_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + + static constexpr size_type npos = size_type(-1); + + // Constructors + constexpr basic_string_view() noexcept : __data_(nullptr), __size_(0) {} + constexpr basic_string_view(const _CharT* __s, size_type __count) noexcept : __data_(__s), __size_(__count) {} + constexpr basic_string_view(const _CharT* __s) noexcept : __data_(__s), __size_(_Traits::length(__s)) {} + constexpr basic_string_view(nullptr_t) = delete; + + constexpr basic_string_view(const basic_string_view&) noexcept = default; + constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default; + + // Iterators + _LIBBASTION_NODISCARD constexpr const_iterator begin() const noexcept { return __data_; } + _LIBBASTION_NODISCARD constexpr const_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_; } + + // Element access + _LIBBASTION_NODISCARD constexpr const_reference operator[](size_type __pos) const { return __data_[__pos]; } + _LIBBASTION_NODISCARD constexpr const_reference at(size_type __pos) const { + _LIBBASTION_ASSERT(__pos < __size_, "string_view::at out of range"); + return __data_[__pos]; + } + _LIBBASTION_NODISCARD constexpr const_reference front() const { return __data_[0]; } + _LIBBASTION_NODISCARD constexpr const_reference back() const { return __data_[__size_ - 1]; } + _LIBBASTION_NODISCARD constexpr const_pointer data() const noexcept { return __data_; } + + // Capacity + _LIBBASTION_NODISCARD constexpr size_type size() const noexcept { return __size_; } + _LIBBASTION_NODISCARD constexpr size_type length() const noexcept { return __size_; } + _LIBBASTION_NODISCARD constexpr bool empty() const noexcept { return __size_ == 0; } + _LIBBASTION_NODISCARD constexpr size_type max_size() const noexcept { return size_type(-1) / sizeof(_CharT); } + + // Modifiers + constexpr void remove_prefix(size_type __n) { __data_ += __n; __size_ -= __n; } + constexpr void remove_suffix(size_type __n) { __size_ -= __n; } + constexpr void swap(basic_string_view& __other) noexcept { + auto __tmp = *this; *this = __other; __other = __tmp; + } + + // Operations + constexpr size_type copy(_CharT* __dest, size_type __count, size_type __pos = 0) const { + _LIBBASTION_ASSERT(__pos <= __size_, "string_view::copy out of range"); + size_type __rlen = std::min(__count, __size_ - __pos); + for (size_type __i = 0; __i < __rlen; ++__i) + __dest[__i] = __data_[__pos + __i]; + return __rlen; + } + + _LIBBASTION_NODISCARD constexpr basic_string_view substr(size_type __pos = 0, size_type __count = npos) const { + _LIBBASTION_ASSERT(__pos <= __size_, "string_view::substr out of range"); + return basic_string_view(__data_ + __pos, std::min(__count, __size_ - __pos)); + } + + // compare + _LIBBASTION_NODISCARD constexpr int compare(basic_string_view __sv) const noexcept { + size_type __rlen = std::min(__size_, __sv.__size_); + int __ret = _Traits::compare(__data_, __sv.__data_, __rlen); + if (__ret != 0) return __ret; + if (__size_ < __sv.__size_) return -1; + if (__size_ > __sv.__size_) return 1; + return 0; + } + + _LIBBASTION_NODISCARD constexpr int compare(const _CharT* __s) const { return compare(basic_string_view(__s)); } + + // starts_with / ends_with (C++20) + _LIBBASTION_NODISCARD constexpr bool starts_with(basic_string_view __sv) const noexcept { + return __size_ >= __sv.__size_ && _Traits::compare(__data_, __sv.__data_, __sv.__size_) == 0; + } + _LIBBASTION_NODISCARD constexpr bool starts_with(_CharT __c) const noexcept { return !empty() && _Traits::eq(front(), __c); } + _LIBBASTION_NODISCARD constexpr bool starts_with(const _CharT* __s) const { return starts_with(basic_string_view(__s)); } + + _LIBBASTION_NODISCARD constexpr bool ends_with(basic_string_view __sv) const noexcept { + return __size_ >= __sv.__size_ && _Traits::compare(__data_ + __size_ - __sv.__size_, __sv.__data_, __sv.__size_) == 0; + } + _LIBBASTION_NODISCARD constexpr bool ends_with(_CharT __c) const noexcept { return !empty() && _Traits::eq(back(), __c); } + _LIBBASTION_NODISCARD constexpr bool ends_with(const _CharT* __s) const { return ends_with(basic_string_view(__s)); } + + // contains (C++23) + _LIBBASTION_NODISCARD constexpr bool contains(basic_string_view __sv) const noexcept { return find(__sv) != npos; } + _LIBBASTION_NODISCARD constexpr bool contains(_CharT __c) const noexcept { return find(__c) != npos; } + _LIBBASTION_NODISCARD constexpr bool contains(const _CharT* __s) const { return find(__s) != npos; } + + // find + _LIBBASTION_NODISCARD constexpr size_type find(basic_string_view __sv, size_type __pos = 0) const noexcept { + if (__sv.empty() && __pos <= __size_) return __pos; + if (__pos + __sv.__size_ > __size_) return npos; + for (size_type __i = __pos; __i <= __size_ - __sv.__size_; ++__i) { + if (_Traits::compare(__data_ + __i, __sv.__data_, __sv.__size_) == 0) + return __i; + } + return npos; + } + + _LIBBASTION_NODISCARD constexpr size_type find(_CharT __c, size_type __pos = 0) const noexcept { + for (size_type __i = __pos; __i < __size_; ++__i) + if (_Traits::eq(__data_[__i], __c)) + return __i; + return npos; + } + + _LIBBASTION_NODISCARD constexpr size_type find(const _CharT* __s, size_type __pos = 0) const { + return find(basic_string_view(__s), __pos); + } + + // rfind + _LIBBASTION_NODISCARD constexpr size_type rfind(basic_string_view __sv, size_type __pos = npos) const noexcept { + if (__sv.__size_ > __size_) return npos; + size_type __last = std::min(__pos, __size_ - __sv.__size_); + for (size_type __i = __last + 1; __i > 0; --__i) { + if (_Traits::compare(__data_ + __i - 1, __sv.__data_, __sv.__size_) == 0) + return __i - 1; + } + return npos; + } + + _LIBBASTION_NODISCARD constexpr size_type rfind(_CharT __c, size_type __pos = npos) const noexcept { + if (__size_ == 0) return npos; + size_type __last = std::min(__pos, __size_ - 1); + for (size_type __i = __last + 1; __i > 0; --__i) + if (_Traits::eq(__data_[__i - 1], __c)) + return __i - 1; + return npos; + } + +private: + const _CharT* __data_; + size_type __size_; +}; + +// Comparison operators +template<class _CharT, class _Traits> +_LIBBASTION_NODISCARD constexpr bool operator==(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) noexcept { + return __lhs.size() == __rhs.size() && __lhs.compare(__rhs) == 0; +} + +template<class _CharT, class _Traits> +_LIBBASTION_NODISCARD constexpr bool operator!=(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) noexcept { + return !(__lhs == __rhs); +} + +template<class _CharT, class _Traits> +_LIBBASTION_NODISCARD constexpr bool operator<(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) noexcept { + return __lhs.compare(__rhs) < 0; +} + +template<class _CharT, class _Traits> +_LIBBASTION_NODISCARD constexpr bool operator>(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) noexcept { + return __rhs < __lhs; +} + +template<class _CharT, class _Traits> +_LIBBASTION_NODISCARD constexpr bool operator<=(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) noexcept { + return !(__rhs < __lhs); +} + +template<class _CharT, class _Traits> +_LIBBASTION_NODISCARD constexpr bool operator>=(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) noexcept { + return !(__lhs < __rhs); +} + +// Type aliases +using string_view = basic_string_view<char>; +using u8string_view = basic_string_view<char8_t>; +using u16string_view = basic_string_view<char16_t>; +using u32string_view = basic_string_view<char32_t>; + +// Deduction guide +template<class _CharT> +basic_string_view(const _CharT*, size_t) -> basic_string_view<_CharT>; + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_STRING_VIEW diff --git a/kernel/lib/libcxx/include/tuple b/kernel/lib/libcxx/include/tuple new file mode 100644 index 0000000..5fd90e9 --- /dev/null +++ b/kernel/lib/libcxx/include/tuple @@ -0,0 +1,15 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TUPLE +#define _LIBBASTION_TUPLE + +#include <__config> +#include <__tuple/tuple_element.h> +#include <__tuple/tuple.h> + +#endif // _LIBBASTION_TUPLE diff --git a/kernel/lib/libcxx/include/type_traits b/kernel/lib/libcxx/include/type_traits new file mode 100644 index 0000000..1f40f39 --- /dev/null +++ b/kernel/lib/libcxx/include/type_traits @@ -0,0 +1,24 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +// Public <type_traits> header — includes all type trait components. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_TYPE_TRAITS +#define _LIBBASTION_TYPE_TRAITS + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/primary_categories.h> +#include <__type_traits/type_properties.h> +#include <__type_traits/type_modifications.h> +#include <__type_traits/construction_traits.h> +#include <__type_traits/type_relationships.h> +// other_transformations defines conditional_t, needed by logical_traits +#include <__type_traits/other_transformations.h> +#include <__type_traits/logical_traits.h> + +#endif // _LIBBASTION_TYPE_TRAITS diff --git a/kernel/lib/libcxx/include/utility b/kernel/lib/libcxx/include/utility new file mode 100644 index 0000000..290c81b --- /dev/null +++ b/kernel/lib/libcxx/include/utility @@ -0,0 +1,36 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_UTILITY +#define _LIBBASTION_UTILITY + +#include <__config> +#include <__utility/move.h> +#include <__utility/declval.h> +#include <__utility/swap.h> +#include <__utility/exchange.h> +#include <__utility/pair.h> +#include <__utility/in_place.h> +#include <__utility/integer_sequence.h> + +// Also pull in type_traits since utility is a core header. +#include <type_traits> + +_LIBBASTION_BEGIN_NAMESPACE_STD + +// to_underlying (C++23) +template<class _Tp> +_LIBBASTION_NODISCARD constexpr underlying_type_t<_Tp> to_underlying(_Tp __val) noexcept { + return static_cast<underlying_type_t<_Tp>>(__val); +} + +// unreachable (C++23) +_LIBBASTION_NORETURN inline void unreachable() { _LIBBASTION_UNREACHABLE(); } + +_LIBBASTION_END_NAMESPACE_STD + +#endif // _LIBBASTION_UTILITY diff --git a/kernel/lib/libcxx/include/variant b/kernel/lib/libcxx/include/variant new file mode 100644 index 0000000..7285235 --- /dev/null +++ b/kernel/lib/libcxx/include/variant @@ -0,0 +1,14 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the BastionOS freestanding C++ standard library. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBBASTION_VARIANT +#define _LIBBASTION_VARIANT + +#include <__config> +#include <__variant/variant.h> + +#endif // _LIBBASTION_VARIANT |
