microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
uuid.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Jarosław Pelczar <jarek@jpelczar.com>
2//
3// SPDX-License-Identifier: BSD-2-Clause
4
5#pragma once
6
9#include "../microfmt.hpp"
10#include <cstddef>
11#include <cstdint>
12#include <reloco/type_id.hpp>
13#include <string_view>
14#include <type_traits>
15
16namespace microfmt {
17
18// ============================================================================
19// UUID View Definition
20// ============================================================================
21
22struct MICROFMT_API_CLASS RELOCO_POINTER uuid_view {
23 span<const uint8_t> bytes{}; // 16 bytes
24 bool uppercase{false};
25 bool braced{false}; // Wrap in { ... }
26};
27
28// ============================================================================
29// Core Formatter Logic
30// ============================================================================
31
32namespace detail {
33MICROFMT_API void format_uuid_bytes(const sink &out, span<const uint8_t> bytes, bool is_upper, bool is_braced) noexcept;
34
35#if MICROFMT_SHARED_PROVIDE_DEFINITIONS
36#include "uuid.ipp"
37#endif
38
39template <typename T, typename = void> struct is_uuid_container : std::false_type {};
40
41template <typename T>
43 T, std::void_t<decltype(std::declval<const T &>().data()), decltype(std::declval<const T &>().size())>>
44 : std::integral_constant<bool, std::is_convertible_v<decltype(std::declval<const T &>().data()), const uint8_t *> &&
45 std::is_convertible_v<decltype(std::declval<const T &>().size()), size_t>> {};
46} // namespace detail
47
48// ============================================================================
49// Factory Helpers (All Overloads)
50// ============================================================================
51
52// From raw byte span / pointer + size
53[[nodiscard]] constexpr uuid_view uuid(span<const uint8_t> b, bool uppercase = false, bool braced = false) noexcept {
54 return uuid_view{b, uppercase, braced};
55}
56
57// From raw 16-byte C-array
58[[nodiscard]] constexpr uuid_view uuid(const uint8_t (&arr)[16], bool uppercase = false, bool braced = false) noexcept {
59 return uuid_view{span<const uint8_t>(arr, 16), uppercase, braced};
60}
61
62// From 16-byte reloco::array or contiguous container
63template <typename ArrayT, std::enable_if_t<detail::is_uuid_container<ArrayT>::value, int> = 0>
64[[nodiscard]] constexpr uuid_view uuid(const ArrayT &arr, bool uppercase = false, bool braced = false) noexcept {
65 return uuid_view{span<const uint8_t>(arr.data(), arr.size()), uppercase, braced};
66}
67
68template <typename ArrayT, std::enable_if_t<!std::is_lvalue_reference_v<ArrayT> &&
69 detail::is_uuid_container<std::remove_reference_t<ArrayT>>::value,
70 int> = 0>
71[[nodiscard]] constexpr uuid_view uuid(ArrayT &&, bool = false, bool = false) noexcept = delete;
72
73#if MICROFMT_HAS_BOOST_UUID
74// From boost::uuids::uuid
75[[nodiscard]] constexpr uuid_view uuid(const boost::uuids::uuid &u, bool uppercase = false,
76 bool braced = false) noexcept {
77 return uuid_view{span<const uint8_t>(u.data, 16), uppercase, braced};
78}
79
80[[nodiscard]] constexpr uuid_view uuid(boost::uuids::uuid &&, bool = false, bool = false) noexcept = delete;
81#endif
82
83// ============================================================================
84// Formatter Specializations
85// ============================================================================
86
87template <> struct formatter<uuid_view> {
88 bool uppercase{false};
89 bool braced{false};
90
91 constexpr void parse(format_parse_context &ctx) noexcept {
92 for (char c : ctx.spec()) {
93 if (c == 'X')
94 uppercase = true;
95 if (c == '#')
96 braced = true;
97 }
98 }
99
100 void format(const uuid_view &u, const sink &out) const noexcept {
101 detail::format_uuid_bytes(out, u.bytes, u.uppercase || uppercase, u.braced || braced);
102 }
103};
104
105#if MICROFMT_HAS_BOOST_UUID
106template <> struct formatter<boost::uuids::uuid> {
107 bool uppercase{false};
108 bool braced{false};
109
110 constexpr void parse(format_parse_context &ctx) noexcept {
111 for (char c : ctx.spec()) {
112 if (c == 'X')
113 uppercase = true;
114 if (c == '#')
115 braced = true;
116 }
117 }
118
119 void format(const boost::uuids::uuid &u, const sink &out) const noexcept {
120 detail::format_uuid_bytes(out, span<const uint8_t>(u.data, 16), uppercase, braced);
121 }
122};
123#endif
124
125} // namespace microfmt
126
127// See <reloco/type_id.hpp> for the full RELOCO_TYPE_ID_NAME rationale;
128// defined here, alongside uuid_view's own definition.
Definition microfmt.hpp:881
#define MICROFMT_API_CLASS
Definition compat.hpp:181
#define MICROFMT_API
Definition compat.hpp:135
MICROFMT_API void format_uuid_bytes(const sink &out, span< const uint8_t > bytes, bool is_upper, bool is_braced) noexcept
Definition assert.hpp:19
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
constexpr uuid_view uuid(span< const uint8_t > b, bool uppercase=false, bool braced=false) noexcept
Definition uuid.hpp:53
RELOCO_CONSTEXPR20 buffer_sink< N > format(microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1786
constexpr bytes_view bytes(uint64_t count) noexcept
Definition format_helpers.hpp:82
void format(const uuid_view &u, const sink &out) const noexcept
Definition uuid.hpp:100
constexpr void parse(format_parse_context &ctx) noexcept
Definition uuid.hpp:91
Definition microfmt.hpp:985
Definition uuid.hpp:22
RELOCO_TYPE_ID_NAME(microfmt::uuid_view, "microfmt::uuid_view")