userver: userver/utils/string_literal.hpp Source File
Loading...
Searching...
No Matches
string_literal.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/string_literal.hpp
4/// @brief @copybrief utils::StringLiteral
5/// @ingroup userver_universal
6
7#include <concepts>
8#include <string_view>
9
10#include <fmt/core.h>
11
12#include <userver/formats/serialize/to.hpp>
13#include <userver/utils/zstring_view.hpp>
14
15USERVER_NAMESPACE_BEGIN
16
17namespace utils {
18
19/// @ingroup userver_containers
20///
21/// @brief Non-empty string view to a compile time known null terminated char array that lives for the lifetime of
22/// program, as per [lex.string]; a drop-in replacement for `static const std::string kVar = "value"` and
23/// `constexpr std::string_view kVar = "value"`.
25public:
26 StringLiteral() = delete;
27
28#if defined(__clang__) && __clang_major__ < 18
29 // clang-16 and below lose (optimize out) the pointer to `literal` with consteval. Clang-18 is know to work
30 constexpr
31#else
32 consteval
33#endif
34 StringLiteral(const char* literal) noexcept
35 : zstring_view{literal} {
36 // data()[size()] == '\0' is guaranteed by std::string_view that calls std::strlen(literal)
37 }
38
39 void swap(zstring_view&) = delete; // loses guarantee on lifetime because zstring_view may refer to non-literal
40 void swap(StringLiteral& other) noexcept { zstring_view::swap(other); }
41
42 /// Constructs a StringLiteral from a pointer and size.
43 /// @warning `str[len]` should be '\0' and `str` should point to compile time literal.
44 static constexpr StringLiteral UnsafeMake(const char* str, std::size_t len) noexcept {
45 return StringLiteral(str, len);
46 }
47
48 friend constexpr auto operator<=>(StringLiteral lhs, StringLiteral rhs) noexcept = default;
49
50 friend constexpr auto operator<=>(StringLiteral lhs, const std::convertible_to<std::string_view> auto& rhs)
51 noexcept {
52 return std::string_view{lhs} <=> std::string_view{rhs};
53 }
54
55 friend constexpr bool operator==(StringLiteral lhs, const std::convertible_to<std::string_view> auto& rhs)
56 noexcept {
57 return std::string_view{lhs} == std::string_view{rhs};
58 }
59
60private:
61 explicit constexpr StringLiteral(const char* str, std::size_t len) noexcept
63};
64
65template <class Value>
66Value Serialize(StringLiteral literal, formats::serialize::To<Value>) {
67 return typename Value::Builder(std::string_view{literal}).ExtractValue();
68}
69
70} // namespace utils
71
72USERVER_NAMESPACE_END
73
74template <>
75struct fmt::formatter<USERVER_NAMESPACE::utils::StringLiteral, char> : fmt::formatter<std::string_view> {};