1 /*
2  * Copyright (C) 1996-2021 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_BASE_INSTANCE_ID_H
10 #define SQUID_BASE_INSTANCE_ID_H
11 
12 #include <iosfwd>
13 
14 /** Identifier for class instances
15  *   - unique IDs for a large number of concurrent instances, but may wrap;
16  *   - useful for debugging and insecure request/response matching;
17  *   - sequential IDs within a class except when wrapping;
18  *   - always positive IDs.
19  *  \todo: add storage type parameter to support configurable Value types?
20  *  \todo: add creation/destruction debugging?
21  */
22 template <class Class>
23 class InstanceId
24 {
25 public:
26     typedef unsigned int Value; ///< id storage type; \todo: parameterize?
27 
InstanceId()28     InstanceId(): value(0) {change();}
29 
Value()30     operator Value() const { return value; }
31     bool operator ==(const InstanceId &o) const { return value == o.value; }
32     bool operator !=(const InstanceId &o) const { return !(*this == o); }
33     void change();
34 
35     /// prints class-pecific prefix followed by ID value; \todo: use HEX for value printing?
36     std::ostream &print(std::ostream &os) const;
37 
38     /// returns the class-pecific prefix
39     const char * const prefix() const;
40 
41 public:
42     Value value; ///< instance identifier
43 
44 private:
45     InstanceId(const InstanceId& right); ///< not implemented; IDs are unique
46     InstanceId& operator=(const InstanceId &right); ///< not implemented
47 };
48 
49 /// convenience macro to instantiate Class-specific stuff in .cc files
50 #define InstanceIdDefinitions(Class, pfx) \
51     template<> const char * const \
52     InstanceId<Class>::prefix() const { \
53         return pfx; \
54     } \
55     template<> std::ostream & \
56     InstanceId<Class>::print(std::ostream &os) const { \
57         return os << pfx << value; \
58     } \
59     template<> void \
60     InstanceId<Class>::change() { \
61         static InstanceId<Class>::Value Last = 0; \
62         value = ++Last ? Last : ++Last; \
63     }
64 
65 /// print the id
66 template <class Class>
67 inline
68 std::ostream &operator <<(std::ostream &os, const InstanceId<Class> &id)
69 {
70     return id.print(os);
71 }
72 
73 #endif /* SQUID_BASE_INSTANCE_ID_H */
74 
75