Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <functional>
8 : #include <optional>
9 : #include <ostream>
10 : #include <pup.h>
11 :
12 : #include "Utilities/Serialization/PupStlCpp17.hpp"
13 :
14 : /// \ingroup DataStructuresGroup
15 : /// An identifier for an element in a sequence
16 : ///
17 : /// The struct contains an ID and the ID for the previous element of
18 : /// the sequence, if any. This allows the sequence to be
19 : /// reconstructed even when elements are received out-of-order.
20 : ///
21 : /// \see LinkedMessageQueue
22 : template <typename Id>
23 1 : struct LinkedMessageId {
24 0 : Id id;
25 0 : std::optional<Id> previous;
26 :
27 : // NOLINTNEXTLINE(google-runtime-references)
28 0 : void pup(PUP::er& p) {
29 : p | id;
30 : p | previous;
31 : }
32 : };
33 :
34 : template <typename Id>
35 0 : bool operator==(const LinkedMessageId<Id>& a, const LinkedMessageId<Id>& b) {
36 : return a.id == b.id and a.previous == b.previous;
37 : }
38 :
39 : template <typename Id>
40 0 : bool operator!=(const LinkedMessageId<Id>& a, const LinkedMessageId<Id>& b) {
41 : return not(a == b);
42 : }
43 :
44 : template <typename Id>
45 0 : std::ostream& operator<<(std::ostream& s, const LinkedMessageId<Id>& id) {
46 : return s << id.id << " (" << id.previous << ")";
47 : }
48 :
49 : template <typename Id>
50 : struct std::hash<LinkedMessageId<Id>> {
51 : size_t operator()(const LinkedMessageId<Id>& id) const {
52 : // For normal use, any particular .id should only appear with one
53 : // .previous, and vice versa, so hashing only one is fine.
54 : return std::hash<Id>{}(id.id);
55 : }
56 : };
57 :
58 : template <typename Id>
59 0 : struct LinkedMessageIdLessComparator {
60 0 : using is_transparent = std::true_type;
61 0 : bool operator()(const Id& id,
62 : const LinkedMessageId<Id>& linked_message_id) const {
63 : return id < linked_message_id.id;
64 : }
65 0 : bool operator()(const LinkedMessageId<Id>& lhs,
66 : const LinkedMessageId<Id>& rhs) const {
67 : return lhs.id < rhs.id or
68 : (lhs.id == rhs.id and lhs.previous < rhs.previous);
69 : }
70 0 : bool operator()(const LinkedMessageId<Id>& linked_message_id,
71 : const Id& id) const {
72 : return linked_message_id.id < id;
73 : }
74 : };
75 :
76 : template <typename Id>
77 0 : bool operator<(const LinkedMessageId<Id>& lhs, const LinkedMessageId<Id>& rhs) {
78 : return LinkedMessageIdLessComparator<Id>{}(lhs, rhs);
79 : }
|