userver: userver/utils/zstring_view.hpp Source File
Loading...
Searching...
No Matches
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 void remove_suffix(std::size_t) = delete; // zstring_view becomes not null-terminated after that function call
38 void swap(std::string_view&) = delete; // zstring_view may become not null-terminated after that function call
39 void swap(zstring_view& other) noexcept { std::string_view::swap(other); }
40
41 constexpr const char* c_str() const noexcept { return std::string_view::data(); }
42
43 /// Constructs a zstring_view from a pointer and size.
44 /// @warning `str[len]` should be '\0'.
45 static constexpr zstring_view UnsafeMake(const char* str, std::size_t len) noexcept {
46 return zstring_view{str, len};
47 }
48
49private:
50 constexpr zstring_view(const char* str, std::size_t len) noexcept : std::string_view{str, len} {
51 UASSERT_MSG(str, "null not allowed");
52 UASSERT_MSG(str[len] == 0, "Not null-terminated");
53 }
54};
55
56template <class Value>
57Value Serialize(zstring_view view, formats::serialize::To<Value>) {
58 return typename Value::Builder(std::string_view{view}).ExtractValue();
59}
60
61} // namespace utils
62
63USERVER_NAMESPACE_END
64
65template <>
66struct fmt::formatter<USERVER_NAMESPACE::utils::zstring_view, char> : fmt::formatter<std::string_view> {};
67
68namespace fmt {
69
70// Allow fmt::runtime() to work with utils::zstring_view
71template <class... NotUsed>
72inline auto runtime(USERVER_NAMESPACE::utils::zstring_view s, NotUsed...) // NOLINT(readability-identifier-naming)
73 -> decltype(fmt::runtime(std::string_view{s})) {
74 static_assert(sizeof...(NotUsed) == 0);
75 return fmt::runtime(std::string_view{s});
76}
77
78} // namespace fmt