5#include "../SqlColumnTypeDefinitions.hpp"
39 static std::optional<
SqlGuid> TryParse(std::string_view const& text) noexcept;
46 static
SqlGuid constexpr UnsafeParse(std::string_view const& text) noexcept;
49 constexpr std::weak_ordering operator<=>(
SqlGuid const& other) const noexcept = default;
52 constexpr
bool operator==(
SqlGuid const& other) const noexcept
54 return (*this <=> other) == std::weak_ordering::equivalent;
60 return !(*
this == other);
64 constexpr explicit operator bool() const noexcept
72 return !
static_cast<bool>(*this);
81 constexpr bool IsHexDigit(
char character)
noexcept
83 return (character >=
'0' && character <=
'9') || (character >=
'a' && character <=
'f')
84 || (character >=
'A' && character <=
'F');
90 constexpr bool IsWellFormedGuidText(std::string_view text)
noexcept
92 constexpr auto IsDashPosition = [](
size_t position) {
93 return position == 8 || position == 13 || position == 18 || position == 23;
95 if (text.size() != 36)
97 return std::ranges::all_of(std::views::iota(
size_t { 0 }, text.size()), [&](
size_t position) {
98 return IsDashPosition(position) ? text[position] ==
'-' : IsHexDigit(text[position]);
105 constexpr uint8_t HexDigitValue(
char character)
noexcept
107 if (character >=
'0' && character <=
'9')
108 return static_cast<uint8_t
>(character -
'0');
109 if (character >=
'a' && character <=
'f')
110 return static_cast<uint8_t
>(character -
'a' + 10);
111 return static_cast<uint8_t
>(character -
'A' + 10);
120 if (!detail::IsWellFormedGuidText(text))
126 for (
size_t const index: std::array<size_t, 16> { 0, 2, 4, 6,
130 24, 26, 28, 30, 32, 34 })
132 guid.
data[i] =
static_cast<uint8_t
>((detail::HexDigitValue(text[index]) << 4)
133 | detail::HexDigitValue(text[index + 1]));
144struct std::formatter<Lightweight::SqlGuid>: std::formatter<std::string>
146 LIGHTWEIGHT_FORCE_INLINE
auto format(
Lightweight::SqlGuid const& guid, format_context& ctx)
const
147 -> format_context::iterator
150 return formatter<std::string>::format(std::format(
151 "{:08X}-{:04X}-{:04X}-{:04X}-{:012X}",
152 (uint32_t) guid.data[3] | (uint32_t) guid.data[2] << 8 |
153 (uint32_t) guid.data[1] << 16 | (uint32_t) guid.data[0] << 24,
154 (uint16_t) guid.data[5] | (uint16_t) guid.data[4] << 8,
155 (uint16_t) guid.data[7] | (uint16_t) guid.data[6] << 8,
156 (uint16_t) guid.data[9] | (uint16_t) guid.data[8] << 8,
157 (uint64_t) guid.data[15] | (uint64_t) guid.data[14] << 8 |
158 (uint64_t) guid.data[13] << 16 | (uint64_t) guid.data[12] << 24 |
159 (uint64_t) guid.data[11] << 32 | (uint64_t) guid.data[10] << 40
170inline LIGHTWEIGHT_FORCE_INLINE std::string to_string(SqlGuid
const& guid)
172 return std::format(
"{}", guid);
189 inline void SwapGuidWireByteOrder(std::span<uint8_t, 16> data)
noexcept
195 static_assert(std::endian::native == std::endian::little);
199 std::ranges::reverse(data.first<4>());
200 std::ranges::reverse(data.subspan<4, 2>());
201 std::ranges::reverse(data.subspan<6, 2>());
206struct LIGHTWEIGHT_API SqlDataBinder<SqlGuid>
208 static constexpr auto ColumnType = SqlColumnTypeDefinitions::Guid {};
210 static SQLRETURN InputParameter(SQLHSTMT stmt,
212 SqlGuid
const& value,
213 SqlDataBinderCallback& cb)
noexcept;
215 static SQLRETURN OutputColumn(
216 SQLHSTMT stmt, SQLUSMALLINT column, SqlGuid* result, SQLLEN* indicator, SqlDataBinderCallback& cb)
noexcept;
218 static SQLRETURN GetColumn(
219 SQLHSTMT stmt, SQLUSMALLINT column, SqlGuid* result, SQLLEN* indicator, SqlDataBinderCallback
const& cb)
noexcept;
221 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(SqlGuid
const& value)
noexcept
223 return std::format(
"{}", value);
constexpr bool operator!=(SqlGuid const &other) const noexcept
Inequality comparison operator.
static SqlGuid constexpr UnsafeParse(std::string_view const &text) noexcept
constexpr bool operator!() const noexcept
Tests if the GUID is empty.
static SqlGuid Create() noexcept
Creates a new non-empty GUID.
uint8_t data[16]
The raw GUID data bytes.