Some work on object & init-related traits
This commit is contained in:
@ -14,6 +14,7 @@ cc_library(
|
||||
name = "%s_tests" % name,
|
||||
srcs = [
|
||||
"%s_tests.cpp" % name,
|
||||
"test_types.hpp",
|
||||
],
|
||||
deps = [
|
||||
":asl",
|
||||
|
35
asl/meta.hpp
35
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; };
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
namespace asl {
|
||||
|
||||
constexpr auto addr(auto&& ref) { return __builtin_addressof(ref); }
|
||||
|
||||
namespace ptr_internal {
|
||||
|
||||
template<is_object T>
|
||||
|
25
asl/test_types.hpp
Normal file
25
asl/test_types.hpp
Normal 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() {} };
|
||||
|
Reference in New Issue
Block a user