Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2008-2017, Petr Kobalicek
3 :
4 : This software is provided 'as-is', without any express or implied
5 : warranty. In no event will the authors be held liable for any damages
6 : arising from the use of this software.
7 :
8 : Permission is granted to anyone to use this software for any purpose,
9 : including commercial applications, and to alter it and redistribute it
10 : freely, subject to the following restrictions:
11 :
12 : 1. The origin of this software must not be misrepresented; you must not
13 : claim that you wrote the original software. If you use this software
14 : in a product, an acknowledgment in the product documentation would be
15 : appreciated but is not required.
16 : 2. Altered source versions must be plainly marked as such, and must not be
17 : misrepresented as being the original software.
18 : 3. This notice may not be removed or altered from any source distribution.
19 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
20 : #ifndef __PLUMED_asmjit_moved_string_h
21 : #define __PLUMED_asmjit_moved_string_h
22 : #ifdef __PLUMED_HAS_ASMJIT
23 : #pragma GCC diagnostic push
24 : #pragma GCC diagnostic ignored "-Wpedantic"
25 : // [AsmJit]
26 : // Complete x86/x64 JIT and Remote Assembler for C++.
27 : //
28 : // [License]
29 : // Zlib - See LICENSE.md file in the package.
30 :
31 : // [Guard]
32 : #ifndef _ASMJIT_BASE_STRING_H
33 : #define _ASMJIT_BASE_STRING_H
34 :
35 : // [Dependencies]
36 : #include "./globals.h"
37 :
38 : // [Api-Begin]
39 : #include "./asmjit_apibegin.h"
40 :
41 : namespace PLMD {
42 : namespace asmjit {
43 :
44 : //! \addtogroup asmjit_base
45 : //! \{
46 :
47 : // ============================================================================
48 : // [asmjit::SmallString]
49 : // ============================================================================
50 :
51 : //! Small string is a template that helps to create strings that can be either
52 : //! statically allocated if they are small, or externally allocated in case
53 : //! their length exceed the limit. The `WholeSize` represents the size of the
54 : //! whole `SmallString` structure, based on that size the maximum size of the
55 : //! internal buffer is determined.
56 : template<size_t WholeSize>
57 : class SmallString {
58 : public:
59 : enum { kMaxEmbeddedLength = WholeSize - 5 };
60 :
61 : ASMJIT_INLINE SmallString() noexcept { reset(); }
62 : ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
63 :
64 0 : ASMJIT_INLINE bool isEmpty() const noexcept { return _length == 0; }
65 : ASMJIT_INLINE bool isEmbedded() const noexcept { return _length <= kMaxEmbeddedLength; }
66 : ASMJIT_INLINE bool mustEmbed(size_t len) const noexcept { return len <= kMaxEmbeddedLength; }
67 :
68 0 : ASMJIT_INLINE uint32_t getLength() const noexcept { return _length; }
69 : ASMJIT_INLINE char* getData() const noexcept {
70 0 : return _length <= kMaxEmbeddedLength ? const_cast<char*>(_embedded) : _external[1];
71 : }
72 :
73 : ASMJIT_INLINE void setEmbedded(const char* data, size_t len) noexcept {
74 : ASMJIT_ASSERT(len <= kMaxEmbeddedLength);
75 :
76 0 : _length = static_cast<uint32_t>(len);
77 0 : ::memcpy(_embedded, data, len);
78 0 : _embedded[len] = '\0';
79 0 : }
80 :
81 : ASMJIT_INLINE void setExternal(const char* data, size_t len) noexcept {
82 : ASMJIT_ASSERT(len > kMaxEmbeddedLength);
83 : ASMJIT_ASSERT(len <= ~static_cast<uint32_t>(0));
84 :
85 0 : _length = static_cast<uint32_t>(len);
86 0 : _external[1] = const_cast<char*>(data);
87 0 : }
88 :
89 : union {
90 : struct {
91 : uint32_t _length;
92 : char _embedded[WholeSize - 4];
93 : };
94 : char* _external[2];
95 : };
96 : };
97 :
98 : // ============================================================================
99 : // [asmjit::StringBuilder]
100 : // ============================================================================
101 :
102 : //! String builder.
103 : //!
104 : //! String builder was designed to be able to build a string using append like
105 : //! operation to append numbers, other strings, or signle characters. It can
106 : //! allocate it's own buffer or use a buffer created on the stack.
107 : //!
108 : //! String builder contains method specific to AsmJit functionality, used for
109 : //! logging or HTML output.
110 : class StringBuilder {
111 : public:
112 : ASMJIT_NONCOPYABLE(StringBuilder)
113 :
114 : //! \internal
115 : //!
116 : //! String operation.
117 : ASMJIT_ENUM(OpType) {
118 : kStringOpSet = 0, //!< Replace the current string by a given content.
119 : kStringOpAppend = 1 //!< Append a given content to the current string.
120 : };
121 :
122 : //! \internal
123 : //!
124 : //! String format flags.
125 : ASMJIT_ENUM(StringFormatFlags) {
126 : kStringFormatShowSign = 0x00000001,
127 : kStringFormatShowSpace = 0x00000002,
128 : kStringFormatAlternate = 0x00000004,
129 : kStringFormatSigned = 0x80000000
130 : };
131 :
132 : // --------------------------------------------------------------------------
133 : // [Construction / Destruction]
134 : // --------------------------------------------------------------------------
135 :
136 : ASMJIT_API StringBuilder() noexcept;
137 : ASMJIT_API ~StringBuilder() noexcept;
138 :
139 1944 : ASMJIT_INLINE StringBuilder(const _NoInit&) noexcept {}
140 :
141 : // --------------------------------------------------------------------------
142 : // [Accessors]
143 : // --------------------------------------------------------------------------
144 :
145 : //! Get string builder capacity.
146 : ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
147 : //! Get length.
148 0 : ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
149 :
150 : //! Get null-terminated string data.
151 0 : ASMJIT_INLINE char* getData() noexcept { return _data; }
152 : //! Get null-terminated string data (const).
153 : ASMJIT_INLINE const char* getData() const noexcept { return _data; }
154 :
155 : // --------------------------------------------------------------------------
156 : // [Prepare / Reserve]
157 : // --------------------------------------------------------------------------
158 :
159 : //! Prepare to set/append.
160 : ASMJIT_API char* prepare(uint32_t op, size_t len) noexcept;
161 :
162 : //! Reserve `to` bytes in string builder.
163 : ASMJIT_API Error reserve(size_t to) noexcept;
164 :
165 : // --------------------------------------------------------------------------
166 : // [Clear]
167 : // --------------------------------------------------------------------------
168 :
169 : //! Clear the content in String builder.
170 : ASMJIT_API void clear() noexcept;
171 :
172 : // --------------------------------------------------------------------------
173 : // [Op]
174 : // --------------------------------------------------------------------------
175 :
176 : ASMJIT_API Error _opString(uint32_t op, const char* str, size_t len = Globals::kInvalidIndex) noexcept;
177 : ASMJIT_API Error _opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept;
178 : ASMJIT_API Error _opChar(uint32_t op, char c) noexcept;
179 : ASMJIT_API Error _opChars(uint32_t op, char c, size_t n) noexcept;
180 : ASMJIT_API Error _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept;
181 : ASMJIT_API Error _opHex(uint32_t op, const void* data, size_t len) noexcept;
182 :
183 : // --------------------------------------------------------------------------
184 : // [Set]
185 : // --------------------------------------------------------------------------
186 :
187 : //! Replace the current string with `str` having `len` characters (or `kInvalidIndex` if it's null terminated).
188 : ASMJIT_INLINE Error setString(const char* str, size_t len = Globals::kInvalidIndex) noexcept { return _opString(kStringOpSet, str, len); }
189 : //! Replace the current content by a formatted string `fmt`.
190 : ASMJIT_API Error setFormat(const char* fmt, ...) noexcept;
191 : //! Replace the current content by a formatted string `fmt` (va_list version).
192 : ASMJIT_INLINE Error setFormatVA(const char* fmt, va_list ap) noexcept { return _opVFormat(kStringOpSet, fmt, ap); }
193 :
194 : //! Replace the current content by a single `c` character.
195 : ASMJIT_INLINE Error setChar(char c) noexcept { return _opChar(kStringOpSet, c); }
196 : //! Replace the current content by `c` character `n` times.
197 : ASMJIT_INLINE Error setChars(char c, size_t n) noexcept { return _opChars(kStringOpSet, c, n); }
198 :
199 : //! Replace the current content by a formatted integer `i` (signed).
200 : ASMJIT_INLINE Error setInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
201 : return _opNumber(kStringOpSet, i, base, width, flags | kStringFormatSigned);
202 : }
203 :
204 : //! Replace the current content by a formatted integer `i` (unsigned).
205 : ASMJIT_INLINE Error setUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
206 : return _opNumber(kStringOpSet, i, base, width, flags);
207 : }
208 :
209 : //! Replace the current content by the given `data` converted to a HEX string.
210 : ASMJIT_INLINE Error setHex(const void* data, size_t len) noexcept {
211 : return _opHex(kStringOpSet, data, len);
212 : }
213 :
214 : // --------------------------------------------------------------------------
215 : // [Append]
216 : // --------------------------------------------------------------------------
217 :
218 : //! Append string `str` having `len` characters (or `kInvalidIndex` if it's null terminated).
219 0 : ASMJIT_INLINE Error appendString(const char* str, size_t len = Globals::kInvalidIndex) noexcept { return _opString(kStringOpAppend, str, len); }
220 : //! Append a formatted string `fmt`.
221 : ASMJIT_API Error appendFormat(const char* fmt, ...) noexcept;
222 : //! Append a formatted string `fmt` (va_list version).
223 0 : ASMJIT_INLINE Error appendFormatVA(const char* fmt, va_list ap) noexcept { return _opVFormat(kStringOpAppend, fmt, ap); }
224 :
225 : //! Append a single `c` character.
226 0 : ASMJIT_INLINE Error appendChar(char c) noexcept { return _opChar(kStringOpAppend, c); }
227 : //! Append `c` character `n` times.
228 0 : ASMJIT_INLINE Error appendChars(char c, size_t n) noexcept { return _opChars(kStringOpAppend, c, n); }
229 :
230 : //! Append `i`.
231 : ASMJIT_INLINE Error appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
232 0 : return _opNumber(kStringOpAppend, static_cast<uint64_t>(i), base, width, flags | kStringFormatSigned);
233 : }
234 :
235 : //! Append `i`.
236 : ASMJIT_INLINE Error appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
237 0 : return _opNumber(kStringOpAppend, i, base, width, flags);
238 : }
239 :
240 : //! Append the given `data` converted to a HEX string.
241 : ASMJIT_INLINE Error appendHex(const void* data, size_t len) noexcept {
242 0 : return _opHex(kStringOpAppend, data, len);
243 : }
244 :
245 : // --------------------------------------------------------------------------
246 : // [Eq]
247 : // --------------------------------------------------------------------------
248 :
249 : //! Check for equality with other `str` of length `len`.
250 : ASMJIT_API bool eq(const char* str, size_t len = Globals::kInvalidIndex) const noexcept;
251 : //! Check for equality with `other`.
252 : ASMJIT_INLINE bool eq(const StringBuilder& other) const noexcept { return eq(other._data, other._length); }
253 :
254 : // --------------------------------------------------------------------------
255 : // [Operator Overload]
256 : // --------------------------------------------------------------------------
257 :
258 : ASMJIT_INLINE bool operator==(const StringBuilder& other) const noexcept { return eq(other); }
259 : ASMJIT_INLINE bool operator!=(const StringBuilder& other) const noexcept { return !eq(other); }
260 :
261 : ASMJIT_INLINE bool operator==(const char* str) const noexcept { return eq(str); }
262 : ASMJIT_INLINE bool operator!=(const char* str) const noexcept { return !eq(str); }
263 :
264 : // --------------------------------------------------------------------------
265 : // [Members]
266 : // --------------------------------------------------------------------------
267 :
268 : char* _data; //!< String data.
269 : size_t _length; //!< String length.
270 : size_t _capacity; //!< String capacity.
271 : size_t _canFree; //!< If the string data can be freed.
272 : };
273 :
274 : // ============================================================================
275 : // [asmjit::StringBuilderTmp]
276 : // ============================================================================
277 :
278 : //! Temporary string builder, has statically allocated `N` bytes.
279 : template<size_t N>
280 0 : class StringBuilderTmp : public StringBuilder {
281 : public:
282 : ASMJIT_NONCOPYABLE(StringBuilderTmp<N>)
283 :
284 : // --------------------------------------------------------------------------
285 : // [Construction / Destruction]
286 : // --------------------------------------------------------------------------
287 :
288 1944 : ASMJIT_INLINE StringBuilderTmp() noexcept : StringBuilder(NoInit) {
289 1944 : _data = _embeddedData;
290 1944 : _data[0] = 0;
291 :
292 1944 : _length = 0;
293 1944 : _capacity = N;
294 0 : _canFree = false;
295 : }
296 :
297 : // --------------------------------------------------------------------------
298 : // [Members]
299 : // --------------------------------------------------------------------------
300 :
301 : //! Embedded data.
302 : char _embeddedData[static_cast<size_t>(
303 : N + 1 + sizeof(intptr_t)) & ~static_cast<size_t>(sizeof(intptr_t) - 1)];
304 : };
305 :
306 : //! \}
307 :
308 : } // asmjit namespace
309 : } // namespace PLMD
310 :
311 : // [Api-End]
312 : #include "./asmjit_apiend.h"
313 :
314 : // [Guard]
315 : #endif // _ASMJIT_BASE_STRING_H
316 : #pragma GCC diagnostic pop
317 : #endif // __PLUMED_HAS_ASMJIT
318 : #endif
|