diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-08-15 23:35:01 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-08-15 23:35:01 +0200 |
commit | 4ad4091b38faa39ddd2deae7455bd3a26531994f (patch) | |
tree | 689496332edb2210ed1500c64f9bcdb2c3926f78 /asl | |
parent | 03e5d14ed191a5a600c7b9f6c33bb2b12fdd5eac (diff) |
Some work on object & init-related traits
Diffstat (limited to 'asl')
-rw-r--r-- | asl/BUILD.bazel | 1 | ||||
-rw-r--r-- | asl/meta.hpp | 35 | ||||
-rw-r--r-- | asl/meta_tests.cpp | 65 | ||||
-rw-r--r-- | asl/object.hpp | 9 | ||||
-rw-r--r-- | asl/object_tests.cpp | 56 | ||||
-rw-r--r-- | asl/ptr.hpp | 2 | ||||
-rw-r--r-- | asl/test_types.hpp | 25 |
7 files changed, 193 insertions, 0 deletions
diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel index 710eaa8..fbbceed 100644 --- a/asl/BUILD.bazel +++ b/asl/BUILD.bazel @@ -14,6 +14,7 @@ cc_library( name = "%s_tests" % name,
srcs = [
"%s_tests.cpp" % name,
+ "test_types.hpp",
],
deps = [
":asl",
diff --git a/asl/meta.hpp b/asl/meta.hpp index c55500a..614fa5d 100644 --- a/asl/meta.hpp +++ b/asl/meta.hpp @@ -2,6 +2,8 @@ namespace asl {
+template<typename T> struct id { using type = T; };
+
template<typename T, T kValue> struct integral_constant { static constexpr T value = kValue; };
template<bool B> using bool_constant = integral_constant<bool, B>;
@@ -13,6 +15,39 @@ template<typename U, typename V> struct _select_helper<true, U, V> template<bool kSelect, typename U, typename V> using select_t = _select_helper<kSelect, U, V>::type;
+template<typename T> auto _as_lref_helper(int) -> id<T&>;
+template<typename T> auto _as_lref_helper(...) -> id<T>;
+
+template<typename T> auto _as_rref_helper(int) -> id<T&&>;
+template<typename T> auto _as_rref_helper(...) -> id<T>;
+
+template<typename T> using as_lref_t = decltype(_as_lref_helper<T>(0))::type;
+template<typename T> using as_rref_t = decltype(_as_rref_helper<T>(0))::type;
+
+template<typename T, typename... Args> concept constructible = __is_constructible(T, Args...);
+
+template<typename T> concept default_constructible = constructible<T>;
+template<typename T> concept copy_constructible = constructible<T, as_lref_t<const T>>;
+template<typename T> concept move_constructible = constructible<T, as_rref_t<T>>;
+
+template<typename T, typename... Args> concept trivially_constructible = __is_trivially_constructible(T, Args...);
+
+template<typename T> concept trivially_default_constructible = trivially_constructible<T>;
+template<typename T> concept trivially_copy_constructible = trivially_constructible<T, as_lref_t<const T>>;
+template<typename T> concept trivially_move_constructible = trivially_constructible<T, as_rref_t<T>>;
+
+template<typename T, typename... Args> concept assignable = __is_assignable(T, Args...);
+
+template<typename T> concept copy_assignable = assignable<as_lref_t<T>, as_lref_t<const T>>;
+template<typename T> concept move_assignable = assignable<as_lref_t<T>, as_rref_t<T>>;
+
+template<typename T, typename... Args> concept trivially_assignable = __is_trivially_assignable(T, Args...);
+
+template<typename T> concept trivially_copy_assignable = trivially_assignable<as_lref_t<T>, as_lref_t<const T>>;
+template<typename T> concept trivially_move_assignable = trivially_assignable<as_lref_t<T>, as_rref_t<T>>;
+
+template<typename T> concept trivially_destructible = __is_trivially_destructible(T);
+
using nullptr_t = decltype(nullptr);
template<typename T> struct un_ref { using type = T; };
diff --git a/asl/meta_tests.cpp b/asl/meta_tests.cpp index 34603e6..2be5c63 100644 --- a/asl/meta_tests.cpp +++ b/asl/meta_tests.cpp @@ -1,4 +1,5 @@ #include "asl/meta.hpp"
+#include "asl/test_types.hpp"
struct EmptyStruct {};
struct Struct { int b: 4; };
@@ -594,4 +595,68 @@ static_assert(asl::is_same<asl::as_raw_ptr_t<const int>, const int*>); static_assert(asl::is_same<asl::as_raw_ptr_t<int(float)>, int(*)(float)>);
static_assert(asl::is_same<asl::as_raw_ptr_t<int&>, 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::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::copy_constructible<int>);
+static_assert(asl::copy_constructible<TriviallyCopyConstructible>);
+static_assert(asl::copy_constructible<CopyConstructible>);
+static_assert(!asl::copy_constructible<NonCopyConstructible>);
+
+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::move_constructible<int>);
+static_assert(asl::move_constructible<TriviallyMoveConstructible>);
+static_assert(asl::move_constructible<MoveConstructible>);
+static_assert(!asl::move_constructible<NonMoveConstructible>);
+
+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::copy_assignable<int>);
+static_assert(asl::copy_assignable<CopyAssignable>);
+static_assert(asl::copy_assignable<TriviallyCopyAssignable>);
+static_assert(!asl::copy_assignable<NoCopyAssignable>);
+
+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<NoCopyAssignable>);
+
+static_assert(asl::move_assignable<int>);
+static_assert(asl::move_assignable<MoveAssignable>);
+static_assert(asl::move_assignable<TriviallyMoveAssignable>);
+static_assert(!asl::move_assignable<NoMoveAssignable>);
+
+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<NoMoveAssignable>);
+
+static_assert(asl::trivially_destructible<int>);
+static_assert(asl::trivially_destructible<TriviallyDestructible>);
+static_assert(!asl::trivially_destructible<HasDestructor>);
+
+static_assert(asl::is_same<asl::as_lref_t<int>, int&>);
+static_assert(asl::is_same<asl::as_lref_t<int&>, int&>);
+static_assert(asl::is_same<asl::as_lref_t<int&&>, int&>);
+static_assert(asl::is_same<asl::as_lref_t<const void>, const void>);
+
+static_assert(asl::is_same<asl::as_rref_t<int>, int&&>);
+static_assert(asl::is_same<asl::as_rref_t<int&>, int&>);
+static_assert(asl::is_same<asl::as_rref_t<int&&>, int&&>);
+static_assert(asl::is_same<asl::as_rref_t<const void>, const void>);
+
int main() { return 0; }
diff --git a/asl/object.hpp b/asl/object.hpp index 936cd25..e45376d 100644 --- a/asl/object.hpp +++ b/asl/object.hpp @@ -12,6 +12,15 @@ class object final ASL_NO_UNIQUE_ADDRESS wrapped m_value;
public:
+ object() requires default_constructible<wrapped> = default;
+
+ object(const object&) = default;
+ object(object&&) = default;
+
+ object& operator=(const object&) = default;
+ object& operator=(object&&) = default;
+
+ ~object() = default;
};
} // namespace asl
diff --git a/asl/object_tests.cpp b/asl/object_tests.cpp index 794c540..e3d7d8d 100644 --- a/asl/object_tests.cpp +++ b/asl/object_tests.cpp @@ -1,4 +1,5 @@ #include "asl/object.hpp"
+#include "asl/test_types.hpp"
static_assert(asl::is_object<asl::object<void>>);
static_assert(asl::is_object<asl::object<int>>);
@@ -6,9 +7,64 @@ static_assert(asl::is_object<asl::object<int&>>); static_assert(asl::is_object<asl::object<int()>>);
static_assert(asl::is_empty<asl::object<void>>);
+static_assert(asl::is_empty<asl::object<asl::empty>>);
static_assert(sizeof(asl::object<int>) == 4);
static_assert(sizeof(asl::object<int*>) == sizeof(void*));
static_assert(sizeof(asl::object<int&>) == sizeof(void*));
static_assert(sizeof(asl::object<int()>) == sizeof(void*));
+static_assert(asl::default_constructible<asl::object<int>>);
+static_assert(asl::default_constructible<asl::object<TriviallyDefaultConstructible>>);
+static_assert(asl::default_constructible<asl::object<DefaultConstructible>>);
+static_assert(!asl::default_constructible<asl::object<NonDefaultConstructible>>);
+
+static_assert(asl::trivially_default_constructible<asl::object<int>>);
+static_assert(asl::trivially_default_constructible<asl::object<TriviallyDefaultConstructible>>);
+static_assert(!asl::trivially_default_constructible<asl::object<DefaultConstructible>>);
+static_assert(!asl::trivially_default_constructible<asl::object<NonDefaultConstructible>>);
+
+static_assert(asl::copy_constructible<asl::object<int>>);
+static_assert(asl::copy_constructible<asl::object<TriviallyCopyConstructible>>);
+static_assert(asl::copy_constructible<asl::object<CopyConstructible>>);
+static_assert(!asl::copy_constructible<asl::object<NonCopyConstructible>>);
+
+static_assert(asl::trivially_copy_constructible<asl::object<int>>);
+static_assert(asl::trivially_copy_constructible<asl::object<TriviallyCopyConstructible>>);
+static_assert(!asl::trivially_copy_constructible<asl::object<CopyConstructible>>);
+static_assert(!asl::trivially_copy_constructible<asl::object<NonCopyConstructible>>);
+
+static_assert(asl::move_constructible<asl::object<int>>);
+static_assert(asl::move_constructible<asl::object<TriviallyMoveConstructible>>);
+static_assert(asl::move_constructible<asl::object<MoveConstructible>>);
+static_assert(!asl::move_constructible<asl::object<NonMoveConstructible>>);
+
+static_assert(asl::trivially_move_constructible<asl::object<int>>);
+static_assert(asl::trivially_move_constructible<asl::object<TriviallyMoveConstructible>>);
+static_assert(!asl::trivially_move_constructible<asl::object<MoveConstructible>>);
+static_assert(!asl::trivially_move_constructible<asl::object<NonMoveConstructible>>);
+
+static_assert(asl::copy_assignable<asl::object<int>>);
+static_assert(asl::copy_assignable<asl::object<CopyAssignable>>);
+static_assert(asl::copy_assignable<asl::object<TriviallyCopyAssignable>>);
+static_assert(!asl::copy_assignable<asl::object<NoCopyAssignable>>);
+
+static_assert(asl::trivially_copy_assignable<asl::object<int>>);
+static_assert(!asl::trivially_copy_assignable<asl::object<CopyAssignable>>);
+static_assert(asl::trivially_copy_assignable<asl::object<TriviallyCopyAssignable>>);
+static_assert(!asl::trivially_copy_assignable<asl::object<NoCopyAssignable>>);
+
+static_assert(asl::move_assignable<asl::object<int>>);
+static_assert(asl::move_assignable<asl::object<MoveAssignable>>);
+static_assert(asl::move_assignable<asl::object<TriviallyMoveAssignable>>);
+static_assert(!asl::move_assignable<asl::object<NoMoveAssignable>>);
+
+static_assert(asl::trivially_move_assignable<asl::object<int>>);
+static_assert(!asl::trivially_move_assignable<asl::object<MoveAssignable>>);
+static_assert(asl::trivially_move_assignable<asl::object<TriviallyMoveAssignable>>);
+static_assert(!asl::trivially_move_assignable<asl::object<NoMoveAssignable>>);
+
+static_assert(asl::trivially_destructible<asl::object<int>>);
+static_assert(asl::trivially_destructible<asl::object<TriviallyDestructible>>);
+static_assert(!asl::trivially_destructible<asl::object<HasDestructor>>);
+
int main() { return 0; }
diff --git a/asl/ptr.hpp b/asl/ptr.hpp index 70dfa7b..1da3f4e 100644 --- a/asl/ptr.hpp +++ b/asl/ptr.hpp @@ -6,6 +6,8 @@ namespace asl {
+constexpr auto addr(auto&& ref) { return __builtin_addressof(ref); }
+
namespace ptr_internal {
template<is_object T>
diff --git a/asl/test_types.hpp b/asl/test_types.hpp new file mode 100644 index 0000000..a5207c6 --- /dev/null +++ b/asl/test_types.hpp @@ -0,0 +1,25 @@ +#pragma once
+
+struct DefaultConstructible { DefaultConstructible() {} };
+struct TriviallyDefaultConstructible { TriviallyDefaultConstructible() = default; };
+struct NonDefaultConstructible { NonDefaultConstructible() = delete; };
+
+struct CopyConstructible { CopyConstructible(const CopyConstructible&) {} };
+struct TriviallyCopyConstructible { TriviallyCopyConstructible(const TriviallyCopyConstructible&) = default; };
+struct NonCopyConstructible { NonCopyConstructible(const NonCopyConstructible&) = delete; };
+
+struct MoveConstructible { MoveConstructible(MoveConstructible&&) {} };
+struct TriviallyMoveConstructible { TriviallyMoveConstructible(TriviallyMoveConstructible&&) = default; };
+struct NonMoveConstructible { NonMoveConstructible(NonMoveConstructible&&) = delete; };
+
+struct CopyAssignable { CopyAssignable& operator=(const CopyAssignable&) { return *this; } };
+struct TriviallyCopyAssignable { TriviallyCopyAssignable& operator=(const TriviallyCopyAssignable&) = default; };
+struct NoCopyAssignable { NoCopyAssignable& operator=(const NoCopyAssignable&) = delete; };
+
+struct MoveAssignable { MoveAssignable& operator=(MoveAssignable&&) { return *this; } };
+struct TriviallyMoveAssignable { TriviallyMoveAssignable& operator=(TriviallyMoveAssignable&&) = default; };
+struct NoMoveAssignable { NoMoveAssignable& operator=(NoMoveAssignable&&) = delete; };
+
+struct TriviallyDestructible { ~TriviallyDestructible() = default; };
+struct HasDestructor { ~HasDestructor() {} };
+
|