From 4409b33145bb0a53a2480bf81f39941197c304ff Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 8 Feb 2024 18:52:03 -0500 Subject: [PATCH] AK: Make IndexSequence use size_t This makes it possible to use MakeIndexSequqnce in functions like: template constexpr auto foo(T (&a)[N]) This means AK/StdLibExtraDetails.h must now include AK/Types.h for size_t, which means AK/Types.h can no longer include AK/StdLibExtras.h (which arguably it shouldn't do anyways), which requires rejiggering some things. (IMHO Types.h shouldn't use AK::Details metaprogramming at all. FlatPtr doesn't necessarily have to use Conditional<> and ssize_t could maybe be in its own header or something. But since it's tangential to this PR, going with the tried and true "lift things that cause the cycle up to the top" approach.) --- AK/FloatingPoint.h | 1 + AK/Forward.h | 1 + AK/StdLibExtraDetails.h | 80 ++----------------- AK/Tuple.h | 24 +++--- AK/TypeList.h | 4 +- AK/Types.h | 80 ++++++++++++++++++- AK/Variant.h | 6 +- Kernel/API/Syscall.h | 1 + Kernel/Arch/aarch64/PageDirectory.h | 1 + Kernel/Arch/aarch64/RegisterState.h | 2 + Kernel/Arch/aarch64/TrapFrame.h | 1 + Kernel/Arch/riscv64/CSR.h | 1 + Kernel/Arch/riscv64/RegisterState.h | 2 + Kernel/Arch/riscv64/SBI.h | 1 + Kernel/Arch/riscv64/TrapFrame.h | 2 + Kernel/Devices/Storage/SD/Commands.h | 1 + Tests/AK/TestIndexSequence.cpp | 2 +- Userland/Libraries/LibC/arch/aarch64/fenv.cpp | 1 + Userland/Libraries/LibC/arch/riscv64/fenv.cpp | 1 + Userland/Libraries/LibJS/Runtime/VM.cpp | 4 +- 20 files changed, 120 insertions(+), 96 deletions(-) diff --git a/AK/FloatingPoint.h b/AK/FloatingPoint.h index 1f3346dcfab..d615d25d6a9 100644 --- a/AK/FloatingPoint.h +++ b/AK/FloatingPoint.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace AK { diff --git a/AK/Forward.h b/AK/Forward.h index 24f18de69f9..997ae19549d 100644 --- a/AK/Forward.h +++ b/AK/Forward.h @@ -8,6 +8,7 @@ #include #include +#include #include namespace AK { diff --git a/AK/StdLibExtraDetails.h b/AK/StdLibExtraDetails.h index e856e3e6847..6790de3f9c4 100644 --- a/AK/StdLibExtraDetails.h +++ b/AK/StdLibExtraDetails.h @@ -9,6 +9,7 @@ #pragma once #include +#include namespace AK::Detail { @@ -175,19 +176,6 @@ inline constexpr bool IsSame = false; template inline constexpr bool IsSame = true; -template -struct __Conditional { - using Type = TrueType; -}; - -template -struct __Conditional { - using Type = FalseType; -}; - -template -using Conditional = typename __Conditional::Type; - template inline constexpr bool IsNullPointer = IsSame>; @@ -284,64 +272,6 @@ struct __MakeUnsigned { template using MakeUnsigned = typename __MakeUnsigned::Type; -template -struct __MakeSigned { - using Type = void; -}; -template<> -struct __MakeSigned { - using Type = signed char; -}; -template<> -struct __MakeSigned { - using Type = short; -}; -template<> -struct __MakeSigned { - using Type = int; -}; -template<> -struct __MakeSigned { - using Type = long; -}; -template<> -struct __MakeSigned { - using Type = long long; -}; -template<> -struct __MakeSigned { - using Type = char; -}; -template<> -struct __MakeSigned { - using Type = short; -}; -template<> -struct __MakeSigned { - using Type = int; -}; -template<> -struct __MakeSigned { - using Type = long; -}; -template<> -struct __MakeSigned { - using Type = long long; -}; -template<> -struct __MakeSigned { - using Type = char; -}; -#if ARCH(AARCH64) -template<> -struct __MakeSigned { - using Type = void; -}; -#endif - -template -using MakeSigned = typename __MakeSigned::Type; - template auto declval() -> T; @@ -451,8 +381,8 @@ struct IntegerSequence { static constexpr unsigned size() noexcept { return sizeof...(Ts); } }; -template -using IndexSequence = IntegerSequence; +template +using IndexSequence = IntegerSequence; #if __has_builtin(__make_integer_seq) template @@ -474,8 +404,8 @@ template using MakeIntegerSequence = decltype(make_integer_sequence_impl()); #endif -template -using MakeIndexSequence = MakeIntegerSequence; +template +using MakeIndexSequence = MakeIntegerSequence; template struct __IdentityType { diff --git a/AK/Tuple.h b/AK/Tuple.h index 46c3ba4113b..df8a3d26fc4 100644 --- a/AK/Tuple.h +++ b/AK/Tuple.h @@ -41,14 +41,14 @@ struct Tuple { return const_cast&>(*this).get(); } - template + template U& get_with_index() { static_assert(IsSame && index == 0, "Invalid tuple access"); return value; } - template + template U const& get_with_index() const { return const_cast&>(*this).get_with_index(); @@ -89,7 +89,7 @@ struct Tuple : Tuple { return const_cast&>(*this).get(); } - template + template U& get_with_index() { if constexpr (IsSame && index == 0) @@ -98,7 +98,7 @@ struct Tuple : Tuple { return Tuple::template get_with_index(); } - template + template U const& get_with_index() const { return const_cast&>(*this).get_with_index(); @@ -146,7 +146,7 @@ struct Tuple : Detail::Tuple { return Detail::Tuple::template get(); } - template + template auto& get() { return Detail::Tuple::template get_with_index, index>(); @@ -158,7 +158,7 @@ struct Tuple : Detail::Tuple { return Detail::Tuple::template get(); } - template + template auto& get() const { return Detail::Tuple::template get_with_index, index>(); @@ -179,37 +179,37 @@ struct Tuple : Detail::Tuple { static constexpr auto size() { return sizeof...(Ts); } private: - template + template Tuple(Tuple&& other, IndexSequence) : Detail::Tuple(move(other.get())...) { } - template + template Tuple(Tuple const& other, IndexSequence) : Detail::Tuple(other.get()...) { } - template + template void set(Tuple&& other, IndexSequence) { ((get() = move(other.get())), ...); } - template + template void set(Tuple const& other, IndexSequence) { ((get() = other.get()), ...); } - template + template auto apply_as_args(F&& f, IndexSequence) { return forward(f)(get()...); } - template + template auto apply_as_args(F&& f, IndexSequence) const { return forward(f)(get()...); diff --git a/AK/TypeList.h b/AK/TypeList.h index e2f3d13e8f5..ef49f8ae7f8 100644 --- a/AK/TypeList.h +++ b/AK/TypeList.h @@ -46,7 +46,7 @@ struct TypeWrapper { using Type = T; }; -template +template constexpr void for_each_type_impl(F&& f, IndexSequence) { (forward(f)(TypeWrapper> {}), ...); @@ -58,7 +58,7 @@ constexpr void for_each_type(F&& f) for_each_type_impl(forward(f), MakeIndexSequence {}); } -template +template constexpr void for_each_type_zipped_impl(F&& f, IndexSequence) { (forward(f)(TypeWrapper> {}, TypeWrapper> {}), ...); diff --git a/AK/Types.h b/AK/Types.h index c60a5ed1830..80adcfbf804 100644 --- a/AK/Types.h +++ b/AK/Types.h @@ -7,7 +7,6 @@ #pragma once #include -#include using u64 = __UINT64_TYPE__; using u32 = __UINT32_TYPE__; @@ -34,6 +33,85 @@ using f128 = long double; # endif #endif +namespace AK::Detail { + +// MakeSigned<> is here instead of in StdLibExtras.h because it's used in the definition of size_t and ssize_t +// and Types.h must not include StdLibExtras.h to avoid circular dependencies. +template +struct __MakeSigned { + using Type = void; +}; +template<> +struct __MakeSigned { + using Type = signed char; +}; +template<> +struct __MakeSigned { + using Type = short; +}; +template<> +struct __MakeSigned { + using Type = int; +}; +template<> +struct __MakeSigned { + using Type = long; +}; +template<> +struct __MakeSigned { + using Type = long long; +}; +template<> +struct __MakeSigned { + using Type = char; +}; +template<> +struct __MakeSigned { + using Type = short; +}; +template<> +struct __MakeSigned { + using Type = int; +}; +template<> +struct __MakeSigned { + using Type = long; +}; +template<> +struct __MakeSigned { + using Type = long long; +}; +template<> +struct __MakeSigned { + using Type = char; +}; +#if ARCH(AARCH64) +template<> +struct __MakeSigned { + using Type = void; +}; +#endif + +template +using MakeSigned = typename __MakeSigned::Type; + +// Conditional<> is here instead of in StdLibExtras.h because it's used in the definition of FlatPtr +// and Types.h must not include StdLibExtras.h to avoid circular dependencies. +template +struct __Conditional { + using Type = TrueType; +}; + +template +struct __Conditional { + using Type = FalseType; +}; + +template +using Conditional = typename __Conditional::Type; + +} + #ifdef AK_OS_SERENITY using size_t = __SIZE_TYPE__; diff --git a/AK/Variant.h b/AK/Variant.h index 307c41a27e3..d8dad496233 100644 --- a/AK/Variant.h +++ b/AK/Variant.h @@ -182,14 +182,14 @@ inline constexpr bool IsTypeInPack> = (IsSame || template using BlankIfDuplicate = Conditional<(IsTypeInPack || ...), Blank, T>; -template +template struct InheritFromUniqueEntries; // InheritFromUniqueEntries will inherit from both Qs and Ts, but only scan entries going *forwards* // that is to say, if it's scanning from index I in Qs, it won't scan for duplicates for entries before I // as that has already been checked before. // This makes sure that the search is linear in time (like the 'merge' step of merge sort). -template +template struct InheritFromUniqueEntries, IndexSequence, Qs...> : public BlankIfDuplicate, Qs>...>... { @@ -201,7 +201,7 @@ struct InheritFromPacks; // InheritFromPacks will attempt to 'merge' the pack 'Ps' with *itself*, but skip the duplicate entries // (via InheritFromUniqueEntries). -template +template struct InheritFromPacks, Ps...> : public InheritFromUniqueEntries, Ps...>... { diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 4e4bdc03b16..8d00db0315a 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include diff --git a/Kernel/Arch/aarch64/PageDirectory.h b/Kernel/Arch/aarch64/PageDirectory.h index c464229167e..6683808e407 100644 --- a/Kernel/Arch/aarch64/PageDirectory.h +++ b/Kernel/Arch/aarch64/PageDirectory.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/Kernel/Arch/aarch64/RegisterState.h b/Kernel/Arch/aarch64/RegisterState.h index efbca3e8e76..4f0caf90b8b 100644 --- a/Kernel/Arch/aarch64/RegisterState.h +++ b/Kernel/Arch/aarch64/RegisterState.h @@ -11,6 +11,8 @@ #include #include +#include + VALIDATE_IS_AARCH64() namespace Kernel { diff --git a/Kernel/Arch/aarch64/TrapFrame.h b/Kernel/Arch/aarch64/TrapFrame.h index cd97a9ed4d3..a72986e0e1f 100644 --- a/Kernel/Arch/aarch64/TrapFrame.h +++ b/Kernel/Arch/aarch64/TrapFrame.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include diff --git a/Kernel/Arch/riscv64/CSR.h b/Kernel/Arch/riscv64/CSR.h index 3a5a6c046f1..a1f3cff971a 100644 --- a/Kernel/Arch/riscv64/CSR.h +++ b/Kernel/Arch/riscv64/CSR.h @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/Kernel/Arch/riscv64/RegisterState.h b/Kernel/Arch/riscv64/RegisterState.h index da5b45f1ae6..9480051c741 100644 --- a/Kernel/Arch/riscv64/RegisterState.h +++ b/Kernel/Arch/riscv64/RegisterState.h @@ -12,6 +12,8 @@ #include #include +#include + VALIDATE_IS_RISCV64() namespace Kernel { diff --git a/Kernel/Arch/riscv64/SBI.h b/Kernel/Arch/riscv64/SBI.h index e08c0d933e1..827dea472fc 100644 --- a/Kernel/Arch/riscv64/SBI.h +++ b/Kernel/Arch/riscv64/SBI.h @@ -8,6 +8,7 @@ #include #include +#include // Documentation about the SBI: // RISC-V Supervisor Binary Interface Specification (https://github.com/riscv-non-isa/riscv-sbi-doc) diff --git a/Kernel/Arch/riscv64/TrapFrame.h b/Kernel/Arch/riscv64/TrapFrame.h index 69de9429840..6e01b3fe4c1 100644 --- a/Kernel/Arch/riscv64/TrapFrame.h +++ b/Kernel/Arch/riscv64/TrapFrame.h @@ -9,6 +9,8 @@ #include #include +#include + VALIDATE_IS_RISCV64() namespace Kernel { diff --git a/Kernel/Devices/Storage/SD/Commands.h b/Kernel/Devices/Storage/SD/Commands.h index f62acc45b72..01164d2b56d 100644 --- a/Kernel/Devices/Storage/SD/Commands.h +++ b/Kernel/Devices/Storage/SD/Commands.h @@ -6,6 +6,7 @@ #pragma once +#include #include namespace Kernel::SD { diff --git a/Tests/AK/TestIndexSequence.cpp b/Tests/AK/TestIndexSequence.cpp index 1b897ff6b8b..f36bdac3d40 100644 --- a/Tests/AK/TestIndexSequence.cpp +++ b/Tests/AK/TestIndexSequence.cpp @@ -37,7 +37,7 @@ TEST_CASE(TestIndexSequence) constexpr auto index_seq2 = MakeIndexSequence<3> {}; static_assert(IsSame, ""); - verify_sequence(MakeIndexSequence<10> {}, std::initializer_list { 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U }); + verify_sequence(MakeIndexSequence<10> {}, std::initializer_list { 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U }); verify_sequence(MakeIntegerSequence {}, std::initializer_list { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }); } diff --git a/Userland/Libraries/LibC/arch/aarch64/fenv.cpp b/Userland/Libraries/LibC/arch/aarch64/fenv.cpp index 286fc738a6d..d9ef2de799c 100644 --- a/Userland/Libraries/LibC/arch/aarch64/fenv.cpp +++ b/Userland/Libraries/LibC/arch/aarch64/fenv.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include diff --git a/Userland/Libraries/LibC/arch/riscv64/fenv.cpp b/Userland/Libraries/LibC/arch/riscv64/fenv.cpp index c406c4ed1c8..3aedf717eb0 100644 --- a/Userland/Libraries/LibC/arch/riscv64/fenv.cpp +++ b/Userland/Libraries/LibC/arch/riscv64/fenv.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 8e38d4f4ab7..af172805f89 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -54,10 +54,10 @@ ErrorOr> VM::create(OwnPtr custom_data) return vm; } -template +template static constexpr auto make_single_ascii_character_strings(IndexSequence) { - return AK::Array { (String::from_code_point(code_points))... }; + return AK::Array { (String::from_code_point(static_cast(code_points)))... }; } static constexpr auto single_ascii_character_strings = make_single_ascii_character_strings(MakeIndexSequence<128>());