Sen API
Sen Libraries
Loading...
Searching...
No Matches
property_flags.h
Go to the documentation of this file.
1// === property_flags.h ================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_CORE_OBJ_DETAIL_PROPERTY_FLAGS_H
9#define SEN_CORE_OBJ_DETAIL_PROPERTY_FLAGS_H
10
11// sen
14
15// std
16#include <array>
17#include <cassert>
18#include <type_traits>
19
20namespace sen::impl
21{
22
23constexpr uint8_t currMask = 0b10000000U;
24constexpr uint8_t nextMask = 0b01000000U;
25constexpr uint8_t dirtMask = 0b00100000U;
26constexpr uint8_t syncMask = 0b00010000U;
27
28template <typename T>
29using PropBuffer = std::array<T, 2U>;
30
31class PropertyFlags final
32{
33public:
34 SEN_COPY_MOVE(PropertyFlags)
35
36public:
37 PropertyFlags() = default;
38 ~PropertyFlags() = default;
39
40public:
41 [[nodiscard]] SEN_ALWAYS_INLINE uint8_t currentIndex() const noexcept { return (state_ & currMask) != 0U ? 1U : 0U; }
42 [[nodiscard]] SEN_ALWAYS_INLINE uint8_t nextIndex() const noexcept { return (state_ & nextMask) != 0U ? 1U : 0U; }
43 [[nodiscard]] SEN_ALWAYS_INLINE bool changedInLastCycle() const noexcept { return (state_ & dirtMask) != 0U; }
44 [[nodiscard]] uint8_t advanceNext() noexcept;
45 void advanceCurrent() noexcept;
46 template <typename T>
47 void setValue(std::array<T, 2>& buffer, const T& value) noexcept(std::is_nothrow_copy_constructible_v<T> &&
48 std::is_nothrow_copy_assignable_v<T> &&
49 noexcept(std::declval<T>() != std::declval<T>()));
50 [[nodiscard]] bool getTypesInSync() const noexcept { return (state_ & syncMask) != 0U; }
51 void setTypesInSync(bool value) noexcept
52 {
53 value ? state_ |= syncMask : state_ &= ~syncMask; // NOLINT(hicpp-signed-bitwise)
54 }
55
56private:
57 uint8_t state_ = 0;
58};
59
60static_assert(sizeof(PropertyFlags) == 1);
61
62//----------------------------------------------------------------------------------------------------------------------
63// Inline implementation
64//----------------------------------------------------------------------------------------------------------------------
65
66template <typename T>
67void PropertyFlags::setValue(std::array<T, 2>& buffer,
68 const T& value) noexcept(std::is_nothrow_copy_constructible_v<T> &&
69 std::is_nothrow_copy_assignable_v<T> &&
70 noexcept(std::declval<T>() != std::declval<T>()))
71{
72 const uint8_t cur = currentIndex();
73 const uint8_t nex = nextIndex();
74 assert(cur < 2 && nex < 2);
75
76 if (cur != nex)
77 {
78 buffer[nex] = value; // NOLINT
79 }
80 else
81 {
82 if (buffer[cur] != value) // NOLINT
83 {
84 buffer[advanceNext()] = value; // NOLINT
85 }
86 }
87}
88
89inline void PropertyFlags::advanceCurrent() noexcept
90{
91 if ((state_ & nextMask) != 0U) // next is 1
92 {
93 if ((state_ & currMask) != 0U) // current is also 1
94 {
95 state_ &= ~dirtMask; // set dirty to 0 (no changes detected) NOLINT(hicpp-signed-bitwise)
96 }
97 else // current is 0
98 {
99 // cur = 1, next = 1, dirty = 1
100 state_ = (state_ & syncMask) | currMask | nextMask | dirtMask; // NOLINT(hicpp-signed-bitwise)
101 }
102 }
103 else // next is 0
104 {
105 if ((state_ & currMask) != 0U) // current is 1
106 {
107 // next = 0, cur = 0, dirty = 1
108 state_ = (state_ & syncMask) | dirtMask; // NOLINT(hicpp-signed-bitwise)
109 }
110 else // current is also 0
111 {
112 // dirty = 0 (no changes made)
113 state_ &= ~dirtMask; // NOLINT(hicpp-signed-bitwise)
114 }
115 }
116}
117
118inline uint8_t PropertyFlags::advanceNext() noexcept
119{
120 if ((state_ & nextMask) != 0U) // next is 1
121 {
122 if ((state_ & currMask) != 0U) // current is also 1
123 {
124 // next = 0
125 state_ &= ~nextMask; // NOLINT(hicpp-signed-bitwise)
126 return 0U;
127 }
128 // current is 0, leave next as 1
129 return 1U;
130 }
131
132 // next is 0
133 if ((state_ & currMask) != 0U) // current is 1
134 {
135 // leave next as 0
136 return 0U;
137 }
138
139 // current is also 0, set next to 1
140 state_ |= nextMask;
141 return 1U;
142}
143
144} // namespace sen::impl
145
146#endif // SEN_CORE_OBJ_DETAIL_PROPERTY_FLAGS_H