Line data Source code
1 : #pragma once
2 :
3 : #include <jage/engine/memory/cacheline_size.hpp>
4 :
5 : #include <array>
6 : #include <cstddef>
7 : #include <type_traits>
8 : #include <utility>
9 :
10 : namespace jage::engine::memory {
11 :
12 : template <class TUnderlyingValue>
13 : class alignas(cacheline_size) cacheline_slot final : public TUnderlyingValue {
14 : [[no_unique_address]] std::array<std::byte,
15 : cacheline_size - (sizeof(TUnderlyingValue) %
16 : cacheline_size)> padding_;
17 :
18 : public:
19 5 : cacheline_slot(auto &&...args)
20 5 : : TUnderlyingValue(std::forward<decltype(args)>(args)...) {}
21 : };
22 :
23 : template <class TUnderlyingValue>
24 : requires(sizeof(TUnderlyingValue) < cacheline_size) and
25 : std::is_arithmetic_v<TUnderlyingValue>
26 : class alignas(cacheline_size) cacheline_slot<TUnderlyingValue> final {
27 : TUnderlyingValue value_;
28 : [[no_unique_address]] std::array<std::byte,
29 : cacheline_size - (sizeof(TUnderlyingValue) %
30 : cacheline_size)> padding_;
31 :
32 : public:
33 2 : cacheline_slot(auto &&...args)
34 2 : : value_{std::forward<decltype(args)>(args)...} {}
35 :
36 2 : operator TUnderlyingValue() const { return value_; }
37 :
38 : operator TUnderlyingValue() { return value_; }
39 : };
40 :
41 : template <class TUnderlyingValue>
42 : requires(sizeof(TUnderlyingValue) < cacheline_size) and
43 : (not std::is_arithmetic_v<TUnderlyingValue>)
44 : class alignas(cacheline_size) cacheline_slot<TUnderlyingValue> final
45 : : public TUnderlyingValue {
46 : [[no_unique_address]] std::array<
47 : std::byte, (cacheline_size - sizeof(TUnderlyingValue))> padding_;
48 :
49 : public:
50 164 : cacheline_slot(auto &&...args)
51 164 : : TUnderlyingValue(std::forward<decltype(args)>(args)...) {}
52 : };
53 :
54 : template <class TUnderlyingValue>
55 : requires(sizeof(TUnderlyingValue) % cacheline_size == 0UZ)
56 : class alignas(cacheline_size) cacheline_slot<TUnderlyingValue> final
57 : : public TUnderlyingValue {
58 : public:
59 152 : cacheline_slot(auto &&...args)
60 152 : : TUnderlyingValue(std::forward<decltype(args)>(args)...) {}
61 : };
62 :
63 : template <class TUnderlyingValue>
64 : requires(sizeof(TUnderlyingValue) < cacheline_size) and
65 : std::is_arithmetic_v<TUnderlyingValue>
66 : cacheline_slot(TUnderlyingValue &&) -> cacheline_slot<TUnderlyingValue>;
67 :
68 : template <class TUnderlyingValue>
69 : requires(sizeof(TUnderlyingValue) < cacheline_size) and
70 : std::is_arithmetic_v<TUnderlyingValue>
71 : cacheline_slot(TUnderlyingValue &) -> cacheline_slot<TUnderlyingValue>;
72 :
73 : template <class TUnderlyingValue>
74 : requires(sizeof(TUnderlyingValue) < cacheline_size) and
75 : (not std::is_arithmetic_v<TUnderlyingValue>)
76 : cacheline_slot(TUnderlyingValue &&) -> cacheline_slot<TUnderlyingValue>;
77 :
78 : template <class TUnderlyingValue>
79 : requires(sizeof(TUnderlyingValue) < cacheline_size) and
80 : (not std::is_arithmetic_v<TUnderlyingValue>)
81 : cacheline_slot(TUnderlyingValue &) -> cacheline_slot<TUnderlyingValue>;
82 :
83 : template <class TUnderlyingValue>
84 : requires(sizeof(TUnderlyingValue) % cacheline_size == 0UZ)
85 : cacheline_slot(TUnderlyingValue &) -> cacheline_slot<TUnderlyingValue>;
86 :
87 : template <class TUnderlyingValue>
88 : requires(sizeof(TUnderlyingValue) % cacheline_size == 0UZ)
89 : cacheline_slot(TUnderlyingValue &&) -> cacheline_slot<TUnderlyingValue>;
90 :
91 : template <class TUnderlyingValue>
92 : cacheline_slot(TUnderlyingValue &) -> cacheline_slot<TUnderlyingValue>;
93 :
94 : template <class TUnderlyingValue>
95 : cacheline_slot(TUnderlyingValue &&) -> cacheline_slot<TUnderlyingValue>;
96 :
97 : } // namespace jage::engine::memory
|