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 
41  constexpr Guid() : m_data1(0U), m_data2(0U), m_data3(0U), m_data4() {}
43  explicit Guid(bool assign) : Guid() { if (assign) create(*this); }
45  constexpr Guid(std::string_view s) { fromString(s); }
46  //Constructor for const char* -- prevents trying to call bool version
47  constexpr Guid(const char *s) { fromString(s); }
49  Guid(const Guid& c) = default;
50  Guid& operator=(const Guid& c) = default;
52  auto operator<=>(const Guid&) const = default;
53  bool operator==(const Guid&) const = default;
54  bool operator==(std::string_view str) const;
55 
56  constexpr static int stringSize() { return StrLen; }
57 
59  constexpr void toString(std::span<char, StrLen> buf, bool uppercase = true) const noexcept;
60  constexpr std::string toString(bool uppercase = true) const{
61  std::string buf(Guid::string::stringSize(), ' ');
62  toString(std::span<char, stringSize()>(buf.data(), stringSize()), uppercase);
63  return buf;
64  }
65  constexpr Guid::string to_fixed_string(bool uppercase = true) const{
67  toString(buffer, uppercase);
68  return buffer;
69  }
70  static bool isGuid(std::string_view) noexcept;
72  constexpr void fromString(std::string_view s);
74  static const Guid& null() noexcept;
75 
80 
84 
86  unsigned int data1() const { return m_data1; }
87  unsigned short data2() const { return m_data2; }
88  unsigned short data3() const { return m_data3; }
89  unsigned char data4(unsigned int i) const { if (i < 8) return m_data4[i]; return 0; }
90 
92  void setData1(unsigned int data) { m_data1 = data; }
93  void setData2(unsigned short data) { m_data2 = data; }
94  void setData3(unsigned short data) { m_data3 = data; }
95  void setData4(unsigned char data, unsigned int i) { if (i < 8) m_data4[i] = data; }
96 
98  friend bool operator==( std::string_view str, const Guid& rhs) { return (rhs.operator==(str)); }
100  friend bool operator!=( std::string_view str, const Guid& rhs) { return !(rhs.operator==(str)); }
102  friend std::ostream& operator<<(std::ostream& os, const Guid& rhs);
103 
104 private:
105  constexpr void setToNull() noexcept;
106  unsigned int m_data1{};
107  unsigned short m_data2{};
108  unsigned short m_data3{};
109  std::array<unsigned char,8> m_data4{};
110 };
111 
112 //This piece of code allows std::format to deal with Guid::string without additional boilerplate
113 //This may be able to be removed in C++23
114 template <>
115 struct std::formatter<Guid::string> : std::formatter<std::string_view> {
116  constexpr auto format(const Guid::string& guid, auto& ctx) const {
117  return std::formatter<std::string_view>::format(static_cast<std::string_view>(guid), ctx);
118  }
119 };
120 
121 //This piece of code allows it to be piped into std::ostream without additional boilerplate
122 //This may be able to be removed in C++23
123 inline std::ostream& operator<<(std::ostream& os, const Guid::string& guid) {
124  return os << static_cast<std::string_view>(guid);
125 }
126 
127 constexpr void Guid::setToNull() noexcept {
128  m_data1 = 0U;
129  m_data2 = 0U;
130  m_data3 = 0U;
131  m_data4.fill('\0');
132 }
133 
134 //This is an unrolled method provided by AI, it should work to ~20ns
135 constexpr void Guid::fromString(std::string_view sv) {
136  // Trim any whitespace
137  if(std::is_constant_evaluated() && std::min(sv.find_first_not_of(' '), sv.size()) > 0){
138  throw std::runtime_error("Remove spaces from GUID");
139  }
140  sv.remove_prefix(std::min(sv.find_first_not_of(' '), sv.size()));
141  auto last_non_space = sv.find_last_not_of(' ');
142  if (last_non_space == std::string_view::npos) {
143  sv = {}; // String is empty or all spaces
144  } else {
145  if(std::is_constant_evaluated() && (sv.size() - last_non_space - 1)!=0){
146  throw std::runtime_error("Remove spaces from GUID");
147  }
148  sv.remove_suffix(sv.size() - last_non_space - 1);
149  }
150 
151  // Validate format
152  if (sv.size() != 36 ||
153  sv[8] != '-' || sv[13] != '-' || sv[18] != '-' || sv[23] != '-') {
154  setToNull();
155  if(std::is_constant_evaluated()){
156  throw std::runtime_error("failed to compile time parse GUID");
157  }
158  return;
159  }
160  bool success = true;
161  // Custom constexpr hex parser
162  auto parse_hex = [&success](std::string_view part) -> unsigned long long {
163  unsigned long long val = 0;
164  for (char c : part) {
165  val <<= 4; // Multiply by 16
166  if (c >= '0' && c <= '9') {
167  val += static_cast<unsigned long long>(c - '0');
168  } else if (c >= 'a' && c <= 'f') {
169  val += static_cast<unsigned long long>(10 + c - 'a');
170  } else if (c >= 'A' && c <= 'F') {
171  val += static_cast<unsigned long long>(10 + c - 'A');
172  } else {
173  success = false;
174  return 0;
175  }
176  }
177  return val;
178  };
179 
180  // Parse m_data1 (positions 0-7)
181  m_data1 = static_cast<unsigned int>(parse_hex(sv.substr(0, 8)));
182 
183  // Parse m_data2 (positions 9-12)
184  m_data2 = static_cast<unsigned short>(parse_hex(sv.substr(9, 4)));
185 
186  // Parse m_data3 (positions 14-17)
187  m_data3 = static_cast<unsigned short>(parse_hex(sv.substr(14, 4)));
188 
189 
190  // Parse m_data4 bytes
191  int pos = 19;
192  for(int i =0; i< 2; i++){
193  auto val = parse_hex(sv.substr(pos, 2));
194  m_data4[i] = static_cast<unsigned char>(val);
195  pos+=2;
196  }
197  //Skip the dash at pos 23
198  pos = 24;
199  for(int i =2; i< 8; i++){
200  auto val = parse_hex(sv.substr(pos, 2));
201  m_data4[i] = static_cast<unsigned char>(val);
202  pos+=2;
203  }
204 
205  if (!success) {
206  setToNull();
207  if(std::is_constant_evaluated()){
208  throw std::runtime_error("failed to compile time parse GUID");
209  }
210  }
211  return;
212 }
213 
214 //This is an unrolled method provided by ai, is should work to ~20ns
215 constexpr void Guid::toString(std::span<char, 36> buf, bool uppercase) const noexcept {
216 
217  constexpr char lowhex[] = "0123456789abcdef";
218  constexpr char uphex[] = "0123456789ABCDEF";
219  const char *hex = uppercase ? uphex : lowhex;
220 
221  // Unrolled for m_data1 (8 hex digits)
222  unsigned int v1 = m_data1;
223  buf[0] = hex[(v1 >> 28) & 0xF];
224  buf[1] = hex[(v1 >> 24) & 0xF];
225  buf[2] = hex[(v1 >> 20) & 0xF];
226  buf[3] = hex[(v1 >> 16) & 0xF];
227  buf[4] = hex[(v1 >> 12) & 0xF];
228  buf[5] = hex[(v1 >> 8) & 0xF];
229  buf[6] = hex[(v1 >> 4) & 0xF];
230  buf[7] = hex[v1 & 0xF];
231  buf[8] = '-';
232 
233  // Unrolled for m_data2 (4 hex digits)
234  unsigned short v2 = m_data2;
235  buf[9] = hex[(v2 >> 12) & 0xF];
236  buf[10] = hex[(v2 >> 8) & 0xF];
237  buf[11] = hex[(v2 >> 4) & 0xF];
238  buf[12] = hex[v2 & 0xF];
239  buf[13] = '-';
240 
241  // Unrolled for m_data3 (4 hex digits)
242  unsigned short v3 = m_data3;
243  buf[14] = hex[(v3 >> 12) & 0xF];
244  buf[15] = hex[(v3 >> 8) & 0xF];
245  buf[16] = hex[(v3 >> 4) & 0xF];
246  buf[17] = hex[v3 & 0xF];
247  buf[18] = '-';
248 
249  // Unrolled for m_data4[0] and [1] (2+2 hex digits)
250  int pos = 19;
251  for(int i =0; i<2;i++){
252  unsigned char c = m_data4[i];
253  buf[pos] = hex[c >> 4];
254  buf[pos+1] = hex[c & 0xF];
255  pos +=2;
256  }
257  buf[23] = '-';
258  pos = 24;
259  // Unrolled for remaining m_data4[2..7] (6 pairs of hex digits)
260  for(int i =2; i<8;i++){
261  unsigned char c = m_data4[i];
262  buf[pos] = hex[c >> 4];
263  buf[pos+1] = hex[c & 0xF];
264  pos +=2;
265  }
266 
267 }
268 
269 
270 namespace std {
271  template<>
272  struct hash<Guid> {
273  size_t operator()(const Guid& g) const noexcept {
274  // Treat the Guid as a 16-byte array for hashing.
275  // Checking the memory layout is contiguous and test for padding at compile time.
276  static_assert(sizeof(Guid) == (sizeof(unsigned int) + sizeof(unsigned short)
277  + sizeof(unsigned short) + sizeof(std::array<unsigned char,8>)));
278  const unsigned char* bytes = reinterpret_cast<const unsigned char*>(&g);
279  size_t hash_value = 0;
280  // Simple hash combiner: FNV-1a inspired for 128-bit data
281  constexpr size_t fnv_prime = sizeof(size_t) == 8 ? 0x100000001b3ULL : 0x01000193U;
282  constexpr size_t fnv_offset = sizeof(size_t) == 8 ? 0xcbf29ce484222325ULL : 0x811c9dc5U;
283  hash_value = fnv_offset;
284  for (size_t i = 0; i < sizeof(Guid); ++i) {
285  hash_value ^= static_cast<size_t>(bytes[i]);
286  hash_value *= fnv_prime;
287  }
288  return hash_value;
289  }
290  };
291 }
292 
293 
294 #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:56
Guid::Guid
constexpr Guid()
Standard constructor.
Definition: Guid.h:41
operator<<
std::ostream & operator<<(std::ostream &os, const Guid::string &guid)
Definition: Guid.h:123
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:92
Guid::setToNull
constexpr void setToNull() noexcept
Definition: Guid.h:127
Guid::fromString
constexpr void fromString(std::string_view s)
Automatic conversion from string representation.
Definition: Guid.h:135
Guid::Guid
constexpr Guid(const char *s)
Definition: Guid.h:47
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
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:65
Guid::m_data3
unsigned short m_data3
Definition: Guid.h:108
Guid::Guid
Guid(bool assign)
Standard constructor (With possible initialization)
Definition: Guid.h:43
Guid::operator=
Guid & operator=(const Guid &c)=default
Guid::data1
unsigned int data1() const
Allow accessors to member data.
Definition: Guid.h:86
Guid::data3
unsigned short data3() const
Definition: Guid.h:88
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:45
Guid::GuidGenByTime
@ GuidGenByTime
Definition: Guid.h:76
Guid::data2
unsigned short data2() const
Definition: Guid.h:87
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:76
Guid::operator
auto operator(const Guid &) const =default
Magic spaceship operator.
Guid::GuidGenMethod
GuidGenMethod
Definition: Guid.h:76
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:76
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
std::hash< Guid >::operator()
size_t operator()(const Guid &g) const noexcept
Definition: Guid.h:273
std::formatter< Guid::string >::format
constexpr auto format(const Guid::string &guid, auto &ctx) const
Definition: Guid.h:116
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::m_data1
unsigned int m_data1
Definition: Guid.h:106
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:77
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:86
Guid::setData3
void setData3(unsigned short data)
Definition: Guid.h:94
Guid::data4
unsigned char data4(unsigned int i) const
Definition: Guid.h:89
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:100
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:95
Guid::m_data4
std::array< unsigned char, 8 > m_data4
Definition: Guid.h:109
Guid::m_data2
unsigned short m_data2
Definition: Guid.h:107
Guid::setData2
void setData2(unsigned short data)
Definition: Guid.h:93
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:98
CP::hash_value
std::size_t hash_value(const SystematicSet &)
Hash function specifically for boost::hash.
Definition: SystematicSet.cxx:319