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 1f3346dcfa..d615d25d6a 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 24f18de69f..997ae19549 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 e856e3e684..6790de3f9c 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 46c3ba4113..df8a3d26fc 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 e2f3d13e8f..ef49f8ae7f 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 c60a5ed183..80adcfbf80 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 307c41a27e..d8dad49623 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 4e4bdc03b1..8d00db0315 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 c464229167..6683808e40 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 efbca3e8e7..4f0caf90b8 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 cd97a9ed4d..a72986e0e1 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 3a5a6c046f..a1f3cff971 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 da5b45f1ae..9480051c74 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 e08c0d933e..827dea472f 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 69de942984..6e01b3fe4c 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 f62acc45b7..01164d2b56 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 1b897ff6b8..f36bdac3d4 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 286fc738a6..d9ef2de799 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 c406c4ed1c..3aedf717eb 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 8e38d4f4ab..af172805f8 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>());