diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-12-27 19:19:40 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-12-28 12:53:01 +0100 |
commit | 5642cba31b5f7610eddf552b1acd984cf718340d (patch) | |
tree | 40dcec36191f4ed8040c6b6f7525cee978b18fa1 /asl | |
parent | 006a09335306da53f32b4662ebc77866427b6841 (diff) |
Rework some metaprogramming stuff
Diffstat (limited to 'asl')
-rw-r--r-- | asl/allocator.cpp | 2 | ||||
-rw-r--r-- | asl/buffer.hpp | 20 | ||||
-rw-r--r-- | asl/memory.hpp | 9 | ||||
-rw-r--r-- | asl/meta.hpp | 2 | ||||
-rw-r--r-- | asl/option.hpp | 33 | ||||
-rw-r--r-- | asl/tests/buffer_tests.cpp | 88 | ||||
-rw-r--r-- | asl/tests/maybe_uninit_tests.cpp | 4 | ||||
-rw-r--r-- | asl/tests/meta_tests.cpp | 101 | ||||
-rw-r--r-- | asl/tests/option_tests.cpp | 44 | ||||
-rw-r--r-- | asl/tests/span_tests.cpp | 6 | ||||
-rw-r--r-- | asl/tests/string_view_tests.cpp | 2 | ||||
-rw-r--r-- | asl/tests/test_types.hpp | 68 | ||||
-rw-r--r-- | 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 <cstdlib>
@@ -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<Allocator> = 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<T>(old_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_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<typename T>
+template<move_constructible T>
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);
}
else
{
- static_assert(move_constructible<T>);
for (isize_t i = 0; i < n; ++i)
{
// NOLINTNEXTLINE(*-pointer-arithmetic)
construct_at<T>(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<typename T> concept trivially_move_assignable = trivially_assignable_fr 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 moveable = move_constructible<T> && move_assignable<T>;
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<is_object T>
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 kHasInlinePayload = kIsTrivial || kHasNiche;
+ static constexpr bool kHasInlinePayload = default_constructible<T> || kHasNiche;
using Storage = select_t<kHasInlinePayload, T, maybe_uninit<T>>;
using HasValueMarker = select_t<kHasNiche, empty, bool>;
- Storage m_payload{};
- ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value;
+ Storage m_payload;
+ ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value{};
template<typename... Args>
constexpr void construct(Args&&... args)
@@ -88,7 +80,7 @@ class option if constexpr (kHasInlinePayload)
{
- construct_at<T>(&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<T> {}
+
+ // NOLINTNEXTLINE(*-explicit-conversions)
+ constexpr option(nullopt_t) requires (!kHasNiche) && (!trivially_default_constructible<T>)
: m_payload{}
- , m_has_value{false}
{}
// NOLINTNEXTLINE(*-explicit-conversions)
@@ -167,7 +161,7 @@ public: !same_as<un_cvref_t<U>, option> &&
!is_niche<U>
)
- : option()
+ : option(nullopt)
{
construct(ASL_FWD(value));
}
@@ -177,7 +171,7 @@ public: constexpr option(const option& other)
requires copy_constructible<T> && (!kHasInlinePayload)
- : option()
+ : option(nullopt)
{
if (other.has_value())
{
@@ -193,7 +187,7 @@ public: constexpr option(option&& other)
requires move_constructible<T> && (!kHasInlinePayload)
- : option()
+ : option(nullopt)
{
if (other.has_value())
{
@@ -211,7 +205,7 @@ public: constructible_from<T, const U&> &&
!option_internal::convertible_constructible_from_option<T, U>
)
- : option()
+ : option(nullopt)
{
if (other.has_value())
{
@@ -226,7 +220,7 @@ public: constructible_from<T, U&&> &&
!option_internal::convertible_constructible_from_option<T, U>
)
- : 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<int32_t> 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<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
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<int>() == asl::layout::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::trivially_destructible<asl::maybe_uninit<TriviallyDestructible>>);
-static_assert(!asl::trivially_destructible<asl::maybe_uninit<HasDestructor>>);
+static_assert(asl::trivially_destructible<asl::maybe_uninit<TrivialType>>);
+static_assert(!asl::trivially_destructible<asl::maybe_uninit<WithDestructor>>);
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<asl::select_t<false, int, float>, float>); static_assert(asl::same_as<asl::select_t<true, int, float>, int>);
static_assert(asl::default_constructible<int>);
-static_assert(asl::default_constructible<TriviallyDefaultConstructible>);
-static_assert(asl::default_constructible<DefaultConstructible>);
-static_assert(!asl::default_constructible<NonDefaultConstructible>);
+static_assert(asl::default_constructible<TrivialType>);
+static_assert(asl::default_constructible<TrivialTypeDefaultValue>);
static_assert(asl::trivially_default_constructible<int>);
-static_assert(asl::trivially_default_constructible<TriviallyDefaultConstructible>);
-static_assert(!asl::trivially_default_constructible<DefaultConstructible>);
-static_assert(!asl::trivially_default_constructible<NonDefaultConstructible>);
+static_assert(asl::trivially_default_constructible<TrivialType>);
+static_assert(!asl::trivially_default_constructible<TrivialTypeDefaultValue>);
static_assert(asl::copy_constructible<int>);
-static_assert(asl::copy_constructible<TriviallyCopyConstructible>);
-static_assert(asl::copy_constructible<CopyConstructible>);
-static_assert(!asl::copy_constructible<NonCopyConstructible>);
+static_assert(asl::copy_constructible<TrivialType>);
+static_assert(asl::copy_constructible<Copyable>);
+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<TriviallyCopyConstructible>);
-static_assert(!asl::trivially_copy_constructible<CopyConstructible>);
-static_assert(!asl::trivially_copy_constructible<NonCopyConstructible>);
+static_assert(asl::trivially_copy_constructible<TrivialType>);
+static_assert(asl::trivially_copy_constructible<TrivialTypeDefaultValue>);
+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<TriviallyMoveConstructible>);
-static_assert(asl::move_constructible<MoveConstructible>);
-static_assert(asl::move_constructible<CopyConstructible>);
-static_assert(!asl::move_constructible<NonMoveConstructible>);
+static_assert(asl::move_constructible<TrivialType>);
+static_assert(asl::move_constructible<Copyable>);
+static_assert(asl::move_constructible<MoveableOnly>);
+static_assert(!asl::move_constructible<Pinned>);
static_assert(asl::trivially_move_constructible<int>);
-static_assert(asl::trivially_move_constructible<TriviallyMoveConstructible>);
-static_assert(!asl::trivially_move_constructible<MoveConstructible>);
-static_assert(!asl::trivially_move_constructible<NonMoveConstructible>);
+static_assert(asl::trivially_move_constructible<TrivialType>);
+static_assert(asl::trivially_move_constructible<TrivialTypeDefaultValue>);
+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<CopyAssignable>);
-static_assert(asl::copy_assignable<TriviallyCopyAssignable>);
-static_assert(!asl::copy_assignable<NonCopyAssignable>);
+static_assert(asl::copy_assignable<TrivialType>);
+static_assert(asl::copy_assignable<Copyable>);
+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<CopyAssignable>);
-static_assert(asl::trivially_copy_assignable<TriviallyCopyAssignable>);
-static_assert(!asl::trivially_copy_assignable<NonCopyAssignable>);
+static_assert(asl::trivially_copy_assignable<TrivialType>);
+static_assert(asl::trivially_copy_assignable<TrivialTypeDefaultValue>);
+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<MoveAssignable>);
-static_assert(asl::move_assignable<TriviallyMoveAssignable>);
-static_assert(!asl::move_assignable<NonMoveAssignable>);
+static_assert(asl::move_assignable<TrivialType>);
+static_assert(asl::move_assignable<Copyable>);
+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<MoveAssignable>);
-static_assert(asl::trivially_move_assignable<TriviallyMoveAssignable>);
-static_assert(!asl::trivially_move_assignable<NonMoveAssignable>);
+static_assert(asl::trivially_move_assignable<TrivialType>);
+static_assert(asl::trivially_move_assignable<TrivialTypeDefaultValue>);
+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<TriviallyDestructible>);
-static_assert(!asl::trivially_destructible<HasDestructor>);
+static_assert(asl::trivially_destructible<TrivialType>);
+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<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<> == 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 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<int>); static_assert(asl::is_option<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<HasDestructor>>);
+static_assert(asl::trivially_destructible<asl::option<TrivialType>>);
+static_assert(!asl::trivially_destructible<asl::option<WithDestructor>>);
static_assert(asl::copy_constructible<asl::option<int>>);
-static_assert(asl::copy_constructible<asl::option<CopyConstructible>>);
-static_assert(!asl::copy_constructible<asl::option<MoveConstructible>>);
-static_assert(!asl::copy_constructible<asl::option<NonMoveConstructible>>);
+static_assert(asl::copy_constructible<asl::option<Copyable>>);
+static_assert(!asl::copy_constructible<asl::option<MoveableOnly>>);
+static_assert(!asl::copy_constructible<asl::option<Pinned>>);
static_assert(asl::move_constructible<asl::option<int>>);
-static_assert(asl::move_constructible<asl::option<CopyConstructible>>);
-static_assert(asl::move_constructible<asl::option<MoveConstructible>>);
-static_assert(!asl::move_constructible<asl::option<NonMoveConstructible>>);
+static_assert(asl::move_constructible<asl::option<Copyable>>);
+static_assert(asl::move_constructible<asl::option<MoveableOnly>>);
+static_assert(!asl::move_constructible<asl::option<Pinned>>);
static_assert(asl::copy_assignable<asl::option<int>>);
-static_assert(asl::copy_assignable<asl::option<CopyAssignable>>);
-static_assert(!asl::copy_assignable<asl::option<MoveAssignable>>);
-static_assert(!asl::copy_assignable<asl::option<NonMoveAssignable>>);
+static_assert(asl::copy_assignable<asl::option<Copyable>>);
+static_assert(!asl::copy_assignable<asl::option<MoveableOnly>>);
+static_assert(!asl::copy_assignable<asl::option<Pinned>>);
static_assert(asl::move_assignable<asl::option<int>>);
-static_assert(asl::move_assignable<asl::option<CopyAssignable>>);
-static_assert(asl::move_assignable<asl::option<MoveAssignable>>);
-static_assert(!asl::move_assignable<asl::option<NonMoveAssignable>>);
+static_assert(asl::move_assignable<asl::option<Copyable>>);
+static_assert(asl::move_assignable<asl::option<MoveableOnly>>);
+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<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::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<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<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<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)
{
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<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_copyable<asl::span<NonCopyConstructible>>); +static_assert(asl::trivially_copy_constructible<asl::span<int>>); +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, 2>> == asl::size_of<void*>); 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<asl::string_view>); -static_assert(asl::trivially_copyable<asl::string_view>); +static_assert(asl::trivially_copy_constructible<asl::string_view>); 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<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>)
{
return __builtin_bit_cast(U, value);
|