39 typename T = obj_type,
40 typename Tx = std::conditional_t<std::is_pointer_v<cast_type>, cast_type, std::add_pointer_t<cast_type>>
44 static_assert(std::is_pointer_v<T>,
"l61::dyn_cast only works on pointer types");
48 if constexpr (std::same_as<T, Tx>)
51 static_assert(std::is_base_of_v<std::remove_pointer_t<Tx>, std::remove_pointer_t<T>>,
"l61::dyn_cast type must be a base of the obj_type's type");
52 return static_cast<Tx
>(obj);
58 static_assert(std::is_pointer_v<T>,
"l61::dyn_cast only works on pointer types");
96 concept isNullableType = !std::same_as<T, nulling::null_t> && (std::default_initializable<T> || std::derived_from<T, nulling::NullableMark>);
101 template<
typename T,
typename C>
104 template<
typename T,
typename C>
107 std::is_trivially_copyable_v<T>;
110 concept stdHashCompatible =
requires { {std::hash<T>()(std::declval<T>())} -> std::convertible_to<std::size_t>; };
119 template<isNullableType T>
120 constexpr operator T() const
122 if constexpr (std::default_initializable<T>)
125 return static_cast<T
>(0);
126 else if constexpr (std::is_pointer_v<T>)