userver: /data/code/userver/libraries/protobuf/include/userver/protobuf/string.hpp Source File
Loading...
Searching...
No Matches
string.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/protobuf/string.hpp
4/// @brief Operations with Protobuf string type.
5
6#include <string>
7#include <string_view>
8#include <type_traits>
9#include <utility>
10
11#if defined(ARCADIA_ROOT)
12#include <google/protobuf/port.h>
13#endif
14
15USERVER_NAMESPACE_BEGIN
16
17namespace protobuf {
18
19#if defined(ARCADIA_ROOT)
20/// @brief String type used by protobuf APIs in Arcadia builds.
21using ProtoStringType = TProtoStringType;
22#else
23/// @brief String type used by protobuf APIs in open-source builds.
24using ProtoStringType = std::string;
25#endif
26
27namespace impl {
28
29template <typename TStringLike>
30concept StringLike = requires(const TStringLike& str) {
31 str.data();
32 str.size();
33};
34
35/// @brief Returns a `std::string_view` over protobuf-compatible string-like data.
36template <StringLike TStringLike>
37[[nodiscard]] inline std::string_view ToStringView(const TStringLike& str) {
38 return {str.data(), str.size()};
39}
40
41/// @brief Converts protobuf-compatible string-like data to `std::string`.
42template <StringLike TStringLike>
43[[nodiscard]] inline decltype(auto) ToString(const TStringLike& str) {
44 if constexpr (std::is_same_v<std::decay_t<TStringLike>, std::string>) {
45 return str;
46 } else {
47 return std::string{str.data(), str.size()};
48 }
49}
50
51/// @brief Preserves an rvalue `std::string` when converting to `std::string`.
52[[nodiscard]] inline std::string ToString(std::string&& str) { return std::move(str); }
53
54/// @brief Converts `std::string` to protobuf string type.
55/// @note Kept templated so `if constexpr` discards the invalid `std::string`
56/// return path when Arcadia protobuf uses `TString` as `ProtoStringType`.
57template <typename TProtoString = ProtoStringType>
58[[nodiscard]] inline decltype(auto) ToProtoString(const std::string& str) {
59 if constexpr (std::is_same_v<TProtoString, std::string>) {
60 return str;
61 } else {
62 return TProtoString{str.data(), str.size()};
63 }
64}
65
66/// @brief Converts an rvalue `std::string` to protobuf string type.
67/// @note Kept templated so the non-selected branch is not instantiated for
68/// Arcadia `TString`.
69template <typename TProtoString = ProtoStringType>
70[[nodiscard]] inline TProtoString ToProtoString(std::string&& str) {
71 if constexpr (std::is_same_v<TProtoString, std::string>) {
72 return std::move(str);
73 } else {
74 return TProtoString{std::move(str)};
75 }
76}
77
78} // namespace impl
79
80} // namespace protobuf
81
82USERVER_NAMESPACE_END