Rework some metaprogramming stuff
This commit is contained in:
@ -2,6 +2,7 @@
|
|||||||
#include "asl/assert.hpp"
|
#include "asl/assert.hpp"
|
||||||
#include "asl/utility.hpp"
|
#include "asl/utility.hpp"
|
||||||
#include "asl/memory.hpp"
|
#include "asl/memory.hpp"
|
||||||
|
#include "asl/print.hpp"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ void* asl::GlobalHeap::realloc(void* old_ptr, [[maybe_unused]] const layout& old
|
|||||||
|
|
||||||
void* new_ptr = alloc(new_layout);
|
void* new_ptr = alloc(new_layout);
|
||||||
asl::memcpy(new_ptr, old_ptr, asl::min(old_layout.size, new_layout.size));
|
asl::memcpy(new_ptr, old_ptr, asl::min(old_layout.size, new_layout.size));
|
||||||
|
dealloc(old_ptr, old_layout);
|
||||||
return new_ptr;
|
return new_ptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -108,13 +108,16 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
constexpr buffer() requires default_constructible<Allocator> = default;
|
constexpr buffer() requires default_constructible<Allocator> = default;
|
||||||
|
|
||||||
explicit constexpr buffer(Allocator allocator)
|
explicit constexpr buffer(Allocator allocator)
|
||||||
: m_allocator{ASL_MOVE(allocator)}
|
: m_allocator{ASL_MOVE(allocator)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// @Todo Destructor
|
||||||
|
// @Todo clear
|
||||||
|
// @Todo Copy/move constructor & assignment
|
||||||
|
|
||||||
constexpr isize_t size() const
|
constexpr isize_t size() const
|
||||||
{
|
{
|
||||||
return decode_size(load_size_encoded());
|
return decode_size(load_size_encoded());
|
||||||
@ -150,7 +153,7 @@ public:
|
|||||||
auto old_layout = layout::array<T>(old_capacity);
|
auto old_layout = layout::array<T>(old_capacity);
|
||||||
auto new_layout = layout::array<T>(new_capacity);
|
auto new_layout = layout::array<T>(new_capacity);
|
||||||
|
|
||||||
if (currently_on_heap && trivially_copyable<T>)
|
if (currently_on_heap && trivially_move_constructible<T>)
|
||||||
{
|
{
|
||||||
m_data = reinterpret_cast<T*>(m_allocator.realloc(m_data, old_layout, new_layout));
|
m_data = reinterpret_cast<T*>(m_allocator.realloc(m_data, old_layout, new_layout));
|
||||||
m_capacity = new_capacity;
|
m_capacity = new_capacity;
|
||||||
@ -204,7 +207,18 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Todo operator[]
|
// @Todo(C++23) Use deducing this
|
||||||
|
constexpr T& operator[](isize_t i)
|
||||||
|
{
|
||||||
|
ASL_ASSERT(i >= 0 && i <= size());
|
||||||
|
return data()[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const T& operator[](isize_t i) const
|
||||||
|
{
|
||||||
|
ASL_ASSERT(i >= 0 && i <= size());
|
||||||
|
return data()[i];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace asl
|
} // namespace asl
|
||||||
|
@ -56,24 +56,23 @@ constexpr void destruct_n(T* data, isize_t n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<move_constructible T>
|
||||||
constexpr void relocate_uninit_n(T* to, T* from, isize_t n)
|
constexpr void relocate_uninit_n(T* to, T* from, isize_t n)
|
||||||
{
|
{
|
||||||
if constexpr (trivially_copyable<T>)
|
if constexpr (trivially_move_constructible<T>)
|
||||||
{
|
{
|
||||||
|
static_assert(trivially_destructible<T>);
|
||||||
memcpy(to, from, size_of<T> * n);
|
memcpy(to, from, size_of<T> * n);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static_assert(move_constructible<T>);
|
|
||||||
for (isize_t i = 0; i < n; ++i)
|
for (isize_t i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(*-pointer-arithmetic)
|
// NOLINTNEXTLINE(*-pointer-arithmetic)
|
||||||
construct_at<T>(to + i, ASL_MOVE(from[i]));
|
construct_at<T>(to + i, ASL_MOVE(from[i]));
|
||||||
}
|
}
|
||||||
|
destruct_n(from, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
destruct_n(from, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace asl
|
} // namespace asl
|
||||||
|
@ -67,8 +67,6 @@ template<typename T> concept trivially_move_assignable = trivially_assignable_fr
|
|||||||
|
|
||||||
template<typename T> concept trivially_destructible = __is_trivially_destructible(T);
|
template<typename T> concept trivially_destructible = __is_trivially_destructible(T);
|
||||||
|
|
||||||
template<typename T> concept trivially_copyable = __is_trivially_copyable(T);
|
|
||||||
|
|
||||||
template<typename T> concept copyable = copy_constructible<T> && copy_assignable<T>;
|
template<typename T> concept copyable = copy_constructible<T> && copy_assignable<T>;
|
||||||
template<typename T> concept moveable = move_constructible<T> && move_assignable<T>;
|
template<typename T> concept moveable = move_constructible<T> && move_assignable<T>;
|
||||||
|
|
||||||
|
@ -63,23 +63,15 @@ concept is_option = requires
|
|||||||
template<is_object T>
|
template<is_object T>
|
||||||
class option
|
class option
|
||||||
{
|
{
|
||||||
static constexpr bool kIsTrivial =
|
|
||||||
trivially_default_constructible<T> &&
|
|
||||||
trivially_copy_constructible<T> &&
|
|
||||||
trivially_move_constructible<T> &&
|
|
||||||
trivially_copy_assignable<T> &&
|
|
||||||
trivially_move_assignable<T> &&
|
|
||||||
trivially_destructible<T>;
|
|
||||||
|
|
||||||
static constexpr bool kHasNiche = has_niche<T>;
|
static constexpr bool kHasNiche = has_niche<T>;
|
||||||
|
|
||||||
static constexpr bool kHasInlinePayload = kIsTrivial || kHasNiche;
|
static constexpr bool kHasInlinePayload = default_constructible<T> || kHasNiche;
|
||||||
|
|
||||||
using Storage = select_t<kHasInlinePayload, T, maybe_uninit<T>>;
|
using Storage = select_t<kHasInlinePayload, T, maybe_uninit<T>>;
|
||||||
using HasValueMarker = select_t<kHasNiche, empty, bool>;
|
using HasValueMarker = select_t<kHasNiche, empty, bool>;
|
||||||
|
|
||||||
Storage m_payload{};
|
Storage m_payload;
|
||||||
ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value;
|
ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value{};
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
constexpr void construct(Args&&... args)
|
constexpr void construct(Args&&... args)
|
||||||
@ -88,7 +80,7 @@ class option
|
|||||||
|
|
||||||
if constexpr (kHasInlinePayload)
|
if constexpr (kHasInlinePayload)
|
||||||
{
|
{
|
||||||
construct_at<T>(&m_payload, ASL_FWD(args)...);
|
m_payload = T(ASL_FWD(args)...);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -122,9 +114,11 @@ public:
|
|||||||
constexpr option() : option(nullopt) {}
|
constexpr option() : option(nullopt) {}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(*-explicit-conversions)
|
// NOLINTNEXTLINE(*-explicit-conversions)
|
||||||
constexpr option(nullopt_t) requires (!kHasNiche)
|
constexpr option(nullopt_t) requires (!kHasNiche) && trivially_default_constructible<T> {}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(*-explicit-conversions)
|
||||||
|
constexpr option(nullopt_t) requires (!kHasNiche) && (!trivially_default_constructible<T>)
|
||||||
: m_payload{}
|
: m_payload{}
|
||||||
, m_has_value{false}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(*-explicit-conversions)
|
// NOLINTNEXTLINE(*-explicit-conversions)
|
||||||
@ -167,7 +161,7 @@ public:
|
|||||||
!same_as<un_cvref_t<U>, option> &&
|
!same_as<un_cvref_t<U>, option> &&
|
||||||
!is_niche<U>
|
!is_niche<U>
|
||||||
)
|
)
|
||||||
: option()
|
: option(nullopt)
|
||||||
{
|
{
|
||||||
construct(ASL_FWD(value));
|
construct(ASL_FWD(value));
|
||||||
}
|
}
|
||||||
@ -177,7 +171,7 @@ public:
|
|||||||
|
|
||||||
constexpr option(const option& other)
|
constexpr option(const option& other)
|
||||||
requires copy_constructible<T> && (!kHasInlinePayload)
|
requires copy_constructible<T> && (!kHasInlinePayload)
|
||||||
: option()
|
: option(nullopt)
|
||||||
{
|
{
|
||||||
if (other.has_value())
|
if (other.has_value())
|
||||||
{
|
{
|
||||||
@ -193,7 +187,7 @@ public:
|
|||||||
|
|
||||||
constexpr option(option&& other)
|
constexpr option(option&& other)
|
||||||
requires move_constructible<T> && (!kHasInlinePayload)
|
requires move_constructible<T> && (!kHasInlinePayload)
|
||||||
: option()
|
: option(nullopt)
|
||||||
{
|
{
|
||||||
if (other.has_value())
|
if (other.has_value())
|
||||||
{
|
{
|
||||||
@ -211,7 +205,7 @@ public:
|
|||||||
constructible_from<T, const U&> &&
|
constructible_from<T, const U&> &&
|
||||||
!option_internal::convertible_constructible_from_option<T, U>
|
!option_internal::convertible_constructible_from_option<T, U>
|
||||||
)
|
)
|
||||||
: option()
|
: option(nullopt)
|
||||||
{
|
{
|
||||||
if (other.has_value())
|
if (other.has_value())
|
||||||
{
|
{
|
||||||
@ -226,7 +220,7 @@ public:
|
|||||||
constructible_from<T, U&&> &&
|
constructible_from<T, U&&> &&
|
||||||
!option_internal::convertible_constructible_from_option<T, U>
|
!option_internal::convertible_constructible_from_option<T, U>
|
||||||
)
|
)
|
||||||
: option()
|
: option(nullopt)
|
||||||
{
|
{
|
||||||
if (other.has_value())
|
if (other.has_value())
|
||||||
{
|
{
|
||||||
@ -415,6 +409,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Todo(C++23) Deducing this
|
||||||
constexpr T&& value() &&
|
constexpr T&& value() &&
|
||||||
{
|
{
|
||||||
ASL_ASSERT_RELEASE(has_value());
|
ASL_ASSERT_RELEASE(has_value());
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "asl/buffer.hpp"
|
#include "asl/buffer.hpp"
|
||||||
|
#include "asl/print.hpp"
|
||||||
|
|
||||||
#include "asl/testing/testing.hpp"
|
#include "asl/testing/testing.hpp"
|
||||||
|
|
||||||
@ -77,7 +78,6 @@ ASL_TEST(reserve_capacity)
|
|||||||
ASL_TEST_EXPECT(count == 2);
|
ASL_TEST_EXPECT(count == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOLINTBEGIN(*-pointer-arithmetic)
|
|
||||||
ASL_TEST(push)
|
ASL_TEST(push)
|
||||||
{
|
{
|
||||||
asl::buffer<int32_t> b;
|
asl::buffer<int32_t> b;
|
||||||
@ -85,28 +85,90 @@ ASL_TEST(push)
|
|||||||
|
|
||||||
b.push(1);
|
b.push(1);
|
||||||
ASL_TEST_EXPECT(b.size() == 1);
|
ASL_TEST_EXPECT(b.size() == 1);
|
||||||
ASL_TEST_EXPECT(b.data()[0] == 1);
|
ASL_TEST_EXPECT(b[0] == 1);
|
||||||
|
|
||||||
b.push(2);
|
b.push(2);
|
||||||
b.push(3);
|
b.push(3);
|
||||||
ASL_TEST_EXPECT(b.size() == 3);
|
ASL_TEST_EXPECT(b.size() == 3);
|
||||||
ASL_TEST_EXPECT(b.data()[0] == 1);
|
ASL_TEST_EXPECT(b[0] == 1);
|
||||||
ASL_TEST_EXPECT(b.data()[1] == 2);
|
ASL_TEST_EXPECT(b[1] == 2);
|
||||||
ASL_TEST_EXPECT(b.data()[2] == 3);
|
ASL_TEST_EXPECT(b[2] == 3);
|
||||||
|
|
||||||
b.push(4);
|
b.push(4);
|
||||||
b.push(5);
|
b.push(5);
|
||||||
b.push(6);
|
b.push(6);
|
||||||
b.push(7);
|
b.push(7);
|
||||||
ASL_TEST_EXPECT(b.size() == 7);
|
ASL_TEST_EXPECT(b.size() == 7);
|
||||||
ASL_TEST_EXPECT(b.data()[0] == 1);
|
ASL_TEST_EXPECT(b[0] == 1);
|
||||||
ASL_TEST_EXPECT(b.data()[1] == 2);
|
ASL_TEST_EXPECT(b[1] == 2);
|
||||||
ASL_TEST_EXPECT(b.data()[2] == 3);
|
ASL_TEST_EXPECT(b[2] == 3);
|
||||||
ASL_TEST_EXPECT(b.data()[3] == 4);
|
ASL_TEST_EXPECT(b[3] == 4);
|
||||||
ASL_TEST_EXPECT(b.data()[4] == 5);
|
ASL_TEST_EXPECT(b[4] == 5);
|
||||||
ASL_TEST_EXPECT(b.data()[5] == 6);
|
ASL_TEST_EXPECT(b[5] == 6);
|
||||||
ASL_TEST_EXPECT(b.data()[6] == 7);
|
ASL_TEST_EXPECT(b[6] == 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MoveableType
|
||||||
|
{
|
||||||
|
int moved{};
|
||||||
|
int value;
|
||||||
|
|
||||||
|
explicit MoveableType(int x) : value{x} {}
|
||||||
|
MoveableType(const MoveableType&) = delete;
|
||||||
|
MoveableType(MoveableType&& other) : moved{other.moved + 1}, value{other.value} {}
|
||||||
|
MoveableType& operator=(const MoveableType&) = delete;
|
||||||
|
MoveableType& operator=(MoveableType&&) = delete;
|
||||||
|
};
|
||||||
|
static_assert(!asl::trivially_copy_constructible<MoveableType>);
|
||||||
|
static_assert(!asl::trivially_move_constructible<MoveableType>);
|
||||||
|
static_assert(!asl::copyable<MoveableType>);
|
||||||
|
static_assert(asl::move_constructible<MoveableType>);
|
||||||
|
|
||||||
|
ASL_TEST(push_move)
|
||||||
|
{
|
||||||
|
asl::buffer<MoveableType> b;
|
||||||
|
|
||||||
|
static_assert(asl::buffer<MoveableType>::kInlineCapacity > 0);
|
||||||
|
|
||||||
|
b.push(0);
|
||||||
|
ASL_TEST_EXPECT(b[0].value == 0);
|
||||||
|
ASL_TEST_EXPECT(b[0].moved == 0);
|
||||||
|
|
||||||
|
b.push(1);
|
||||||
|
ASL_TEST_EXPECT(b[0].value == 0);
|
||||||
|
ASL_TEST_EXPECT(b[0].moved == 0);
|
||||||
|
ASL_TEST_EXPECT(b[1].value == 1);
|
||||||
|
ASL_TEST_EXPECT(b[1].moved == 0);
|
||||||
|
|
||||||
|
b.push(2);
|
||||||
|
ASL_TEST_EXPECT(b[0].value == 0);
|
||||||
|
ASL_TEST_EXPECT(b[0].moved == 1);
|
||||||
|
ASL_TEST_EXPECT(b[1].value == 1);
|
||||||
|
ASL_TEST_EXPECT(b[1].moved == 1);
|
||||||
|
ASL_TEST_EXPECT(b[2].value == 2);
|
||||||
|
ASL_TEST_EXPECT(b[2].moved == 0);
|
||||||
|
|
||||||
|
b.push(3);
|
||||||
|
ASL_TEST_EXPECT(b[0].value == 0);
|
||||||
|
ASL_TEST_EXPECT(b[0].moved == 1);
|
||||||
|
ASL_TEST_EXPECT(b[1].value == 1);
|
||||||
|
ASL_TEST_EXPECT(b[1].moved == 1);
|
||||||
|
ASL_TEST_EXPECT(b[2].value == 2);
|
||||||
|
ASL_TEST_EXPECT(b[2].moved == 0);
|
||||||
|
ASL_TEST_EXPECT(b[3].value == 3);
|
||||||
|
ASL_TEST_EXPECT(b[3].moved == 0);
|
||||||
|
|
||||||
|
b.push(4);
|
||||||
|
ASL_TEST_EXPECT(b[0].value == 0);
|
||||||
|
ASL_TEST_EXPECT(b[0].moved == 2);
|
||||||
|
ASL_TEST_EXPECT(b[1].value == 1);
|
||||||
|
ASL_TEST_EXPECT(b[1].moved == 2);
|
||||||
|
ASL_TEST_EXPECT(b[2].value == 2);
|
||||||
|
ASL_TEST_EXPECT(b[2].moved == 1);
|
||||||
|
ASL_TEST_EXPECT(b[3].value == 3);
|
||||||
|
ASL_TEST_EXPECT(b[3].moved == 1);
|
||||||
|
ASL_TEST_EXPECT(b[4].value == 4);
|
||||||
|
ASL_TEST_EXPECT(b[4].moved == 0);
|
||||||
}
|
}
|
||||||
// NOLINTEND(*-pointer-arithmetic)
|
|
||||||
|
|
||||||
// @Todo Test push with non trivial move (non copy) types
|
// @Todo Test push with non trivial move (non copy) types
|
||||||
|
@ -5,6 +5,6 @@ static_assert(asl::layout::of<int>() == asl::layout::of<asl::maybe_uninit<int>>(
|
|||||||
static_assert(asl::size_of<int> == asl::size_of<asl::maybe_uninit<int>>);
|
static_assert(asl::size_of<int> == asl::size_of<asl::maybe_uninit<int>>);
|
||||||
static_assert(asl::align_of<int> == asl::align_of<asl::maybe_uninit<int>>);
|
static_assert(asl::align_of<int> == asl::align_of<asl::maybe_uninit<int>>);
|
||||||
|
|
||||||
static_assert(asl::trivially_destructible<asl::maybe_uninit<TriviallyDestructible>>);
|
static_assert(asl::trivially_destructible<asl::maybe_uninit<TrivialType>>);
|
||||||
static_assert(!asl::trivially_destructible<asl::maybe_uninit<HasDestructor>>);
|
static_assert(!asl::trivially_destructible<asl::maybe_uninit<WithDestructor>>);
|
||||||
|
|
||||||
|
@ -13,59 +13,88 @@ static_assert(asl::same_as<asl::select_t<false, int, float>, float>);
|
|||||||
static_assert(asl::same_as<asl::select_t<true, int, float>, int>);
|
static_assert(asl::same_as<asl::select_t<true, int, float>, int>);
|
||||||
|
|
||||||
static_assert(asl::default_constructible<int>);
|
static_assert(asl::default_constructible<int>);
|
||||||
static_assert(asl::default_constructible<TriviallyDefaultConstructible>);
|
static_assert(asl::default_constructible<TrivialType>);
|
||||||
static_assert(asl::default_constructible<DefaultConstructible>);
|
static_assert(asl::default_constructible<TrivialTypeDefaultValue>);
|
||||||
static_assert(!asl::default_constructible<NonDefaultConstructible>);
|
|
||||||
|
|
||||||
static_assert(asl::trivially_default_constructible<int>);
|
static_assert(asl::trivially_default_constructible<int>);
|
||||||
static_assert(asl::trivially_default_constructible<TriviallyDefaultConstructible>);
|
static_assert(asl::trivially_default_constructible<TrivialType>);
|
||||||
static_assert(!asl::trivially_default_constructible<DefaultConstructible>);
|
static_assert(!asl::trivially_default_constructible<TrivialTypeDefaultValue>);
|
||||||
static_assert(!asl::trivially_default_constructible<NonDefaultConstructible>);
|
|
||||||
|
|
||||||
static_assert(asl::copy_constructible<int>);
|
static_assert(asl::copy_constructible<int>);
|
||||||
static_assert(asl::copy_constructible<TriviallyCopyConstructible>);
|
static_assert(asl::copy_constructible<TrivialType>);
|
||||||
static_assert(asl::copy_constructible<CopyConstructible>);
|
static_assert(asl::copy_constructible<Copyable>);
|
||||||
static_assert(!asl::copy_constructible<NonCopyConstructible>);
|
static_assert(!asl::copy_constructible<MoveableOnly>);
|
||||||
|
static_assert(!asl::copy_constructible<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::trivially_copy_constructible<int>);
|
static_assert(asl::trivially_copy_constructible<int>);
|
||||||
static_assert(asl::trivially_copy_constructible<TriviallyCopyConstructible>);
|
static_assert(asl::trivially_copy_constructible<TrivialType>);
|
||||||
static_assert(!asl::trivially_copy_constructible<CopyConstructible>);
|
static_assert(asl::trivially_copy_constructible<TrivialTypeDefaultValue>);
|
||||||
static_assert(!asl::trivially_copy_constructible<NonCopyConstructible>);
|
static_assert(!asl::trivially_copy_constructible<WithDestructor>);
|
||||||
|
static_assert(!asl::trivially_copy_constructible<Copyable>);
|
||||||
|
static_assert(!asl::trivially_copy_constructible<MoveableOnly>);
|
||||||
|
static_assert(!asl::trivially_copy_constructible<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::move_constructible<int>);
|
static_assert(asl::move_constructible<int>);
|
||||||
static_assert(asl::move_constructible<TriviallyMoveConstructible>);
|
static_assert(asl::move_constructible<TrivialType>);
|
||||||
static_assert(asl::move_constructible<MoveConstructible>);
|
static_assert(asl::move_constructible<Copyable>);
|
||||||
static_assert(asl::move_constructible<CopyConstructible>);
|
static_assert(asl::move_constructible<MoveableOnly>);
|
||||||
static_assert(!asl::move_constructible<NonMoveConstructible>);
|
static_assert(!asl::move_constructible<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::trivially_move_constructible<int>);
|
static_assert(asl::trivially_move_constructible<int>);
|
||||||
static_assert(asl::trivially_move_constructible<TriviallyMoveConstructible>);
|
static_assert(asl::trivially_move_constructible<TrivialType>);
|
||||||
static_assert(!asl::trivially_move_constructible<MoveConstructible>);
|
static_assert(asl::trivially_move_constructible<TrivialTypeDefaultValue>);
|
||||||
static_assert(!asl::trivially_move_constructible<NonMoveConstructible>);
|
static_assert(!asl::trivially_move_constructible<WithDestructor>);
|
||||||
|
static_assert(!asl::trivially_move_constructible<Copyable>);
|
||||||
|
static_assert(!asl::trivially_move_constructible<MoveableOnly>);
|
||||||
|
static_assert(!asl::trivially_move_constructible<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::copy_assignable<int>);
|
static_assert(asl::copy_assignable<int>);
|
||||||
static_assert(asl::copy_assignable<CopyAssignable>);
|
static_assert(asl::copy_assignable<TrivialType>);
|
||||||
static_assert(asl::copy_assignable<TriviallyCopyAssignable>);
|
static_assert(asl::copy_assignable<Copyable>);
|
||||||
static_assert(!asl::copy_assignable<NonCopyAssignable>);
|
static_assert(!asl::copy_assignable<MoveableOnly>);
|
||||||
|
static_assert(!asl::copy_assignable<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::trivially_copy_assignable<int>);
|
static_assert(asl::trivially_copy_assignable<int>);
|
||||||
static_assert(!asl::trivially_copy_assignable<CopyAssignable>);
|
static_assert(asl::trivially_copy_assignable<TrivialType>);
|
||||||
static_assert(asl::trivially_copy_assignable<TriviallyCopyAssignable>);
|
static_assert(asl::trivially_copy_assignable<TrivialTypeDefaultValue>);
|
||||||
static_assert(!asl::trivially_copy_assignable<NonCopyAssignable>);
|
static_assert(asl::trivially_copy_assignable<WithDestructor>);
|
||||||
|
static_assert(!asl::trivially_copy_assignable<Copyable>);
|
||||||
|
static_assert(!asl::trivially_copy_assignable<MoveableOnly>);
|
||||||
|
static_assert(!asl::trivially_copy_assignable<Pinned>);
|
||||||
|
|
||||||
|
static_assert(asl::copyable<int>);
|
||||||
|
static_assert(asl::copyable<TrivialType>);
|
||||||
|
static_assert(asl::copyable<Copyable>);
|
||||||
|
static_assert(!asl::copyable<MoveableOnly>);
|
||||||
|
static_assert(!asl::copyable<Pinned>);
|
||||||
|
|
||||||
|
static_assert(asl::moveable<int>);
|
||||||
|
static_assert(asl::moveable<TrivialType>);
|
||||||
|
static_assert(asl::moveable<Copyable>);
|
||||||
|
static_assert(asl::moveable<MoveableOnly>);
|
||||||
|
static_assert(!asl::moveable<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::move_assignable<int>);
|
static_assert(asl::move_assignable<int>);
|
||||||
static_assert(asl::move_assignable<MoveAssignable>);
|
static_assert(asl::move_assignable<TrivialType>);
|
||||||
static_assert(asl::move_assignable<TriviallyMoveAssignable>);
|
static_assert(asl::move_assignable<Copyable>);
|
||||||
static_assert(!asl::move_assignable<NonMoveAssignable>);
|
static_assert(asl::move_assignable<MoveableOnly>);
|
||||||
|
static_assert(!asl::move_assignable<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::trivially_move_assignable<int>);
|
static_assert(asl::trivially_move_assignable<int>);
|
||||||
static_assert(!asl::trivially_move_assignable<MoveAssignable>);
|
static_assert(asl::trivially_move_assignable<TrivialType>);
|
||||||
static_assert(asl::trivially_move_assignable<TriviallyMoveAssignable>);
|
static_assert(asl::trivially_move_assignable<TrivialTypeDefaultValue>);
|
||||||
static_assert(!asl::trivially_move_assignable<NonMoveAssignable>);
|
static_assert(asl::trivially_move_assignable<WithDestructor>);
|
||||||
|
static_assert(!asl::trivially_move_assignable<Copyable>);
|
||||||
|
static_assert(!asl::trivially_move_assignable<MoveableOnly>);
|
||||||
|
static_assert(!asl::trivially_move_assignable<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::trivially_destructible<int>);
|
static_assert(asl::trivially_destructible<int>);
|
||||||
static_assert(asl::trivially_destructible<TriviallyDestructible>);
|
static_assert(asl::trivially_destructible<TrivialType>);
|
||||||
static_assert(!asl::trivially_destructible<HasDestructor>);
|
static_assert(asl::trivially_destructible<TrivialTypeDefaultValue>);
|
||||||
|
static_assert(!asl::trivially_destructible<WithDestructor>);
|
||||||
|
static_assert(asl::trivially_destructible<Copyable>);
|
||||||
|
static_assert(asl::trivially_destructible<MoveableOnly>);
|
||||||
|
static_assert(asl::trivially_destructible<Pinned>);
|
||||||
|
|
||||||
static_assert(asl::same_as<int, asl::un_const_t<int>>);
|
static_assert(asl::same_as<int, asl::un_const_t<int>>);
|
||||||
static_assert(asl::same_as<int, asl::un_const_t<const int>>);
|
static_assert(asl::same_as<int, asl::un_const_t<const int>>);
|
||||||
@ -164,12 +193,6 @@ static_assert(asl::types_count<int, int> == 2);
|
|||||||
static_assert(asl::types_count<int> == 1);
|
static_assert(asl::types_count<int> == 1);
|
||||||
static_assert(asl::types_count<> == 0);
|
static_assert(asl::types_count<> == 0);
|
||||||
|
|
||||||
static_assert(asl::trivially_copyable<int>);
|
|
||||||
static_assert(!asl::trivially_copyable<HasDestructor>);
|
|
||||||
static_assert(!asl::trivially_copyable<CopyAssignable>);
|
|
||||||
static_assert(asl::trivially_copyable<DefaultConstructible>);
|
|
||||||
static_assert(asl::trivially_copyable<TriviallyDefaultConstructible>);
|
|
||||||
|
|
||||||
class Base {};
|
class Base {};
|
||||||
class Derived : public Base {};
|
class Derived : public Base {};
|
||||||
class C {};
|
class C {};
|
||||||
|
@ -28,28 +28,28 @@ static_assert(!asl::is_option<int>);
|
|||||||
static_assert(asl::is_option<asl::option<int>>);
|
static_assert(asl::is_option<asl::option<int>>);
|
||||||
static_assert(asl::is_option<const asl::option<int>>);
|
static_assert(asl::is_option<const asl::option<int>>);
|
||||||
|
|
||||||
static_assert(asl::trivially_destructible<asl::option<TriviallyDestructible>>);
|
static_assert(asl::trivially_destructible<asl::option<TrivialType>>);
|
||||||
static_assert(!asl::trivially_destructible<asl::option<HasDestructor>>);
|
static_assert(!asl::trivially_destructible<asl::option<WithDestructor>>);
|
||||||
|
|
||||||
static_assert(asl::copy_constructible<asl::option<int>>);
|
static_assert(asl::copy_constructible<asl::option<int>>);
|
||||||
static_assert(asl::copy_constructible<asl::option<CopyConstructible>>);
|
static_assert(asl::copy_constructible<asl::option<Copyable>>);
|
||||||
static_assert(!asl::copy_constructible<asl::option<MoveConstructible>>);
|
static_assert(!asl::copy_constructible<asl::option<MoveableOnly>>);
|
||||||
static_assert(!asl::copy_constructible<asl::option<NonMoveConstructible>>);
|
static_assert(!asl::copy_constructible<asl::option<Pinned>>);
|
||||||
|
|
||||||
static_assert(asl::move_constructible<asl::option<int>>);
|
static_assert(asl::move_constructible<asl::option<int>>);
|
||||||
static_assert(asl::move_constructible<asl::option<CopyConstructible>>);
|
static_assert(asl::move_constructible<asl::option<Copyable>>);
|
||||||
static_assert(asl::move_constructible<asl::option<MoveConstructible>>);
|
static_assert(asl::move_constructible<asl::option<MoveableOnly>>);
|
||||||
static_assert(!asl::move_constructible<asl::option<NonMoveConstructible>>);
|
static_assert(!asl::move_constructible<asl::option<Pinned>>);
|
||||||
|
|
||||||
static_assert(asl::copy_assignable<asl::option<int>>);
|
static_assert(asl::copy_assignable<asl::option<int>>);
|
||||||
static_assert(asl::copy_assignable<asl::option<CopyAssignable>>);
|
static_assert(asl::copy_assignable<asl::option<Copyable>>);
|
||||||
static_assert(!asl::copy_assignable<asl::option<MoveAssignable>>);
|
static_assert(!asl::copy_assignable<asl::option<MoveableOnly>>);
|
||||||
static_assert(!asl::copy_assignable<asl::option<NonMoveAssignable>>);
|
static_assert(!asl::copy_assignable<asl::option<Pinned>>);
|
||||||
|
|
||||||
static_assert(asl::move_assignable<asl::option<int>>);
|
static_assert(asl::move_assignable<asl::option<int>>);
|
||||||
static_assert(asl::move_assignable<asl::option<CopyAssignable>>);
|
static_assert(asl::move_assignable<asl::option<Copyable>>);
|
||||||
static_assert(asl::move_assignable<asl::option<MoveAssignable>>);
|
static_assert(asl::move_assignable<asl::option<MoveableOnly>>);
|
||||||
static_assert(!asl::move_assignable<asl::option<NonMoveAssignable>>);
|
static_assert(!asl::move_assignable<asl::option<Pinned>>);
|
||||||
|
|
||||||
static_assert(asl::assignable_from<asl::option<Base*>&, asl::option<Derived*>>);
|
static_assert(asl::assignable_from<asl::option<Base*>&, asl::option<Derived*>>);
|
||||||
static_assert(!asl::assignable_from<asl::option<Derived*>&, asl::option<Base*>>);
|
static_assert(!asl::assignable_from<asl::option<Derived*>&, asl::option<Base*>>);
|
||||||
@ -70,16 +70,24 @@ static_assert(!asl::convertible_from<asl::option<ExplicitConversion>, asl::optio
|
|||||||
static_assert(asl::convertible_from<asl::option<ImplicitConversion>, asl::option<int>>);
|
static_assert(asl::convertible_from<asl::option<ImplicitConversion>, asl::option<int>>);
|
||||||
|
|
||||||
static_assert(asl::trivially_copy_constructible<asl::option<int>>);
|
static_assert(asl::trivially_copy_constructible<asl::option<int>>);
|
||||||
static_assert(!asl::trivially_copy_constructible<asl::option<CopyConstructible>>);
|
static_assert(asl::trivially_copy_constructible<asl::option<TrivialType>>);
|
||||||
|
static_assert(asl::trivially_copy_constructible<asl::option<TrivialTypeDefaultValue>>);
|
||||||
|
static_assert(!asl::trivially_copy_constructible<asl::option<Copyable>>);
|
||||||
|
|
||||||
static_assert(asl::trivially_move_constructible<asl::option<int>>);
|
static_assert(asl::trivially_move_constructible<asl::option<int>>);
|
||||||
static_assert(!asl::trivially_move_constructible<asl::option<MoveConstructible>>);
|
static_assert(asl::trivially_move_constructible<asl::option<TrivialType>>);
|
||||||
|
static_assert(asl::trivially_move_constructible<asl::option<TrivialTypeDefaultValue>>);
|
||||||
|
static_assert(!asl::trivially_move_constructible<asl::option<MoveableOnly>>);
|
||||||
|
|
||||||
static_assert(asl::trivially_copy_assignable<asl::option<int>>);
|
static_assert(asl::trivially_copy_assignable<asl::option<int>>);
|
||||||
static_assert(!asl::trivially_copy_assignable<asl::option<CopyAssignable>>);
|
static_assert(asl::trivially_copy_assignable<asl::option<TrivialType>>);
|
||||||
|
static_assert(asl::trivially_copy_assignable<asl::option<TrivialTypeDefaultValue>>);
|
||||||
|
static_assert(!asl::trivially_copy_assignable<asl::option<Copyable>>);
|
||||||
|
|
||||||
static_assert(asl::trivially_move_assignable<asl::option<int>>);
|
static_assert(asl::trivially_move_assignable<asl::option<int>>);
|
||||||
static_assert(!asl::trivially_move_assignable<asl::option<MoveAssignable>>);
|
static_assert(asl::trivially_move_assignable<asl::option<TrivialType>>);
|
||||||
|
static_assert(asl::trivially_move_assignable<asl::option<TrivialTypeDefaultValue>>);
|
||||||
|
static_assert(!asl::trivially_move_assignable<asl::option<MoveableOnly>>);
|
||||||
|
|
||||||
ASL_TEST(make_null)
|
ASL_TEST(make_null)
|
||||||
{
|
{
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
#include "asl/tests/test_types.hpp"
|
#include "asl/tests/test_types.hpp"
|
||||||
|
|
||||||
static_assert(asl::trivially_destructible<asl::span<int>>);
|
static_assert(asl::trivially_destructible<asl::span<int>>);
|
||||||
static_assert(asl::trivially_destructible<asl::span<HasDestructor>>);
|
static_assert(asl::trivially_destructible<asl::span<WithDestructor>>);
|
||||||
|
|
||||||
static_assert(asl::trivially_copyable<asl::span<int>>);
|
static_assert(asl::trivially_copy_constructible<asl::span<int>>);
|
||||||
static_assert(asl::trivially_copyable<asl::span<NonCopyConstructible>>);
|
static_assert(asl::trivially_copy_constructible<asl::span<Pinned>>);
|
||||||
|
|
||||||
static_assert(asl::size_of<asl::span<int>> == asl::size_of<void*> * 2);
|
static_assert(asl::size_of<asl::span<int>> == asl::size_of<void*> * 2);
|
||||||
static_assert(asl::size_of<asl::span<int, 2>> == asl::size_of<void*>);
|
static_assert(asl::size_of<asl::span<int, 2>> == asl::size_of<void*>);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "asl/testing/testing.hpp"
|
#include "asl/testing/testing.hpp"
|
||||||
|
|
||||||
static_assert(asl::trivially_destructible<asl::string_view>);
|
static_assert(asl::trivially_destructible<asl::string_view>);
|
||||||
static_assert(asl::trivially_copyable<asl::string_view>);
|
static_assert(asl::trivially_copy_constructible<asl::string_view>);
|
||||||
|
|
||||||
ASL_TEST(default)
|
ASL_TEST(default)
|
||||||
{
|
{
|
||||||
|
@ -2,28 +2,59 @@
|
|||||||
|
|
||||||
#include "asl/utility.hpp"
|
#include "asl/utility.hpp"
|
||||||
|
|
||||||
struct DefaultConstructible { DefaultConstructible() {} };
|
struct TrivialType
|
||||||
struct TriviallyDefaultConstructible { TriviallyDefaultConstructible() = default; };
|
{
|
||||||
struct NonDefaultConstructible { NonDefaultConstructible() = delete; };
|
int x;
|
||||||
|
TrivialType() = default;
|
||||||
|
TrivialType(const TrivialType&) = default;
|
||||||
|
TrivialType(TrivialType&&) = default;
|
||||||
|
TrivialType& operator=(const TrivialType&) = default;
|
||||||
|
TrivialType& operator=(TrivialType&&) = default;
|
||||||
|
~TrivialType() = default;
|
||||||
|
};
|
||||||
|
|
||||||
struct CopyConstructible { CopyConstructible(const CopyConstructible&) {} };
|
struct TrivialTypeDefaultValue
|
||||||
struct TriviallyCopyConstructible { TriviallyCopyConstructible(const TriviallyCopyConstructible&) = default; };
|
{
|
||||||
struct NonCopyConstructible { NonCopyConstructible(const NonCopyConstructible&) = delete; };
|
int x{};
|
||||||
|
TrivialTypeDefaultValue() = default;
|
||||||
|
TrivialTypeDefaultValue(const TrivialTypeDefaultValue&) = default;
|
||||||
|
TrivialTypeDefaultValue(TrivialTypeDefaultValue&&) = default;
|
||||||
|
TrivialTypeDefaultValue& operator=(const TrivialTypeDefaultValue&) = default;
|
||||||
|
TrivialTypeDefaultValue& operator=(TrivialTypeDefaultValue&&) = default;
|
||||||
|
~TrivialTypeDefaultValue() = default;
|
||||||
|
};
|
||||||
|
|
||||||
struct MoveConstructible { MoveConstructible(MoveConstructible&&) {} };
|
struct WithDestructor
|
||||||
struct TriviallyMoveConstructible { TriviallyMoveConstructible(TriviallyMoveConstructible&&) = default; };
|
{
|
||||||
struct NonMoveConstructible { NonMoveConstructible(NonMoveConstructible&&) = delete; };
|
WithDestructor() = default;
|
||||||
|
WithDestructor(const WithDestructor&) = default;
|
||||||
|
WithDestructor(WithDestructor&&) = default;
|
||||||
|
WithDestructor& operator=(const WithDestructor&) = default;
|
||||||
|
WithDestructor& operator=(WithDestructor&&) = default;
|
||||||
|
~WithDestructor() {} // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
struct CopyAssignable { CopyAssignable(const CopyAssignable&) {} CopyAssignable& operator=(const CopyAssignable&) { return *this; } };
|
struct Copyable // NOLINT
|
||||||
struct TriviallyCopyAssignable { TriviallyCopyAssignable& operator=(const TriviallyCopyAssignable&) = default; };
|
{
|
||||||
struct NonCopyAssignable { NonCopyAssignable& operator=(const NonCopyAssignable&) = delete; };
|
Copyable(const Copyable&) {} // NOLINT
|
||||||
|
Copyable& operator=(const Copyable&); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
struct MoveAssignable { MoveAssignable(MoveAssignable&&) {} MoveAssignable& operator=(MoveAssignable&&) { return *this; } };
|
struct MoveableOnly // NOLINT
|
||||||
struct TriviallyMoveAssignable { TriviallyMoveAssignable& operator=(TriviallyMoveAssignable&&) = default; };
|
{
|
||||||
struct NonMoveAssignable { NonMoveAssignable& operator=(NonMoveAssignable&&) = delete; };
|
MoveableOnly(const MoveableOnly&) = delete;
|
||||||
|
MoveableOnly& operator=(const MoveableOnly&) = delete;
|
||||||
|
MoveableOnly(MoveableOnly&&);
|
||||||
|
MoveableOnly& operator=(MoveableOnly&&); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
struct TriviallyDestructible { ~TriviallyDestructible() = default; };
|
struct Pinned // NOLINT
|
||||||
struct HasDestructor { ~HasDestructor() {} };
|
{
|
||||||
|
Pinned(const Pinned&) = delete;
|
||||||
|
Pinned& operator=(const Pinned&) = delete;
|
||||||
|
Pinned(Pinned&&) = delete;
|
||||||
|
Pinned& operator=(Pinned&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
struct DestructorObserver
|
struct DestructorObserver
|
||||||
{
|
{
|
||||||
@ -31,6 +62,9 @@ struct DestructorObserver
|
|||||||
|
|
||||||
explicit DestructorObserver(bool* destroyed_) : destroyed{destroyed_} {}
|
explicit DestructorObserver(bool* destroyed_) : destroyed{destroyed_} {}
|
||||||
|
|
||||||
|
DestructorObserver(const DestructorObserver&) = delete;
|
||||||
|
DestructorObserver& operator=(const DestructorObserver&) = delete;
|
||||||
|
|
||||||
DestructorObserver(DestructorObserver&& other)
|
DestructorObserver(DestructorObserver&& other)
|
||||||
: destroyed{asl::exchange(other.destroyed, nullptr)}
|
: destroyed{asl::exchange(other.destroyed, nullptr)}
|
||||||
{}
|
{}
|
||||||
|
@ -19,7 +19,7 @@ T exchange(T& obj, U&& new_value)
|
|||||||
return old_value;
|
return old_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<trivially_copyable U, trivially_copyable T>
|
template<trivially_copy_constructible U, trivially_copy_constructible T>
|
||||||
constexpr U bit_cast(T value) requires (size_of<T> == size_of<U>)
|
constexpr U bit_cast(T value) requires (size_of<T> == size_of<U>)
|
||||||
{
|
{
|
||||||
return __builtin_bit_cast(U, value);
|
return __builtin_bit_cast(U, value);
|
||||||
|
Reference in New Issue
Block a user