diff options
Diffstat (limited to 'deimos/core/std.h')
-rw-r--r-- | deimos/core/std.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/deimos/core/std.h b/deimos/core/std.h index 601bfb9..c789d95 100644 --- a/deimos/core/std.h +++ b/deimos/core/std.h @@ -23,12 +23,29 @@ template<typename U, typename V> constexpr bool _is_same_helper = false; template<typename T> constexpr bool _is_same_helper<T, T> = true;
template<typename U, typename V> concept same_as = _is_same_helper<U, V> && _is_same_helper<V, U>;
+template<typename T> struct make_void { using type = void; };
+template<typename T> using void_t = make_void<T>::type;
+
+template<typename T, typename = void> struct _add_reference_helper { using lvalue = T; using rvalue = T; };
+template<typename T> struct _add_reference_helper<T, void_t<T&>> { using lvalue = T&; using rvalue = T&&; };
+template<typename T> using add_lvalue_reference_t = _add_reference_helper<T>::lvalue;
+template<typename T> using add_rvalue_reference_t = _add_reference_helper<T>::rvalue;
+
template<typename T> struct remove_reference { using type = T; };
template<typename T> struct remove_reference<T&> { using type = T; };
template<typename T> struct remove_reference<T&&> { using type = T; };
template<typename T> using remove_reference_t = remove_reference<T>::type;
template<typename T>
+consteval add_rvalue_reference_t<T> declval()
+{
+ static_assert(false, "Don't use declval outside of constant evaluation");
+}
+
+template<typename From, typename To>
+concept convertible_to = __is_convertible(From, To) && requires { static_cast<To>(declval<From>()); };
+
+template<typename T>
constexpr remove_reference_t<T>&& move(T&& r) noexcept
{
return static_cast<remove_reference_t<T>&&>(r);
@@ -66,6 +83,19 @@ static_assert(std::same_as<std::remove_reference_t<int>, int>, ""); static_assert(std::same_as<std::remove_reference_t<int&>, int>, "");
static_assert(std::same_as<std::remove_reference_t<int&&>, int>, "");
+static_assert(std::same_as<std::add_lvalue_reference_t<int>, int&>, "");
+static_assert(std::same_as<std::add_lvalue_reference_t<int&>, int&>, "");
+static_assert(std::same_as<std::add_lvalue_reference_t<int&&>, int&>, "");
+static_assert(std::same_as<std::add_lvalue_reference_t<void>, void>, "");
+
+static_assert(std::same_as<std::add_rvalue_reference_t<int>, int&&>, "");
+static_assert(std::same_as<std::add_rvalue_reference_t<int&>, int&>, "");
+static_assert(std::same_as<std::add_rvalue_reference_t<int&&>, int&&>, "");
+static_assert(std::same_as<std::add_rvalue_reference_t<void>, void>, "");
+
+static_assert(std::convertible_to<int*, const int*>, "");
+static_assert(!std::convertible_to<int*, float*>, "");
+
constexpr void* operator new(size_t, void* ptr)
{
return ptr;
|