Skip to content
Flecs v4.1
string.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/utils/string.hpp
3 * @brief String utility that doesn't implicitly allocate memory.
4 */
5
6namespace flecs {
7
8struct string_view;
9
10/** Owned string wrapper.
11 * This removes dependencies on std::string (and therefore STL) and allows the
12 * API to return allocated strings without incurring additional allocations when
13 * wrapping in an std::string.
14 */
15struct string {
16 /** Default constructor. */
17 explicit string()
18 : str_(nullptr)
19 , const_str_("")
20 , length_(0) { }
21
22 /** Construct from an owned char pointer. */
23 explicit string(char *str)
24 : str_(str)
25 , const_str_(str ? str : "")
26 , length_(str ? ecs_os_strlen(str) : 0) { }
27
28 /** Destructor. Free the owned string if set. */
30 // If flecs is included in a binary but is not used, it is possible that
31 // the OS API is not initialized. Calling ecs_os_free in that case could
32 // crash the application during exit. However, if a string has been set
33 // flecs has been used, and OS API should have been initialized.
34 if (str_) {
35 ecs_os_free(str_);
36 }
37 }
38
39 /** Move constructor. */
40 string(string&& str) noexcept {
41 ecs_os_free(str_);
42 str_ = str.str_;
43 const_str_ = str.const_str_;
44 length_ = str.length_;
45 str.str_ = nullptr;
46 }
47
48 /** Implicit conversion to const char*. */
49 operator const char*() const {
50 return const_str_;
51 }
52
53 /** Move assignment operator. */
54 string& operator=(string&& str) noexcept {
55 ecs_os_free(str_);
56 str_ = str.str_;
57 const_str_ = str.const_str_;
58 length_ = str.length_;
59 str.str_ = nullptr;
60 return *this;
61 }
62
63 /** Ban implicit copies/allocations. */
64 string& operator=(const string& str) = delete;
65 /** Ban implicit copies/allocations. */
66 string(const string& str) = delete;
67
68 /** Equality operator. */
69 bool operator==(const flecs::string& str) const {
70 if (str.const_str_ == const_str_) {
71 return true;
72 }
73
74 if (!const_str_ || !str.const_str_) {
75 return false;
76 }
77
78 if (str.length_ != length_) {
79 return false;
80 }
81
82 return ecs_os_strcmp(str, const_str_) == 0;
83 }
84
85 /** Inequality operator. */
86 bool operator!=(const flecs::string& str) const {
87 return !(*this == str);
88 }
89
90 /** Equality operator for a C string. */
91 bool operator==(const char *str) const {
92 if (const_str_ == str) {
93 return true;
94 }
95
96 if (!const_str_ || !str) {
97 return false;
98 }
99
100 return ecs_os_strcmp(str, const_str_) == 0;
101 }
102
103 /** Inequality operator for a C string. */
104 bool operator!=(const char *str) const {
105 return !(*this == str);
106 }
107
108 /** Return the C string. */
109 const char* c_str() const {
110 return const_str_;
111 }
112
113 /** Return the string length. */
114 std::size_t length() const {
115 return static_cast<std::size_t>(length_);
116 }
117
118 /** Return the length of a string literal at compile time. */
119 template <size_t N>
120 static constexpr size_t length( char const (&)[N] ) {
121 return N - 1;
122 }
123
124 /** Return the string size (same as length). */
125 std::size_t size() const {
126 return length();
127 }
128
129 /** Clear the string, freeing the owned memory. */
130 void clear() {
131 ecs_os_free(str_);
132 str_ = nullptr;
133 const_str_ = nullptr;
134 }
135
136 /** Check if the string contains a substring. */
137 bool contains(const char *substr) {
138 if (const_str_) {
139 return strstr(const_str_, substr) != nullptr;
140 } else {
141 return false;
142 }
143 }
144
145protected:
146 /** Construct from a non-owned C string.
147 * Must be constructed through string_view. This allows for using the string
148 * class for both owned and non-owned strings, which can reduce allocations
149 * when code conditionally should store a literal or an owned string.
150 * Making this constructor protected forces the code to explicitly create a
151 * string_view, which emphasizes that the string won't be freed by the class.
152 */
153 string(const char *str)
154 : str_(nullptr)
155 , const_str_(str ? str : "")
156 , length_(str ? ecs_os_strlen(str) : 0) { }
157
158 char *str_ = nullptr;
159 const char *const_str_;
160 ecs_size_t length_;
161};
162
163/** Non-owning string view.
164 * For consistency, the API returns a string_view where it could have returned
165 * a const char*, so an application won't have to think about whether to call
166 * c_str() or not. The string_view is a thin wrapper around a string that forces
167 * the API to indicate explicitly when a string is owned or not.
168 */
170 /** Construct from a C string (non-owning). */
171 explicit string_view(const char *str)
172 : string(str) { }
173};
174
175}
Non-owning string view.
Definition string.hpp:169
string_view(const char *str)
Construct from a C string (non-owning).
Definition string.hpp:171
Owned string wrapper.
Definition string.hpp:15
static constexpr size_t length(char const (&)[N])
Return the length of a string literal at compile time.
Definition string.hpp:120
bool operator!=(const char *str) const
Inequality operator for a C string.
Definition string.hpp:104
string(const char *str)
Construct from a non-owned C string.
Definition string.hpp:153
string & operator=(const string &str)=delete
Ban implicit copies/allocations.
bool contains(const char *substr)
Check if the string contains a substring.
Definition string.hpp:137
string()
Default constructor.
Definition string.hpp:17
string(string &&str) noexcept
Move constructor.
Definition string.hpp:40
std::size_t length() const
Return the string length.
Definition string.hpp:114
string(const string &str)=delete
Ban implicit copies/allocations.
string & operator=(string &&str) noexcept
Move assignment operator.
Definition string.hpp:54
const char * c_str() const
Return the C string.
Definition string.hpp:109
void clear()
Clear the string, freeing the owned memory.
Definition string.hpp:130
bool operator==(const flecs::string &str) const
Equality operator.
Definition string.hpp:69
~string()
Destructor.
Definition string.hpp:29
string(char *str)
Construct from an owned char pointer.
Definition string.hpp:23
bool operator!=(const flecs::string &str) const
Inequality operator.
Definition string.hpp:86
std::size_t size() const
Return the string size (same as length).
Definition string.hpp:125
bool operator==(const char *str) const
Equality operator for a C string.
Definition string.hpp:91