]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/InstanceId.h
a918f73b73293e9e7d9c5b969535f291f02475f6
[thirdparty/squid.git] / src / base / InstanceId.h
1 /*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID_SRC_BASE_INSTANCEID_H
10 #define SQUID_SRC_BASE_INSTANCEID_H
11
12 #include <iosfwd>
13
14 /// Represents an InstanceId<C> value independent from its owner class C. These
15 /// "detached" IDs can be stored by and exchanged among C-unaware users at the
16 /// price of storing a short scope c-string (that InstanceIds hard-code instead)
17 /// and, in some cases, using more bits/space than InstanceId<C>::value uses.
18 class ScopedId
19 {
20 public:
21 ScopedId(): scope(nullptr), value(0) {}
22 explicit ScopedId(const char *s): scope(s), value(0) {}
23 // when the values is zero/unknown, use other constructors
24 ScopedId(const char *s, uint64_t v): scope(s), value(v) { /* assert(value) */ }
25
26 /// either the prefix() of the InstanceId object that we were detached from
27 /// or, for 0 values, some other description (with endless lifetime) or nil
28 const char *scope;
29
30 /// either the value of the InstanceId object that we were detached from
31 /// or, if our creator did not know the exact value, zero
32 uint64_t value;
33 };
34
35 std::ostream &operator <<(std::ostream &os, const ScopedId &id);
36
37 typedef unsigned int InstanceIdDefaultValueType;
38 /** Identifier for class instances
39 * - unique IDs for a large number of concurrent instances, but may wrap;
40 * - useful for debugging and insecure request/response matching;
41 * - sequential IDs within a class except when wrapping;
42 * - always positive IDs.
43 * TODO: add creation/destruction debugging?
44 */
45 template <class Class, class ValueType = InstanceIdDefaultValueType>
46 class InstanceId
47 {
48 public:
49 typedef ValueType Value; ///< id storage type
50
51 InstanceId() {change();}
52 InstanceId(InstanceId &&) = delete; // no copying/moving of any kind
53
54 operator Value() const { return value; }
55 bool operator ==(const InstanceId &o) const { return value == o.value; }
56 bool operator !=(const InstanceId &o) const { return !(*this == o); }
57 void change();
58
59 /// writes a compact text representation of the ID
60 std::ostream &print(std::ostream &) const;
61
62 // TODO: Refactor into static Scope().
63 /// \returns Class-specific nickname (with endless lifetime)
64 const char * prefix() const;
65
66 /// \returns a copy of the ID usable outside our Class context
67 ScopedId detach() const { return ScopedId(prefix(), value); }
68
69 public:
70 Value value = Value(); ///< instance identifier
71 };
72
73 /// An InstanceIdDefinitions() helper. Avoid direct use.
74 #define InstanceIdDefinitions3(Class, pfx, ValueType, ...) \
75 template<> const char * \
76 InstanceId<Class, ValueType>::prefix() const { \
77 return pfx; \
78 } \
79 template<> std::ostream & \
80 InstanceId<Class, ValueType>::print(std::ostream &os) const { \
81 return os << pfx << value; \
82 } \
83 template<> void \
84 InstanceId<Class, ValueType>::change() { \
85 static auto Last = Value(); \
86 value = ++Last ? Last : ++Last; \
87 }
88
89 /// convenience macro to instantiate Class-specific stuff in .cc files
90 #define InstanceIdDefinitions(...) InstanceIdDefinitions3(__VA_ARGS__, InstanceIdDefaultValueType)
91
92 /// print the id
93 template <class Class, class ValueType>
94 inline
95 std::ostream &operator <<(std::ostream &os, const InstanceId<Class, ValueType> &id)
96 {
97 return id.print(os);
98 }
99
100 #endif /* SQUID_SRC_BASE_INSTANCEID_H */
101