1 #ifndef __MULTI_CLOCK_HPP 2 #define __MULTI_CLOCK_HPP 52 template<
class key_type,
53 class value_type, uint32_t clock_count, key_type invalid_index, key_type invalid_clock_index = clock_count>
70 _hands.fill(invalid_index);
90 template<ClockIndex clock>
92 static_assert(clock < clock_count);
93 if (!isEmpty<clock>()) {
99 invalid_clock_index>(
this, clock);
112 template<ClockIndex clock>
114 static_assert(clock < clock_count);
115 if (!isEmpty<clock>()) {
119 invalid_clock_index>(
this, clock);
132 template<ClockIndex clock>
134 static_assert(clock < clock_count);
135 if (!isEmpty<clock>()) {
137 headIndex =
_hands[clock];
140 invalid_clock_index>(
this, clock);
155 template<ClockIndex clock>
157 static_assert(clock < clock_count);
158 if (!isEmpty<clock>()) {
163 invalid_clock_index>(
this, clock);
181 template<ClockIndex clock>
183 static_assert(clock < clock_count);
186 invalid_clock_index>(
this, index);
189 invalid_clock_index>(
this, index);
191 if (isEmpty<clock>()) {
193 _clocks[index]._before = index;
220 template<ClockIndex clock>
222 static_assert(clock < clock_count);
225 invalid_clock_index>(
this, index);
228 invalid_clock_index>(
this, index);
230 if (isEmpty<clock>()) {
232 _clocks[index]._before = index;
261 void addBefore(
const key_type& inside,
const key_type& newEntry) {
264 invalid_clock_index>(
this, newEntry);
267 invalid_clock_index>(
this, inside);
270 invalid_clock_index>(
this, newEntry);
273 invalid_clock_index>(
this, inside);
277 _clocks[newEntry]._after = inside;
278 _clocks[inside]._before = newEntry;
300 void addBefore(
const key_type& inside, key_type&& newEntry) {
303 invalid_clock_index>(
this, newEntry);
306 invalid_clock_index>(
this, inside);
309 invalid_clock_index>(
this, newEntry);
312 invalid_clock_index>(
this, inside);
316 _clocks[newEntry]._after = inside;
317 _clocks[inside]._before = newEntry;
339 void addAfter(
const key_type& inside,
const key_type& newEntry) {
342 invalid_clock_index>(
this, newEntry);
345 invalid_clock_index>(
this, inside);
348 invalid_clock_index>(
this, newEntry);
351 invalid_clock_index>(
this, inside);
355 _clocks[newEntry]._before = inside;
356 _clocks[inside]._after = newEntry;
378 void addAfter(
const key_type& inside,
const key_type&& newEntry) {
381 invalid_clock_index>(
this, newEntry);
384 invalid_clock_index>(
this, inside);
387 invalid_clock_index>(
this, newEntry);
390 invalid_clock_index>(
this, inside);
394 _clocks[newEntry]._before = inside;
395 _clocks[inside]._after = newEntry;
411 template<ClockIndex clock>
413 static_assert(clock < clock_count);
414 if (!isEmpty<clock>()) {
415 removedIndex =
_hands[clock];
416 remove(removedIndex);
420 invalid_clock_index>(
this, clock);
437 void remove(
const key_type& index) {
440 invalid_clock_index>(
this, index);
443 invalid_clock_index>(
this, index);
451 _clocks[index]._before = invalid_index;
452 _clocks[index]._after = invalid_index;
453 _hands[clock] = invalid_index;
460 _clocks[index]._before = invalid_index;
461 _clocks[index]._after = invalid_index;
483 template<ClockIndex source, ClockIndex destination>
485 static_assert(source < clock_count);
486 static_assert(destination < clock_count);
487 movedIndex = invalid_index;
488 removeHead<source>(movedIndex);
492 addTail<destination>(movedIndex);
502 template<ClockIndex clock>
503 inline key_type
sizeOf() const noexcept {
504 static_assert(clock < clock_count);
515 template<ClockIndex clock>
517 static_assert(clock < clock_count);
518 return sizeOf<clock>() == 0;
529 return index != invalid_index && index >= 0 && index <=
_entryCount - 1;
554 inline value_type&
get(
const key_type& index) noexcept {
563 inline const value_type&
get(
const key_type& index)
const noexcept {
580 inline void set(
const key_type& index,
const value_type& newValue) noexcept {
595 inline void set(
const key_type& index, value_type&& newValue) noexcept {
611 inline value_type&
operator[](
const key_type& index) noexcept {
620 inline const value_type&
operator[](
const key_type& index)
const noexcept {
643 return invalid_clock_index;
648 inline const ClockIndex&
getClockIndex(
const key_type& index)
const noexcept {
652 return invalid_clock_index;
678 IndexPair(
const key_type& before,
const key_type& after) :
731 std::array<key_type, clock_count>
_hands;
737 std::array<key_type, clock_count>
_sizes;
741 #endif // __MULTI_CLOCK_HPP std::array< key_type, clock_count > _sizes
Number of elements in the clocks.
Definition: multi_clock.hpp:737
std::vector< ClockIndex > _clockMembership
Membership of indexes to clocks.
Definition: multi_clock.hpp:724
key_type _before
Key before this key.
Definition: multi_clock.hpp:687
void moveHead()
Move the clock hand forward.
Definition: multi_clock.hpp:156
#define w_assert1(x)
Level 1 should not add significant extra time.
Definition: w_base.h:198
Exception Thrown When an Access to a MultiHandedClock with an Invalid Index Happens.
Definition: multi_clock_exceptions.hpp:138
Exception thrown when a MultiHandedClock is empty.
Definition: multi_clock_exceptions.hpp:84
bool isContainedIndex(const key_type &index) const noexcept
Returns true if the specified index is contained in any clock.
Definition: multi_clock.hpp:540
Pair of keys.
Definition: multi_clock.hpp:661
bool isEmpty() const noexcept
Returns true if the specified clock is empty.
Definition: multi_clock.hpp:516
ClockIndex & getClockIndex(const key_type &index) noexcept
Returns a reference to the index of the clock where the specified index is contained in...
Definition: multi_clock.hpp:639
void addTail(key_type &&index)
Make the specified index the tail of the specified clock (with move semantics)
Definition: multi_clock.hpp:221
key_type _after
Key after this key.
Definition: multi_clock.hpp:694
IndexPair(const key_type &before, const key_type &after)
Constructor of a pair of keys with initial values.
Definition: multi_clock.hpp:678
uint32_t ClockIndex
Data type of clock indexes.
Definition: multi_clock.hpp:17
bool isValidIndex(const key_type &index) const noexcept
Returns true if the specified index is valid.
Definition: multi_clock.hpp:528
void switchHeadToTail(key_type &movedIndex)
Moves an entry from the head of one clock to the tail of another one.
Definition: multi_clock.hpp:484
void getHeadIndex(key_type &headIndex) const
Get the index of the entry where the clock hand of the specified clock points to. ...
Definition: multi_clock.hpp:133
std::vector< IndexPair > _clocks
Clocks.
Definition: multi_clock.hpp:717
IndexPair()
Constructor for an empty pair of keys.
Definition: multi_clock.hpp:668
Definition: multi_clock.hpp:11
void getHead(value_type &head) const
Get the value of the entry where the clock hand of the specified clock points to. ...
Definition: multi_clock.hpp:91
~MultiHandedClock()
Destructor of Multiple Clocks with a Common Set of Entries.
Definition: multi_clock.hpp:79
std::vector< value_type > _values
Values.
Definition: multi_clock.hpp:709
void addBefore(const key_type &inside, key_type &&newEntry)
Add the specified index before another index in an arbitrary clock (with move semantics) ...
Definition: multi_clock.hpp:300
Exception thrown when a key is already contained in a MultiHandedClock.
Definition: multi_clock_exceptions.hpp:191
MultiHandedClock(key_type entryCount)
Constructor of Multiple Clocks with a Common Set of Entries.
Definition: multi_clock.hpp:65
value_type & operator[](const key_type &index) noexcept
Returns a reference to the value that corresponds to the specified index.
Definition: multi_clock.hpp:611
const ClockIndex & getClockIndex(const key_type &index) const noexcept
Returns a reference to the index of the clock where the specified index is contained in...
Definition: multi_clock.hpp:648
void addTail(const key_type &index)
Make the specified index the__ZERO_MULTICLOCK_HPP tail of the specified clock.
Definition: multi_clock.hpp:182
void addAfter(const key_type &inside, const key_type &&newEntry)
Add the specified index after another index in an arbitrary clock (with move semantics) ...
Definition: multi_clock.hpp:378
key_type _entryCount
Number of entries the clocks can hold.
Definition: multi_clock.hpp:703
void addBefore(const key_type &inside, const key_type &newEntry)
Add the specified index before another index in an arbitrary clock.
Definition: multi_clock.hpp:261
void setHead(const value_type newValue)
Set the value of the entry where the clock hand of the specified clock points to. ...
Definition: multi_clock.hpp:113
key_type sizeOf() const noexcept
Returns the number of entries in the specified clock.
Definition: multi_clock.hpp:503
Multiple Clocks with a Common Set of Entries.
Definition: multi_clock.hpp:54
const value_type & operator[](const key_type &index) const noexcept
Returns a reference to the value that corresponds to the specified index. noexcept ...
Definition: multi_clock.hpp:620
Exception thrown when a key is not already contained in a MultiHandedClock.
Definition: multi_clock_exceptions.hpp:246
void removeHead(key_type &removedIndex)
Remove the head entry from the specified clock.
Definition: multi_clock.hpp:412
void addAfter(const key_type &inside, const key_type &newEntry)
Add the specified index after another index in an arbitrary clock.
Definition: multi_clock.hpp:339
std::array< key_type, clock_count > _hands
Clock hands.
Definition: multi_clock.hpp:731