Remake deref
This commit is contained in:
@ -90,6 +90,9 @@ template<typename T> concept moveable = move_constructible<T> && move_assignable
|
||||
template<typename To, typename From>
|
||||
concept convertible_from = __is_convertible(From, To);
|
||||
|
||||
template<typename From, typename To>
|
||||
concept convertible_to = __is_convertible(From, To);
|
||||
|
||||
template<typename Derived, class Base>
|
||||
concept derived_from = __is_class(Derived) && __is_class(Base) && convertible_from<const volatile Base*, const volatile Derived*>;
|
||||
|
||||
@ -244,29 +247,28 @@ concept has_niche = constructible_from<T, niche_t> && equality_comparable_with<T
|
||||
template<typename T>
|
||||
concept is_niche = same_as<un_cvref_t<T>, niche_t>;
|
||||
|
||||
template<typename T, typename U>
|
||||
concept _derefs_with_indirection_as = requires(T& t)
|
||||
template<typename From, typename To>
|
||||
concept _dereferenceable_as_convertible = requires(From& t)
|
||||
{
|
||||
*t;
|
||||
requires convertible_from<U&, decltype(*t)>;
|
||||
{ *t } -> convertible_to<To&>;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
concept _derefs_reference_as = is_ref<T> && convertible_from<U&, T>;
|
||||
template<typename From, typename To>
|
||||
concept derefs_as = is_object<To> &&
|
||||
(convertible_to<un_ref_t<From>&, To&> || _dereferenceable_as_convertible<un_ref_t<From>, To>);
|
||||
|
||||
template<typename T, typename U>
|
||||
concept _derefs_value_as = !is_ref<T> && convertible_from<U&, T&>;
|
||||
|
||||
template<typename U, _derefs_with_indirection_as<U> T>
|
||||
constexpr U& deref(T&& t) { return static_cast<U&>(*t); }
|
||||
|
||||
template<typename U, _derefs_reference_as<U> T>
|
||||
constexpr U& deref(T&& t) { return static_cast<U&>(t); }
|
||||
|
||||
template<typename U, _derefs_value_as<U> T>
|
||||
constexpr U& deref(T&& t) { return static_cast<U&>(t); }
|
||||
|
||||
template<typename T, typename U>
|
||||
concept derefs_as = _derefs_with_indirection_as<T, U> || _derefs_reference_as<T, U> || _derefs_value_as<T, U>;
|
||||
template<typename To, derefs_as<To> From>
|
||||
constexpr auto&& deref(From&& from) // NOLINT(*forward*)
|
||||
{
|
||||
if constexpr (_dereferenceable_as_convertible<From, To>)
|
||||
{
|
||||
using deref_type = decltype(*declval<From&&>());
|
||||
return static_cast<copy_cref_t<deref_type, To>>(*static_cast<From&&>(from));
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<copy_cref_t<From&&, To>>(from);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace asl
|
||||
|
@ -255,16 +255,22 @@ static_assert(asl::is_enum<Enum2>);
|
||||
|
||||
static_assert(asl::derefs_as<int, int>);
|
||||
static_assert(asl::derefs_as<int*, int>);
|
||||
static_assert(!asl::derefs_as<const int*, int>);
|
||||
static_assert(asl::derefs_as<int&, int>);
|
||||
static_assert(!asl::derefs_as<const int&, int>);
|
||||
static_assert(asl::derefs_as<asl::box<int>, int>);
|
||||
|
||||
static_assert(asl::derefs_as<Derived, Base>);
|
||||
static_assert(!asl::derefs_as<Base, Derived>);
|
||||
static_assert(asl::derefs_as<Derived*, Base>);
|
||||
static_assert(asl::derefs_as<Derived&, Base>);
|
||||
static_assert(!asl::derefs_as<Base&, Derived>);
|
||||
static_assert(asl::derefs_as<asl::box<Derived>, Base>);
|
||||
static_assert(asl::derefs_as<asl::box<Derived>, Derived>);
|
||||
static_assert(asl::derefs_as<asl::box<Base>, Base>);
|
||||
|
||||
static void wants_int(int) {}
|
||||
static void wants_base(Base&) {}
|
||||
static void wants_base(const Base&) {}
|
||||
static void wants_base_ptr(Base*) {}
|
||||
|
||||
ASL_TEST(deref)
|
||||
@ -285,10 +291,11 @@ ASL_TEST(deref)
|
||||
wants_base(asl::deref<Base>(&c));
|
||||
wants_base(asl::deref<Base>(d));
|
||||
|
||||
wants_base_ptr(&asl::deref<Base>(Derived{}));
|
||||
wants_base_ptr(&asl::deref<Base>(c));
|
||||
wants_base_ptr(&asl::deref<Base>(&c));
|
||||
wants_base_ptr(&asl::deref<Base>(d));
|
||||
|
||||
wants_base(asl::deref<Base>(std::move(d)));
|
||||
}
|
||||
|
||||
static_assert(asl::same_as<asl::copy_cref_t<int, float>, float>);
|
||||
|
@ -19,7 +19,7 @@ struct intrusive_list_node
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept is_intrusive_list_node = convertible_from<intrusive_list_node<T>*, T*>;
|
||||
concept is_intrusive_list_node = derived_from<T, intrusive_list_node<T>>;
|
||||
|
||||
template<is_intrusive_list_node T>
|
||||
class IntrusiveList
|
||||
|
@ -76,18 +76,21 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
constexpr T* get() const { return m_ptr; }
|
||||
|
||||
constexpr T& operator*() const
|
||||
constexpr auto* get(this auto&& self)
|
||||
{
|
||||
ASL_ASSERT(m_ptr != nullptr);
|
||||
return *m_ptr;
|
||||
return self.m_ptr;
|
||||
}
|
||||
|
||||
constexpr T* operator->() const
|
||||
constexpr auto&& operator*(this auto&& self)
|
||||
{
|
||||
ASL_ASSERT(m_ptr != nullptr);
|
||||
return m_ptr;
|
||||
ASL_ASSERT(self.m_ptr != nullptr);
|
||||
return std::forward_like<decltype(self)&&>(*self.m_ptr);
|
||||
}
|
||||
|
||||
constexpr auto* operator->(this auto&& self)
|
||||
{
|
||||
ASL_ASSERT(self.m_ptr != nullptr);
|
||||
return self.m_ptr;
|
||||
}
|
||||
|
||||
constexpr bool operator==(niche_t) const
|
||||
|
@ -75,21 +75,21 @@ public:
|
||||
}
|
||||
|
||||
template<isize_t N>
|
||||
constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions)
|
||||
constexpr span(T (&array)[N]) // NOLINT(*explicit*)
|
||||
requires (kIsDynamic)
|
||||
: m_data{array}
|
||||
, m_size{N}
|
||||
{}
|
||||
|
||||
template<isize_t N>
|
||||
constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions)
|
||||
constexpr span(T (&array)[N]) // NOLINT(*explicit*)
|
||||
requires (!kIsDynamic) && (N == kSize)
|
||||
: m_data{array}
|
||||
{}
|
||||
|
||||
template<is_object U, isize_t kOtherSize>
|
||||
constexpr explicit(!kIsDynamic)
|
||||
span(const span<U, kOtherSize>& other) // NOLINT(*-explicit-conversions)
|
||||
span(const span<U, kOtherSize>& other)
|
||||
requires (
|
||||
(
|
||||
kIsDynamic ||
|
||||
@ -217,7 +217,7 @@ template<is_object T, isize_t kSize>
|
||||
inline span<const byte> as_bytes(span<T, kSize> s)
|
||||
{
|
||||
return span<const byte>(
|
||||
reinterpret_cast<const byte*>(s.data()),
|
||||
reinterpret_cast<const byte*>(s.data()), // NOLINT(*-reinterpret-cast)
|
||||
s.size_bytes());
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ inline span<byte> as_mutable_bytes(span<T, kSize> s)
|
||||
requires (!is_const<T>)
|
||||
{
|
||||
return span<byte>(
|
||||
reinterpret_cast<byte*>(s.data()),
|
||||
reinterpret_cast<byte*>(s.data()), // NOLINT(*-reinterpret-cast)
|
||||
s.size_bytes());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user