From b8f794a87990d61de86140671f99d64e2f6854be Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sat, 20 Dec 2025 22:21:57 +0800 Subject: [PATCH] feat: add polyfill for llvm libcxx to make it possible to compile --- src/CMakeLists.txt | 2 + src/yycc/carton/clap/manual.cpp | 1 + src/yycc/carton/tabulate.cpp | 1 + src/yycc/panic.cpp | 1 + src/yycc/patch/libcxx/enumerate.hpp | 251 +++++++++++++++++++++++++++ src/yycc/patch/libcxx/stacktrace.hpp | 146 ++++++++++++++++ 6 files changed, 402 insertions(+) create mode 100644 src/yycc/patch/libcxx/enumerate.hpp create mode 100644 src/yycc/patch/libcxx/stacktrace.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index caba745..fdb980f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,8 @@ FILES yycc/patch/fopen.hpp yycc/patch/stream.hpp yycc/patch/format.hpp + yycc/patch/libcxx/enumerate.hpp + yycc/patch/libcxx/stacktrace.hpp yycc/num/parse.hpp yycc/num/stringify.hpp yycc/num/safe_cast.hpp diff --git a/src/yycc/carton/clap/manual.cpp b/src/yycc/carton/clap/manual.cpp index 37acc56..092cc88 100644 --- a/src/yycc/carton/clap/manual.cpp +++ b/src/yycc/carton/clap/manual.cpp @@ -2,6 +2,7 @@ #include "../termcolor.hpp" #include "../../patch/stream.hpp" #include "../../patch/format.hpp" +#include "../../patch/libcxx/stacktrace.hpp" #include "../../string/op.hpp" #include "../../env.hpp" #include diff --git a/src/yycc/carton/tabulate.cpp b/src/yycc/carton/tabulate.cpp index d894607..77bf475 100644 --- a/src/yycc/carton/tabulate.cpp +++ b/src/yycc/carton/tabulate.cpp @@ -2,6 +2,7 @@ #include "wcwidth.hpp" #include "../num/safe_op.hpp" #include "../patch/stream.hpp" +#include "../patch/libcxx/stacktrace.hpp" #include #include diff --git a/src/yycc/panic.cpp b/src/yycc/panic.cpp index e77ddc7..06a5310 100644 --- a/src/yycc/panic.cpp +++ b/src/yycc/panic.cpp @@ -1,6 +1,7 @@ #include "panic.hpp" #include "carton/termcolor.hpp" #include "patch/stream.hpp" +#include "patch/libcxx/stacktrace.hpp" #include #include #include diff --git a/src/yycc/patch/libcxx/enumerate.hpp b/src/yycc/patch/libcxx/enumerate.hpp new file mode 100644 index 0000000..cb5fb96 --- /dev/null +++ b/src/yycc/patch/libcxx/enumerate.hpp @@ -0,0 +1,251 @@ +#pragma once +#include "../../macro/stl_detector.hpp" + +#if defined(YYCC_STL_CLANGSTL) + +/** + * @private + * @file This is the polyfill for LLVM libcxx std::enumerate. + * This should be removed once libcxx provide it. + * This polyfill is generated by AI. + */ + +#include +#include +#include +#include + +namespace std { + +namespace ranges { +namespace views { + +namespace detail { + +template +concept can_reference = requires { typename T&; }; + +template +concept enumerable = + ranges::input_range && + integral && + ranges::view; + +} // namespace detail + +// enumerate_view实现 +template +requires detail::enumerable +class enumerate_view : public ranges::view_interface> { +private: + V _base; + I _start; + + // 迭代器实现 + template + class iterator { + private: + using Base = conditional_t; + using Parent = conditional_t; + + Parent* _parent = nullptr; + ranges::iterator_t _current; + I _index; + + public: + using iterator_category = typename iterator_traits>::iterator_category; + using iterator_concept = iterator_category; + using value_type = tuple>; + using difference_type = ranges::range_difference_t; + + iterator() = default; + + constexpr iterator(Parent* parent, ranges::iterator_t current, I index) + : _parent(parent), _current(current), _index(index) {} + + constexpr iterator(iterator other) requires Const && + convertible_to, ranges::iterator_t> + : _parent(other._parent), _current(other._current), _index(other._index) {} + + constexpr ranges::iterator_t base() const { + return _current; + } + + constexpr auto operator*() const { + return tuple>(_index, *_current); + } + + constexpr iterator& operator++() { + ++_current; + ++_index; + return *this; + } + + constexpr iterator operator++(int) { + auto tmp = *this; + ++*this; + return tmp; + } + + constexpr iterator& operator--() requires ranges::bidirectional_range { + --_current; + --_index; + return *this; + } + + constexpr iterator operator--(int) requires ranges::bidirectional_range { + auto tmp = *this; + --*this; + return tmp; + } + + constexpr iterator& operator+=(difference_type n) + requires ranges::random_access_range { + _current += n; + _index += static_cast(n); + return *this; + } + + constexpr iterator& operator-=(difference_type n) + requires ranges::random_access_range { + _current -= n; + _index -= static_cast(n); + return *this; + } + + constexpr auto operator[](difference_type n) const + requires ranges::random_access_range { + return tuple>( + _index + static_cast(n), _current[n]); + } + + friend constexpr bool operator==(const iterator& x, const iterator& y) { + return x._current == y._current; + } + + friend constexpr bool operator<(const iterator& x, const iterator& y) + requires ranges::random_access_range { + return x._current < y._current; + } + + friend constexpr bool operator>(const iterator& x, const iterator& y) + requires ranges::random_access_range { + return x._current > y._current; + } + + friend constexpr bool operator<=(const iterator& x, const iterator& y) + requires ranges::random_access_range { + return x._current <= y._current; + } + + friend constexpr bool operator>=(const iterator& x, const iterator& y) + requires ranges::random_access_range { + return x._current >= y._current; + } + + friend constexpr iterator operator+(const iterator& i, difference_type n) + requires ranges::random_access_range { + auto r = i; + r += n; + return r; + } + + friend constexpr iterator operator+(difference_type n, const iterator& i) + requires ranges::random_access_range { + return i + n; + } + + friend constexpr iterator operator-(const iterator& i, difference_type n) + requires ranges::random_access_range { + auto r = i; + r -= n; + return r; + } + + friend constexpr difference_type operator-(const iterator& x, const iterator& y) + requires ranges::random_access_range { + return x._current - y._current; + } + }; + +public: + enumerate_view() = default; + + constexpr enumerate_view(V base, I start = 0) + : _base(std::move(base)), _start(start) {} + + constexpr V base() const & requires copy_constructible { + return _base; + } + + constexpr V base() && { + return std::move(_base); + } + + constexpr I start() const { + return _start; + } + + constexpr auto begin() requires (!ranges::simple_view) { + return iterator(this, ranges::begin(_base), _start); + } + + constexpr auto begin() const requires ranges::range { + return iterator(this, ranges::begin(_base), _start); + } + + constexpr auto end() requires (!ranges::simple_view) { + return iterator(this, ranges::end(_base), + _start + static_cast(ranges::distance(_base))); + } + + constexpr auto end() const requires ranges::range { + return iterator(this, ranges::end(_base), + _start + static_cast(ranges::distance(_base))); + } + + constexpr auto size() requires ranges::sized_range { + return ranges::size(_base); + } + + constexpr auto size() const requires ranges::sized_range { + return ranges::size(_base); + } +}; + +// 推导指引 +template +enumerate_view(R&&, I) -> enumerate_view, I>; + +template +enumerate_view(R&&) -> enumerate_view, size_t>; + +// enumerate适配器对象 +struct enumerate_fn { + template + requires detail::enumerable, I> + constexpr auto operator()(R&& r, I start = 0) const { + return enumerate_view(views::all(forward(r)), start); + } + + template + constexpr auto operator()(I start = 0) const { + return ranges::views::__adaptor_invoke(*this, start); + } +}; + +// 适配器对象实例 +inline constexpr enumerate_fn enumerate; + +} // namespace views + +// 使enumerate_view成为view +template +inline constexpr bool enable_borrowed_range> = + ranges::enable_borrowed_range; + +} // namespace ranges + +} // namespace std + +#endif diff --git a/src/yycc/patch/libcxx/stacktrace.hpp b/src/yycc/patch/libcxx/stacktrace.hpp new file mode 100644 index 0000000..0fbb2a1 --- /dev/null +++ b/src/yycc/patch/libcxx/stacktrace.hpp @@ -0,0 +1,146 @@ +#pragma once +#include "../../macro/stl_detector.hpp" + +#if defined(YYCC_STL_CLANGSTL) + +/** + * @private + * @file This is the polyfill for LLVM libcxx std::stacktrace. + * This should be removed once libcxx provide it. + * This polyfill is generated by AI. + */ + +#include +#include +#include +#include +#include +#include + +namespace std { + +// 空实现的stacktrace_entry +class stacktrace_entry { +public: + constexpr stacktrace_entry() noexcept = default; + constexpr stacktrace_entry(const stacktrace_entry&) noexcept = default; + stacktrace_entry& operator=(const stacktrace_entry&) noexcept = default; + + constexpr explicit operator bool() const noexcept { return false; } + + string description() const { return ""; } + + constexpr void* native_handle() const noexcept { return nullptr; } + +private: + // 使用void*作为占位符 + void* _handle = nullptr; +}; + +// 比较运算符 +constexpr bool operator==(const stacktrace_entry&, const stacktrace_entry&) noexcept { + return true; +} + +constexpr bool operator!=(const stacktrace_entry&, const stacktrace_entry&) noexcept { + return false; +} + +constexpr bool operator<(const stacktrace_entry&, const stacktrace_entry&) noexcept { + return false; +} + +constexpr bool operator<=(const stacktrace_entry&, const stacktrace_entry&) noexcept { + return true; +} + +constexpr bool operator>(const stacktrace_entry&, const stacktrace_entry&) noexcept { + return false; +} + +constexpr bool operator>=(const stacktrace_entry&, const stacktrace_entry&) noexcept { + return true; +} + +// 流输出运算符 +template +basic_ostream& operator<<( + basic_ostream& os, const stacktrace_entry&) { + return os << basic_string(""); +} + +// 空实现的stacktrace类 +class stacktrace { +public: + using value_type = stacktrace_entry; + using const_iterator = const stacktrace_entry*; + using iterator = const_iterator; + using reference = const stacktrace_entry&; + using const_reference = const stacktrace_entry&; + using difference_type = ptrdiff_t; + using size_type = size_t; + + // 构造和析构 + constexpr stacktrace() noexcept = default; + stacktrace(const stacktrace&) = default; + stacktrace& operator=(const stacktrace&) = default; + ~stacktrace() = default; + + // 始终返回空的stacktrace + static stacktrace current(size_t = 0) noexcept { + return stacktrace(); + } + + // 容量 + constexpr size_type size() const noexcept { return 0; } + constexpr size_type max_size() const noexcept { return 0; } + constexpr bool empty() const noexcept { return true; } + + // 元素访问 + const_reference operator[](size_type) const noexcept { + static stacktrace_entry entry; + return entry; + } + + const_reference at(size_type) const { + throw out_of_range("stacktrace is empty"); + } + + // 迭代器 + constexpr const_iterator begin() const noexcept { return nullptr; } + constexpr const_iterator end() const noexcept { return nullptr; } + constexpr const_iterator cbegin() const noexcept { return nullptr; } + constexpr const_iterator cend() const noexcept { return nullptr; } + + // 比较 + friend bool operator==(const stacktrace&, const stacktrace&) noexcept { + return true; + } + + friend bool operator!=(const stacktrace&, const stacktrace&) noexcept { + return false; + } + +private: + // 无数据成员 +}; + +// stacktrace的流输出 +template +basic_ostream& operator<<( + basic_ostream& os, const stacktrace&) { + return os << basic_string("Stacktrace is not supported in this implementation"); +} + +// to_string函数 +inline string to_string(const stacktrace_entry&) { + return ""; +} + +inline string to_string(const stacktrace&) { + return "stacktrace not supported"; +} + +} // namespace std + +#endif