OXYGENHUB
◆ main openmsx / src / utils / TemporaryString.hh
3.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
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
/** TemporaryString
14
 *
15
 * This a type meant to store temporary strings. Typically it stores the string
16
 * in the object itself. Except when the string is too large, then it falls
17
 * back to heap-allocation. So it's more or less like a std::string but with a
18
 * relatively large (127 character) "small-string-buffer". (Typical std::string
19
 * implementations only have a buffer for 15 or 23 characters).
20
 *
21
 * Because of this internal buffer, TemporaryString objects are quite large.
22
 * The intention is that they are only used as local variable (so stored on the
23
 * stack). Not as member variables.
24
 *
25
 * The API of this type is still very minimal. It can be extended when needed.
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