userver: userver/utils/statistics/labels.hpp Source File
Loading...
Searching...
No Matches
labels.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/statistics/labels.hpp
4/// @brief Owning and non owning labels representations.
5
6#include <string>
7#include <string_view>
8#include <type_traits>
9
10#include <fmt/format.h>
11
12#include <userver/utils/assert.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16namespace utils::statistics {
17
18class Label;
19
20/// @ingroup userver_universal
21///
22/// @brief Non owning label name+value storage.
23class LabelView final {
24public:
25 LabelView() = delete;
26 LabelView(Label&& label) = delete;
27 explicit LabelView(const Label& label);
28 constexpr LabelView(std::string_view name, std::string_view value)
29 : name_(name),
30 value_(value)
31 {
32 UINVARIANT(!name_.empty(), "The label name must not be empty.");
33 }
34
35 template <class T, std::enable_if_t<std::is_arithmetic_v<T>>* = nullptr>
36 constexpr LabelView(std::string_view, T) {
37 static_assert(sizeof(T) && false, "Labels should not be arithmetic values, only strings!");
38 }
39
40 constexpr explicit operator bool() const { return !name_.empty(); }
41
42 constexpr std::string_view Name() const { return name_; }
43 constexpr std::string_view Value() const { return value_; }
44
45private:
46 std::string_view name_{};
47 std::string_view value_{};
48};
49
50bool operator<(const LabelView& x, const LabelView& y) noexcept;
51bool operator==(const LabelView& x, const LabelView& y) noexcept;
52
53/// @ingroup userver_universal
54///
55/// @brief Label name+value storage.
56class Label final {
57public:
58 Label() = default;
59 explicit Label(LabelView view);
60 Label(std::string name, std::string value);
61
62 template <class T, std::enable_if_t<std::is_arithmetic_v<T>>* = nullptr>
63 Label(std::string, T) {
64 static_assert(sizeof(T) && false, "Labels should not be arithmetic values, only strings!");
65 }
66
67 explicit operator bool() const { return !name_.empty(); }
68 explicit operator LabelView() const { return {name_, value_}; }
69
70 const std::string& Name() const { return name_; }
71 const std::string& Value() const& { return value_; }
72 std::string& Value() & { return value_; }
73 std::string&& Value() && { return std::move(value_); }
74
75private:
76 std::string name_;
77 std::string value_;
78};
79
80bool operator<(const Label& x, const Label& y) noexcept;
81bool operator==(const Label& x, const Label& y) noexcept;
82
83/// @ingroup userver_universal
84///
85/// @brief View over a continuous range of LabelView.
86class LabelsSpan final {
87public:
88 using iterator = const LabelView*;
89 using const_iterator = const LabelView*;
90
91 LabelsSpan() = default;
92 LabelsSpan(const LabelView* begin, const LabelView* end) noexcept;
93 LabelsSpan(std::initializer_list<LabelView> il) noexcept : LabelsSpan(il.begin(), il.end()) {}
94
95 template <
96 class Container,
97 std::enable_if_t<
98 std::is_same_v<
99 decltype(*(std::declval<const Container&>().data() + std::declval<const Container&>().size())),
100 const LabelView&>,
101 int> = 0>
102 /*implicit*/ LabelsSpan(const Container& cont) noexcept : LabelsSpan(cont.data(), cont.data() + cont.size()) {}
103
104 const LabelView* begin() const noexcept { return begin_; }
105 const LabelView* end() const noexcept { return end_; }
106 std::size_t size() const noexcept { return end_ - begin_; }
107 bool empty() const noexcept { return end_ == begin_; }
108
109private:
110 const LabelView* begin_{nullptr};
111 const LabelView* end_{nullptr};
112};
113
114} // namespace utils::statistics
115
116USERVER_NAMESPACE_END
117
118template <>
119struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelView> {
120 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
121
122 template <typename FormatContext>
123 auto format(USERVER_NAMESPACE::utils::statistics::LabelView value, FormatContext& ctx) const {
124 return fmt::format_to(ctx.out(), "{}={}", value.Name(), value.Value());
125 }
126};
127
128template <>
129struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::Label>
130 : public fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelView> {
131 template <typename FormatContext>
132 auto format(const USERVER_NAMESPACE::utils::statistics::Label& value, FormatContext& ctx) const {
133 return formatter<USERVER_NAMESPACE::utils::statistics::LabelView>::format(
134 USERVER_NAMESPACE::utils::statistics::LabelView{value},
135 ctx
136 );
137 }
138};
139
140template <>
141struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelsSpan> {
142 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
143
144 fmt::format_context::iterator format(
145 USERVER_NAMESPACE::utils::statistics::LabelsSpan value,
146 fmt::format_context& ctx
147 ) const;
148};