AK: Make IndexSequence use size_t

This makes it possible to use MakeIndexSequqnce in functions like:

    template<typename T, size_t N>
    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.)
This commit is contained in:
Nico Weber 2024-02-08 18:52:03 -05:00 committed by Ali Mohammad Pur
parent 1c7ec9c770
commit 4409b33145
Notes: sideshowbarker 2024-07-18 02:47:59 +09:00
20 changed files with 120 additions and 96 deletions

View file

@ -7,6 +7,7 @@
#pragma once
#include <AK/BitCast.h>
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
namespace AK {

View file

@ -8,6 +8,7 @@
#include <AK/DefaultDelete.h>
#include <AK/SinglyLinkedListSizePolicy.h>
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
namespace AK {

View file

@ -9,6 +9,7 @@
#pragma once
#include <AK/Platform.h>
#include <AK/Types.h>
namespace AK::Detail {
@ -175,19 +176,6 @@ inline constexpr bool IsSame = false;
template<typename T>
inline constexpr bool IsSame<T, T> = true;
template<bool condition, class TrueType, class FalseType>
struct __Conditional {
using Type = TrueType;
};
template<class TrueType, class FalseType>
struct __Conditional<false, TrueType, FalseType> {
using Type = FalseType;
};
template<bool condition, class TrueType, class FalseType>
using Conditional = typename __Conditional<condition, TrueType, FalseType>::Type;
template<typename T>
inline constexpr bool IsNullPointer = IsSame<decltype(nullptr), RemoveCV<T>>;
@ -284,64 +272,6 @@ struct __MakeUnsigned<wchar_t> {
template<typename T>
using MakeUnsigned = typename __MakeUnsigned<T>::Type;
template<typename T>
struct __MakeSigned {
using Type = void;
};
template<>
struct __MakeSigned<signed char> {
using Type = signed char;
};
template<>
struct __MakeSigned<short> {
using Type = short;
};
template<>
struct __MakeSigned<int> {
using Type = int;
};
template<>
struct __MakeSigned<long> {
using Type = long;
};
template<>
struct __MakeSigned<long long> {
using Type = long long;
};
template<>
struct __MakeSigned<unsigned char> {
using Type = char;
};
template<>
struct __MakeSigned<unsigned short> {
using Type = short;
};
template<>
struct __MakeSigned<unsigned int> {
using Type = int;
};
template<>
struct __MakeSigned<unsigned long> {
using Type = long;
};
template<>
struct __MakeSigned<unsigned long long> {
using Type = long long;
};
template<>
struct __MakeSigned<char> {
using Type = char;
};
#if ARCH(AARCH64)
template<>
struct __MakeSigned<wchar_t> {
using Type = void;
};
#endif
template<typename T>
using MakeSigned = typename __MakeSigned<T>::Type;
template<typename T>
auto declval() -> T;
@ -451,8 +381,8 @@ struct IntegerSequence {
static constexpr unsigned size() noexcept { return sizeof...(Ts); }
};
template<unsigned... Indices>
using IndexSequence = IntegerSequence<unsigned, Indices...>;
template<size_t... Indices>
using IndexSequence = IntegerSequence<size_t, Indices...>;
#if __has_builtin(__make_integer_seq)
template<typename T, T N>
@ -474,8 +404,8 @@ template<typename T, T N>
using MakeIntegerSequence = decltype(make_integer_sequence_impl<T, N>());
#endif
template<unsigned N>
using MakeIndexSequence = MakeIntegerSequence<unsigned, N>;
template<size_t N>
using MakeIndexSequence = MakeIntegerSequence<size_t, N>;
template<typename T>
struct __IdentityType {

View file

@ -41,14 +41,14 @@ struct Tuple<T> {
return const_cast<Tuple<T>&>(*this).get<U>();
}
template<typename U, unsigned index>
template<typename U, size_t index>
U& get_with_index()
{
static_assert(IsSame<T, U> && index == 0, "Invalid tuple access");
return value;
}
template<typename U, unsigned index>
template<typename U, size_t index>
U const& get_with_index() const
{
return const_cast<Tuple<T>&>(*this).get_with_index<U, index>();
@ -89,7 +89,7 @@ struct Tuple<T, TRest...> : Tuple<TRest...> {
return const_cast<Tuple<T, TRest...>&>(*this).get<U>();
}
template<typename U, unsigned index>
template<typename U, size_t index>
U& get_with_index()
{
if constexpr (IsSame<T, U> && index == 0)
@ -98,7 +98,7 @@ struct Tuple<T, TRest...> : Tuple<TRest...> {
return Tuple<TRest...>::template get_with_index<U, index - 1>();
}
template<typename U, unsigned index>
template<typename U, size_t index>
U const& get_with_index() const
{
return const_cast<Tuple<T, TRest...>&>(*this).get_with_index<U, index>();
@ -146,7 +146,7 @@ struct Tuple : Detail::Tuple<Ts...> {
return Detail::Tuple<Ts...>::template get<T>();
}
template<unsigned index>
template<size_t index>
auto& get()
{
return Detail::Tuple<Ts...>::template get_with_index<typename Types::template Type<index>, index>();
@ -158,7 +158,7 @@ struct Tuple : Detail::Tuple<Ts...> {
return Detail::Tuple<Ts...>::template get<T>();
}
template<unsigned index>
template<size_t index>
auto& get() const
{
return Detail::Tuple<Ts...>::template get_with_index<typename Types::template Type<index>, index>();
@ -179,37 +179,37 @@ struct Tuple : Detail::Tuple<Ts...> {
static constexpr auto size() { return sizeof...(Ts); }
private:
template<unsigned... Is>
template<size_t... Is>
Tuple(Tuple&& other, IndexSequence<Is...>)
: Detail::Tuple<Ts...>(move(other.get<Is>())...)
{
}
template<unsigned... Is>
template<size_t... Is>
Tuple(Tuple const& other, IndexSequence<Is...>)
: Detail::Tuple<Ts...>(other.get<Is>()...)
{
}
template<unsigned... Is>
template<size_t... Is>
void set(Tuple&& other, IndexSequence<Is...>)
{
((get<Is>() = move(other.get<Is>())), ...);
}
template<unsigned... Is>
template<size_t... Is>
void set(Tuple const& other, IndexSequence<Is...>)
{
((get<Is>() = other.get<Is>()), ...);
}
template<typename F, unsigned... Is>
template<typename F, size_t... Is>
auto apply_as_args(F&& f, IndexSequence<Is...>)
{
return forward<F>(f)(get<Is>()...);
}
template<typename F, unsigned... Is>
template<typename F, size_t... Is>
auto apply_as_args(F&& f, IndexSequence<Is...>) const
{
return forward<F>(f)(get<Is>()...);

View file

@ -46,7 +46,7 @@ struct TypeWrapper {
using Type = T;
};
template<typename List, typename F, unsigned... Indices>
template<typename List, typename F, size_t... Indices>
constexpr void for_each_type_impl(F&& f, IndexSequence<Indices...>)
{
(forward<F>(f)(TypeWrapper<typename List::template Type<Indices>> {}), ...);
@ -58,7 +58,7 @@ constexpr void for_each_type(F&& f)
for_each_type_impl<List>(forward<F>(f), MakeIndexSequence<List::size> {});
}
template<typename ListA, typename ListB, typename F, unsigned... Indices>
template<typename ListA, typename ListB, typename F, size_t... Indices>
constexpr void for_each_type_zipped_impl(F&& f, IndexSequence<Indices...>)
{
(forward<F>(f)(TypeWrapper<typename ListA::template Type<Indices>> {}, TypeWrapper<typename ListB::template Type<Indices>> {}), ...);

View file

@ -7,7 +7,6 @@
#pragma once
#include <AK/Platform.h>
#include <AK/StdLibExtras.h>
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<typename T>
struct __MakeSigned {
using Type = void;
};
template<>
struct __MakeSigned<signed char> {
using Type = signed char;
};
template<>
struct __MakeSigned<short> {
using Type = short;
};
template<>
struct __MakeSigned<int> {
using Type = int;
};
template<>
struct __MakeSigned<long> {
using Type = long;
};
template<>
struct __MakeSigned<long long> {
using Type = long long;
};
template<>
struct __MakeSigned<unsigned char> {
using Type = char;
};
template<>
struct __MakeSigned<unsigned short> {
using Type = short;
};
template<>
struct __MakeSigned<unsigned int> {
using Type = int;
};
template<>
struct __MakeSigned<unsigned long> {
using Type = long;
};
template<>
struct __MakeSigned<unsigned long long> {
using Type = long long;
};
template<>
struct __MakeSigned<char> {
using Type = char;
};
#if ARCH(AARCH64)
template<>
struct __MakeSigned<wchar_t> {
using Type = void;
};
#endif
template<typename T>
using MakeSigned = typename __MakeSigned<T>::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<bool condition, class TrueType, class FalseType>
struct __Conditional {
using Type = TrueType;
};
template<class TrueType, class FalseType>
struct __Conditional<false, TrueType, FalseType> {
using Type = FalseType;
};
template<bool condition, class TrueType, class FalseType>
using Conditional = typename __Conditional<condition, TrueType, FalseType>::Type;
}
#ifdef AK_OS_SERENITY
using size_t = __SIZE_TYPE__;

View file

@ -182,14 +182,14 @@ inline constexpr bool IsTypeInPack<T, ParameterPack<Ts...>> = (IsSame<T, Ts> ||
template<typename T, typename... Qs>
using BlankIfDuplicate = Conditional<(IsTypeInPack<T, Qs> || ...), Blank<T>, T>;
template<unsigned I, typename...>
template<size_t I, typename...>
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<unsigned I, typename... Ts, unsigned... Js, typename... Qs>
template<size_t I, typename... Ts, size_t... Js, typename... Qs>
struct InheritFromUniqueEntries<I, ParameterPack<Ts...>, IndexSequence<Js...>, Qs...>
: public BlankIfDuplicate<Ts, Conditional<Js <= I, ParameterPack<>, 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<unsigned... Is, typename... Ps>
template<size_t... Is, typename... Ps>
struct InheritFromPacks<IndexSequence<Is...>, Ps...>
: public InheritFromUniqueEntries<Is, Ps, IndexSequence<Is...>, Ps...>... {

View file

@ -6,6 +6,7 @@
#pragma once
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
#include <AK/Userspace.h>
#include <Kernel/API/POSIX/sched.h>

View file

@ -12,6 +12,7 @@
#include <AK/HashMap.h>
#include <AK/IntrusiveRedBlackTree.h>
#include <AK/RefPtr.h>
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
#include <Kernel/Forward.h>
#include <Kernel/Locking/Spinlock.h>

View file

@ -11,6 +11,8 @@
#include <Kernel/Security/ExecutionMode.h>
#include <AK/Platform.h>
#include <AK/StdLibExtras.h>
VALIDATE_IS_AARCH64()
namespace Kernel {

View file

@ -8,6 +8,7 @@
#pragma once
#include <AK/Platform.h>
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
#include <Kernel/Arch/RegisterState.h>

View file

@ -8,6 +8,7 @@
#include <AK/BitCast.h>
#include <AK/Format.h>
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
#include <AK/Platform.h>

View file

@ -12,6 +12,8 @@
#include <Kernel/Security/ExecutionMode.h>
#include <AK/Platform.h>
#include <AK/StdLibExtras.h>
VALIDATE_IS_RISCV64()
namespace Kernel {

View file

@ -8,6 +8,7 @@
#include <AK/Error.h>
#include <AK/Format.h>
#include <AK/StdLibExtras.h>
// Documentation about the SBI:
// RISC-V Supervisor Binary Interface Specification (https://github.com/riscv-non-isa/riscv-sbi-doc)

View file

@ -9,6 +9,8 @@
#include <Kernel/Arch/RegisterState.h>
#include <AK/Platform.h>
#include <AK/StdLibExtras.h>
VALIDATE_IS_RISCV64()
namespace Kernel {

View file

@ -6,6 +6,7 @@
#pragma once
#include <AK/StdLibExtras.h>
#include <AK/Types.h>
namespace Kernel::SD {

View file

@ -37,7 +37,7 @@ TEST_CASE(TestIndexSequence)
constexpr auto index_seq2 = MakeIndexSequence<3> {};
static_assert(IsSame<decltype(index_seq1), decltype(index_seq2)>, "");
verify_sequence(MakeIndexSequence<10> {}, std::initializer_list<unsigned> { 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U });
verify_sequence(MakeIndexSequence<10> {}, std::initializer_list<size_t> { 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U });
verify_sequence(MakeIntegerSequence<long, 16> {}, std::initializer_list<long> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 });
}

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Assertions.h>
#include <AK/Types.h>
#include <fenv.h>

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Assertions.h>
#include <AK/Types.h>
#include <fenv.h>

View file

@ -54,10 +54,10 @@ ErrorOr<NonnullRefPtr<VM>> VM::create(OwnPtr<CustomData> custom_data)
return vm;
}
template<u32... code_points>
template<size_t... code_points>
static constexpr auto make_single_ascii_character_strings(IndexSequence<code_points...>)
{
return AK::Array { (String::from_code_point(code_points))... };
return AK::Array { (String::from_code_point(static_cast<u32>(code_points)))... };
}
static constexpr auto single_ascii_character_strings = make_single_ascii_character_strings(MakeIndexSequence<128>());