YOrch 1.0.0
Loading...
Searching...
No Matches
slot_view.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <memory>
5#include <new>
6#include <type_traits>
7#include <utility>
8
9#include "../../assert.hpp"
10#include "policy.hpp"
11
12namespace yorch::detail {
13
23template <typename T>
24struct slot_view {
25 static_assert(!std::is_void_v<T>,
26 "yorch::detail::slot_view<T> requires a non-void type");
27
28 std::byte* storage = nullptr;
29 bool* engaged = nullptr;
30 // Points at the owning erased slot's persistent owner-node record.
31 std::size_t* slot_owner_node = nullptr;
32 // The node id this transient view writes into `slot_owner_node`.
35
44 template <typename Slot>
45 requires (!std::is_same_v<std::remove_cvref_t<Slot>, slot_view>)
46 constexpr explicit slot_view(Slot& slot, std::size_t owner_node = no_physical_slot) noexcept
47 : storage(slot.raw_storage()),
48 engaged(slot.engaged_ptr()),
49 slot_owner_node(slot.owner_node_ptr()),
51 policy(Slot::physical_policy) {}
52
53 slot_view() = default;
54
55 template <typename... Args>
56 constexpr T& emplace(Args&&... args)
57 noexcept(std::is_nothrow_constructible_v<T, Args&&...>) {
59 YORCH_ASSERT(engaged != nullptr &&
60 "yorch::detail::slot_view<T> maybe_payload slots require an engagement flag");
62 "yorch::detail::slot_view<T>::emplace() called on a live value");
63 auto* object = std::construct_at(ptr(), std::forward<Args>(args)...);
64 *engaged = true;
65 if (slot_owner_node != nullptr) {
67 }
68 return *object;
69 }
70
71 auto* object = std::construct_at(ptr(), std::forward<Args>(args)...);
72 if (slot_owner_node != nullptr) {
74 }
75 return *object;
76 }
77
78 [[nodiscard]] constexpr T& get() & noexcept {
80 YORCH_ASSERT(engaged != nullptr && *engaged &&
81 "yorch::detail::slot_view<T>::get() called on an empty value");
82 }
83
84 return *ptr();
85 }
86
87 [[nodiscard]] constexpr const T& get() const& noexcept {
89 YORCH_ASSERT(engaged != nullptr && *engaged &&
90 "yorch::detail::slot_view<T>::get() called on an empty value");
91 }
92
93 return *ptr();
94 }
95
96 constexpr void destroy() noexcept {
98 if (engaged == nullptr || !*engaged) {
99 return;
100 }
101
102 std::destroy_at(ptr());
103 *engaged = false;
104 if (slot_owner_node != nullptr) {
106 }
107 return;
108 }
109
110 std::destroy_at(ptr());
111 if (slot_owner_node != nullptr) {
113 }
114 }
115
116 [[nodiscard]] constexpr bool has_value() const noexcept {
118 ? (engaged != nullptr && *engaged)
119 : true;
120 }
121
122private:
123 [[nodiscard]] constexpr T* ptr() noexcept {
124 return std::launder(reinterpret_cast<T*>(storage));
125 }
126
127 [[nodiscard]] constexpr const T* ptr() const noexcept {
128 return std::launder(reinterpret_cast<const T*>(storage));
129 }
130};
131
132} // namespace yorch::detail
#define YORCH_ASSERT(condition)
Definition assert.hpp:10
constexpr std::size_t no_physical_slot
Sentinel physical slot index meaning "this node has no storage".
Definition policy.hpp:59
slot_physical_policy
Storage-level policy for a physical slot after layout selection.
Definition policy.hpp:32
constexpr bool is_adapter_descriptor_v
Definition adapters.hpp:63
Non-owning typed access view over a slot-like storage object.
Definition slot_view.hpp:24
constexpr const T & get() const &noexcept
Definition slot_view.hpp:87
constexpr slot_view(Slot &slot, std::size_t owner_node=no_physical_slot) noexcept
Creates a typed view over slot.
Definition slot_view.hpp:46
slot_physical_policy policy
Definition slot_view.hpp:34
std::size_t * slot_owner_node
Definition slot_view.hpp:31
constexpr void destroy() noexcept
Definition slot_view.hpp:96
constexpr bool has_value() const noexcept
constexpr T & get() &noexcept
Definition slot_view.hpp:78
constexpr T & emplace(Args &&... args) noexcept(std::is_nothrow_constructible_v< T, Args &&... >)
Definition slot_view.hpp:56
std::size_t view_owner_node
Definition slot_view.hpp:33