neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
uuid.hpp
Go to the documentation of this file.
1// uuid.hpp - v1.1
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <string>
40#include <cstdint>
41#include <array>
42#include <tuple>
43#include <utility>
44#include <iostream>
45#include <sstream>
46#include <iomanip>
47
48namespace neolib
49{
50 struct uuid
51 {
53 uint32_t part1;
54 uint16_t part2;
55 uint16_t part3;
56 uint16_t part4;
57 std::array<uint8_t, 6> part5;
58
59 auto operator<=>(const uuid&) const = default;
60 };
61
62 inline uuid make_uuid(const std::string& aHyphenatedHexString /* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */)
63 {
64 uuid result;
65 result.part1 = static_cast<uint32_t>(std::strtoul(aHyphenatedHexString.substr(0, 8).c_str(), 0, 16));
66 result.part2 = static_cast<uint16_t>(std::strtoul(aHyphenatedHexString.substr(9, 4).c_str(), 0, 16));
67 result.part3 = static_cast<uint16_t>(std::strtoul(aHyphenatedHexString.substr(14, 4).c_str(), 0, 16));
68 result.part4 = static_cast<uint16_t>(std::strtoul(aHyphenatedHexString.substr(19, 4).c_str(), 0, 16));
69 uint64_t bytes = static_cast<uint64_t>(std::strtoull(aHyphenatedHexString.substr(24, 12).c_str(), 0, 16));
70 for (size_t i = 0; i <= 5; ++i)
71 result.part5[i] = static_cast<uint8_t>((bytes >> (5 - i) * 8) & 0xFF);
72 return result;
73 }
74
75 struct unable_to_generate_uuid : std::runtime_error { unable_to_generate_uuid() : std::runtime_error("neolib::unable_to_generate_uuid") {} };
76
77 NEOLIB_EXPORT uuid generate_uuid();
78
79 inline std::istream& operator>>(std::istream& aStream, uuid& aId)
80 {
81 std::string hyphenatedHexString;
82 aStream >> hyphenatedHexString;
83 aId = make_uuid(hyphenatedHexString);
84 return aStream;
85 }
86
87 inline std::ostream& operator<<(std::ostream& aStream, const uuid& aId)
88 {
89 char oldFill = aStream.fill('0');
90 aStream << std::hex << std::uppercase << std::setw(8) << aId.part1 << "-";
91 aStream << std::hex << std::uppercase << std::setw(4) << aId.part2 << "-";
92 aStream << std::hex << std::uppercase << std::setw(4) << aId.part3 << "-";
93 aStream << std::hex << std::uppercase << std::setw(4) << aId.part4 << "-";
94 for (size_t i = 0; i <= 5; ++i)
95 aStream << std::hex << std::uppercase << std::setw(2) << static_cast<uint32_t>(aId.part5[i]);
96 aStream << std::dec;
97 aStream.fill(oldFill);
98 return aStream;
99 }
100
101 inline std::string uuid_to_string(const uuid& aId)
102 {
103 std::ostringstream oss;
104 oss << aId;
105 return oss.str();
106 }
107
109 {
111 typedef std::size_t result_type;
113 {
114 return aUuid.part1;
115 }
116 };
117}
118
119namespace std
120{
121 template <> struct hash<neolib::uuid>
122 {
124 typedef std::size_t result_type;
126 {
127 if constexpr (sizeof(std::size_t) == sizeof(uint64_t))
128 {
129 // type punning is serious business...
130 struct badf00d
131 {
132 uint64_t bat;
133 uint64_t pangolin;
134 };
135 badf00d covid19;
136 std::memcpy(&covid19, &aUuid, sizeof(covid19));
137 return covid19.bat ^ covid19.pangolin;
138 }
139 else
140 {
141 // type punning is serious business...
142 struct badf00d
143 {
144 uint32_t bat1;
145 uint32_t bat2;
146 uint32_t pangolin1;
147 uint32_t pangolin2;
148 };
149 badf00d covid19;
150 std::memcpy(&covid19, &aUuid, sizeof(covid19));
151 return covid19.bat1 ^ covid19.bat2 ^ covid19.pangolin1 ^ covid19.pangolin2;
152 }
153 }
154 };
155}
std::string uuid_to_string(const uuid &aId)
Definition uuid.hpp:101
uuid make_uuid(const std::string &aHyphenatedHexString)
Definition uuid.hpp:62
NEOLIB_EXPORT uuid generate_uuid()
Definition plf_hive.h:79
neolib::uuid argument_type
Definition uuid.hpp:110
result_type operator()(argument_type const &aUuid) const
Definition uuid.hpp:112
std::size_t result_type
Definition uuid.hpp:111
auto operator<=>(const uuid &) const =default
uint16_t part4
Definition uuid.hpp:56
uint32_t part1
Definition uuid.hpp:53
std::array< uint8_t, 6 > part5
Definition uuid.hpp:57
uuid abstract_type
Definition uuid.hpp:52
uint16_t part2
Definition uuid.hpp:54
uint16_t part3
Definition uuid.hpp:55
result_type operator()(argument_type const &aUuid) const
Definition uuid.hpp:125
neolib::uuid argument_type
Definition uuid.hpp:123
std::size_t result_type
Definition uuid.hpp:124