mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:07:45 +00:00
AK: Replace some SFINAE with requires clauses, clean up existing ones
Add requires clauses to constraints on InputStream and OutputStream operator<< / operator>>. Make the constraint on String::number a requires clause instead of SFINAE. Also, fix some unecessary IsSame in Trie where specialized traits exist for the given use cases.
This commit is contained in:
parent
49a76164c8
commit
7d49ea9836
4 changed files with 40 additions and 29 deletions
27
AK/Stream.h
27
AK/Stream.h
|
@ -147,14 +147,14 @@ InputStream& operator>>(InputStream& stream, Optional<T>& value)
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Integral, typename EnableIf<IsIntegral<Integral>::value, int>::Type = 0>
|
template<typename Integral>
|
||||||
InputStream& operator>>(InputStream& stream, Integral& value)
|
InputStream& operator>>(InputStream& stream, Integral& value) requires IsIntegral<Integral>::value
|
||||||
{
|
{
|
||||||
stream.read_or_error({ &value, sizeof(value) });
|
stream.read_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
template<typename Integral, typename EnableIf<IsIntegral<Integral>::value, int>::Type = 0>
|
template<typename Integral>
|
||||||
OutputStream& operator<<(OutputStream& stream, Integral value)
|
OutputStream& operator<<(OutputStream& stream, Integral value) requires IsIntegral<Integral>::value
|
||||||
{
|
{
|
||||||
stream.write_or_error({ &value, sizeof(value) });
|
stream.write_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
|
@ -162,14 +162,14 @@ OutputStream& operator<<(OutputStream& stream, Integral value)
|
||||||
|
|
||||||
#ifndef KERNEL
|
#ifndef KERNEL
|
||||||
|
|
||||||
template<typename FloatingPoint, typename EnableIf<IsFloatingPoint<FloatingPoint>::value, int>::Type = 0>
|
template<typename FloatingPoint>
|
||||||
InputStream& operator>>(InputStream& stream, FloatingPoint& value)
|
InputStream& operator>>(InputStream& stream, FloatingPoint& value) requires IsFloatingPoint<FloatingPoint>::value
|
||||||
{
|
{
|
||||||
stream.read_or_error({ &value, sizeof(value) });
|
stream.read_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
template<typename FloatingPoint, typename EnableIf<IsFloatingPoint<FloatingPoint>::value, int>::Type = 0>
|
template<typename FloatingPoint>
|
||||||
OutputStream& operator<<(OutputStream& stream, FloatingPoint value)
|
OutputStream& operator<<(OutputStream& stream, FloatingPoint value) requires IsFloatingPoint<FloatingPoint>::value
|
||||||
{
|
{
|
||||||
stream.write_or_error({ &value, sizeof(value) });
|
stream.write_or_error({ &value, sizeof(value) });
|
||||||
return stream;
|
return stream;
|
||||||
|
@ -177,15 +177,4 @@ OutputStream& operator<<(OutputStream& stream, FloatingPoint value)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline InputStream& operator>>(InputStream& stream, bool& value)
|
|
||||||
{
|
|
||||||
stream.read_or_error({ &value, sizeof(value) });
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
inline OutputStream& operator<<(OutputStream& stream, bool value)
|
|
||||||
{
|
|
||||||
stream.write_or_error({ &value, sizeof(value) });
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,8 +252,8 @@ public:
|
||||||
return vformatted(fmtstr, VariadicFormatParams { parameters... });
|
return vformatted(fmtstr, VariadicFormatParams { parameters... });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename EnableIf<IsArithmetic<T>::value>::Type* = nullptr>
|
template<typename T>
|
||||||
static String number(T value) { return formatted("{}", value); }
|
static String number(T value) requires IsArithmetic<T>::value { return formatted("{}", value); }
|
||||||
|
|
||||||
StringView view() const;
|
StringView view() const;
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,28 @@ TEST_CASE(read_an_integer)
|
||||||
EXPECT_EQ(expected, actual);
|
EXPECT_EQ(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(read_a_bool)
|
||||||
|
{
|
||||||
|
bool expected = true, actual;
|
||||||
|
|
||||||
|
InputMemoryStream stream { { &expected, sizeof(expected) } };
|
||||||
|
stream >> actual;
|
||||||
|
|
||||||
|
EXPECT(!stream.has_any_error() && stream.eof());
|
||||||
|
EXPECT_EQ(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE(read_a_double)
|
||||||
|
{
|
||||||
|
double expected = 3.141592653589793, actual;
|
||||||
|
|
||||||
|
InputMemoryStream stream { { &expected, sizeof(expected) } };
|
||||||
|
stream >> actual;
|
||||||
|
|
||||||
|
EXPECT(!stream.has_any_error() && stream.eof());
|
||||||
|
EXPECT_EQ(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(recoverable_error)
|
TEST_CASE(recoverable_error)
|
||||||
{
|
{
|
||||||
u32 expected = 0x01020304, actual = 0;
|
u32 expected = 0x01020304, actual = 0;
|
||||||
|
|
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(!IsSame<MetadataType, decltype(nullptr)>::value) { return m_metadata; }
|
Optional<MetadataType> metadata() const requires(!IsNullPointer<MetadataType>::value) { return m_metadata; }
|
||||||
void set_metadata(MetadataType metadata) requires(!IsSame<MetadataType, decltype(nullptr)>::value) { m_metadata = move(metadata); }
|
void set_metadata(MetadataType metadata) requires(!IsNullPointer<MetadataType>::value) { m_metadata = move(metadata); }
|
||||||
const MetadataType& metadata_value() const requires(!IsSame<MetadataType, decltype(nullptr)>::value) { return m_metadata.value(); }
|
const MetadataType& metadata_value() const requires(!IsNullPointer<MetadataType>::value) { 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(!IsSame<MetadataType, decltype(nullptr)>::value)
|
It& it, const It& end, MetadataType metadata, ProvideMetadataFunction provide_missing_metadata) requires(!IsNullPointer<MetadataType>::value)
|
||||||
{
|
{
|
||||||
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(IsSame<MetadataType, decltype(nullptr)>::value)
|
BaseType& insert(It& it, const It& end) requires(IsNullPointer<MetadataType>::value)
|
||||||
{
|
{
|
||||||
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(!IsSame<MetadataType, decltype(nullptr)>::value)
|
const It& begin, const It& end, MetadataType metadata, ProvideMetadataFunction provide_missing_metadata) requires(!IsNullPointer<MetadataType>::value)
|
||||||
{
|
{
|
||||||
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(IsSame<MetadataType, decltype(nullptr)>::value)
|
BaseType& insert(const It& begin, const It& end) requires(IsNullPointer<MetadataType>::value)
|
||||||
{
|
{
|
||||||
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(!IsSame<MetadataType, void>::value && !IsSame<MetadataType, decltype(nullptr)>::value)
|
Trie(ValueType value, MetadataType metadata) requires(!IsVoid<MetadataType>::value && !IsNullPointer<MetadataType>::value)
|
||||||
: DetailTrie(move(value), move(metadata))
|
: DetailTrie(move(value), move(metadata))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue