Some work on object & init-related traits

This commit is contained in:
2024-08-15 23:35:01 +02:00
parent 03e5d14ed1
commit 4ad4091b38
7 changed files with 193 additions and 0 deletions

View File

@ -14,6 +14,7 @@ cc_library(
name = "%s_tests" % name, name = "%s_tests" % name,
srcs = [ srcs = [
"%s_tests.cpp" % name, "%s_tests.cpp" % name,
"test_types.hpp",
], ],
deps = [ deps = [
":asl", ":asl",

View File

@ -2,6 +2,8 @@
namespace asl { namespace asl {
template<typename T> struct id { using type = T; };
template<typename T, T kValue> struct integral_constant { static constexpr T value = kValue; }; template<typename T, T kValue> struct integral_constant { static constexpr T value = kValue; };
template<bool B> using bool_constant = integral_constant<bool, B>; 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<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); using nullptr_t = decltype(nullptr);
template<typename T> struct un_ref { using type = T; }; template<typename T> struct un_ref { using type = T; };

View File

@ -1,4 +1,5 @@
#include "asl/meta.hpp" #include "asl/meta.hpp"
#include "asl/test_types.hpp"
struct EmptyStruct {}; struct EmptyStruct {};
struct Struct { int b: 4; }; 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(float)>, int(*)(float)>);
static_assert(asl::is_same<asl::as_raw_ptr_t<int&>, int*>); 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; } int main() { return 0; }

View File

@ -12,6 +12,15 @@ class object final
ASL_NO_UNIQUE_ADDRESS wrapped m_value; ASL_NO_UNIQUE_ADDRESS wrapped m_value;
public: 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 } // namespace asl

View File

@ -1,4 +1,5 @@
#include "asl/object.hpp" #include "asl/object.hpp"
#include "asl/test_types.hpp"
static_assert(asl::is_object<asl::object<void>>); static_assert(asl::is_object<asl::object<void>>);
static_assert(asl::is_object<asl::object<int>>); 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_object<asl::object<int()>>);
static_assert(asl::is_empty<asl::object<void>>); 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>) == 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(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; } int main() { return 0; }

View File

@ -6,6 +6,8 @@
namespace asl { namespace asl {
constexpr auto addr(auto&& ref) { return __builtin_addressof(ref); }
namespace ptr_internal { namespace ptr_internal {
template<is_object T> template<is_object T>

25
asl/test_types.hpp Normal file
View File

@ -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() {} };