From 5642cba31b5f7610eddf552b1acd984cf718340d Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Fri, 27 Dec 2024 19:19:40 +0100 Subject: Rework some metaprogramming stuff --- asl/allocator.cpp | 2 + asl/buffer.hpp | 20 ++++++-- asl/memory.hpp | 9 ++-- asl/meta.hpp | 2 - asl/option.hpp | 33 ++++++------- asl/tests/buffer_tests.cpp | 88 +++++++++++++++++++++++++++++----- asl/tests/maybe_uninit_tests.cpp | 4 +- asl/tests/meta_tests.cpp | 101 ++++++++++++++++++++++++--------------- asl/tests/option_tests.cpp | 44 ++++++++++------- asl/tests/span_tests.cpp | 6 +-- asl/tests/string_view_tests.cpp | 2 +- asl/tests/test_types.hpp | 68 +++++++++++++++++++------- asl/utility.hpp | 2 +- 13 files changed, 258 insertions(+), 123 deletions(-) diff --git a/asl/allocator.cpp b/asl/allocator.cpp index 7479bd7..645dd22 100644 --- a/asl/allocator.cpp +++ b/asl/allocator.cpp @@ -2,6 +2,7 @@ #include "asl/assert.hpp" #include "asl/utility.hpp" #include "asl/memory.hpp" +#include "asl/print.hpp" #include @@ -40,6 +41,7 @@ void* asl::GlobalHeap::realloc(void* old_ptr, [[maybe_unused]] const layout& old void* new_ptr = alloc(new_layout); asl::memcpy(new_ptr, old_ptr, asl::min(old_layout.size, new_layout.size)); + dealloc(old_ptr, old_layout); return new_ptr; #endif } diff --git a/asl/buffer.hpp b/asl/buffer.hpp index e001ee0..74465bd 100644 --- a/asl/buffer.hpp +++ b/asl/buffer.hpp @@ -108,13 +108,16 @@ private: } public: - constexpr buffer() requires default_constructible = default; explicit constexpr buffer(Allocator allocator) : m_allocator{ASL_MOVE(allocator)} {} + // @Todo Destructor + // @Todo clear + // @Todo Copy/move constructor & assignment + constexpr isize_t size() const { return decode_size(load_size_encoded()); @@ -150,7 +153,7 @@ public: auto old_layout = layout::array(old_capacity); auto new_layout = layout::array(new_capacity); - if (currently_on_heap && trivially_copyable) + if (currently_on_heap && trivially_move_constructible) { m_data = reinterpret_cast(m_allocator.realloc(m_data, old_layout, new_layout)); 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 diff --git a/asl/memory.hpp b/asl/memory.hpp index 7601a7f..0441c8c 100644 --- a/asl/memory.hpp +++ b/asl/memory.hpp @@ -56,24 +56,23 @@ constexpr void destruct_n(T* data, isize_t n) } } -template +template constexpr void relocate_uninit_n(T* to, T* from, isize_t n) { - if constexpr (trivially_copyable) + if constexpr (trivially_move_constructible) { + static_assert(trivially_destructible); memcpy(to, from, size_of * n); } else { - static_assert(move_constructible); for (isize_t i = 0; i < n; ++i) { // NOLINTNEXTLINE(*-pointer-arithmetic) construct_at(to + i, ASL_MOVE(from[i])); } + destruct_n(from, n); } - - destruct_n(from, n); } } // namespace asl diff --git a/asl/meta.hpp b/asl/meta.hpp index 35e238b..3fd76b4 100644 --- a/asl/meta.hpp +++ b/asl/meta.hpp @@ -67,8 +67,6 @@ template concept trivially_move_assignable = trivially_assignable_fr template concept trivially_destructible = __is_trivially_destructible(T); -template concept trivially_copyable = __is_trivially_copyable(T); - template concept copyable = copy_constructible && copy_assignable; template concept moveable = move_constructible && move_assignable; diff --git a/asl/option.hpp b/asl/option.hpp index b22b295..8deed69 100644 --- a/asl/option.hpp +++ b/asl/option.hpp @@ -63,23 +63,15 @@ concept is_option = requires template class option { - static constexpr bool kIsTrivial = - trivially_default_constructible && - trivially_copy_constructible && - trivially_move_constructible && - trivially_copy_assignable && - trivially_move_assignable && - trivially_destructible; - static constexpr bool kHasNiche = has_niche; - static constexpr bool kHasInlinePayload = kIsTrivial || kHasNiche; + static constexpr bool kHasInlinePayload = default_constructible || kHasNiche; using Storage = select_t>; using HasValueMarker = select_t; - Storage m_payload{}; - ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value; + Storage m_payload; + ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value{}; template constexpr void construct(Args&&... args) @@ -88,7 +80,7 @@ class option if constexpr (kHasInlinePayload) { - construct_at(&m_payload, ASL_FWD(args)...); + m_payload = T(ASL_FWD(args)...); } else { @@ -122,9 +114,11 @@ public: constexpr option() : option(nullopt) {} // NOLINTNEXTLINE(*-explicit-conversions) - constexpr option(nullopt_t) requires (!kHasNiche) + constexpr option(nullopt_t) requires (!kHasNiche) && trivially_default_constructible {} + + // NOLINTNEXTLINE(*-explicit-conversions) + constexpr option(nullopt_t) requires (!kHasNiche) && (!trivially_default_constructible) : m_payload{} - , m_has_value{false} {} // NOLINTNEXTLINE(*-explicit-conversions) @@ -167,7 +161,7 @@ public: !same_as, option> && !is_niche ) - : option() + : option(nullopt) { construct(ASL_FWD(value)); } @@ -177,7 +171,7 @@ public: constexpr option(const option& other) requires copy_constructible && (!kHasInlinePayload) - : option() + : option(nullopt) { if (other.has_value()) { @@ -193,7 +187,7 @@ public: constexpr option(option&& other) requires move_constructible && (!kHasInlinePayload) - : option() + : option(nullopt) { if (other.has_value()) { @@ -211,7 +205,7 @@ public: constructible_from && !option_internal::convertible_constructible_from_option ) - : option() + : option(nullopt) { if (other.has_value()) { @@ -226,7 +220,7 @@ public: constructible_from && !option_internal::convertible_constructible_from_option ) - : option() + : option(nullopt) { if (other.has_value()) { @@ -415,6 +409,7 @@ public: } } + // @Todo(C++23) Deducing this constexpr T&& value() && { ASL_ASSERT_RELEASE(has_value()); diff --git a/asl/tests/buffer_tests.cpp b/asl/tests/buffer_tests.cpp index 5376dc1..b677402 100644 --- a/asl/tests/buffer_tests.cpp +++ b/asl/tests/buffer_tests.cpp @@ -1,4 +1,5 @@ #include "asl/buffer.hpp" +#include "asl/print.hpp" #include "asl/testing/testing.hpp" @@ -77,7 +78,6 @@ ASL_TEST(reserve_capacity) ASL_TEST_EXPECT(count == 2); } -// NOLINTBEGIN(*-pointer-arithmetic) ASL_TEST(push) { asl::buffer b; @@ -85,28 +85,90 @@ ASL_TEST(push) b.push(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(3); ASL_TEST_EXPECT(b.size() == 3); - ASL_TEST_EXPECT(b.data()[0] == 1); - ASL_TEST_EXPECT(b.data()[1] == 2); - ASL_TEST_EXPECT(b.data()[2] == 3); + ASL_TEST_EXPECT(b[0] == 1); + ASL_TEST_EXPECT(b[1] == 2); + ASL_TEST_EXPECT(b[2] == 3); b.push(4); b.push(5); b.push(6); b.push(7); ASL_TEST_EXPECT(b.size() == 7); - ASL_TEST_EXPECT(b.data()[0] == 1); - ASL_TEST_EXPECT(b.data()[1] == 2); - ASL_TEST_EXPECT(b.data()[2] == 3); - ASL_TEST_EXPECT(b.data()[3] == 4); - ASL_TEST_EXPECT(b.data()[4] == 5); - ASL_TEST_EXPECT(b.data()[5] == 6); - ASL_TEST_EXPECT(b.data()[6] == 7); + ASL_TEST_EXPECT(b[0] == 1); + ASL_TEST_EXPECT(b[1] == 2); + ASL_TEST_EXPECT(b[2] == 3); + ASL_TEST_EXPECT(b[3] == 4); + ASL_TEST_EXPECT(b[4] == 5); + ASL_TEST_EXPECT(b[5] == 6); + 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); +static_assert(!asl::trivially_move_constructible); +static_assert(!asl::copyable); +static_assert(asl::move_constructible); + +ASL_TEST(push_move) +{ + asl::buffer b; + + static_assert(asl::buffer::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 diff --git a/asl/tests/maybe_uninit_tests.cpp b/asl/tests/maybe_uninit_tests.cpp index 3f60558..92999a2 100644 --- a/asl/tests/maybe_uninit_tests.cpp +++ b/asl/tests/maybe_uninit_tests.cpp @@ -5,6 +5,6 @@ static_assert(asl::layout::of() == asl::layout::of>( static_assert(asl::size_of == asl::size_of>); static_assert(asl::align_of == asl::align_of>); -static_assert(asl::trivially_destructible>); -static_assert(!asl::trivially_destructible>); +static_assert(asl::trivially_destructible>); +static_assert(!asl::trivially_destructible>); diff --git a/asl/tests/meta_tests.cpp b/asl/tests/meta_tests.cpp index fcafe1c..24e9754 100644 --- a/asl/tests/meta_tests.cpp +++ b/asl/tests/meta_tests.cpp @@ -13,59 +13,88 @@ static_assert(asl::same_as, float>); static_assert(asl::same_as, int>); static_assert(asl::default_constructible); -static_assert(asl::default_constructible); -static_assert(asl::default_constructible); -static_assert(!asl::default_constructible); +static_assert(asl::default_constructible); +static_assert(asl::default_constructible); static_assert(asl::trivially_default_constructible); -static_assert(asl::trivially_default_constructible); -static_assert(!asl::trivially_default_constructible); -static_assert(!asl::trivially_default_constructible); +static_assert(asl::trivially_default_constructible); +static_assert(!asl::trivially_default_constructible); static_assert(asl::copy_constructible); -static_assert(asl::copy_constructible); -static_assert(asl::copy_constructible); -static_assert(!asl::copy_constructible); +static_assert(asl::copy_constructible); +static_assert(asl::copy_constructible); +static_assert(!asl::copy_constructible); +static_assert(!asl::copy_constructible); static_assert(asl::trivially_copy_constructible); -static_assert(asl::trivially_copy_constructible); -static_assert(!asl::trivially_copy_constructible); -static_assert(!asl::trivially_copy_constructible); +static_assert(asl::trivially_copy_constructible); +static_assert(asl::trivially_copy_constructible); +static_assert(!asl::trivially_copy_constructible); +static_assert(!asl::trivially_copy_constructible); +static_assert(!asl::trivially_copy_constructible); +static_assert(!asl::trivially_copy_constructible); static_assert(asl::move_constructible); -static_assert(asl::move_constructible); -static_assert(asl::move_constructible); -static_assert(asl::move_constructible); -static_assert(!asl::move_constructible); +static_assert(asl::move_constructible); +static_assert(asl::move_constructible); +static_assert(asl::move_constructible); +static_assert(!asl::move_constructible); static_assert(asl::trivially_move_constructible); -static_assert(asl::trivially_move_constructible); -static_assert(!asl::trivially_move_constructible); -static_assert(!asl::trivially_move_constructible); +static_assert(asl::trivially_move_constructible); +static_assert(asl::trivially_move_constructible); +static_assert(!asl::trivially_move_constructible); +static_assert(!asl::trivially_move_constructible); +static_assert(!asl::trivially_move_constructible); +static_assert(!asl::trivially_move_constructible); static_assert(asl::copy_assignable); -static_assert(asl::copy_assignable); -static_assert(asl::copy_assignable); -static_assert(!asl::copy_assignable); +static_assert(asl::copy_assignable); +static_assert(asl::copy_assignable); +static_assert(!asl::copy_assignable); +static_assert(!asl::copy_assignable); static_assert(asl::trivially_copy_assignable); -static_assert(!asl::trivially_copy_assignable); -static_assert(asl::trivially_copy_assignable); -static_assert(!asl::trivially_copy_assignable); +static_assert(asl::trivially_copy_assignable); +static_assert(asl::trivially_copy_assignable); +static_assert(asl::trivially_copy_assignable); +static_assert(!asl::trivially_copy_assignable); +static_assert(!asl::trivially_copy_assignable); +static_assert(!asl::trivially_copy_assignable); + +static_assert(asl::copyable); +static_assert(asl::copyable); +static_assert(asl::copyable); +static_assert(!asl::copyable); +static_assert(!asl::copyable); + +static_assert(asl::moveable); +static_assert(asl::moveable); +static_assert(asl::moveable); +static_assert(asl::moveable); +static_assert(!asl::moveable); static_assert(asl::move_assignable); -static_assert(asl::move_assignable); -static_assert(asl::move_assignable); -static_assert(!asl::move_assignable); +static_assert(asl::move_assignable); +static_assert(asl::move_assignable); +static_assert(asl::move_assignable); +static_assert(!asl::move_assignable); static_assert(asl::trivially_move_assignable); -static_assert(!asl::trivially_move_assignable); -static_assert(asl::trivially_move_assignable); -static_assert(!asl::trivially_move_assignable); +static_assert(asl::trivially_move_assignable); +static_assert(asl::trivially_move_assignable); +static_assert(asl::trivially_move_assignable); +static_assert(!asl::trivially_move_assignable); +static_assert(!asl::trivially_move_assignable); +static_assert(!asl::trivially_move_assignable); static_assert(asl::trivially_destructible); -static_assert(asl::trivially_destructible); -static_assert(!asl::trivially_destructible); +static_assert(asl::trivially_destructible); +static_assert(asl::trivially_destructible); +static_assert(!asl::trivially_destructible); +static_assert(asl::trivially_destructible); +static_assert(asl::trivially_destructible); +static_assert(asl::trivially_destructible); static_assert(asl::same_as>); static_assert(asl::same_as>); @@ -164,12 +193,6 @@ static_assert(asl::types_count == 2); static_assert(asl::types_count == 1); static_assert(asl::types_count<> == 0); -static_assert(asl::trivially_copyable); -static_assert(!asl::trivially_copyable); -static_assert(!asl::trivially_copyable); -static_assert(asl::trivially_copyable); -static_assert(asl::trivially_copyable); - class Base {}; class Derived : public Base {}; class C {}; diff --git a/asl/tests/option_tests.cpp b/asl/tests/option_tests.cpp index 8261583..557e2fe 100644 --- a/asl/tests/option_tests.cpp +++ b/asl/tests/option_tests.cpp @@ -28,28 +28,28 @@ static_assert(!asl::is_option); static_assert(asl::is_option>); static_assert(asl::is_option>); -static_assert(asl::trivially_destructible>); -static_assert(!asl::trivially_destructible>); +static_assert(asl::trivially_destructible>); +static_assert(!asl::trivially_destructible>); static_assert(asl::copy_constructible>); -static_assert(asl::copy_constructible>); -static_assert(!asl::copy_constructible>); -static_assert(!asl::copy_constructible>); +static_assert(asl::copy_constructible>); +static_assert(!asl::copy_constructible>); +static_assert(!asl::copy_constructible>); static_assert(asl::move_constructible>); -static_assert(asl::move_constructible>); -static_assert(asl::move_constructible>); -static_assert(!asl::move_constructible>); +static_assert(asl::move_constructible>); +static_assert(asl::move_constructible>); +static_assert(!asl::move_constructible>); static_assert(asl::copy_assignable>); -static_assert(asl::copy_assignable>); -static_assert(!asl::copy_assignable>); -static_assert(!asl::copy_assignable>); +static_assert(asl::copy_assignable>); +static_assert(!asl::copy_assignable>); +static_assert(!asl::copy_assignable>); static_assert(asl::move_assignable>); -static_assert(asl::move_assignable>); -static_assert(asl::move_assignable>); -static_assert(!asl::move_assignable>); +static_assert(asl::move_assignable>); +static_assert(asl::move_assignable>); +static_assert(!asl::move_assignable>); static_assert(asl::assignable_from&, asl::option>); static_assert(!asl::assignable_from&, asl::option>); @@ -70,16 +70,24 @@ static_assert(!asl::convertible_from, asl::optio static_assert(asl::convertible_from, asl::option>); static_assert(asl::trivially_copy_constructible>); -static_assert(!asl::trivially_copy_constructible>); +static_assert(asl::trivially_copy_constructible>); +static_assert(asl::trivially_copy_constructible>); +static_assert(!asl::trivially_copy_constructible>); static_assert(asl::trivially_move_constructible>); -static_assert(!asl::trivially_move_constructible>); +static_assert(asl::trivially_move_constructible>); +static_assert(asl::trivially_move_constructible>); +static_assert(!asl::trivially_move_constructible>); static_assert(asl::trivially_copy_assignable>); -static_assert(!asl::trivially_copy_assignable>); +static_assert(asl::trivially_copy_assignable>); +static_assert(asl::trivially_copy_assignable>); +static_assert(!asl::trivially_copy_assignable>); static_assert(asl::trivially_move_assignable>); -static_assert(!asl::trivially_move_assignable>); +static_assert(asl::trivially_move_assignable>); +static_assert(asl::trivially_move_assignable>); +static_assert(!asl::trivially_move_assignable>); ASL_TEST(make_null) { diff --git a/asl/tests/span_tests.cpp b/asl/tests/span_tests.cpp index 8b5db76..52e7736 100644 --- a/asl/tests/span_tests.cpp +++ b/asl/tests/span_tests.cpp @@ -3,10 +3,10 @@ #include "asl/tests/test_types.hpp" static_assert(asl::trivially_destructible>); -static_assert(asl::trivially_destructible>); +static_assert(asl::trivially_destructible>); -static_assert(asl::trivially_copyable>); -static_assert(asl::trivially_copyable>); +static_assert(asl::trivially_copy_constructible>); +static_assert(asl::trivially_copy_constructible>); static_assert(asl::size_of> == asl::size_of * 2); static_assert(asl::size_of> == asl::size_of); diff --git a/asl/tests/string_view_tests.cpp b/asl/tests/string_view_tests.cpp index 708877d..b00da45 100644 --- a/asl/tests/string_view_tests.cpp +++ b/asl/tests/string_view_tests.cpp @@ -2,7 +2,7 @@ #include "asl/testing/testing.hpp" static_assert(asl::trivially_destructible); -static_assert(asl::trivially_copyable); +static_assert(asl::trivially_copy_constructible); ASL_TEST(default) { diff --git a/asl/tests/test_types.hpp b/asl/tests/test_types.hpp index f988aec..f91afb3 100644 --- a/asl/tests/test_types.hpp +++ b/asl/tests/test_types.hpp @@ -2,28 +2,59 @@ #include "asl/utility.hpp" -struct DefaultConstructible { DefaultConstructible() {} }; -struct TriviallyDefaultConstructible { TriviallyDefaultConstructible() = default; }; -struct NonDefaultConstructible { NonDefaultConstructible() = delete; }; +struct TrivialType +{ + 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 TriviallyCopyConstructible { TriviallyCopyConstructible(const TriviallyCopyConstructible&) = default; }; -struct NonCopyConstructible { NonCopyConstructible(const NonCopyConstructible&) = delete; }; +struct TrivialTypeDefaultValue +{ + 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 TriviallyMoveConstructible { TriviallyMoveConstructible(TriviallyMoveConstructible&&) = default; }; -struct NonMoveConstructible { NonMoveConstructible(NonMoveConstructible&&) = delete; }; +struct WithDestructor +{ + 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 TriviallyCopyAssignable { TriviallyCopyAssignable& operator=(const TriviallyCopyAssignable&) = default; }; -struct NonCopyAssignable { NonCopyAssignable& operator=(const NonCopyAssignable&) = delete; }; +struct Copyable // NOLINT +{ + Copyable(const Copyable&) {} // NOLINT + Copyable& operator=(const Copyable&); // NOLINT +}; -struct MoveAssignable { MoveAssignable(MoveAssignable&&) {} MoveAssignable& operator=(MoveAssignable&&) { return *this; } }; -struct TriviallyMoveAssignable { TriviallyMoveAssignable& operator=(TriviallyMoveAssignable&&) = default; }; -struct NonMoveAssignable { NonMoveAssignable& operator=(NonMoveAssignable&&) = delete; }; +struct MoveableOnly // NOLINT +{ + MoveableOnly(const MoveableOnly&) = delete; + MoveableOnly& operator=(const MoveableOnly&) = delete; + MoveableOnly(MoveableOnly&&); + MoveableOnly& operator=(MoveableOnly&&); // NOLINT +}; -struct TriviallyDestructible { ~TriviallyDestructible() = default; }; -struct HasDestructor { ~HasDestructor() {} }; +struct Pinned // NOLINT +{ + Pinned(const Pinned&) = delete; + Pinned& operator=(const Pinned&) = delete; + Pinned(Pinned&&) = delete; + Pinned& operator=(Pinned&&) = delete; +}; struct DestructorObserver { @@ -31,6 +62,9 @@ struct DestructorObserver explicit DestructorObserver(bool* destroyed_) : destroyed{destroyed_} {} + DestructorObserver(const DestructorObserver&) = delete; + DestructorObserver& operator=(const DestructorObserver&) = delete; + DestructorObserver(DestructorObserver&& other) : destroyed{asl::exchange(other.destroyed, nullptr)} {} diff --git a/asl/utility.hpp b/asl/utility.hpp index 451a1e3..2877447 100644 --- a/asl/utility.hpp +++ b/asl/utility.hpp @@ -19,7 +19,7 @@ T exchange(T& obj, U&& new_value) return old_value; } -template +template constexpr U bit_cast(T value) requires (size_of == size_of) { return __builtin_bit_cast(U, value); -- cgit