"ScL Feature"/
ScL Feature 0.0.1
C++20 composable proxy wrapper with pluggable executor strategy
Loading...
Searching...
No Matches
uninitialized.h
Go to the documentation of this file.
1#pragma once
2
6
7#include <algorithm>
8#include <concepts>
9#include <cstddef>
10#include <functional>
11#include <type_traits>
12#include <utility>
13
14#include <scl/utility/type_traits/forward_like.h>
15
16#define SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(cv_ref) \
17 constexpr explicit uninitialized(self_type cv_ref other) /**/ \
18 noexcept \
19 requires(::std::is_trivially_copyable_v<value_type> && ::std::constructible_from<value_type, value_type cv_ref>) \
20 { \
21 ::std::ranges::copy(other.m_storage, m_storage); \
22 }
23
24#define SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF \
25 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(&) \
26 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const &) \
27 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(volatile &) \
28 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const volatile &) \
29 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(&&) \
30 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const &&) \
31 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(volatile &&) \
32 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const volatile &&)
33
34namespace scl::feature::inplace
35{
55 // NOLINTBEGIN(cppcoreguidelines-special-member-functions, cppcoreguidelines-missing-std-forward, cppcoreguidelines-pro-type-member-init, cppcoreguidelines-c-copy-assignment-signature, bugprone-unhandled-self-assignment)
56 template <typename Value>
57 class uninitialized
58 {
59 using self_type = uninitialized<Value>;
60
61 public:
62 using value_type = Value;
63
64 public:
65 constexpr uninitialized() noexcept = default;
66
67 SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF
68
69 // An executor carries no assignment operator of its own; assignment is
70 // performed value-semantically by the wrapper through execute().
71 uninitialized & operator=(uninitialized const &) = delete;
72 uninitialized & operator=(uninitialized &&) = delete;
73
74 public:
75 template <typename Self, typename Func, typename... Args>
76 static constexpr decltype(auto) execute(Self && self, Func && func, Args &&... args)
77 requires(::std::same_as<::std::remove_cvref_t<Self>, self_type> && ::std::invocable<Func, Args && ...>)
78 {
79 return ::std::invoke(::std::forward<Func>(func), ::std::forward<Args>(args)...);
80 }
81
82 template <typename Self>
83 static constexpr decltype(auto) access(Self && self)
84 requires ::std::same_as<::std::remove_cvref_t<Self>, self_type>
85 {
86 // reinterpret_cast<value_type*> for raw storage access;
87 // const correctness is restored by forward_like<Self>.
88 return reinterpret_cast<::scl::forward_like_t<Self, value_type>>(*self.m_storage); // NOLINT(*-reinterpret-cast)
89 }
90
91 private:
92 alignas(value_type)::std::byte m_storage[sizeof(value_type)]; // NOLINT(*-avoid-c-arrays)
93 };
94 // NOLINTEND(cppcoreguidelines-special-member-functions, cppcoreguidelines-missing-std-forward, cppcoreguidelines-pro-type-member-init, cppcoreguidelines-c-copy-assignment-signature, bugprone-unhandled-self-assignment)
95} // namespace scl::feature::inplace
96
97#undef SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF
98#undef SCL_EXECUTOR_CONSTRUCTOR_FOR_SELF_PROTOTYPE