Use concepts and constraints instead of std::enable_if etc

concepts_and_span
elsid 2 years ago
parent 00112aec77
commit 9c8e20a1eb
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -11,8 +11,8 @@
#include <LinearMath/btTransform.h>
#include <type_traits>
#include <concepts>
#if BT_BULLET_VERSION < 310
// Older Bullet versions only support `btScalar` heightfields.
// Our heightfield data is `float`.
//
@ -20,35 +20,32 @@
// `btScalar` is `double` (`BT_USE_DOUBLE_PRECISION`).
namespace
{
template <class T>
auto makeHeights(const T* heights, int verts)
-> std::enable_if_t<std::is_same<btScalar, T>::value, std::vector<btScalar>>
template <std::same_as<btScalar> T>
std::vector<btScalar> makeHeights(const T* /*heights*/, int /*verts*/)
{
return {};
}
template <class T>
auto makeHeights(const T* heights, int verts)
-> std::enable_if_t<!std::is_same<btScalar, T>::value, std::vector<btScalar>>
std::vector<btScalar> makeHeights(const T* heights, int verts)
requires (!std::is_same_v<btScalar, T>)
{
return std::vector<btScalar>(heights, heights + static_cast<std::ptrdiff_t>(verts * verts));
}
template <class T>
auto getHeights(const T* floatHeights, const std::vector<btScalar>&)
-> std::enable_if_t<std::is_same<btScalar, T>::value, const btScalar*>
template <std::same_as<btScalar> T>
const btScalar* getHeights(const T* floatHeights, const std::vector<btScalar>&)
{
return floatHeights;
}
template <class T>
auto getHeights(const T*, const std::vector<btScalar>& btScalarHeights)
-> std::enable_if_t<!std::is_same<btScalar, T>::value, const btScalar*>
requires (!std::is_same_v<btScalar, T>)
const btScalar* getHeights(const T*, const std::vector<btScalar>& btScalarHeights)
{
return btScalarHeights.data();
}
}
#endif
namespace MWPhysics
{

@ -11,8 +11,8 @@ namespace DetourNavigator
namespace Tests
{
template <class T, class Random>
inline auto generateValue(T& value, Random& random)
-> std::enable_if_t<sizeof(T) >= 2>
requires (sizeof(T) >= 2)
inline void generateValue(T& value, Random& random)
{
using Distribution = std::conditional_t<
std::is_floating_point_v<T>,
@ -24,8 +24,8 @@ namespace DetourNavigator
}
template <class T, class Random>
inline auto generateValue(T& value, Random& random)
-> std::enable_if_t<sizeof(T) == 1>
requires (sizeof(T) == 1)
inline void generateValue(T& value, Random& random)
{
unsigned short v;
generateValue(v, random);

@ -6,6 +6,7 @@
#include <utility>
#include <type_traits>
#include <cstdint>
#include <array>
namespace SerializationTesting
{
@ -38,6 +39,7 @@ namespace SerializationTesting
std::vector<Pod> mPodBuffer;
std::size_t mCharDataSize = 0;
std::vector<char> mCharBuffer;
std::array<std::uint16_t, 2> mStdArray;
};
template <Serialization::Mode mode>
@ -46,16 +48,16 @@ namespace SerializationTesting
using Serialization::Format<mode, TestFormat<mode>>::operator();
template <class Visitor, class T>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, Pod>>
requires std::is_same_v<std::decay_t<T>, Pod>
void operator()(Visitor&& visitor, T& value) const
{
visitor(*this, value.mInt);
visitor(*this, value.mDouble);
}
template <class Visitor, class T>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, Composite>>
requires std::is_same_v<std::decay_t<T>, Composite>
void operator()(Visitor&& visitor, T& value) const
{
visitor(*this, value.mFloatArray);
visitor(*this, value.mIntVector);
@ -69,6 +71,7 @@ namespace SerializationTesting
if constexpr (mode == Serialization::Mode::Read)
value.mCharBuffer.resize(value.mCharDataSize);
visitor(*this, value.mCharBuffer.data(), value.mCharDataSize);
visitor(*this, value.mStdArray);
}
};
}

@ -29,6 +29,7 @@ namespace
std::string charData = "serialization";
mComposite.mCharBuffer = {charData.begin(), charData.end()};
mComposite.mCharDataSize = charData.size();
mComposite.mStdArray = {42, 13};
}
};
@ -36,12 +37,12 @@ namespace
{
SizeAccumulator sizeAccumulator;
TestFormat<Mode::Write>{}(sizeAccumulator, mComposite);
EXPECT_EQ(sizeAccumulator.value(), 143);
EXPECT_EQ(sizeAccumulator.value(), 155);
}
TEST_F(DetourNavigatorSerializationIntegrationTest, binaryReaderShouldDeserializeDataWrittenByBinaryWriter)
{
std::vector<std::byte> data(143);
std::vector<std::byte> data(155);
TestFormat<Mode::Write>{}(BinaryWriter(data.data(), data.data() + data.size()), mComposite);
Composite result;
TestFormat<Mode::Read>{}(BinaryReader(data.data(), data.data() + data.size()), result);
@ -52,5 +53,6 @@ namespace
EXPECT_EQ(result.mPodBuffer, mComposite.mPodBuffer);
EXPECT_EQ(result.mCharDataSize, mComposite.mCharDataSize);
EXPECT_EQ(result.mCharBuffer, mComposite.mCharBuffer);
EXPECT_EQ(result.mStdArray, mComposite.mStdArray);
}
}

@ -149,8 +149,8 @@ namespace
}
template <class Visitor, class T>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, rcPolyMesh>>
requires std::is_same_v<std::decay_t<T>, rcPolyMesh>
void operator()(Visitor&& visitor, T& value) const
{
visitor(*this, value.nverts);
visitor(*this, value.npolys);
@ -183,8 +183,8 @@ namespace
}
template <class Visitor, class T>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, rcPolyMeshDetail>>
requires std::is_same_v<std::decay_t<T>, rcPolyMeshDetail>
void operator()(Visitor&& visitor, T& value) const
{
visitor(*this, value.nmeshes);
if constexpr (mode == Serialization::Mode::Read)
@ -204,8 +204,8 @@ namespace
}
template <class Visitor, class T>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, PreparedNavMeshData>>
requires std::is_same_v<std::decay_t<T>, PreparedNavMeshData>
void operator()(Visitor&& visitor, T& value) const
{
if constexpr (mode == Serialization::Mode::Write)
{

@ -9,6 +9,7 @@
#include <cassert>
#include <limits>
#include <type_traits>
#include <concepts>
namespace ESM
{
@ -126,7 +127,7 @@ struct FixedString
}
};
template <std::size_t capacity, class T, typename = std::enable_if_t<std::is_same_v<T, char>>>
template <std::size_t capacity, std::same_as<char> T>
inline bool operator==(const FixedString<capacity>& lhs, const T* const& rhs) noexcept
{
for (std::size_t i = 0; i < capacity; ++i)

@ -79,8 +79,8 @@ namespace EsmLoader
constexpr bool hasId = HasId<T>::value;
template <class T>
requires hasId<T>
auto loadRecord(ESM::ESMReader& reader, Records<T>& records)
-> std::enable_if_t<hasId<T>>
{
T record;
bool deleted = false;
@ -92,8 +92,8 @@ namespace EsmLoader
}
template <class T>
requires (!hasId<T>)
auto loadRecord(ESM::ESMReader& reader, Records<T>& records)
-> std::enable_if_t<!hasId<T>>
{
T record;
bool deleted = false;

@ -18,8 +18,8 @@ namespace NavMeshTool
using Serialization::Format<mode, Format<mode>>::operator();
template <class Visitor, class T>
requires std::is_same_v<std::decay_t<T>, Message>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, Message>>
{
if constexpr (mode == Serialization::Mode::Write)
visitor(*this, messageMagic);
@ -40,29 +40,29 @@ namespace NavMeshTool
}
template <class Visitor, class T>
requires std::is_same_v<std::decay_t<T>, ExpectedCells>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, ExpectedCells>>
{
visitor(*this, value.mCount);
}
template <class Visitor, class T>
requires std::is_same_v<std::decay_t<T>, ProcessedCells>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, ProcessedCells>>
{
visitor(*this, value.mCount);
}
template <class Visitor, class T>
requires std::is_same_v<std::decay_t<T>, ExpectedTiles>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, ExpectedTiles>>
{
visitor(*this, value.mCount);
}
template <class Visitor, class T>
requires std::is_same_v<std::decay_t<T>, GeneratedTiles>
auto operator()(Visitor&& visitor, T& value) const
-> std::enable_if_t<std::is_same_v<std::decay_t<T>, GeneratedTiles>>
{
visitor(*this, value.mCount);
}

@ -64,21 +64,16 @@ namespace NifOsg
ValueInterpolator() = default;
template<
class T,
typename = std::enable_if_t<
std::conjunction_v<
std::disjunction<
std::is_same<ValueT, float>,
std::is_same<ValueT, osg::Vec3f>,
std::is_same<ValueT, bool>,
std::is_same<ValueT, osg::Vec4f>
>,
std::is_same<decltype(T::defaultVal), ValueT>
>,
T
>
>
template <class T>
requires (
(
std::is_same_v<ValueT, float>
|| std::is_same_v<ValueT, osg::Vec3f>
|| std::is_same_v<ValueT, bool>
|| std::is_same_v<ValueT, osg::Vec4f>
)
&& std::is_same_v<decltype(T::defaultVal), ValueT>
)
ValueInterpolator(const T* interpolator) : mDefaultVal(interpolator->defaultVal)
{
if (interpolator->data.empty())

@ -8,6 +8,7 @@
#include <utility>
#include <vector>
#include <cstdint>
#include <stdexcept>
namespace Serialization
{
@ -17,17 +18,37 @@ namespace Serialization
Write,
};
template <class>
struct IsContiguousContainer : std::false_type {};
template <class T>
concept ContiguousContainer = requires (T v)
{
std::data(v);
std::size(v);
};
template <class T>
concept Resizeable = requires (T v)
{
v.resize(std::size_t{});
};
template <class ... Args>
struct IsContiguousContainer<std::vector<Args ...>> : std::true_type {};
template <class T, std::size_t size>
void resize(std::size_t dataSize, T(&/*value*/)[size])
{
if (static_cast<std::size_t>(dataSize) > size)
throw std::runtime_error("Not enough array size");
}
template <class T, std::size_t n>
struct IsContiguousContainer<std::array<T, n>> : std::true_type {};
template <class T, std::size_t size>
void resize(std::size_t dataSize, std::array<T, size>& /*value*/)
{
if (static_cast<std::size_t>(dataSize) > size)
throw std::runtime_error("Not enough std::array size");
}
template <class T>
inline constexpr bool isContiguousContainer = IsContiguousContainer<std::decay_t<T>>::value;
void resize(std::size_t size, Resizeable auto& value)
{
value.resize(size);
}
template <Mode mode, class Derived>
struct Format
@ -47,20 +68,19 @@ namespace Serialization
self()(std::forward<Visitor>(visitor), data, size);
}
template <class Visitor, class T>
auto operator()(Visitor&& visitor, T&& value) const
-> std::enable_if_t<isContiguousContainer<T>>
template <class Visitor>
void operator()(Visitor&& visitor, ContiguousContainer auto&& value) const
{
if constexpr (mode == Mode::Write)
visitor(self(), static_cast<std::uint64_t>(value.size()));
visitor(self(), static_cast<std::uint64_t>(std::size(value)));
else
{
static_assert(mode == Mode::Read);
std::uint64_t size = 0;
visitor(self(), size);
value.resize(static_cast<std::size_t>(size));
resize(static_cast<std::size_t>(size), value);
}
self()(std::forward<Visitor>(visitor), value.data(), value.size());
self()(std::forward<Visitor>(visitor), std::data(value), std::size(value));
}
const Derived& self() const { return static_cast<const Derived&>(*this); }

Loading…
Cancel
Save