mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 05:25:32 +03:00
AK+Everywhere: Make StdLibExtras templates less wrapper-y
This commit makes the user-facing StdLibExtras templates and utilities arguably more nice-looking by removing the need to reach into the wrapper structs generated by them to get the value/type needed. The C++ standard library had to invent `_v` and `_t` variants (likely because of backwards compat), but we don't need to cater to any codebase except our own, so might as well have good things for free. :^)
This commit is contained in:
parent
d8d16dea95
commit
a6e4482080
Notes:
sideshowbarker
2024-07-18 20:34:39 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/a6e44820805 Pull-request: https://github.com/SerenityOS/serenity/pull/6214
14
AK/Atomic.h
14
AK/Atomic.h
@ -53,13 +53,13 @@ static inline T atomic_exchange(volatile T* var, T desired, MemoryOrder order =
|
|||||||
return __atomic_exchange_n(var, desired, order);
|
return __atomic_exchange_n(var, desired, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
template<typename T, typename V = RemoveVolatile<T>>
|
||||||
static inline V* atomic_exchange(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept
|
static inline V* atomic_exchange(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept
|
||||||
{
|
{
|
||||||
return __atomic_exchange_n(var, desired, order);
|
return __atomic_exchange_n(var, desired, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
template<typename T, typename V = RemoveVolatile<T>>
|
||||||
static inline V* atomic_exchange(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept
|
static inline V* atomic_exchange(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept
|
||||||
{
|
{
|
||||||
return __atomic_exchange_n(const_cast<V**>(var), nullptr, order);
|
return __atomic_exchange_n(const_cast<V**>(var), nullptr, order);
|
||||||
@ -74,7 +74,7 @@ template<typename T>
|
|||||||
return __atomic_compare_exchange_n(var, &expected, desired, false, order, order);
|
return __atomic_compare_exchange_n(var, &expected, desired, false, order, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
template<typename T, typename V = RemoveVolatile<T>>
|
||||||
[[nodiscard]] static inline bool atomic_compare_exchange_strong(volatile T** var, V*& expected, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept
|
[[nodiscard]] static inline bool atomic_compare_exchange_strong(volatile T** var, V*& expected, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept
|
||||||
{
|
{
|
||||||
if (order == memory_order_acq_rel || order == memory_order_release)
|
if (order == memory_order_acq_rel || order == memory_order_release)
|
||||||
@ -83,7 +83,7 @@ template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
|||||||
return __atomic_compare_exchange_n(var, &expected, desired, false, order, order);
|
return __atomic_compare_exchange_n(var, &expected, desired, false, order, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
template<typename T, typename V = RemoveVolatile<T>>
|
||||||
[[nodiscard]] static inline bool atomic_compare_exchange_strong(volatile T** var, V*& expected, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept
|
[[nodiscard]] static inline bool atomic_compare_exchange_strong(volatile T** var, V*& expected, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept
|
||||||
{
|
{
|
||||||
if (order == memory_order_acq_rel || order == memory_order_release)
|
if (order == memory_order_acq_rel || order == memory_order_release)
|
||||||
@ -128,7 +128,7 @@ static inline T atomic_load(volatile T* var, MemoryOrder order = memory_order_se
|
|||||||
return __atomic_load_n(var, order);
|
return __atomic_load_n(var, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
template<typename T, typename V = RemoveVolatile<T>>
|
||||||
static inline V* atomic_load(volatile T** var, MemoryOrder order = memory_order_seq_cst) noexcept
|
static inline V* atomic_load(volatile T** var, MemoryOrder order = memory_order_seq_cst) noexcept
|
||||||
{
|
{
|
||||||
return __atomic_load_n(const_cast<V**>(var), order);
|
return __atomic_load_n(const_cast<V**>(var), order);
|
||||||
@ -140,13 +140,13 @@ static inline void atomic_store(volatile T* var, T desired, MemoryOrder order =
|
|||||||
__atomic_store_n(var, desired, order);
|
__atomic_store_n(var, desired, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
template<typename T, typename V = RemoveVolatile<T>>
|
||||||
static inline void atomic_store(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept
|
static inline void atomic_store(volatile T** var, V* desired, MemoryOrder order = memory_order_seq_cst) noexcept
|
||||||
{
|
{
|
||||||
__atomic_store_n(var, desired, order);
|
__atomic_store_n(var, desired, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename V = typename RemoveVolatile<T>::Type>
|
template<typename T, typename V = RemoveVolatile<T>>
|
||||||
static inline void atomic_store(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept
|
static inline void atomic_store(volatile T** var, std::nullptr_t, MemoryOrder order = memory_order_seq_cst) noexcept
|
||||||
{
|
{
|
||||||
__atomic_store_n(const_cast<V**>(var), nullptr, order);
|
__atomic_store_n(const_cast<V**>(var), nullptr, order);
|
||||||
|
@ -41,7 +41,7 @@ template<typename StreamType, size_t Size = 4096, typename = void>
|
|||||||
class Buffered;
|
class Buffered;
|
||||||
|
|
||||||
template<typename StreamType, size_t Size>
|
template<typename StreamType, size_t Size>
|
||||||
class Buffered<StreamType, Size, typename EnableIf<IsBaseOf<InputStream, StreamType>::value>::Type> final : public InputStream {
|
class Buffered<StreamType, Size, typename EnableIf<IsBaseOf<InputStream, StreamType>>::Type> final : public InputStream {
|
||||||
AK_MAKE_NONCOPYABLE(Buffered);
|
AK_MAKE_NONCOPYABLE(Buffered);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -137,7 +137,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename StreamType, size_t Size>
|
template<typename StreamType, size_t Size>
|
||||||
class Buffered<StreamType, Size, typename EnableIf<IsBaseOf<OutputStream, StreamType>::value>::Type> final : public OutputStream {
|
class Buffered<StreamType, Size, typename EnableIf<IsBaseOf<OutputStream, StreamType>>::Type> final : public OutputStream {
|
||||||
AK_MAKE_NONCOPYABLE(Buffered);
|
AK_MAKE_NONCOPYABLE(Buffered);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -237,6 +237,6 @@ private:
|
|||||||
namespace AK {
|
namespace AK {
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
using CheckedFormatString = Format::Detail::CheckedFormatString<typename IdentityType<Args>::Type...>;
|
using CheckedFormatString = Format::Detail::CheckedFormatString<IdentityType<Args>...>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,19 +33,19 @@ namespace AK::Concepts {
|
|||||||
#if defined(__cpp_concepts) && !defined(__COVERITY__)
|
#if defined(__cpp_concepts) && !defined(__COVERITY__)
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept Integral = IsIntegral<T>::value;
|
concept Integral = IsIntegral<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept FloatingPoint = IsFloatingPoint<T>::value;
|
concept FloatingPoint = IsFloatingPoint<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept Arithmetic = IsArithmetic<T>::value;
|
concept Arithmetic = IsArithmetic<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept Signed = IsSigned<T>::value;
|
concept Signed = IsSigned<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept Unsigned = IsUnsigned<T>::value;
|
concept Unsigned = IsUnsigned<T>;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ public:
|
|||||||
template<typename U>
|
template<typename U>
|
||||||
void prepend(U&& value)
|
void prepend(U&& value)
|
||||||
{
|
{
|
||||||
static_assert(IsSame<T, U>::value);
|
static_assert(IsSame<T, U>);
|
||||||
auto* node = new Node(forward<U>(value));
|
auto* node = new Node(forward<U>(value));
|
||||||
if (!m_head) {
|
if (!m_head) {
|
||||||
VERIFY(!m_tail);
|
VERIFY(!m_tail);
|
||||||
|
@ -44,35 +44,35 @@
|
|||||||
\
|
\
|
||||||
[[nodiscard]] Prefix constexpr inline Enum operator|(Enum lhs, Enum rhs) \
|
[[nodiscard]] Prefix constexpr inline Enum operator|(Enum lhs, Enum rhs) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
return static_cast<Enum>( \
|
return static_cast<Enum>( \
|
||||||
static_cast<Type>(lhs) | static_cast<Type>(rhs)); \
|
static_cast<Type>(lhs) | static_cast<Type>(rhs)); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
[[nodiscard]] Prefix constexpr inline Enum operator&(Enum lhs, Enum rhs) \
|
[[nodiscard]] Prefix constexpr inline Enum operator&(Enum lhs, Enum rhs) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
return static_cast<Enum>( \
|
return static_cast<Enum>( \
|
||||||
static_cast<Type>(lhs) & static_cast<Type>(rhs)); \
|
static_cast<Type>(lhs) & static_cast<Type>(rhs)); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
[[nodiscard]] Prefix constexpr inline Enum operator^(Enum lhs, Enum rhs) \
|
[[nodiscard]] Prefix constexpr inline Enum operator^(Enum lhs, Enum rhs) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
return static_cast<Enum>( \
|
return static_cast<Enum>( \
|
||||||
static_cast<Type>(lhs) ^ static_cast<Type>(rhs)); \
|
static_cast<Type>(lhs) ^ static_cast<Type>(rhs)); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
[[nodiscard]] Prefix constexpr inline Enum operator~(Enum rhs) \
|
[[nodiscard]] Prefix constexpr inline Enum operator~(Enum rhs) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
return static_cast<Enum>( \
|
return static_cast<Enum>( \
|
||||||
~static_cast<Type>(rhs)); \
|
~static_cast<Type>(rhs)); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
Prefix constexpr inline Enum& operator|=(Enum& lhs, Enum rhs) \
|
Prefix constexpr inline Enum& operator|=(Enum& lhs, Enum rhs) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
lhs = static_cast<Enum>( \
|
lhs = static_cast<Enum>( \
|
||||||
static_cast<Type>(lhs) | static_cast<Type>(rhs)); \
|
static_cast<Type>(lhs) | static_cast<Type>(rhs)); \
|
||||||
return lhs; \
|
return lhs; \
|
||||||
@ -80,7 +80,7 @@
|
|||||||
\
|
\
|
||||||
Prefix constexpr inline Enum& operator&=(Enum& lhs, Enum rhs) \
|
Prefix constexpr inline Enum& operator&=(Enum& lhs, Enum rhs) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
lhs = static_cast<Enum>( \
|
lhs = static_cast<Enum>( \
|
||||||
static_cast<Type>(lhs) & static_cast<Type>(rhs)); \
|
static_cast<Type>(lhs) & static_cast<Type>(rhs)); \
|
||||||
return lhs; \
|
return lhs; \
|
||||||
@ -88,7 +88,7 @@
|
|||||||
\
|
\
|
||||||
Prefix constexpr inline Enum& operator^=(Enum& lhs, Enum rhs) \
|
Prefix constexpr inline Enum& operator^=(Enum& lhs, Enum rhs) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
lhs = static_cast<Enum>( \
|
lhs = static_cast<Enum>( \
|
||||||
static_cast<Type>(lhs) ^ static_cast<Type>(rhs)); \
|
static_cast<Type>(lhs) ^ static_cast<Type>(rhs)); \
|
||||||
return lhs; \
|
return lhs; \
|
||||||
@ -96,6 +96,6 @@
|
|||||||
\
|
\
|
||||||
Prefix constexpr inline bool has_flag(Enum value, Enum mask) \
|
Prefix constexpr inline bool has_flag(Enum value, Enum mask) \
|
||||||
{ \
|
{ \
|
||||||
using Type = UnderlyingType<Enum>::Type; \
|
using Type = UnderlyingType<Enum>; \
|
||||||
return static_cast<Type>(value & mask) != 0; \
|
return static_cast<Type>(value & mask) != 0; \
|
||||||
}
|
}
|
||||||
|
@ -534,7 +534,7 @@ void Formatter<FormatString>::vformat(FormatBuilder& builder, StringView fmtstr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Formatter<T, typename EnableIf<IsIntegral<T>::value>::Type>::format(FormatBuilder& builder, T value)
|
void Formatter<T, typename EnableIf<IsIntegral<T>>::Type>::format(FormatBuilder& builder, T value)
|
||||||
{
|
{
|
||||||
if (m_mode == Mode::Character) {
|
if (m_mode == Mode::Character) {
|
||||||
// FIXME: We just support ASCII for now, in the future maybe unicode?
|
// FIXME: We just support ASCII for now, in the future maybe unicode?
|
||||||
@ -587,7 +587,7 @@ void Formatter<T, typename EnableIf<IsIntegral<T>::value>::Type>::format(FormatB
|
|||||||
|
|
||||||
m_width = m_width.value_or(0);
|
m_width = m_width.value_or(0);
|
||||||
|
|
||||||
if (IsSame<typename MakeUnsigned<T>::Type, T>::value)
|
if constexpr (IsSame<MakeUnsigned<T>, T>)
|
||||||
builder.put_u64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
|
builder.put_u64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
|
||||||
else
|
else
|
||||||
builder.put_i64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
|
builder.put_i64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
|
||||||
|
19
AK/Format.h
19
AK/Format.h
@ -93,10 +93,10 @@ struct TypeErasedParameter {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
static Type get_type()
|
static Type get_type()
|
||||||
{
|
{
|
||||||
if (IsIntegral<T>::value)
|
if constexpr (IsIntegral<T>)
|
||||||
return get_type_from_size(sizeof(T), IsUnsigned<T>::value);
|
return get_type_from_size(sizeof(T), IsUnsigned<T>);
|
||||||
|
else
|
||||||
return Type::Custom;
|
return Type::Custom;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t to_size() const;
|
size_t to_size() const;
|
||||||
@ -269,7 +269,7 @@ struct StandardFormatter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Formatter<T, typename EnableIf<IsIntegral<T>::value>::Type> : StandardFormatter {
|
struct Formatter<T, typename EnableIf<IsIntegral<T>>::Type> : StandardFormatter {
|
||||||
Formatter() = default;
|
Formatter() = default;
|
||||||
explicit Formatter(StandardFormatter formatter)
|
explicit Formatter(StandardFormatter formatter)
|
||||||
: StandardFormatter(formatter)
|
: StandardFormatter(formatter)
|
||||||
@ -416,11 +416,10 @@ void dmesgln(CheckedFormatString<Parameters...>&& fmt, const Parameters&... para
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T, typename = void>
|
template<typename T, typename = void>
|
||||||
struct HasFormatter : TrueType {
|
inline constexpr bool HasFormatter = true;
|
||||||
};
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct HasFormatter<T, typename Formatter<T>::__no_formatter_defined> : FalseType {
|
inline constexpr bool HasFormatter<T, typename Formatter<T>::__no_formatter_defined> = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class FormatIfSupported {
|
class FormatIfSupported {
|
||||||
@ -450,7 +449,7 @@ struct __FormatIfSupported<T, true> : Formatter<T> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Formatter<FormatIfSupported<T>> : __FormatIfSupported<T, HasFormatter<T>::value> {
|
struct Formatter<FormatIfSupported<T>> : __FormatIfSupported<T, HasFormatter<T>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a helper class, the idea is that if you want to implement a formatter you can inherit
|
// This is a helper class, the idea is that if you want to implement a formatter you can inherit
|
||||||
|
@ -39,13 +39,13 @@ class Function<Out(In...)> {
|
|||||||
public:
|
public:
|
||||||
Function() = default;
|
Function() = default;
|
||||||
|
|
||||||
template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType>::value && IsFunction<typename RemovePointer<CallableType>::Type>::value) && IsRvalueReference<CallableType&&>::value>::Type>
|
template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType> && IsFunction<RemovePointer<CallableType>>)&&IsRvalueReference<CallableType&&>>::Type>
|
||||||
Function(CallableType&& callable)
|
Function(CallableType&& callable)
|
||||||
: m_callable_wrapper(make<CallableWrapper<CallableType>>(move(callable)))
|
: m_callable_wrapper(make<CallableWrapper<CallableType>>(move(callable)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType>::value && IsFunction<typename RemovePointer<FunctionType>::Type>::value>::Type>
|
template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType> && IsFunction<RemovePointer<FunctionType>>>::Type>
|
||||||
Function(FunctionType f)
|
Function(FunctionType f)
|
||||||
: m_callable_wrapper(make<CallableWrapper<FunctionType>>(move(f)))
|
: m_callable_wrapper(make<CallableWrapper<FunctionType>>(move(f)))
|
||||||
{
|
{
|
||||||
@ -59,14 +59,14 @@ public:
|
|||||||
|
|
||||||
explicit operator bool() const { return !!m_callable_wrapper; }
|
explicit operator bool() const { return !!m_callable_wrapper; }
|
||||||
|
|
||||||
template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType>::value && IsFunction<typename RemovePointer<CallableType>::Type>::value) && IsRvalueReference<CallableType&&>::value>::Type>
|
template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType> && IsFunction<RemovePointer<CallableType>>)&&IsRvalueReference<CallableType&&>>::Type>
|
||||||
Function& operator=(CallableType&& callable)
|
Function& operator=(CallableType&& callable)
|
||||||
{
|
{
|
||||||
m_callable_wrapper = make<CallableWrapper<CallableType>>(move(callable));
|
m_callable_wrapper = make<CallableWrapper<CallableType>>(move(callable));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType>::value && IsFunction<typename RemovePointer<FunctionType>::Type>::value>::Type>
|
template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType> && IsFunction<RemovePointer<FunctionType>>>::Type>
|
||||||
Function& operator=(FunctionType f)
|
Function& operator=(FunctionType f)
|
||||||
{
|
{
|
||||||
m_callable_wrapper = make<CallableWrapper<FunctionType>>(move(f));
|
m_callable_wrapper = make<CallableWrapper<FunctionType>>(move(f));
|
||||||
@ -103,7 +103,7 @@ private:
|
|||||||
return m_callable(forward<In>(in)...);
|
return m_callable(forward<In>(in)...);
|
||||||
} else if constexpr (requires { m_callable(); }) {
|
} else if constexpr (requires { m_callable(); }) {
|
||||||
return m_callable();
|
return m_callable();
|
||||||
} else if constexpr (IsSame<void, Out>::value) {
|
} else if constexpr (IsVoid<Out>) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return {};
|
return {};
|
||||||
|
@ -89,9 +89,9 @@ private:
|
|||||||
static constexpr SimpleIterator begin(Container& container) { return { container, 0 }; }
|
static constexpr SimpleIterator begin(Container& container) { return { container, 0 }; }
|
||||||
static constexpr SimpleIterator end(Container& container)
|
static constexpr SimpleIterator end(Container& container)
|
||||||
{
|
{
|
||||||
using RawContainerType = typename RemoveCV<Container>::Type;
|
using RawContainerType = RemoveCV<Container>;
|
||||||
|
|
||||||
if constexpr (IsSame<StringView, RawContainerType>::value || IsSame<String, RawContainerType>::value)
|
if constexpr (IsSame<StringView, RawContainerType> || IsSame<String, RawContainerType>)
|
||||||
return { container, container.length() };
|
return { container, container.length() };
|
||||||
else
|
else
|
||||||
return { container, container.size() };
|
return { container, container.size() };
|
||||||
|
@ -379,7 +379,7 @@ public:
|
|||||||
|
|
||||||
ALWAYS_INLINE bool is_null() const { return PtrTraits::is_null(m_bits.load(AK::MemoryOrder::memory_order_relaxed)); }
|
ALWAYS_INLINE bool is_null() const { return PtrTraits::is_null(m_bits.load(AK::MemoryOrder::memory_order_relaxed)); }
|
||||||
|
|
||||||
template<typename U = T, typename EnableIf<IsSame<U, T>::value && !IsNullPointer<typename PtrTraits::NullType>::value>::Type* = nullptr>
|
template<typename U = T, typename EnableIf<IsSame<U, T> && !IsNullPointer<typename PtrTraits::NullType>>::Type* = nullptr>
|
||||||
typename PtrTraits::NullType null_value() const
|
typename PtrTraits::NullType null_value() const
|
||||||
{
|
{
|
||||||
// make sure we are holding a null value
|
// make sure we are holding a null value
|
||||||
@ -387,7 +387,7 @@ public:
|
|||||||
VERIFY(PtrTraits::is_null(bits));
|
VERIFY(PtrTraits::is_null(bits));
|
||||||
return PtrTraits::to_null_value(bits);
|
return PtrTraits::to_null_value(bits);
|
||||||
}
|
}
|
||||||
template<typename U = T, typename EnableIf<IsSame<U, T>::value && !IsNullPointer<typename PtrTraits::NullType>::value>::Type* = nullptr>
|
template<typename U = T, typename EnableIf<IsSame<U, T> && !IsNullPointer<typename PtrTraits::NullType>>::Type* = nullptr>
|
||||||
void set_null_value(typename PtrTraits::NullType value)
|
void set_null_value(typename PtrTraits::NullType value)
|
||||||
{
|
{
|
||||||
// make sure that new null value would be interpreted as a null value
|
// make sure that new null value would be interpreted as a null value
|
||||||
|
@ -167,16 +167,16 @@ public:
|
|||||||
__builtin_memcpy(this->data() + offset, data, data_size);
|
__builtin_memcpy(this->data() + offset, data, data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE constexpr size_t copy_to(Span<typename RemoveConst<T>::Type> other) const
|
ALWAYS_INLINE constexpr size_t copy_to(Span<RemoveConst<T>> other) const
|
||||||
{
|
{
|
||||||
VERIFY(other.size() >= size());
|
VERIFY(other.size() >= size());
|
||||||
return TypedTransfer<typename RemoveConst<T>::Type>::copy(other.data(), data(), size());
|
return TypedTransfer<RemoveConst<T>>::copy(other.data(), data(), size());
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE constexpr size_t copy_trimmed_to(Span<typename RemoveConst<T>::Type> other) const
|
ALWAYS_INLINE constexpr size_t copy_trimmed_to(Span<RemoveConst<T>> other) const
|
||||||
{
|
{
|
||||||
const auto count = min(size(), other.size());
|
const auto count = min(size(), other.size());
|
||||||
return TypedTransfer<typename RemoveConst<T>::Type>::copy(other.data(), data(), count);
|
return TypedTransfer<RemoveConst<T>>::copy(other.data(), data(), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE constexpr size_t fill(const T& value)
|
ALWAYS_INLINE constexpr size_t fill(const T& value)
|
||||||
|
498
AK/StdLibExtraDetails.h
Normal file
498
AK/StdLibExtraDetails.h
Normal file
@ -0,0 +1,498 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2021, Ali Mohammad Pur <ali.mpfard@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace AK::Detail {
|
||||||
|
|
||||||
|
template<bool B, class T = void>
|
||||||
|
struct EnableIf {
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct EnableIf<true, T> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, T v>
|
||||||
|
struct IntegralConstant {
|
||||||
|
static constexpr T value = v;
|
||||||
|
using ValueType = T;
|
||||||
|
using Type = IntegralConstant;
|
||||||
|
constexpr operator ValueType() const { return value; }
|
||||||
|
constexpr ValueType operator()() const { return value; }
|
||||||
|
};
|
||||||
|
|
||||||
|
using FalseType = IntegralConstant<bool, false>;
|
||||||
|
using TrueType = IntegralConstant<bool, true>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using AddConst = const T;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct __RemoveConst {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
struct __RemoveConst<const T> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
using RemoveConst = typename __RemoveConst<T>::Type;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct __RemoveVolatile {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct __RemoveVolatile<volatile T> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using RemoveVolatile = typename __RemoveVolatile<T>::Type;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using RemoveCV = RemoveVolatile<RemoveConst<T>>;
|
||||||
|
|
||||||
|
template<typename...>
|
||||||
|
using VoidType = void;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsLvalueReference = false;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsLvalueReference<T&> = true;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool __IsPointerHelper = false;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool __IsPointerHelper<T*> = true;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsPointer = __IsPointerHelper<RemoveCV<T>>;
|
||||||
|
|
||||||
|
template<class>
|
||||||
|
inline constexpr bool IsFunction = false;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...)> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...)> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) const> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) const> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) volatile> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) volatile> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) const volatile> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) const volatile> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...)&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...)&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) const&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) const&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) volatile&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) volatile&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) const volatile&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) const volatile&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) &&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) &&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) const&&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) const&&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) volatile&&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) volatile&&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args...) const volatile&&> = true;
|
||||||
|
template<class Ret, class... Args>
|
||||||
|
inline constexpr bool IsFunction<Ret(Args..., ...) const volatile&&> = true;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsRvalueReference = false;
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsRvalueReference<T&&> = true;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct __RemovePointer {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
struct __RemovePointer<T*> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
struct __RemovePointer<T* const> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
struct __RemovePointer<T* volatile> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
struct __RemovePointer<T* const volatile> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
using RemovePointer = typename __RemovePointer<T>::Type;
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
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>>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct __RemoveReference {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
struct __RemoveReference<T&> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
struct __RemoveReference<T&&> {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using RemoveReference = typename __RemoveReference<T>::Type;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct __MakeUnsigned {
|
||||||
|
using Type = void;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<signed char> {
|
||||||
|
using Type = unsigned char;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<short> {
|
||||||
|
using Type = unsigned short;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<int> {
|
||||||
|
using Type = unsigned int;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<long> {
|
||||||
|
using Type = unsigned long;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<long long> {
|
||||||
|
using Type = unsigned long long;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<unsigned char> {
|
||||||
|
using Type = unsigned char;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<unsigned short> {
|
||||||
|
using Type = unsigned short;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<unsigned int> {
|
||||||
|
using Type = unsigned int;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<unsigned long> {
|
||||||
|
using Type = unsigned long;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<unsigned long long> {
|
||||||
|
using Type = unsigned long long;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<char> {
|
||||||
|
using Type = unsigned char;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<char8_t> {
|
||||||
|
using Type = char8_t;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<char16_t> {
|
||||||
|
using Type = char16_t;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<char32_t> {
|
||||||
|
using Type = char32_t;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct __MakeUnsigned<bool> {
|
||||||
|
using Type = bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using MakeUnsigned = typename __MakeUnsigned<T>::Type;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct __MakeSigned {
|
||||||
|
};
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using MakeSigned = typename __MakeSigned<T>::Type;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsVoid = IsSame<void, RemoveCV<T>>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsConst = false;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline constexpr bool IsConst<const T> = true;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsEnum = __is_enum(T);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsUnion = __is_union(T);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsClass = __is_class(T);
|
||||||
|
|
||||||
|
template<typename Base, typename Derived>
|
||||||
|
inline constexpr bool IsBaseOf = __is_base_of(Base, Derived);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool __IsIntegral = false;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<bool> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<unsigned char> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<char8_t> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<char16_t> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<char32_t> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<unsigned short> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<unsigned int> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<unsigned long> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsIntegral<unsigned long long> = true;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsIntegral = __IsIntegral<MakeUnsigned<RemoveCV<T>>>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool __IsFloatingPoint = false;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsFloatingPoint<float> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsFloatingPoint<double> = true;
|
||||||
|
template<>
|
||||||
|
inline constexpr bool __IsFloatingPoint<long double> = true;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsFloatingPoint = __IsFloatingPoint<RemoveCV<T>>;
|
||||||
|
|
||||||
|
template<typename ReferenceType, typename T>
|
||||||
|
using CopyConst = Conditional<IsConst<ReferenceType>, AddConst<T>, RemoveConst<T>>;
|
||||||
|
|
||||||
|
template<typename... Ts>
|
||||||
|
using Void = void;
|
||||||
|
|
||||||
|
template<typename... _Ignored>
|
||||||
|
constexpr auto DependentFalse = false;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsSigned = IsSame<T, MakeSigned<T>>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsUnsigned = IsSame<T, MakeUnsigned<T>>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsArithmetic = IsIntegral<T> || IsFloatingPoint<T>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsFundamental = IsArithmetic<T> || IsVoid<T> || IsNullPointer<T>;
|
||||||
|
|
||||||
|
template<typename T, T... Ts>
|
||||||
|
struct IntegerSequence {
|
||||||
|
using Type = T;
|
||||||
|
static constexpr unsigned size() noexcept { return sizeof...(Ts); };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned... Indices>
|
||||||
|
using IndexSequence = IntegerSequence<unsigned, Indices...>;
|
||||||
|
|
||||||
|
template<typename T, T N, T... Ts>
|
||||||
|
auto make_integer_sequence_impl()
|
||||||
|
{
|
||||||
|
if constexpr (N == 0)
|
||||||
|
return IntegerSequence<T, Ts...> {};
|
||||||
|
else
|
||||||
|
return make_integer_sequence_impl<T, N - 1, N - 1, Ts...>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, T N>
|
||||||
|
using MakeIntegerSequence = decltype(make_integer_sequence_impl<T, N>());
|
||||||
|
|
||||||
|
template<unsigned N>
|
||||||
|
using MakeIndexSequence = MakeIntegerSequence<unsigned, N>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct __IdentityType {
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using IdentityType = typename __IdentityType<T>::Type;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
requires(IsEnum<T>) using UnderlyingType = __underlying_type(T);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsTrivial = __is_trivial(T);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool IsTriviallyCopyable = __is_trivially_copyable(T);
|
||||||
|
|
||||||
|
}
|
||||||
|
using AK::Detail::AddConst;
|
||||||
|
using AK::Detail::Conditional;
|
||||||
|
using AK::Detail::CopyConst;
|
||||||
|
using AK::Detail::DependentFalse;
|
||||||
|
using AK::Detail::EnableIf;
|
||||||
|
using AK::Detail::FalseType;
|
||||||
|
using AK::Detail::IdentityType;
|
||||||
|
using AK::Detail::IndexSequence;
|
||||||
|
using AK::Detail::IntegerSequence;
|
||||||
|
using AK::Detail::IsArithmetic;
|
||||||
|
using AK::Detail::IsBaseOf;
|
||||||
|
using AK::Detail::IsClass;
|
||||||
|
using AK::Detail::IsConst;
|
||||||
|
using AK::Detail::IsEnum;
|
||||||
|
using AK::Detail::IsFloatingPoint;
|
||||||
|
using AK::Detail::IsFunction;
|
||||||
|
using AK::Detail::IsFundamental;
|
||||||
|
using AK::Detail::IsIntegral;
|
||||||
|
using AK::Detail::IsLvalueReference;
|
||||||
|
using AK::Detail::IsNullPointer;
|
||||||
|
using AK::Detail::IsPointer;
|
||||||
|
using AK::Detail::IsRvalueReference;
|
||||||
|
using AK::Detail::IsSame;
|
||||||
|
using AK::Detail::IsSigned;
|
||||||
|
using AK::Detail::IsTrivial;
|
||||||
|
using AK::Detail::IsTriviallyCopyable;
|
||||||
|
using AK::Detail::IsUnion;
|
||||||
|
using AK::Detail::IsUnsigned;
|
||||||
|
using AK::Detail::IsVoid;
|
||||||
|
using AK::Detail::MakeIndexSequence;
|
||||||
|
using AK::Detail::MakeIntegerSequence;
|
||||||
|
using AK::Detail::MakeSigned;
|
||||||
|
using AK::Detail::MakeUnsigned;
|
||||||
|
using AK::Detail::RemoveConst;
|
||||||
|
using AK::Detail::RemoveCV;
|
||||||
|
using AK::Detail::RemovePointer;
|
||||||
|
using AK::Detail::RemoveReference;
|
||||||
|
using AK::Detail::RemoveVolatile;
|
||||||
|
using AK::Detail::TrueType;
|
||||||
|
using AK::Detail::UnderlyingType;
|
||||||
|
using AK::Detail::Void;
|
@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/StdLibExtraDetails.h>
|
||||||
|
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
|
|
||||||
constexpr unsigned round_up_to_power_of_two(unsigned value, unsigned power_of_two)
|
constexpr unsigned round_up_to_power_of_two(unsigned value, unsigned power_of_two)
|
||||||
@ -52,6 +54,19 @@ namespace AK {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
auto declval() -> T;
|
auto declval() -> T;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
constexpr T&& forward(RemoveReference<T>& param)
|
||||||
|
{
|
||||||
|
return static_cast<T&&>(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
constexpr T&& forward(RemoveReference<T>&& param) noexcept
|
||||||
|
{
|
||||||
|
static_assert(!IsLvalueReference<T>, "Can't forward an rvalue as an lvalue.");
|
||||||
|
return static_cast<T&&>(param);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, typename SizeType = decltype(sizeof(T)), SizeType N>
|
template<typename T, typename SizeType = decltype(sizeof(T)), SizeType N>
|
||||||
constexpr SizeType array_size(T (&)[N])
|
constexpr SizeType array_size(T (&)[N])
|
||||||
{
|
{
|
||||||
@ -99,359 +114,6 @@ inline void swap(T& a, U& b)
|
|||||||
b = move(tmp);
|
b = move(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool B, class T = void>
|
|
||||||
struct EnableIf {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct EnableIf<true, T> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct AddConst {
|
|
||||||
using Type = const T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct RemoveConst {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct RemoveConst<const T> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct RemoveVolatile {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemoveVolatile<volatile T> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemoveCV {
|
|
||||||
using Type = typename RemoveVolatile<typename RemoveConst<T>::Type>::Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, T v>
|
|
||||||
struct IntegralConstant {
|
|
||||||
static constexpr T value = v;
|
|
||||||
using ValueType = T;
|
|
||||||
using Type = IntegralConstant;
|
|
||||||
constexpr operator ValueType() const { return value; }
|
|
||||||
constexpr ValueType operator()() const { return value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
using FalseType = IntegralConstant<bool, false>;
|
|
||||||
using TrueType = IntegralConstant<bool, true>;
|
|
||||||
template<typename...>
|
|
||||||
using VoidType = void;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct IsLvalueReference : FalseType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct IsLvalueReference<T&> : TrueType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct __IsPointerHelper : FalseType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct __IsPointerHelper<T*> : TrueType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct IsPointer : __IsPointerHelper<typename RemoveCV<T>::Type> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class>
|
|
||||||
struct IsFunction : FalseType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...)> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...)> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) const> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) const> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) volatile> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) volatile> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) const volatile> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) const volatile> : TrueType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...)&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...)&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) const&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) const&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) volatile&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) volatile&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) const volatile&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) const volatile&> : TrueType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) &&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) &&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) const&&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) const&&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) volatile&&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) volatile&&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args...) const volatile&&> : TrueType {
|
|
||||||
};
|
|
||||||
template<class Ret, class... Args>
|
|
||||||
struct IsFunction<Ret(Args..., ...) const volatile&&> : TrueType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct IsRvalueReference : FalseType {
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct IsRvalueReference<T&&> : TrueType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct RemovePointer {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemovePointer<T*> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemovePointer<T* const> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemovePointer<T* volatile> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemovePointer<T* const volatile> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename U>
|
|
||||||
struct IsSame {
|
|
||||||
static constexpr bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsSame<T, T> {
|
|
||||||
static constexpr bool value = 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<typename T>
|
|
||||||
struct IsNullPointer : IsSame<decltype(nullptr), typename RemoveCV<T>::Type> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct RemoveReference {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemoveReference<T&> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct RemoveReference<T&&> {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
constexpr T&& forward(typename RemoveReference<T>::Type& param)
|
|
||||||
{
|
|
||||||
return static_cast<T&&>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
constexpr T&& forward(typename RemoveReference<T>::Type&& param) noexcept
|
|
||||||
{
|
|
||||||
static_assert(!IsLvalueReference<T>::value, "Can't forward an rvalue as an lvalue.");
|
|
||||||
return static_cast<T&&>(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct MakeUnsigned {
|
|
||||||
using Type = void;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<signed char> {
|
|
||||||
using Type = unsigned char;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<short> {
|
|
||||||
using Type = unsigned short;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<int> {
|
|
||||||
using Type = unsigned int;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<long> {
|
|
||||||
using Type = unsigned long;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<long long> {
|
|
||||||
using Type = unsigned long long;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<unsigned char> {
|
|
||||||
using Type = unsigned char;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<unsigned short> {
|
|
||||||
using Type = unsigned short;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<unsigned int> {
|
|
||||||
using Type = unsigned int;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<unsigned long> {
|
|
||||||
using Type = unsigned long;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<unsigned long long> {
|
|
||||||
using Type = unsigned long long;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<char> {
|
|
||||||
using Type = unsigned char;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<char8_t> {
|
|
||||||
using Type = char8_t;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<char16_t> {
|
|
||||||
using Type = char16_t;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<char32_t> {
|
|
||||||
using Type = char32_t;
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct MakeUnsigned<bool> {
|
|
||||||
using Type = bool;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct MakeSigned {
|
|
||||||
};
|
|
||||||
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 = signed char;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct IsVoid : IsSame<void, typename RemoveCV<T>::Type> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct IsConst : FalseType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct IsConst<const T> : TrueType {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename U = T>
|
template<typename T, typename U = T>
|
||||||
constexpr T exchange(T& slot, U&& value)
|
constexpr T exchange(T& slot, U&& value)
|
||||||
{
|
{
|
||||||
@ -460,183 +122,14 @@ constexpr T exchange(T& slot, U&& value)
|
|||||||
return old_value;
|
return old_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsEnum : public IntegralConstant<bool, __is_enum(T)> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsUnion : public IntegralConstant<bool, __is_union(T)> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsClass : public IntegralConstant<bool, __is_class(T)> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Base, typename Derived>
|
|
||||||
struct IsBaseOf : public IntegralConstant<bool, __is_base_of(Base, Derived)> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool is_trivial()
|
|
||||||
{
|
|
||||||
return __is_trivial(T);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool is_trivially_copyable()
|
|
||||||
{
|
|
||||||
return __is_trivially_copyable(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct __IsIntegral : FalseType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<bool> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<unsigned char> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<char8_t> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<char16_t> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<char32_t> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<unsigned short> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<unsigned int> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<unsigned long> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsIntegral<unsigned long long> : TrueType {
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
using IsIntegral = __IsIntegral<typename MakeUnsigned<typename RemoveCV<T>::Type>::Type>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct __IsFloatingPoint : FalseType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsFloatingPoint<float> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsFloatingPoint<double> : TrueType {
|
|
||||||
};
|
|
||||||
template<>
|
|
||||||
struct __IsFloatingPoint<long double> : TrueType {
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
using IsFloatingPoint = __IsFloatingPoint<typename RemoveCV<T>::Type>;
|
|
||||||
|
|
||||||
template<typename ReferenceType, typename T>
|
|
||||||
using CopyConst =
|
|
||||||
typename Conditional<IsConst<ReferenceType>::value, typename AddConst<T>::Type, typename RemoveConst<T>::Type>::Type;
|
|
||||||
|
|
||||||
template<typename... Ts>
|
|
||||||
using Void = void;
|
|
||||||
|
|
||||||
template<typename... _Ignored>
|
|
||||||
constexpr auto DependentFalse = false;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using IsSigned = IsSame<T, typename MakeSigned<T>::Type>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using IsUnsigned = IsSame<T, typename MakeUnsigned<T>::Type>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using IsArithmetic = IntegralConstant<bool, IsIntegral<T>::value || IsFloatingPoint<T>::value>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using IsFundamental = IntegralConstant<bool, IsArithmetic<T>::value || IsVoid<T>::value || IsNullPointer<T>::value>;
|
|
||||||
|
|
||||||
template<typename T, T... Ts>
|
|
||||||
struct IntegerSequence {
|
|
||||||
using Type = T;
|
|
||||||
static constexpr unsigned size() noexcept { return sizeof...(Ts); };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<unsigned... Indices>
|
|
||||||
using IndexSequence = IntegerSequence<unsigned, Indices...>;
|
|
||||||
|
|
||||||
template<typename T, T N, T... Ts>
|
|
||||||
auto make_integer_sequence_impl()
|
|
||||||
{
|
|
||||||
if constexpr (N == 0)
|
|
||||||
return IntegerSequence<T, Ts...> {};
|
|
||||||
else
|
|
||||||
return make_integer_sequence_impl<T, N - 1, N - 1, Ts...>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, T N>
|
|
||||||
using MakeIntegerSequence = decltype(make_integer_sequence_impl<T, N>());
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
using MakeIndexSequence = MakeIntegerSequence<unsigned, N>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IdentityType {
|
|
||||||
using Type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, bool = IsEnum<T>::value>
|
|
||||||
struct __UnderlyingType {
|
|
||||||
using Type = __underlying_type(T);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct __UnderlyingType<T, false> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct UnderlyingType : __UnderlyingType<T> {
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
using AK::AddConst;
|
|
||||||
using AK::array_size;
|
using AK::array_size;
|
||||||
using AK::ceil_div;
|
using AK::ceil_div;
|
||||||
using AK::clamp;
|
using AK::clamp;
|
||||||
using AK::Conditional;
|
|
||||||
using AK::declval;
|
using AK::declval;
|
||||||
using AK::DependentFalse;
|
|
||||||
using AK::exchange;
|
using AK::exchange;
|
||||||
using AK::forward;
|
using AK::forward;
|
||||||
using AK::IdentityType;
|
|
||||||
using AK::IndexSequence;
|
|
||||||
using AK::IntegerSequence;
|
|
||||||
using AK::is_trivial;
|
|
||||||
using AK::is_trivially_copyable;
|
|
||||||
using AK::IsArithmetic;
|
|
||||||
using AK::IsBaseOf;
|
|
||||||
using AK::IsClass;
|
|
||||||
using AK::IsConst;
|
|
||||||
using AK::IsEnum;
|
|
||||||
using AK::IsFloatingPoint;
|
|
||||||
using AK::IsFundamental;
|
|
||||||
using AK::IsIntegral;
|
|
||||||
using AK::IsNullPointer;
|
|
||||||
using AK::IsSame;
|
|
||||||
using AK::IsSigned;
|
|
||||||
using AK::IsUnion;
|
|
||||||
using AK::IsUnsigned;
|
|
||||||
using AK::IsVoid;
|
|
||||||
using AK::MakeIndexSequence;
|
|
||||||
using AK::MakeIntegerSequence;
|
|
||||||
using AK::MakeSigned;
|
|
||||||
using AK::MakeUnsigned;
|
|
||||||
using AK::max;
|
using AK::max;
|
||||||
using AK::min;
|
using AK::min;
|
||||||
using AK::RemoveConst;
|
|
||||||
using AK::swap;
|
using AK::swap;
|
||||||
using AK::UnderlyingType;
|
|
||||||
using AK::Void;
|
|
||||||
|
@ -148,13 +148,13 @@ InputStream& operator>>(InputStream& stream, Optional<T>& value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Integral>
|
template<typename Integral>
|
||||||
InputStream& operator>>(InputStream& stream, Integral& value) requires IsIntegral<Integral>::value
|
InputStream& operator>>(InputStream& stream, Integral& value) requires IsIntegral<Integral>
|
||||||
{
|
{
|
||||||
stream.read_or_error({ &value, sizeof(value) });
|
stream.read_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
template<typename Integral>
|
template<typename Integral>
|
||||||
OutputStream& operator<<(OutputStream& stream, Integral value) requires IsIntegral<Integral>::value
|
OutputStream& operator<<(OutputStream& stream, Integral value) requires IsIntegral<Integral>
|
||||||
{
|
{
|
||||||
stream.write_or_error({ &value, sizeof(value) });
|
stream.write_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
@ -163,13 +163,13 @@ OutputStream& operator<<(OutputStream& stream, Integral value) requires IsIntegr
|
|||||||
#ifndef KERNEL
|
#ifndef KERNEL
|
||||||
|
|
||||||
template<typename FloatingPoint>
|
template<typename FloatingPoint>
|
||||||
InputStream& operator>>(InputStream& stream, FloatingPoint& value) requires IsFloatingPoint<FloatingPoint>::value
|
InputStream& operator>>(InputStream& stream, FloatingPoint& value) requires IsFloatingPoint<FloatingPoint>
|
||||||
{
|
{
|
||||||
stream.read_or_error({ &value, sizeof(value) });
|
stream.read_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
template<typename FloatingPoint>
|
template<typename FloatingPoint>
|
||||||
OutputStream& operator<<(OutputStream& stream, FloatingPoint value) requires IsFloatingPoint<FloatingPoint>::value
|
OutputStream& operator<<(OutputStream& stream, FloatingPoint value) requires IsFloatingPoint<FloatingPoint>
|
||||||
{
|
{
|
||||||
stream.write_or_error({ &value, sizeof(value) });
|
stream.write_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
|
@ -276,7 +276,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static String number(T value) requires IsArithmetic<T>::value
|
static String number(T value) requires IsArithmetic<T>
|
||||||
{
|
{
|
||||||
return formatted("{}", value);
|
return formatted("{}", value);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
TEST_CASE(should_provide_underlying_type)
|
TEST_CASE(should_provide_underlying_type)
|
||||||
{
|
{
|
||||||
static_assert(IsSame<int, Badge<int>::Type>::value);
|
static_assert(IsSame<int, Badge<int>::Type>);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_MAIN(Badge)
|
TEST_MAIN(Badge)
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
TEST_CASE(is_integral_works_properly)
|
TEST_CASE(is_integral_works_properly)
|
||||||
{
|
{
|
||||||
EXPECT(!IsIntegral<const char*>::value);
|
EXPECT(!IsIntegral<const char*>);
|
||||||
EXPECT(IsIntegral<unsigned long>::value);
|
EXPECT(IsIntegral<unsigned long>);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(format_string_literals)
|
TEST_CASE(format_string_literals)
|
||||||
|
@ -46,14 +46,14 @@ TEST_CASE(TestIndexSequence)
|
|||||||
{
|
{
|
||||||
constexpr auto integer_seq1 = IntegerSequence<int, 0, 1, 2, 3, 4> {};
|
constexpr auto integer_seq1 = IntegerSequence<int, 0, 1, 2, 3, 4> {};
|
||||||
constexpr auto integer_seq2 = MakeIntegerSequence<int, 5> {};
|
constexpr auto integer_seq2 = MakeIntegerSequence<int, 5> {};
|
||||||
static_assert(IsSame<decltype(integer_seq1), decltype(integer_seq2)>::value, "");
|
static_assert(IsSame<decltype(integer_seq1), decltype(integer_seq2)>, "");
|
||||||
|
|
||||||
static_assert(integer_seq1.size() == 5, "");
|
static_assert(integer_seq1.size() == 5, "");
|
||||||
static_assert(integer_seq2.size() == 5, "");
|
static_assert(integer_seq2.size() == 5, "");
|
||||||
|
|
||||||
constexpr auto index_seq1 = IndexSequence<0, 1, 2> {};
|
constexpr auto index_seq1 = IndexSequence<0, 1, 2> {};
|
||||||
constexpr auto index_seq2 = MakeIndexSequence<3> {};
|
constexpr auto index_seq2 = MakeIndexSequence<3> {};
|
||||||
static_assert(IsSame<decltype(index_seq1), decltype(index_seq2)>::value, "");
|
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<unsigned> { 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 });
|
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 });
|
||||||
@ -62,9 +62,9 @@ TEST_CASE(TestIndexSequence)
|
|||||||
TEST_CASE(TypeList)
|
TEST_CASE(TypeList)
|
||||||
{
|
{
|
||||||
using MyTypes = TypeList<int, bool, char>;
|
using MyTypes = TypeList<int, bool, char>;
|
||||||
static_assert(IsSame<MyTypes::Type<0>, int>::value, "");
|
static_assert(IsSame<MyTypes::Type<0>, int>, "");
|
||||||
static_assert(IsSame<MyTypes::Type<1>, bool>::value, "");
|
static_assert(IsSame<MyTypes::Type<1>, bool>, "");
|
||||||
static_assert(IsSame<MyTypes::Type<2>, char>::value, "");
|
static_assert(IsSame<MyTypes::Type<2>, char>, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_MAIN(IndexSequence);
|
TEST_MAIN(IndexSequence);
|
||||||
|
@ -49,7 +49,7 @@ TEST_CASE(span_works_with_constant_types)
|
|||||||
static constexpr u8 buffer[4] { 1, 2, 3, 4 };
|
static constexpr u8 buffer[4] { 1, 2, 3, 4 };
|
||||||
constexpr ReadonlyBytes bytes { buffer, 4 };
|
constexpr ReadonlyBytes bytes { buffer, 4 };
|
||||||
|
|
||||||
static_assert(IsConst<AK::RemoveReference<decltype(bytes[1])>::Type>::value);
|
static_assert(IsConst<RemoveReference<decltype(bytes[1])>>);
|
||||||
static_assert(bytes[2] == 3);
|
static_assert(bytes[2] == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@
|
|||||||
#include <AK/TypeList.h>
|
#include <AK/TypeList.h>
|
||||||
|
|
||||||
#define STATIC_EXPECT_EQ(lhs, rhs) \
|
#define STATIC_EXPECT_EQ(lhs, rhs) \
|
||||||
static_assert(IsSame<lhs, rhs>::value, "");
|
static_assert(IsSame<lhs, rhs>, "");
|
||||||
|
|
||||||
#define STATIC_EXPECT_FALSE(Expression) \
|
#define STATIC_EXPECT_FALSE(Expression) \
|
||||||
static_assert(!Expression::value, "");
|
static_assert(!Expression, "");
|
||||||
|
|
||||||
#define STATIC_EXPECT_TRUE(Expression) \
|
#define STATIC_EXPECT_TRUE(Expression) \
|
||||||
static_assert(Expression::value, "");
|
static_assert(Expression, "");
|
||||||
|
|
||||||
#define EXPECT_TRAIT_TRUE(trait, ...) \
|
#define EXPECT_TRAIT_TRUE(trait, ...) \
|
||||||
for_each_type<TypeList<__VA_ARGS__>>([]<typename T>(TypeWrapper<T>) { \
|
for_each_type<TypeList<__VA_ARGS__>>([]<typename T>(TypeWrapper<T>) { \
|
||||||
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
#define EXPECT_EQ_WITH_TRAIT(trait, ListA, ListB) \
|
#define EXPECT_EQ_WITH_TRAIT(trait, ListA, ListB) \
|
||||||
for_each_type_zipped<ListA, ListB>([]<typename A, typename B>(TypeWrapper<A>, TypeWrapper<B>) { \
|
for_each_type_zipped<ListA, ListB>([]<typename A, typename B>(TypeWrapper<A>, TypeWrapper<B>) { \
|
||||||
STATIC_EXPECT_EQ(typename trait<A>::Type, B); \
|
STATIC_EXPECT_EQ(trait<A>, B); \
|
||||||
})
|
})
|
||||||
|
|
||||||
struct Empty {
|
struct Empty {
|
||||||
@ -120,7 +120,7 @@ TEST_CASE(AddConst)
|
|||||||
|
|
||||||
TEST_CASE(UnderlyingType)
|
TEST_CASE(UnderlyingType)
|
||||||
{
|
{
|
||||||
using Type = UnderlyingType<Enummer>::Type;
|
using Type = UnderlyingType<Enummer>;
|
||||||
|
|
||||||
STATIC_EXPECT_EQ(Type, u8);
|
STATIC_EXPECT_EQ(Type, u8);
|
||||||
}
|
}
|
||||||
|
16
AK/Trie.h
16
AK/Trie.h
@ -140,9 +140,9 @@ public:
|
|||||||
return const_cast<Trie*>(this)->traverse_until_last_accessible_node(it, end);
|
return const_cast<Trie*>(this)->traverse_until_last_accessible_node(it, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<MetadataType> metadata() const requires(!IsNullPointer<MetadataType>::value) { return m_metadata; }
|
Optional<MetadataType> metadata() const requires(!IsNullPointer<MetadataType>) { return m_metadata; }
|
||||||
void set_metadata(MetadataType metadata) requires(!IsNullPointer<MetadataType>::value) { m_metadata = move(metadata); }
|
void set_metadata(MetadataType metadata) requires(!IsNullPointer<MetadataType>) { m_metadata = move(metadata); }
|
||||||
const MetadataType& metadata_value() const requires(!IsNullPointer<MetadataType>::value) { return m_metadata.value(); }
|
const MetadataType& metadata_value() const requires(!IsNullPointer<MetadataType>) { return m_metadata.value(); }
|
||||||
|
|
||||||
const ValueType& value() const { return m_value; }
|
const ValueType& value() const { return m_value; }
|
||||||
ValueType& value() { return m_value; }
|
ValueType& value() { return m_value; }
|
||||||
@ -165,7 +165,7 @@ public:
|
|||||||
|
|
||||||
template<typename It, typename ProvideMetadataFunction>
|
template<typename It, typename ProvideMetadataFunction>
|
||||||
BaseType& insert(
|
BaseType& insert(
|
||||||
It& it, const It& end, MetadataType metadata, ProvideMetadataFunction provide_missing_metadata) requires(!IsNullPointer<MetadataType>::value)
|
It& it, const It& end, MetadataType metadata, ProvideMetadataFunction provide_missing_metadata) requires(!IsNullPointer<MetadataType>)
|
||||||
{
|
{
|
||||||
Trie* last_root_node = &traverse_until_last_accessible_node(it, end);
|
Trie* last_root_node = &traverse_until_last_accessible_node(it, end);
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
@ -175,7 +175,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename It>
|
template<typename It>
|
||||||
BaseType& insert(It& it, const It& end) requires(IsNullPointer<MetadataType>::value)
|
BaseType& insert(It& it, const It& end) requires(IsNullPointer<MetadataType>)
|
||||||
{
|
{
|
||||||
Trie* last_root_node = &traverse_until_last_accessible_node(it, end);
|
Trie* last_root_node = &traverse_until_last_accessible_node(it, end);
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
@ -185,14 +185,14 @@ public:
|
|||||||
|
|
||||||
template<typename It, typename ProvideMetadataFunction>
|
template<typename It, typename ProvideMetadataFunction>
|
||||||
BaseType& insert(
|
BaseType& insert(
|
||||||
const It& begin, const It& end, MetadataType metadata, ProvideMetadataFunction provide_missing_metadata) requires(!IsNullPointer<MetadataType>::value)
|
const It& begin, const It& end, MetadataType metadata, ProvideMetadataFunction provide_missing_metadata) requires(!IsNullPointer<MetadataType>)
|
||||||
{
|
{
|
||||||
auto it = begin;
|
auto it = begin;
|
||||||
return insert(it, end, move(metadata), move(provide_missing_metadata));
|
return insert(it, end, move(metadata), move(provide_missing_metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename It>
|
template<typename It>
|
||||||
BaseType& insert(const It& begin, const It& end) requires(IsNullPointer<MetadataType>::value)
|
BaseType& insert(const It& begin, const It& end) requires(IsNullPointer<MetadataType>)
|
||||||
{
|
{
|
||||||
auto it = begin;
|
auto it = begin;
|
||||||
return insert(it, end);
|
return insert(it, end);
|
||||||
@ -231,7 +231,7 @@ public:
|
|||||||
using DetailTrie = Detail::Trie<BaseT, Trie<ValueType, MetadataT, ValueTraits>, ValueType, MetadataT, ValueTraits>;
|
using DetailTrie = Detail::Trie<BaseT, Trie<ValueType, MetadataT, ValueTraits>, ValueType, MetadataT, ValueTraits>;
|
||||||
using MetadataType = typename DetailTrie::MetadataType;
|
using MetadataType = typename DetailTrie::MetadataType;
|
||||||
|
|
||||||
Trie(ValueType value, MetadataType metadata) requires(!IsVoid<MetadataType>::value && !IsNullPointer<MetadataType>::value)
|
Trie(ValueType value, MetadataType metadata) requires(!IsVoid<MetadataType> && !IsNullPointer<MetadataType>)
|
||||||
: DetailTrie(move(value), move(metadata))
|
: DetailTrie(move(value), move(metadata))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ ALWAYS_INLINE bool is(InputType* input)
|
|||||||
template<typename OutputType, typename InputType>
|
template<typename OutputType, typename InputType>
|
||||||
ALWAYS_INLINE CopyConst<InputType, OutputType>* downcast(InputType* input)
|
ALWAYS_INLINE CopyConst<InputType, OutputType>* downcast(InputType* input)
|
||||||
{
|
{
|
||||||
static_assert(IsBaseOf<InputType, OutputType>::value);
|
static_assert(IsBaseOf<InputType, OutputType>);
|
||||||
VERIFY(!input || is<OutputType>(*input));
|
VERIFY(!input || is<OutputType>(*input));
|
||||||
return static_cast<CopyConst<InputType, OutputType>*>(input);
|
return static_cast<CopyConst<InputType, OutputType>*>(input);
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ ALWAYS_INLINE CopyConst<InputType, OutputType>* downcast(InputType* input)
|
|||||||
template<typename OutputType, typename InputType>
|
template<typename OutputType, typename InputType>
|
||||||
ALWAYS_INLINE CopyConst<InputType, OutputType>& downcast(InputType& input)
|
ALWAYS_INLINE CopyConst<InputType, OutputType>& downcast(InputType& input)
|
||||||
{
|
{
|
||||||
static_assert(IsBaseOf<InputType, OutputType>::value);
|
static_assert(IsBaseOf<InputType, OutputType>);
|
||||||
VERIFY(is<OutputType>(input));
|
VERIFY(is<OutputType>(input));
|
||||||
return static_cast<CopyConst<InputType, OutputType>&>(input);
|
return static_cast<CopyConst<InputType, OutputType>&>(input);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ using i8 = __INT8_TYPE__;
|
|||||||
#ifdef __serenity__
|
#ifdef __serenity__
|
||||||
|
|
||||||
using size_t = __SIZE_TYPE__;
|
using size_t = __SIZE_TYPE__;
|
||||||
using ssize_t = MakeSigned<size_t>::Type;
|
using ssize_t = MakeSigned<size_t>;
|
||||||
|
|
||||||
using ptrdiff_t = __PTRDIFF_TYPE__;
|
using ptrdiff_t = __PTRDIFF_TYPE__;
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ using __ptrdiff_t = __PTRDIFF_TYPE__;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using FlatPtr = Conditional<sizeof(void*) == 8, u64, u32>::Type;
|
using FlatPtr = Conditional<sizeof(void*) == 8, u64, u32>;
|
||||||
|
|
||||||
constexpr u64 KiB = 1024;
|
constexpr u64 KiB = 1024;
|
||||||
constexpr u64 MiB = KiB * KiB;
|
constexpr u64 MiB = KiB * KiB;
|
||||||
|
@ -36,10 +36,10 @@ namespace AK {
|
|||||||
// Once it supports C++20 concepts, we can remove this.
|
// Once it supports C++20 concepts, we can remove this.
|
||||||
#if defined(__cpp_concepts) && !defined(__COVERITY__)
|
#if defined(__cpp_concepts) && !defined(__COVERITY__)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept PointerTypeName = IsPointer<T>::value;
|
concept PointerTypeName = IsPointer<T>;
|
||||||
template<PointerTypeName T>
|
template<PointerTypeName T>
|
||||||
#else
|
#else
|
||||||
template<typename T, typename EnableIf<IsPointer<T>::value, int>::Type = 0>
|
template<typename T, typename EnableIf<IsPointer<T>, int>::Type = 0>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Userspace {
|
class Userspace {
|
||||||
|
28
AK/WeakPtr.h
28
AK/WeakPtr.h
@ -38,26 +38,26 @@ class WeakPtr {
|
|||||||
public:
|
public:
|
||||||
WeakPtr() = default;
|
WeakPtr() = default;
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr(const WeakPtr<U>& other)
|
WeakPtr(const WeakPtr<U>& other)
|
||||||
: m_link(other.m_link)
|
: m_link(other.m_link)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr(WeakPtr<U>&& other)
|
WeakPtr(WeakPtr<U>&& other)
|
||||||
: m_link(other.take_link())
|
: m_link(other.take_link())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr& operator=(WeakPtr<U>&& other)
|
WeakPtr& operator=(WeakPtr<U>&& other)
|
||||||
{
|
{
|
||||||
m_link = other.take_link();
|
m_link = other.take_link();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr& operator=(const WeakPtr<U>& other)
|
WeakPtr& operator=(const WeakPtr<U>& other)
|
||||||
{
|
{
|
||||||
if ((const void*)this != (const void*)&other)
|
if ((const void*)this != (const void*)&other)
|
||||||
@ -71,20 +71,20 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr(const U& object)
|
WeakPtr(const U& object)
|
||||||
: m_link(object.template make_weak_ptr<U>().take_link())
|
: m_link(object.template make_weak_ptr<U>().take_link())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr(const U* object)
|
WeakPtr(const U* object)
|
||||||
{
|
{
|
||||||
if (object)
|
if (object)
|
||||||
m_link = object->template make_weak_ptr<U>().take_link();
|
m_link = object->template make_weak_ptr<U>().take_link();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr(const RefPtr<U>& object)
|
WeakPtr(const RefPtr<U>& object)
|
||||||
{
|
{
|
||||||
object.do_while_locked([&](U* obj) {
|
object.do_while_locked([&](U* obj) {
|
||||||
@ -93,7 +93,7 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr(const NonnullRefPtr<U>& object)
|
WeakPtr(const NonnullRefPtr<U>& object)
|
||||||
{
|
{
|
||||||
object.do_while_locked([&](U* obj) {
|
object.do_while_locked([&](U* obj) {
|
||||||
@ -102,14 +102,14 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr& operator=(const U& object)
|
WeakPtr& operator=(const U& object)
|
||||||
{
|
{
|
||||||
m_link = object.template make_weak_ptr<U>().take_link();
|
m_link = object.template make_weak_ptr<U>().take_link();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr& operator=(const U* object)
|
WeakPtr& operator=(const U* object)
|
||||||
{
|
{
|
||||||
if (object)
|
if (object)
|
||||||
@ -119,7 +119,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr& operator=(const RefPtr<U>& object)
|
WeakPtr& operator=(const RefPtr<U>& object)
|
||||||
{
|
{
|
||||||
object.do_while_locked([&](U* obj) {
|
object.do_while_locked([&](U* obj) {
|
||||||
@ -131,7 +131,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename EnableIf<IsBaseOf<T, U>::value>::Type* = nullptr>
|
template<typename U, typename EnableIf<IsBaseOf<T, U>>::Type* = nullptr>
|
||||||
WeakPtr& operator=(const NonnullRefPtr<U>& object)
|
WeakPtr& operator=(const NonnullRefPtr<U>& object)
|
||||||
{
|
{
|
||||||
object.do_while_locked([&](U* obj) {
|
object.do_while_locked([&](U* obj) {
|
||||||
@ -199,7 +199,7 @@ template<typename T>
|
|||||||
template<typename U>
|
template<typename U>
|
||||||
inline WeakPtr<U> Weakable<T>::make_weak_ptr() const
|
inline WeakPtr<U> Weakable<T>::make_weak_ptr() const
|
||||||
{
|
{
|
||||||
if constexpr (IsBaseOf<RefCountedBase, T>::value) {
|
if constexpr (IsBaseOf<RefCountedBase, T>) {
|
||||||
// Checking m_being_destroyed isn't sufficient when dealing with
|
// Checking m_being_destroyed isn't sufficient when dealing with
|
||||||
// a RefCounted type.The reference count will drop to 0 before the
|
// a RefCounted type.The reference count will drop to 0 before the
|
||||||
// destructor is invoked and revoke_weak_ptrs is called. So, try
|
// destructor is invoked and revoke_weak_ptrs is called. So, try
|
||||||
@ -223,7 +223,7 @@ inline WeakPtr<U> Weakable<T>::make_weak_ptr() const
|
|||||||
|
|
||||||
WeakPtr<U> weak_ptr(m_link);
|
WeakPtr<U> weak_ptr(m_link);
|
||||||
|
|
||||||
if constexpr (IsBaseOf<RefCountedBase, T>::value) {
|
if constexpr (IsBaseOf<RefCountedBase, T>) {
|
||||||
// Now drop the reference we temporarily added
|
// Now drop the reference we temporarily added
|
||||||
if (static_cast<const T*>(this)->unref()) {
|
if (static_cast<const T*>(this)->unref()) {
|
||||||
// We just dropped the last reference, which should have called
|
// We just dropped the last reference, which should have called
|
||||||
|
@ -49,7 +49,7 @@ class WeakLink : public RefCounted<WeakLink> {
|
|||||||
friend class WeakPtr;
|
friend class WeakPtr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T, typename PtrTraits = RefPtrTraits<T>, typename EnableIf<IsBaseOf<RefCountedBase, T>::value>::Type* = nullptr>
|
template<typename T, typename PtrTraits = RefPtrTraits<T>, typename EnableIf<IsBaseOf<RefCountedBase, T>>::Type* = nullptr>
|
||||||
RefPtr<T, PtrTraits> strong_ref() const
|
RefPtr<T, PtrTraits> strong_ref() const
|
||||||
{
|
{
|
||||||
RefPtr<T, PtrTraits> ref;
|
RefPtr<T, PtrTraits> ref;
|
||||||
|
@ -77,28 +77,28 @@ const void* memmem(const void* haystack, size_t, const void* needle, size_t);
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_from_user(T* dest, const T* src)
|
[[nodiscard]] inline bool copy_from_user(T* dest, const T* src)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
return copy_from_user(dest, src, sizeof(T));
|
return copy_from_user(dest, src, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_to_user(T* dest, const T* src)
|
[[nodiscard]] inline bool copy_to_user(T* dest, const T* src)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
return copy_to_user(dest, src, sizeof(T));
|
return copy_to_user(dest, src, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_from_user(T* dest, Userspace<const T*> src)
|
[[nodiscard]] inline bool copy_from_user(T* dest, Userspace<const T*> src)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
return copy_from_user(dest, src.unsafe_userspace_ptr(), sizeof(T));
|
return copy_from_user(dest, src.unsafe_userspace_ptr(), sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_from_user(T* dest, Userspace<T*> src)
|
[[nodiscard]] inline bool copy_from_user(T* dest, Userspace<T*> src)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
return copy_from_user(dest, src.unsafe_userspace_ptr(), sizeof(T));
|
return copy_from_user(dest, src.unsafe_userspace_ptr(), sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,28 +125,28 @@ DEPRECATE_COPY_FROM_USER_TYPE(timeval, copy_time_from_user)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_to_user(Userspace<T*> dest, const T* src)
|
[[nodiscard]] inline bool copy_to_user(Userspace<T*> dest, const T* src)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
return copy_to_user(dest.unsafe_userspace_ptr(), src, sizeof(T));
|
return copy_to_user(dest.unsafe_userspace_ptr(), src, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_to_user(Userspace<T*> dest, const void* src, size_t size)
|
[[nodiscard]] inline bool copy_to_user(Userspace<T*> dest, const void* src, size_t size)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
return copy_to_user(dest.unsafe_userspace_ptr(), src, size);
|
return copy_to_user(dest.unsafe_userspace_ptr(), src, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_from_user(void* dest, Userspace<const T*> src, size_t size)
|
[[nodiscard]] inline bool copy_from_user(void* dest, Userspace<const T*> src, size_t size)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
return copy_from_user(dest, src.unsafe_userspace_ptr(), size);
|
return copy_from_user(dest, src.unsafe_userspace_ptr(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_n_from_user(T* dest, const T* src, size_t count)
|
[[nodiscard]] inline bool copy_n_from_user(T* dest, const T* src, size_t count)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
Checked size = sizeof(T);
|
Checked size = sizeof(T);
|
||||||
size *= count;
|
size *= count;
|
||||||
if (size.has_overflow())
|
if (size.has_overflow())
|
||||||
@ -157,7 +157,7 @@ template<typename T>
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_n_to_user(T* dest, const T* src, size_t count)
|
[[nodiscard]] inline bool copy_n_to_user(T* dest, const T* src, size_t count)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
Checked size = sizeof(T);
|
Checked size = sizeof(T);
|
||||||
size *= count;
|
size *= count;
|
||||||
if (size.has_overflow())
|
if (size.has_overflow())
|
||||||
@ -168,7 +168,7 @@ template<typename T>
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_n_from_user(T* dest, Userspace<const T*> src, size_t count)
|
[[nodiscard]] inline bool copy_n_from_user(T* dest, Userspace<const T*> src, size_t count)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
Checked size = sizeof(T);
|
Checked size = sizeof(T);
|
||||||
size *= count;
|
size *= count;
|
||||||
if (size.has_overflow())
|
if (size.has_overflow())
|
||||||
@ -179,7 +179,7 @@ template<typename T>
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] inline bool copy_n_to_user(Userspace<T*> dest, const T* src, size_t count)
|
[[nodiscard]] inline bool copy_n_to_user(Userspace<T*> dest, const T* src, size_t count)
|
||||||
{
|
{
|
||||||
static_assert(is_trivially_copyable<T>());
|
static_assert(IsTriviallyCopyable<T>);
|
||||||
Checked size = sizeof(T);
|
Checked size = sizeof(T);
|
||||||
size *= count;
|
size *= count;
|
||||||
if (size.has_overflow())
|
if (size.has_overflow())
|
||||||
|
@ -277,19 +277,19 @@ struct ReadElement {
|
|||||||
case Short:
|
case Short:
|
||||||
return ReadElementConcrete<T, short, kind> {}(input_lexer, ap);
|
return ReadElementConcrete<T, short, kind> {}(input_lexer, ap);
|
||||||
case Long:
|
case Long:
|
||||||
if constexpr (IsSame<T, int>::value)
|
if constexpr (IsSame<T, int>)
|
||||||
return ReadElementConcrete<T, long, kind> {}(input_lexer, ap);
|
return ReadElementConcrete<T, long, kind> {}(input_lexer, ap);
|
||||||
if constexpr (IsSame<T, unsigned>::value)
|
if constexpr (IsSame<T, unsigned>)
|
||||||
return ReadElementConcrete<T, unsigned, kind> {}(input_lexer, ap);
|
return ReadElementConcrete<T, unsigned, kind> {}(input_lexer, ap);
|
||||||
if constexpr (IsSame<T, float>::value)
|
if constexpr (IsSame<T, float>)
|
||||||
return ReadElementConcrete<int, double, kind> {}(input_lexer, ap);
|
return ReadElementConcrete<int, double, kind> {}(input_lexer, ap);
|
||||||
return false;
|
return false;
|
||||||
case LongLong:
|
case LongLong:
|
||||||
if constexpr (IsSame<T, int>::value)
|
if constexpr (IsSame<T, int>)
|
||||||
return ReadElementConcrete<long long, long long, kind> {}(input_lexer, ap);
|
return ReadElementConcrete<long long, long long, kind> {}(input_lexer, ap);
|
||||||
if constexpr (IsSame<T, unsigned>::value)
|
if constexpr (IsSame<T, unsigned>)
|
||||||
return ReadElementConcrete<unsigned long long, unsigned long long, kind> {}(input_lexer, ap);
|
return ReadElementConcrete<unsigned long long, unsigned long long, kind> {}(input_lexer, ap);
|
||||||
if constexpr (IsSame<T, float>::value)
|
if constexpr (IsSame<T, float>)
|
||||||
return ReadElementConcrete<long long, double, kind> {}(input_lexer, ap);
|
return ReadElementConcrete<long long, double, kind> {}(input_lexer, ap);
|
||||||
return false;
|
return false;
|
||||||
case IntMax:
|
case IntMax:
|
||||||
|
@ -68,7 +68,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
T* data()
|
T* data()
|
||||||
{
|
{
|
||||||
static_assert(IsVoid<T>::value || is_trivial<T>());
|
static_assert(IsVoid<T> || IsTrivial<T>);
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return (T*)m_impl->data();
|
return (T*)m_impl->data();
|
||||||
@ -77,7 +77,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
const T* data() const
|
const T* data() const
|
||||||
{
|
{
|
||||||
static_assert(IsVoid<T>::value || is_trivial<T>());
|
static_assert(IsVoid<T> || IsTrivial<T>);
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return (const T*)m_impl->data();
|
return (const T*)m_impl->data();
|
||||||
|
@ -90,13 +90,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Callback>
|
template<typename T, typename Callback>
|
||||||
void for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>::value;
|
void for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* find_child_of_type_named(const String&) requires IsBaseOf<Object, T>::value;
|
T* find_child_of_type_named(const String&) requires IsBaseOf<Object, T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* find_descendant_of_type_named(const String&) requires IsBaseOf<Object, T>::value;
|
T* find_descendant_of_type_named(const String&) requires IsBaseOf<Object, T>;
|
||||||
|
|
||||||
bool is_ancestor_of(const Object&) const;
|
bool is_ancestor_of(const Object&) const;
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ struct AK::Formatter<Core::Object> : AK::Formatter<FormatString> {
|
|||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
template<typename T, typename Callback>
|
template<typename T, typename Callback>
|
||||||
inline void Object::for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>::value
|
inline void Object::for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>
|
||||||
{
|
{
|
||||||
for_each_child([&](auto& child) {
|
for_each_child([&](auto& child) {
|
||||||
if (auto* child_as_t = dynamic_cast<T*>(&child); child_as_t)
|
if (auto* child_as_t = dynamic_cast<T*>(&child); child_as_t)
|
||||||
@ -197,7 +197,7 @@ inline void Object::for_each_child_of_type(Callback callback) requires IsBaseOf<
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* Object::find_child_of_type_named(const String& name) requires IsBaseOf<Object, T>::value
|
T* Object::find_child_of_type_named(const String& name) requires IsBaseOf<Object, T>
|
||||||
{
|
{
|
||||||
T* found_child = nullptr;
|
T* found_child = nullptr;
|
||||||
for_each_child_of_type<T>([&](auto& child) {
|
for_each_child_of_type<T>([&](auto& child) {
|
||||||
@ -212,7 +212,7 @@ T* Object::find_child_of_type_named(const String& name) requires IsBaseOf<Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* Object::find_descendant_of_type_named(const String& name) requires IsBaseOf<Object, T>::value
|
T* Object::find_descendant_of_type_named(const String& name) requires IsBaseOf<Object, T>
|
||||||
{
|
{
|
||||||
auto* this_as_t = dynamic_cast<T*>(this);
|
auto* this_as_t = dynamic_cast<T*>(this);
|
||||||
if (this_as_t && this->name() == name)
|
if (this_as_t && this->name() == name)
|
||||||
|
@ -37,13 +37,13 @@ class ItemListModel : public Model {
|
|||||||
public:
|
public:
|
||||||
static constexpr auto IsTwoDimensional = requires(Container data)
|
static constexpr auto IsTwoDimensional = requires(Container data)
|
||||||
{
|
{
|
||||||
requires !IsVoid<ColumnNameListType>::value;
|
requires !IsVoid<ColumnNameListType>;
|
||||||
data.at(0).at(0);
|
data.at(0).at(0);
|
||||||
data.at(0).size();
|
data.at(0).size();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Substitute 'void' for a dummy u8.
|
// Substitute 'void' for a dummy u8.
|
||||||
using ColumnNamesT = typename Conditional<IsVoid<ColumnNameListType>::value, u8, ColumnNameListType>::Type;
|
using ColumnNamesT = Conditional<IsVoid<ColumnNameListType>, u8, ColumnNameListType>;
|
||||||
|
|
||||||
static NonnullRefPtr<ItemListModel> create(const Container& data, const ColumnNamesT& column_names, const Optional<size_t>& row_count = {}) requires(IsTwoDimensional)
|
static NonnullRefPtr<ItemListModel> create(const Container& data, const ColumnNamesT& column_names, const Optional<size_t>& row_count = {}) requires(IsTwoDimensional)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
|
||||||
template<size_t N, typename = typename AK::EnableIf<N % 2 == 1>::Type>
|
template<size_t N, typename = typename EnableIf<N % 2 == 1>::Type>
|
||||||
class SpatialGaussianBlurFilter : public GenericConvolutionFilter<N> {
|
class SpatialGaussianBlurFilter : public GenericConvolutionFilter<N> {
|
||||||
public:
|
public:
|
||||||
SpatialGaussianBlurFilter() { }
|
SpatialGaussianBlurFilter() { }
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
auto* memory = allocate_cell(sizeof(T));
|
auto* memory = allocate_cell(sizeof(T));
|
||||||
new (memory) T(forward<Args>(args)...);
|
new (memory) T(forward<Args>(args)...);
|
||||||
auto* cell = static_cast<T*>(memory);
|
auto* cell = static_cast<T*>(memory);
|
||||||
constexpr bool is_object = IsBaseOf<Object, T>::value;
|
constexpr bool is_object = IsBaseOf<Object, T>;
|
||||||
if constexpr (is_object)
|
if constexpr (is_object)
|
||||||
static_cast<Object*>(cell)->disable_transitions();
|
static_cast<Object*>(cell)->disable_transitions();
|
||||||
cell->initialize(global_object);
|
cell->initialize(global_object);
|
||||||
|
@ -101,7 +101,7 @@ public:
|
|||||||
return Value((i32)data()[property_index]);
|
return Value((i32)data()[property_index]);
|
||||||
} else if constexpr (sizeof(T) == 4 || sizeof(T) == 8) {
|
} else if constexpr (sizeof(T) == 4 || sizeof(T) == 8) {
|
||||||
auto value = data()[property_index];
|
auto value = data()[property_index];
|
||||||
if constexpr (IsFloatingPoint<T>::value) {
|
if constexpr (IsFloatingPoint<T>) {
|
||||||
return Value((double)value);
|
return Value((double)value);
|
||||||
} else if constexpr (NumericLimits<T>::is_signed()) {
|
} else if constexpr (NumericLimits<T>::is_signed()) {
|
||||||
if (value > NumericLimits<i32>::max() || value < NumericLimits<i32>::min())
|
if (value > NumericLimits<i32>::max() || value < NumericLimits<i32>::min())
|
||||||
|
@ -68,7 +68,7 @@ Result<T, ThreadError> Thread::join()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_tid = 0;
|
m_tid = 0;
|
||||||
if constexpr (IsVoid<T>::value)
|
if constexpr (IsVoid<T>)
|
||||||
return {};
|
return {};
|
||||||
else
|
else
|
||||||
return { static_cast<T>(thread_return) };
|
return { static_cast<T>(thread_return) };
|
||||||
|
@ -34,12 +34,10 @@
|
|||||||
namespace Web::Bindings {
|
namespace Web::Bindings {
|
||||||
|
|
||||||
template<typename>
|
template<typename>
|
||||||
struct IsExceptionOr : AK::FalseType {
|
constexpr bool IsExceptionOr = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsExceptionOr<DOM::ExceptionOr<T>> : AK::TrueType {
|
constexpr bool IsExceptionOr<DOM::ExceptionOr<T>> = true;
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ALWAYS_INLINE bool throw_dom_exception(JS::VM& vm, JS::GlobalObject& global_object, DOM::ExceptionOr<T>& result)
|
ALWAYS_INLINE bool throw_dom_exception(JS::VM& vm, JS::GlobalObject& global_object, DOM::ExceptionOr<T>& result)
|
||||||
@ -51,17 +49,17 @@ ALWAYS_INLINE bool throw_dom_exception(JS::VM& vm, JS::GlobalObject& global_obje
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F, typename T = decltype(declval<F>()()), typename Ret = typename Conditional<!IsExceptionOr<T>::value && !IsVoid<T>::value, T, JS::Value>::Type>
|
template<typename F, typename T = decltype(declval<F>()()), typename Ret = Conditional<!IsExceptionOr<T> && !IsVoid<T>, T, JS::Value>>
|
||||||
Ret throw_dom_exception_if_needed(auto&& vm, auto&& global_object, F&& fn)
|
Ret throw_dom_exception_if_needed(auto&& vm, auto&& global_object, F&& fn)
|
||||||
{
|
{
|
||||||
if constexpr (IsExceptionOr<T>::value) {
|
if constexpr (IsExceptionOr<T>) {
|
||||||
auto&& result = fn();
|
auto&& result = fn();
|
||||||
if (throw_dom_exception(vm, global_object, result))
|
if (throw_dom_exception(vm, global_object, result))
|
||||||
return JS::Value();
|
return JS::Value();
|
||||||
if constexpr (requires(T v) { v.value(); })
|
if constexpr (requires(T v) { v.value(); })
|
||||||
return result.value();
|
return result.value();
|
||||||
return JS::Value();
|
return JS::Value();
|
||||||
} else if constexpr (IsVoid<T>::value) {
|
} else if constexpr (IsVoid<T>) {
|
||||||
fn();
|
fn();
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
} else {
|
} else {
|
||||||
@ -72,7 +70,7 @@ Ret throw_dom_exception_if_needed(auto&& vm, auto&& global_object, F&& fn)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
bool should_return_empty(T&& value)
|
bool should_return_empty(T&& value)
|
||||||
{
|
{
|
||||||
if constexpr (IsSame<JS::Value, T>::value)
|
if constexpr (IsSame<JS::Value, T>)
|
||||||
return value.is_empty();
|
return value.is_empty();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class Performance final
|
|||||||
, public Bindings::Wrappable {
|
, public Bindings::Wrappable {
|
||||||
public:
|
public:
|
||||||
using WrapperType = Bindings::PerformanceWrapper;
|
using WrapperType = Bindings::PerformanceWrapper;
|
||||||
using AllowOwnPtr = AK::TrueType;
|
using AllowOwnPtr = TrueType;
|
||||||
|
|
||||||
explicit Performance(DOM::Window&);
|
explicit Performance(DOM::Window&);
|
||||||
~Performance();
|
~Performance();
|
||||||
|
@ -34,7 +34,7 @@ namespace Web::NavigationTiming {
|
|||||||
class PerformanceTiming final : public Bindings::Wrappable {
|
class PerformanceTiming final : public Bindings::Wrappable {
|
||||||
public:
|
public:
|
||||||
using WrapperType = Bindings::PerformanceTimingWrapper;
|
using WrapperType = Bindings::PerformanceTimingWrapper;
|
||||||
using AllowOwnPtr = AK::TrueType;
|
using AllowOwnPtr = TrueType;
|
||||||
|
|
||||||
explicit PerformanceTiming(DOM::Window&);
|
explicit PerformanceTiming(DOM::Window&);
|
||||||
~PerformanceTiming();
|
~PerformanceTiming();
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
VERIFY(!m_in_removed_last_ref);
|
VERIFY(!m_in_removed_last_ref);
|
||||||
VERIFY(m_ref_count);
|
VERIFY(m_ref_count);
|
||||||
if (!--m_ref_count) {
|
if (!--m_ref_count) {
|
||||||
if constexpr (IsBaseOf<DOM::Node, T>::value) {
|
if constexpr (IsBaseOf<DOM::Node, T>) {
|
||||||
m_in_removed_last_ref = true;
|
m_in_removed_last_ref = true;
|
||||||
static_cast<T*>(this)->removed_last_ref();
|
static_cast<T*>(this)->removed_last_ref();
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,7 +47,7 @@ template<typename T>
|
|||||||
struct TypeTrivia {
|
struct TypeTrivia {
|
||||||
static const size_t bits = sizeof(T) * 8;
|
static const size_t bits = sizeof(T) * 8;
|
||||||
static const T sign_bit = 1 << (bits - 1);
|
static const T sign_bit = 1 << (bits - 1);
|
||||||
static const T mask = typename MakeUnsigned<T>::Type(-1);
|
static const T mask = MakeUnsigned<T>(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
Loading…
Reference in New Issue
Block a user