]>
Commit | Line | Data |
---|---|---|
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 |