Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
GUID.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Common_GUID_h_
5#define _Stroika_Foundation_Common_GUID_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <compare>
10
11#if qStroika_Foundation_Common_Platform_Windows
12#include <guiddef.h>
13#endif
14
17#include "Stroika/Foundation/Common/Common.h"
18#include "Stroika/Foundation/Common/Concepts.h"
19
20/**
21 */
22
23namespace Stroika::Foundation::Memory {
24 class BLOB; // Forward declare to avoid mutual include issues
25}
26
28
29 /**
30 * A very common 16-byte opaque ID structure.
31 *
32 * \note Satisfies Concepts:
33 * o static_assert (sizeof (GUID) == 16);
34 * o static_assert (ranges::range<GUID>);
35 * o static_assert (regular<GUID>);
36 * o static_assert (totally_ordered<GUID>);
37 *
38 * \note <a href="Design-Overview.md#Comparisons">Comparisons</a>:
39 * o static_assert (totally_ordered<GUID>);
40 */
41 struct GUID {
42 private:
43 static GUID mk_ (const string& src);
44
45 public:
46 /**
47 * \note - when converting from a string, GUID allows the leading/trailing {} to be optionally provided.
48 * - format's supported {61e4d49d-8c26-3480-f5c8-564e155c67a6}
49 * or 61e4d49d-8c26-3480-f5c8-564e155c67a6
50 * no argument CTOR, creates an all-zero GUID.
51 *
52 * @todo maybe support more input formats, such as https://stackoverflow.com/questions/7775439/is-the-format-of-guid-always-the-same
53 * @todo - should allow input format of raw bytes (though unclear of endian interpretation that would be best
54 * in that case)
55 */
56 constexpr GUID () noexcept = default;
57#if qStroika_Foundation_Common_Platform_Windows
58 constexpr GUID (const ::GUID& src) noexcept;
59#endif
60 template <Characters::IConvertibleToString STRISH_TYPE>
61 GUID (STRISH_TYPE&& src);
62 GUID (const Memory::BLOB& src);
63 GUID (const array<byte, 16>& src) noexcept;
64 GUID (const array<uint8_t, 16>& src) noexcept;
65
66 public:
67 uint32_t Data1{};
68 uint16_t Data2{};
69 uint16_t Data3{};
70 uint8_t Data4[8]{};
71
72 public:
73 using value_type = byte;
74
75 public:
76 /**
77 * \nb: Stroika v2.1 allowed iterating and modifying in place of the GUID as a sequence of bytes, but no more
78 */
79 nonvirtual const byte* begin () const noexcept;
80
81 public:
82 /**
83 * \nb: Stroika v2.1 allowed iterating and modifying in place of the GUID as a sequence of bytes, but no more
84 */
85 nonvirtual const byte* end () const noexcept;
86
87 public:
88 /**
89 */
90 constexpr size_t size () const noexcept;
91
92 public:
93 /**
94 */
95 nonvirtual explicit operator Memory::BLOB () const;
96
97 public:
98 /**
99 * Like Windows UuidCreate, or CoCreateGuid - create a random GUID (but portably).
100 */
101 static GUID GenerateNew () noexcept;
102
103 public:
104 /**
105 */
106 nonvirtual strong_ordering operator<=> (const GUID&) const noexcept = default;
107
108 public:
109 /**
110 */
111 nonvirtual const uint8_t* data () const noexcept;
112
113 public:
114 /**
115 * For now, only supported formats are
116 * o String -- format: 61e4d49d-8c26-3480-f5c8-564e155c67a6
117 * o string -- same
118 * o BLOB
119 * o array<uint8_t, 16> or array<byte, 16>
120 */
121 template <IAnyOf<Characters::String, std::string, Memory::BLOB, array<byte, 16>, array<uint8_t, 16>> T>
122 nonvirtual T As () const;
123
124 public:
125 /**
126 * @see Characters::ToString ()
127 */
128 nonvirtual Characters::String ToString () const;
129 };
130 static_assert (sizeof (GUID) == 16);
131 static_assert (ranges::range<GUID>);
132 static_assert (regular<GUID>);
133 static_assert (totally_ordered<GUID>);
134
135}
136
137/*
138 * Already default-implemented in ToString() code, but this implementation is better (because by default
139 * 'range version' used) and this takes precedence.
140 */
141template <>
142struct qStroika_Foundation_Characters_FMT_PREFIX_::formatter<Stroika::Foundation::Common::GUID, wchar_t>
143 : qStroika_Foundation_Characters_FMT_PREFIX_::formatter<std::wstring, wchar_t> {
144 using inherited = qStroika_Foundation_Characters_FMT_PREFIX_::formatter<std::wstring, wchar_t>;
145 template <class FmtContext>
146 typename FmtContext::iterator format (const Stroika::Foundation::Common::GUID& s, FmtContext& ctx) const;
147};
148template <>
149struct qStroika_Foundation_Characters_FMT_PREFIX_::formatter<Stroika::Foundation::Common::GUID, char>
150 : qStroika_Foundation_Characters_FMT_PREFIX_::formatter<std::string, char> {
151 using inherited = qStroika_Foundation_Characters_FMT_PREFIX_::formatter<std::string, char>;
152 template <class FmtContext>
153 typename FmtContext::iterator format (const Stroika::Foundation::Common::GUID& s, FmtContext& ctx) const;
154};
155
157 template <typename T>
158 struct DefaultSerializer; // Forward declare to avoid mutual include issues
159 template <>
160 struct DefaultSerializer<Stroika::Foundation::Common::GUID> {
161 Memory::BLOB operator() (const Stroika::Foundation::Common::GUID& arg) const;
162 };
163}
164
165/*
166 ********************************************************************************
167 ***************************** Implementation Details ***************************
168 ********************************************************************************
169 */
170#include "GUID.inl"
171
172#endif /*_Stroika_Foundation_Common_GUID_h_*/
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
STL namespace.
static GUID GenerateNew() noexcept
Definition GUID.cpp:76
constexpr GUID() noexcept=default
nonvirtual const byte * end() const noexcept
Definition GUID.inl:51
nonvirtual const byte * begin() const noexcept
Definition GUID.inl:47
nonvirtual Characters::String ToString() const
Definition GUID.cpp:64