diff --git a/.github/workflows/realworld-perf-pr.yml b/.github/workflows/realworld-perf-pr.yml index ea61ed67..378bd5d2 100644 --- a/.github/workflows/realworld-perf-pr.yml +++ b/.github/workflows/realworld-perf-pr.yml @@ -37,7 +37,7 @@ jobs: - name: Compare build time (PR vs main) run: >- python3 scripts/compare_realworld.py ${{ matrix.project }} - --time-budget 5m --max-reps 5 + --time-budget 10m --max-reps 10 | tee diff.md - name: Post realworld perf diff as PR comment uses: marocchino/sticky-pull-request-comment@v3 diff --git a/include/__psychicstd_char_traits b/include/__psychicstd_char_traits index b280b1f7..28a64d0c 100644 --- a/include/__psychicstd_char_traits +++ b/include/__psychicstd_char_traits @@ -25,10 +25,25 @@ template struct char_traits { size_t n) noexcept { if (!n) return dst; + if (__builtin_is_constant_evaluated()) { + for (size_t i = 0; i < n; ++i) + dst[i] = src[i]; + return dst; + } return (char_type*)__builtin_memcpy(dst, src, n * sizeof(char_type)); } static constexpr char_type* move(char_type* dst, const char_type* src, size_t n) noexcept { + if (__builtin_is_constant_evaluated()) { + if (dst < src) { + for (size_t i = 0; i < n; ++i) + dst[i] = src[i]; + } else if (dst > src) { + for (size_t i = n; i-- > 0;) + dst[i] = src[i]; + } + return dst; + } return (char_type*)__builtin_memmove(dst, src, n * sizeof(char_type)); } static constexpr const char_type* find(const char_type* s, size_t n, @@ -76,6 +91,15 @@ template <> struct char_traits { } 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) { + if ((unsigned char)s1[i] < (unsigned char)s2[i]) + return -1; + if ((unsigned char)s1[i] > (unsigned char)s2[i]) + return 1; + } + return 0; + } return __builtin_memcmp(s1, s2, n); } static constexpr size_t length(const char* s) noexcept { @@ -89,10 +113,12 @@ template <> struct char_traits { #pragma GCC diagnostic ignored "-Wrestrict" #endif static constexpr char* copy(char* d, const char* s, size_t n) noexcept { - if (n) { - return (char*)__builtin_memcpy(d, s, n); + if (__builtin_is_constant_evaluated()) { + for (size_t i = 0; i < n; ++i) + d[i] = s[i]; + return d; } - return d; + return n ? (char*)__builtin_memcpy(d, s, n) : d; } #ifndef __clang__ #pragma GCC diagnostic pop @@ -102,6 +128,16 @@ template <> struct char_traits { #pragma GCC diagnostic ignored "-Wrestrict" #endif static constexpr char* move(char* d, const char* s, size_t n) noexcept { + if (__builtin_is_constant_evaluated()) { + if (d < s) { + for (size_t i = 0; i < n; ++i) + d[i] = s[i]; + } else if (d > s) { + for (size_t i = n; i-- > 0;) + d[i] = s[i]; + } + return d; + } return (char*)__builtin_memmove(d, s, n); } #ifndef __clang__ diff --git a/include/__psychicstd_contiguous_iterator b/include/__psychicstd_contiguous_iterator index 75a42aa3..516eb064 100644 --- a/include/__psychicstd_contiguous_iterator +++ b/include/__psychicstd_contiguous_iterator @@ -27,21 +27,31 @@ template struct __vec_iter { constexpr T& operator*() const noexcept { return *ptr_; } constexpr T* operator->() const noexcept { return ptr_; } constexpr T& operator[](ptrdiff_t n) const noexcept { return ptr_[n]; } - constexpr __vec_iter& operator++() noexcept { return ++ptr_, *this; } + constexpr __vec_iter& operator++() noexcept { + ++ptr_; + return *this; + } constexpr __vec_iter operator++(int) noexcept { auto t = *this; - return ++ptr_, t; + ++ptr_; + return t; + } + constexpr __vec_iter& operator--() noexcept { + --ptr_; + return *this; } - constexpr __vec_iter& operator--() noexcept { return --ptr_, *this; } constexpr __vec_iter operator--(int) noexcept { auto t = *this; - return --ptr_, t; + --ptr_; + return t; } constexpr __vec_iter& operator+=(ptrdiff_t n) noexcept { - return ptr_ += n, *this; + ptr_ += n; + return *this; } constexpr __vec_iter& operator-=(ptrdiff_t n) noexcept { - return ptr_ -= n, *this; + ptr_ -= n; + return *this; } constexpr __vec_iter operator+(ptrdiff_t n) const noexcept { return __vec_iter{ptr_ + n}; diff --git a/include/compare b/include/compare index 8254d5e0..6b15f90c 100644 --- a/include/compare +++ b/include/compare @@ -196,12 +196,12 @@ constexpr bool is_lteq(partial_ordering v) noexcept { return v <= 0; } constexpr bool is_gteq(partial_ordering v) noexcept { return v >= 0; } // three_way_comparable concept -template +template concept three_way_comparable = requires(const __psychicstd_detail::remove_reference_t& a, - const __psychicstd_detail::remove_reference_t& b) { - a <=> b; - b <=> a; + const __psychicstd_detail::remove_reference_t& b) { + static_cast(a <=> b); + static_cast(b <=> a); }; template diff --git a/include/memory b/include/memory index a3aa4137..802f92d1 100644 --- a/include/memory +++ b/include/memory @@ -20,6 +20,17 @@ inline void* align(size_t alignment, size_t size, void*& ptr, } namespace __detail { +template struct __pointer_element; +template