aboutsummaryrefslogtreecommitdiffstats
path: root/nihil.generator/manual_lifetime.ccm
diff options
context:
space:
mode:
authorLexi Winter <lexi@le-fay.org>2025-06-29 17:16:22 +0100
committerLexi Winter <lexi@le-fay.org>2025-06-29 17:16:22 +0100
commit4fa6821e0645ff61a9380cd090abff472205c630 (patch)
treebd95f13b2dc0bd9692681f50c365d2914a520bfe /nihil.generator/manual_lifetime.ccm
parente5180acf5f2dfac788e8c12886095ed1ac66fae5 (diff)
downloadnihil-4fa6821e0645ff61a9380cd090abff472205c630.tar.gz
nihil-4fa6821e0645ff61a9380cd090abff472205c630.tar.bz2
add clang-tidy support
Diffstat (limited to 'nihil.generator/manual_lifetime.ccm')
-rw-r--r--nihil.generator/manual_lifetime.ccm117
1 files changed, 117 insertions, 0 deletions
diff --git a/nihil.generator/manual_lifetime.ccm b/nihil.generator/manual_lifetime.ccm
new file mode 100644
index 0000000..d249e99
--- /dev/null
+++ b/nihil.generator/manual_lifetime.ccm
@@ -0,0 +1,117 @@
+///////////////////////////////////////////////////////////////////////////////
+// Reference implementation of std::generator proposal P2168.
+//
+// See https://wg21.link/P2168 for details.
+//
+///////////////////////////////////////////////////////////////////////////////
+// Copyright Lewis Baker, Corentin Jabot
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0.
+// (See accompanying file LICENSE or http://www.boost.org/LICENSE_1_0.txt)
+///////////////////////////////////////////////////////////////////////////////
+
+module;
+
+#include <concepts>
+#include <memory>
+
+export module nihil.generator:manual_lifetime;
+
+namespace nihil {
+
+template <typename T>
+struct manual_lifetime {
+ manual_lifetime() noexcept {}
+ ~manual_lifetime() {}
+
+ template <typename ...Args>
+ auto construct(this manual_lifetime &self, Args && ...args)
+ noexcept(std::is_nothrow_constructible_v<T, Args...>)
+ -> T &
+ {
+ return *::new (static_cast<void*>(std::addressof(self.m_value)))
+ T(static_cast<Args &&>(args)...);
+ }
+
+ void destruct(this manual_lifetime &self)
+ noexcept(std::is_nothrow_destructible_v<T>)
+ {
+ self.m_value.~T();
+ }
+
+ auto get(this manual_lifetime &self) noexcept -> T &
+ {
+ return self.m_value;
+ }
+
+ auto get(this manual_lifetime &&self) noexcept -> T &&
+ {
+ return static_cast<T&&>(self.m_value);
+ }
+
+ auto get(this manual_lifetime const &self) noexcept -> T const &
+ {
+ return self.m_value;
+ }
+
+ auto get(this manual_lifetime const &&self) noexcept -> T const &&
+ {
+ return static_cast<T const &&>(self.m_value);
+ }
+
+private:
+ union {
+ std::remove_const_t<T> m_value;
+ };
+};
+
+template <typename T>
+class manual_lifetime<T &> {
+ manual_lifetime() noexcept {}
+ ~manual_lifetime() {}
+
+ auto construct(this manual_lifetime &self, T &value) noexcept -> T &
+ {
+ self.m_value = std::addressof(value);
+ return self.m_value;
+ }
+
+ auto destruct(this manual_lifetime &) noexcept -> void
+ {
+ }
+
+ auto get(this manual_lifetime const &self) noexcept -> T &
+ {
+ return *self.m_value;
+ }
+
+private:
+ T *m_value = nullptr;
+};
+
+template <typename T>
+class manual_lifetime<T &&> {
+ manual_lifetime() noexcept {}
+ ~manual_lifetime() {}
+
+ auto construct(this manual_lifetime &self, T &&value) noexcept -> T &&
+ {
+ self.m_value = std::addressof(value);
+ return static_cast<T &&>(value);
+ }
+
+ void destruct(this manual_lifetime &) noexcept
+ {
+ }
+
+ auto get(this manual_lifetime const &self) noexcept -> T &&
+ {
+ return static_cast<T &&>(*self.m_value);
+ }
+
+private:
+ T* m_value = nullptr;
+};
+
+}