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 : };