ATLAS Offline Software
Guid.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #ifndef PERSISTENTDATAMODEL_GUID_H
6 #define PERSISTENTDATAMODEL_GUID_H
7 
13 #include <iosfwd> // for std::ostream
14 #include <string>
15 #include <array>
16 #include <stdexcept>
17 #include <type_traits>
18 #include <span>
19 #include <algorithm>
20 #include <format>
21 
25 class Guid {
26 public:
27  static constexpr size_t StrLen = 36;
31  class string : public std::array<char, StrLen> {
32  public:
33  constexpr operator std::string_view() const {
34  return std::string_view(data(), size());
35  }
36  constexpr std::string_view sv() const {return std::string_view(data(), size());}
37  static constexpr int stringSize() { return StrLen; }
38  };
39 
40  //Remove FallBack code if there is no need for it is discovered
41  struct FallBack{};
43  constexpr Guid() : m_data1(0U), m_data2(0U), m_data3(0U), m_data4() {}
45  explicit Guid(bool assign) : Guid() { if (assign) create(*this); }
46 
47  //Use this constructor if you find an old malformed Guid and can't correct it
48  Guid(const std::string& s, FallBack) { fromStringFallBack(s); }
50  constexpr Guid(std::string_view s) { fromString(s); }
51  //Constructor for const char* -- prevents trying to call bool version
52  constexpr Guid(const char *s) { fromString(s); }
54  Guid(const Guid& c) = default;
55  Guid& operator=(const Guid& c) = default;
57  auto operator<=>(const Guid&) const = default;
58  bool operator==(const Guid&) const = default;
59  bool operator==(std::string_view str) const;
60 
61  constexpr static int stringSize() { return StrLen; }
62 
64  constexpr void toString(std::span<char, StrLen> buf, bool uppercase = true) const noexcept;
65  constexpr std::string toString(bool uppercase = true) const{
66  std::string buf(Guid::string::stringSize(), ' ');
67  toString(std::span<char, stringSize()>(buf.data(), stringSize()), uppercase);
68  return buf;
69  }
70  constexpr Guid::string to_fixed_string(bool uppercase = true) const{
72  toString(buffer, uppercase);
73  return buffer;
74  }
75  static bool isGuid(std::string_view) noexcept;
77  constexpr void fromString(std::string_view s);
78 
79  void fromStringFallBack(const std::string&);
80 
82  static const Guid& null() noexcept;
83 
88 
92 
94  unsigned int data1() const { return m_data1; }
95  unsigned short data2() const { return m_data2; }
96  unsigned short data3() const { return m_data3; }
97  unsigned char data4(unsigned int i) const { if (i < 8) return m_data4[i]; return 0; }
98 
100  void setData1(unsigned int data) { m_data1 = data; }
101  void setData2(unsigned short data) { m_data2 = data; }
102  void setData3(unsigned short data) { m_data3 = data; }
103  void setData4(unsigned char data, unsigned int i) { if (i < 8) m_data4[i] = data; }
104 
106  friend bool operator==( std::string_view str, const Guid& rhs) { return (rhs.operator==(str)); }
108  friend bool operator!=( std::string_view str, const Guid& rhs) { return !(rhs.operator==(str)); }
110  friend std::ostream& operator<<(std::ostream& os, const Guid& rhs);
111 
112 private:
113  constexpr void setToNull() noexcept;
114  unsigned int m_data1{};
115  unsigned short m_data2{};
116  unsigned short m_data3{};
117  std::array<unsigned char,8> m_data4{};
118 };
119 
120 //This piece of code allows std::format to deal with Guid::string without additional boilerplate
121 //This may be able to be removed in C++23
122 template <>
123 struct std::formatter<Guid::string> : std::formatter<std::string_view> {
124  constexpr auto format(const Guid::string& guid, auto& ctx) const {
125  return std::formatter<std::string_view>::format(static_cast<std::string_view>(guid), ctx);
126  }
127 };
128 
129 //This piece of code allows it to be piped into std::ostream without additional boilerplate
130 //This may be able to be removed in C++23
131 inline std::ostream& operator<<(std::ostream& os, const Guid::string& guid) {
132  return os << static_cast<std::string_view>(guid);
133 }
134 
135 constexpr void Guid::setToNull() noexcept {
136  m_data1 = 0U;
137  m_data2 = 0U;
138  m_data3 = 0U;
139  m_data4.fill('\0');
140 }
141 
142 //This is an unrolled method provided by AI, it should work to ~20ns
143 constexpr void Guid::fromString(std::string_view sv) {
144  // Trim any whitespace
145  if(std::is_constant_evaluated() && std::min(sv.find_first_not_of(' '), sv.size()) > 0){
146  throw std::runtime_error("Remove spaces from GUID");
147  }
148  sv.remove_prefix(std::min(sv.find_first_not_of(' '), sv.size()));
149  auto last_non_space = sv.find_last_not_of(' ');
150  if (last_non_space == std::string_view::npos) {
151  sv = {}; // String is empty or all spaces
152  } else {
153  if(std::is_constant_evaluated() && (sv.size() - last_non_space - 1)!=0){
154  throw std::runtime_error("Remove spaces from GUID");
155  }
156  sv.remove_suffix(sv.size() - last_non_space - 1);
157  }
158 
159  // Validate format
160  if (sv.size() != 36 ||
161  sv[8] != '-' || sv[13] != '-' || sv[18] != '-' || sv[23] != '-') {
162  setToNull();
163  if(std::is_constant_evaluated()){
164  throw std::runtime_error("failed to compile time parse GUID");
165  }
166  return;
167  }
168  bool success = true;
169  // Custom constexpr hex parser
170  auto parse_hex = [&success](std::string_view part) -> unsigned long long {
171  unsigned long long val = 0;
172  for (char c : part) {
173  val <<= 4; // Multiply by 16
174  if (c >= '0' && c <= '9') {
175  val += static_cast<unsigned long long>(c - '0');
176  } else if (c >= 'a' && c <= 'f') {
177  val += static_cast<unsigned long long>(10 + c - 'a');
178  } else if (c >= 'A' && c <= 'F') {
179  val += static_cast<unsigned long long>(10 + c - 'A');
180  } else {
181  success = false;
182  return 0;
183  }
184  }
185  return val;
186  };
187 
188  // Parse m_data1 (positions 0-7)
189  m_data1 = static_cast<unsigned int>(parse_hex(sv.substr(0, 8)));
190 
191  // Parse m_data2 (positions 9-12)
192  m_data2 = static_cast<unsigned short>(parse_hex(sv.substr(9, 4)));
193 
194  // Parse m_data3 (positions 14-17)
195  m_data3 = static_cast<unsigned short>(parse_hex(sv.substr(14, 4)));
196 
197 
198  // Parse m_data4 bytes
199  int pos = 19;
200  for(int i =0; i< 2; i++){
201  auto val = parse_hex(sv.substr(pos, 2));
202  m_data4[i] = static_cast<unsigned char>(val);
203  pos+=2;
204  }
205  //Skip the dash at pos 23
206  pos = 24;
207  for(int i =2; i< 8; i++){
208  auto val = parse_hex(sv.substr(pos, 2));
209  m_data4[i] = static_cast<unsigned char>(val);
210  pos+=2;
211  }
212 
213  if (!success) {
214  setToNull();
215  if(std::is_constant_evaluated()){
216  throw std::runtime_error("failed to compile time parse GUID");
217  }
218  }
219  return;
220 }
221 
222 //This is an unrolled method provided by ai, is should work to ~20ns
223 constexpr void Guid::toString(std::span<char, 36> buf, bool uppercase) const noexcept {
224 
225  constexpr char lowhex[] = "0123456789abcdef";
226  constexpr char uphex[] = "0123456789ABCDEF";
227  const char *hex = uppercase ? uphex : lowhex;
228 
229  // Unrolled for m_data1 (8 hex digits)
230  unsigned int v1 = m_data1;
231  buf[0] = hex[(v1 >> 28) & 0xF];
232  buf[1] = hex[(v1 >> 24) & 0xF];
233  buf[2] = hex[(v1 >> 20) & 0xF];
234  buf[3] = hex[(v1 >> 16) & 0xF];
235  buf[4] = hex[(v1 >> 12) & 0xF];
236  buf[5] = hex[(v1 >> 8) & 0xF];
237  buf[6] = hex[(v1 >> 4) & 0xF];
238  buf[7] = hex[v1 & 0xF];
239  buf[8] = '-';
240 
241  // Unrolled for m_data2 (4 hex digits)
242  unsigned short v2 = m_data2;
243  buf[9] = hex[(v2 >> 12) & 0xF];
244  buf[10] = hex[(v2 >> 8) & 0xF];
245  buf[11] = hex[(v2 >> 4) & 0xF];
246  buf[12] = hex[v2 & 0xF];
247  buf[13] = '-';
248 
249  // Unrolled for m_data3 (4 hex digits)
250  unsigned short v3 = m_data3;
251  buf[14] = hex[(v3 >> 12) & 0xF];
252  buf[15] = hex[(v3 >> 8) & 0xF];
253  buf[16] = hex[(v3 >> 4) & 0xF];
254  buf[17] = hex[v3 & 0xF];
255  buf[18] = '-';
256 
257  // Unrolled for m_data4[0] and [1] (2+2 hex digits)
258  int pos = 19;
259  for(int i =0; i<2;i++){
260  unsigned char c = m_data4[i];
261  buf[pos] = hex[c >> 4];
262  buf[pos+1] = hex[c & 0xF];
263  pos +=2;
264  }
265  buf[23] = '-';
266  pos = 24;
267  // Unrolled for remaining m_data4[2..7] (6 pairs of hex digits)
268  for(int i =2; i<8;i++){
269  unsigned char c = m_data4[i];
270  buf[pos] = hex[c >> 4];
271  buf[pos+1] = hex[c & 0xF];
272  pos +=2;
273  }
274 
275 }
276 
277 
278 namespace std {
279  template<>
280  struct hash<Guid> {
281  size_t operator()(const Guid& g) const noexcept {
282  // Treat the Guid as a 16-byte array for hashing.
283  // Checking the memory layout is contiguous and test for padding at compile time.
284  static_assert(sizeof(Guid) == (sizeof(unsigned int) + sizeof(unsigned short)
285  + sizeof(unsigned short) + sizeof(std::array<unsigned char,8>)));
286  const unsigned char* bytes = reinterpret_cast<const unsigned char*>(&g);
287  size_t hash_value = 0;
288  // Simple hash combiner: FNV-1a inspired for 128-bit data
289  constexpr size_t fnv_prime = sizeof(size_t) == 8 ? 0x100000001b3ULL : 0x01000193U;
290  constexpr size_t fnv_offset = sizeof(size_t) == 8 ? 0xcbf29ce484222325ULL : 0x811c9dc5U;
291  hash_value = fnv_offset;
292  for (size_t i = 0; i < sizeof(Guid); ++i) {
293  hash_value ^= static_cast<size_t>(bytes[i]);
294  hash_value *= fnv_prime;
295  }
296  return hash_value;
297  }
298  };
299 }
300 
301 
302 #endif
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
Guid::operator==
bool operator==(const Guid &) const =default
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
CxxUtils::span
span(T *ptr, std::size_t sz) -> span< T >
A couple needed deduction guides.
Guid::stringSize
constexpr static int stringSize()
Definition: Guid.h:61
Guid::Guid
constexpr Guid()
Standard constructor.
Definition: Guid.h:43
operator<<
std::ostream & operator<<(std::ostream &os, const Guid::string &guid)
Definition: Guid.h:131
vtune_athena.format
format
Definition: vtune_athena.py:14
Guid::initGuidGenMethod
static GuidGenMethod initGuidGenMethod()
Checks for POOL_GUID_TIME or POOL_GUID_RANDOM env variables.
Definition: Guid.cxx:20
Guid::setData1
void setData1(unsigned int data)
Allow modifiers for member data.
Definition: Guid.h:100
Guid::setToNull
constexpr void setToNull() noexcept
Definition: Guid.h:135
Guid::fromString
constexpr void fromString(std::string_view s)
Automatic conversion from string representation.
Definition: Guid.h:143
Guid::Guid
constexpr Guid(const char *s)
Definition: Guid.h:52
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
Guid::StrLen
static constexpr size_t StrLen
Definition: Guid.h:27
Guid::string::stringSize
static constexpr int stringSize()
Definition: Guid.h:37
Guid::Guid
Guid(const std::string &s, FallBack)
Definition: Guid.h:48
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
Guid::to_fixed_string
constexpr Guid::string to_fixed_string(bool uppercase=true) const
Definition: Guid.h:70
Guid::fromStringFallBack
void fromStringFallBack(const std::string &)
Definition: Guid.cxx:86
Guid::m_data3
unsigned short m_data3
Definition: Guid.h:116
Guid::Guid
Guid(bool assign)
Standard constructor (With possible initialization)
Definition: Guid.h:45
Guid::operator=
Guid & operator=(const Guid &c)=default
Guid::data1
unsigned int data1() const
Allow accessors to member data.
Definition: Guid.h:94
Guid::data3
unsigned short data3() const
Definition: Guid.h:96
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
pool::Guid
::Guid Guid
Definition: T_AthenaPoolCustCnv.h:19
Guid::Guid
constexpr Guid(std::string_view s)
Constructor for Guid from string_view.
Definition: Guid.h:50
Guid::GuidGenByTime
@ GuidGenByTime
Definition: Guid.h:84
Guid::data2
unsigned short data2() const
Definition: Guid.h:95
Guid::create
static void create(Guid &guid, GuidGenMethod method=GuidGenDefault)
Create a new Guid default method is currently Random, can be changed by param, API or environment.
Definition: Guid.cxx:29
Guid::toString
constexpr void toString(std::span< char, StrLen > buf, bool uppercase=true) const noexcept
Automatic conversion to string representation.
createCoolChannelIdFile.buffer
buffer
Definition: createCoolChannelIdFile.py:11
Guid::GuidGenRandom
@ GuidGenRandom
Definition: Guid.h:84
Guid::operator
auto operator(const Guid &) const =default
Magic spaceship operator.
Guid::GuidGenMethod
GuidGenMethod
Definition: Guid.h:84
lumiFormat.i
int i
Definition: lumiFormat.py:85
python.DecayParser.buf
buf
print ("=> [%s]"cmd)
Definition: DecayParser.py:26
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
Guid::GuidGenDefault
@ GuidGenDefault
Definition: Guid.h:84
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
std::hash< Guid >::operator()
size_t operator()(const Guid &g) const noexcept
Definition: Guid.h:281
std::formatter< Guid::string >::format
constexpr auto format(const Guid::string &guid, auto &ctx) const
Definition: Guid.h:124
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
pool_uuid.guid
guid
Definition: pool_uuid.py:112
lumiFormat.array
array
Definition: lumiFormat.py:91
vtune_athena.formatter
formatter
Definition: vtune_athena.py:19
Guid::FallBack
Definition: Guid.h:41
Guid::m_data1
unsigned int m_data1
Definition: Guid.h:114
Guid::string::sv
constexpr std::string_view sv() const
Definition: Guid.h:36
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
Guid
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
Definition: Guid.h:25
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
Guid::string
A class designed to facilitate exchange of Guid::string objects without additional allocations.
Definition: Guid.h:31
Guid::m_guidGenMethod
static const GuidGenMethod m_guidGenMethod
Definition: Guid.h:85
Guid::Guid
Guid(const Guid &c)=default
Copy constructor.
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
Guid::operator<<
friend std::ostream & operator<<(std::ostream &os, const Guid &rhs)
Extraction operators.
Definition: Guid.cxx:106
Guid::setData3
void setData3(unsigned short data)
Definition: Guid.h:102
Guid::data4
unsigned char data4(unsigned int i) const
Definition: Guid.h:97
LArCellConditions.sv
bool sv
Definition: LArCellConditions.py:45
Guid::operator!=
friend bool operator!=(std::string_view str, const Guid &rhs)
Non-equality operator.
Definition: Guid.h:108
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
str
Definition: BTagTrackIpAccessor.cxx:11
Guid::setData4
void setData4(unsigned char data, unsigned int i)
Definition: Guid.h:103
Guid::m_data4
std::array< unsigned char, 8 > m_data4
Definition: Guid.h:117
Guid::m_data2
unsigned short m_data2
Definition: Guid.h:115
Guid::setData2
void setData2(unsigned short data)
Definition: Guid.h:101
Guid::isGuid
static bool isGuid(std::string_view) noexcept
Definition: Guid.cxx:54
python.compressB64.c
def c
Definition: compressB64.py:93
Guid::operator==
friend bool operator==(std::string_view str, const Guid &rhs)
Equality operator.
Definition: Guid.h:106
CP::hash_value
std::size_t hash_value(const SystematicSet &)
Hash function specifically for boost::hash.
Definition: SystematicSet.cxx:319