summaryrefslogtreecommitdiff
path: root/deimos
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-04-04 00:29:55 +0200
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-04-04 00:31:57 +0200
commitee4ce45b36061964eec1602c7bd3692fb9a40a2f (patch)
tree383605bd1f56f0841e3b73ea4dc0a9b1533a5ff2 /deimos
parentfcc3c353fd250994dec73c4aa4bd66d976c910bb (diff)
Start implementing Span
Diffstat (limited to 'deimos')
-rw-r--r--deimos/core/base.h24
-rw-r--r--deimos/core/std.h30
2 files changed, 54 insertions, 0 deletions
diff --git a/deimos/core/base.h b/deimos/core/base.h
index 2482e68..3dc3bad 100644
--- a/deimos/core/base.h
+++ b/deimos/core/base.h
@@ -53,5 +53,29 @@ struct SourceLocation
{}
};
+template<typename T>
+class Span
+{
+ T* m_begin = nullptr;
+ int64_t m_size = 0;
+
+public:
+ constexpr Span() = default;
+ ~Span() = default;
+
+ deimos_DEFAULT_COPY_MOVE(Span);
+
+ template<typename U>
+ requires std::convertible_to<U*, T*>
+ constexpr Span(const Span<U>& other) : // NOLINT
+ m_begin{other.begin()},
+ m_size{other.size()}
+ {}
+
+ constexpr T* begin() const { return m_begin; }
+ constexpr T* end() const { return m_begin + m_size; }
+ constexpr int64_t size() const { return m_size; }
+};
+
} // namespace deimos
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;