userver: userver/utils/zstring_view.hpp Source File
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
zstring_view.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief @copybrief utils::zstring_view
5/// @ingroup userver_universal
6
7#include <string>
8#include <string_view>
9#include <type_traits>
10
11#include <fmt/format.h>
12
13#include <userver/formats/serialize/to.hpp>
14#include <userver/utils/assert.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace utils {
19
20/// @ingroup userver_containers
21///
22/// @brief Non-empty string view type that guarantees null-termination and has a `c_str()` member function.
23class zstring_view : public std::string_view { // NOLINT(readability-identifier-naming)
24public:
25 zstring_view() = delete;
26 zstring_view(const zstring_view& str) = default;
27
28 constexpr zstring_view(const char* str) noexcept : std::string_view{str} {
29 // data()[size()] == '\0' is guaranteed by std::string_view that calls std::strlen(str)
30 }
31
32 zstring_view(const std::string& str) noexcept : std::string_view{str} {}
33
34 zstring_view& operator=(std::string_view) = delete;
35 zstring_view& operator=(const zstring_view&) = default;
36
37 constexpr const char* c_str() const noexcept { return std::string_view::data(); }
38
39 /// Constructs a zstring_view from a pointer and size.
40 /// @warning `str[len]` should be '\0'.
41 static constexpr zstring_view UnsafeMake(const char* str, std::size_t len) noexcept {
42 return zstring_view{str, len};
43 }
44
45private:
46 constexpr zstring_view(const char* str, std::size_t len) noexcept : std::string_view{str, len} {
47 UASSERT_MSG(str, "null not allowed");
48 UASSERT_MSG(str[len] == 0, "Not null-terminated");
49 }
50};
51
52template <class Value>
53Value Serialize(zstring_view view, formats::serialize::To<Value>) {
54 return typename Value::Builder(std::string_view{view}).ExtractValue();
55}
56
57} // namespace utils
58
59USERVER_NAMESPACE_END
60
61template <>
62struct fmt::formatter<USERVER_NAMESPACE::utils::zstring_view, char> : fmt::formatter<std::string_view> {};
63
64namespace fmt {
65
66// Allow fmt::runtime() to work with utils::zstring_view
67template <class... NotUsed>
68inline auto runtime(USERVER_NAMESPACE::utils::zstring_view s, NotUsed...)
69 -> decltype(fmt::runtime(std::string_view{s})) {
70 static_assert(sizeof...(NotUsed) == 0);
71 return fmt::runtime(std::string_view{s});
72}
73
74} // namespace fmt