mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-26 04:35:41 +03:00
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:
parent
1c7ec9c770
commit
4409b33145
Notes:
sideshowbarker
2024-07-18 02:47:59 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/4409b33145 Pull-request: https://github.com/SerenityOS/serenity/pull/23129
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AK/BitCast.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace AK {
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <AK/DefaultDelete.h>
|
||||
#include <AK/SinglyLinkedListSizePolicy.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace AK {
|
||||
|
@ -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 {
|
||||
|
24
AK/Tuple.h
24
AK/Tuple.h
@ -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>()...);
|
||||
|
@ -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>> {}), ...);
|
||||
|
80
AK/Types.h
80
AK/Types.h
@ -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__;
|
||||
|
@ -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...>... {
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Userspace.h>
|
||||
#include <Kernel/API/POSIX/sched.h>
|
||||
|
@ -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>
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <Kernel/Security/ExecutionMode.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
VALIDATE_IS_AARCH64()
|
||||
|
||||
namespace Kernel {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Arch/RegisterState.h>
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <AK/BitCast.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <Kernel/Security/ExecutionMode.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
VALIDATE_IS_RISCV64()
|
||||
|
||||
namespace Kernel {
|
||||
|
@ -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)
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <Kernel/Arch/RegisterState.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
VALIDATE_IS_RISCV64()
|
||||
|
||||
namespace Kernel {
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace Kernel::SD {
|
||||
|
@ -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 });
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Types.h>
|
||||
#include <fenv.h>
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Types.h>
|
||||
#include <fenv.h>
|
||||
|
||||
|
@ -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>());
|
||||
|
Loading…
Reference in New Issue
Block a user