| 1 |
#ifndef TEMPORARYSTRING_HH |
| 2 |
#define TEMPORARYSTRING_HH |
| 3 |
|
| 4 |
#include "StringStorage.hh" |
| 5 |
#include "zstring_view.hh" |
| 6 |
|
| 7 |
#include <array> |
| 8 |
#include <concepts> |
| 9 |
#include <iostream> |
| 10 |
#include <string_view> |
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
class TemporaryString { |
| 28 |
public: |
| 29 |
static constexpr size_t BUFSIZE = 127; |
| 30 |
|
| 31 |
explicit TemporaryString() |
| 32 |
: n(0) |
| 33 |
{ |
| 34 |
ptr = buffer.data(); |
| 35 |
buffer[0] = '\0'; |
| 36 |
} |
| 37 |
|
| 38 |
explicit TemporaryString(const char* s) |
| 39 |
: n(std::char_traits<char>::length(s)), ptr(s) {} |
| 40 |
explicit TemporaryString(zstring_view s) |
| 41 |
: n(s.size()), ptr(s.data()) {} |
| 42 |
|
| 43 |
explicit TemporaryString(size_t n_, std::invocable<char*> auto fillOp) |
| 44 |
: n(n_) |
| 45 |
{ |
| 46 |
char* p = [&] { |
| 47 |
if (n <= BUFSIZE) { |
| 48 |
return buffer.data(); |
| 49 |
} else { |
| 50 |
owner = allocate_string_storage(n + 1); |
| 51 |
return owner.get(); |
| 52 |
} |
| 53 |
}(); |
| 54 |
ptr = p; |
| 55 |
fillOp(p); |
| 56 |
p[n] = '\0'; |
| 57 |
} |
| 58 |
TemporaryString(const TemporaryString&) = delete; |
| 59 |
TemporaryString(TemporaryString&&) = delete; |
| 60 |
TemporaryString& operator=(const TemporaryString&) = delete; |
| 61 |
TemporaryString& operator=(TemporaryString&&) = delete; |
| 62 |
~TemporaryString() = default; |
| 63 |
|
| 64 |
[[nodiscard]] auto size() const { return n; } |
| 65 |
[[nodiscard]] auto empty() const { return n == 0; } |
| 66 |
|
| 67 |
[[nodiscard]] const char* data() const { return ptr; } |
| 68 |
[[nodiscard]] const char* c_str() const { return ptr; } |
| 69 |
|
| 70 |
[[nodiscard]] std::string_view view() const { return {ptr, n}; } |
| 71 |
[[nodiscard]] operator std::string_view() const { return {ptr, n}; } |
| 72 |
[[nodiscard]] operator zstring_view() const { return {ptr, n}; } |
| 73 |
|
| 74 |
[[nodiscard]] bool starts_with(std::string_view s) const { return view().starts_with(s); } |
| 75 |
[[nodiscard]] bool starts_with(char c) const { return view().starts_with(c); } |
| 76 |
[[nodiscard]] bool starts_with(const char* s) const { return view().starts_with(s); } |
| 77 |
[[nodiscard]] bool ends_with(std::string_view s) const { return view().ends_with(s); } |
| 78 |
[[nodiscard]] bool ends_with(char c) const { return view().ends_with(c); } |
| 79 |
[[nodiscard]] bool ends_with(const char* s) const { return view().ends_with(s); } |
| 80 |
|
| 81 |
[[nodiscard]] friend bool operator==(const TemporaryString& x, const TemporaryString& y) { |
| 82 |
return std::string_view(x) == std::string_view(y); |
| 83 |
} |
| 84 |
[[nodiscard]] friend bool operator==(const TemporaryString& x, const zstring_view& y) { |
| 85 |
return std::string_view(x) == std::string_view(y); |
| 86 |
} |
| 87 |
[[nodiscard]] friend bool operator==(const TemporaryString& x, const std::string& y) { |
| 88 |
return std::string_view(x) == std::string_view(y); |
| 89 |
} |
| 90 |
[[nodiscard]] friend bool operator==(const TemporaryString& x, const std::string_view& y) { |
| 91 |
return std::string_view(x) == y; |
| 92 |
} |
| 93 |
[[nodiscard]] friend bool operator==(const TemporaryString& x, const char* y) { |
| 94 |
return std::string_view(x) == std::string_view(y); |
| 95 |
} |
| 96 |
|
| 97 |
friend std::ostream& operator<<(std::ostream& os, const TemporaryString& str) |
| 98 |
{ |
| 99 |
os << std::string_view(str); |
| 100 |
return os; |
| 101 |
} |
| 102 |
|
| 103 |
private: |
| 104 |
size_t n; |
| 105 |
const char* ptr; |
| 106 |
StringStorage owner; |
| 107 |
std::array<char, BUFSIZE + 1> buffer; |
| 108 |
}; |
| 109 |
|
| 110 |
#endif |