diff options
Diffstat (limited to '3rdparty/asmjit/src/asmjit/core/string.h')
-rw-r--r-- | 3rdparty/asmjit/src/asmjit/core/string.h | 269 |
1 files changed, 126 insertions, 143 deletions
diff --git a/3rdparty/asmjit/src/asmjit/core/string.h b/3rdparty/asmjit/src/asmjit/core/string.h index 4c490d87b1d..c4dee14b00e 100644 --- a/3rdparty/asmjit/src/asmjit/core/string.h +++ b/3rdparty/asmjit/src/asmjit/core/string.h @@ -1,25 +1,7 @@ -// AsmJit - Machine code generation for C++ +// This file is part of AsmJit project <https://asmjit.com> // -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. +// See asmjit.h or LICENSE.md for license and copyright information +// SPDX-License-Identifier: Zlib #ifndef ASMJIT_CORE_STRING_H_INCLUDED #define ASMJIT_CORE_STRING_H_INCLUDED @@ -32,70 +14,79 @@ ASMJIT_BEGIN_NAMESPACE //! \addtogroup asmjit_utilities //! \{ -// ============================================================================ -// [asmjit::FixedString] -// ============================================================================ +//! Format flags used by \ref String API. +enum class StringFormatFlags : uint32_t { + //! No flags. + kNone = 0x00000000u, + //! Show sign. + kShowSign = 0x00000001u, + //! Show space. + kShowSpace = 0x00000002u, + //! Alternate form (use 0x when formatting HEX number). + kAlternate = 0x00000004u, + //! The input is signed. + kSigned = 0x80000000u +}; +ASMJIT_DEFINE_ENUM_FLAGS(StringFormatFlags) -//! A fixed string - only useful for strings that would never exceed `N - 1` -//! characters; always null-terminated. +//! Fixed string - only useful for strings that would never exceed `N - 1` characters; always null-terminated. template<size_t N> union FixedString { + //! \name Constants + //! \{ + + // This cannot be constexpr as GCC 4.8 refuses constexpr members of unions. enum : uint32_t { - kNumU32 = uint32_t((N + sizeof(uint32_t) - 1) / sizeof(uint32_t)) + kNumUInt32Words = uint32_t((N + sizeof(uint32_t) - 1) / sizeof(uint32_t)) }; - char str[kNumU32 * sizeof(uint32_t)]; - uint32_t u32[kNumU32]; + //! \} + + //! \name Members + //! \{ + + char str[kNumUInt32Words * sizeof(uint32_t)]; + uint32_t u32[kNumUInt32Words]; + + //! \} //! \name Utilities //! \{ - inline bool eq(const char* other) const noexcept { - return strcmp(str, other) == 0; - } + inline bool equals(const char* other) const noexcept { return strcmp(str, other) == 0; } + +#if !defined(ASMJIT_NO_DEPRECATED) + ASMJIT_DEPRECATED("Use FixedString::equals() instead") + inline bool eq(const char* other) const noexcept { return equals(other); } +#endif // !ASMJIT_NO_DEPRECATED //! \} }; -// ============================================================================ -// [asmjit::String] -// ============================================================================ //! A simple non-reference counted string that uses small string optimization (SSO). //! //! This string has 3 allocation possibilities: //! -//! 1. Small - embedded buffer is used for up to `kSSOCapacity` characters. -//! This should handle most small strings and thus avoid dynamic -//! memory allocation for most use-cases. +//! 1. Small - embedded buffer is used for up to `kSSOCapacity` characters. This should handle most small +//! strings and thus avoid dynamic memory allocation for most use-cases. //! -//! 2. Large - string that doesn't fit into an embedded buffer (or string -//! that was truncated from a larger buffer) and is owned by -//! AsmJit. When you destroy the string AsmJit would automatically +//! 2. Large - string that doesn't fit into an embedded buffer (or string that was truncated from a larger +//! buffer) and is owned by AsmJit. When you destroy the string AsmJit would automatically //! release the large buffer. //! -//! 3. External - like Large (2), however, the large buffer is not owned by -//! AsmJit and won't be released when the string is destroyed -//! or reallocated. This is mostly useful for working with -//! larger temporary strings allocated on stack or with immutable -//! strings. +//! 3. External - like Large (2), however, the large buffer is not owned by AsmJit and won't be released when +//! the string is destroyed or reallocated. This is mostly useful for working with larger temporary +//! strings allocated on stack or with immutable strings. class String { public: ASMJIT_NONCOPYABLE(String) //! String operation. - enum Op : uint32_t { + enum class ModifyOp : uint32_t { //! Assignment - a new content replaces the current one. - kOpAssign = 0, + kAssign = 0, //! Append - a new content is appended to the string. - kOpAppend = 1 - }; - - //! String format flags. - enum FormatFlags : uint32_t { - kFormatShowSign = 0x00000001u, - kFormatShowSpace = 0x00000002u, - kFormatAlternate = 0x00000004u, - kFormatSigned = 0x80000000u + kAppend = 1 }; //! \cond INTERNAL @@ -106,8 +97,10 @@ public: //! String type. enum Type : uint8_t { - kTypeLarge = 0x1Fu, //!< Large string (owned by String). - kTypeExternal = 0x20u //!< External string (zone allocated or not owned by String). + //! Large string (owned by String). + kTypeLarge = 0x1Fu, + //! External string (zone allocated or not owned by String). + kTypeExternal = 0x20u }; union Raw { @@ -141,16 +134,16 @@ public: //! \{ //! Creates a default-initialized string if zero length. - inline String() noexcept + ASMJIT_INLINE_NODEBUG String() noexcept : _small {} {} //! Creates a string that takes ownership of the content of the `other` string. - inline String(String&& other) noexcept { + ASMJIT_INLINE_NODEBUG String(String&& other) noexcept { _raw = other._raw; other._resetInternal(); } - inline ~String() noexcept { + ASMJIT_INLINE_NODEBUG ~String() noexcept { reset(); } @@ -168,37 +161,37 @@ public: return *this; } - inline bool operator==(const char* other) const noexcept { return eq(other); } - inline bool operator!=(const char* other) const noexcept { return !eq(other); } + ASMJIT_INLINE_NODEBUG bool operator==(const char* other) const noexcept { return equals(other); } + ASMJIT_INLINE_NODEBUG bool operator!=(const char* other) const noexcept { return !equals(other); } - inline bool operator==(const String& other) const noexcept { return eq(other); } - inline bool operator!=(const String& other) const noexcept { return !eq(other); } + ASMJIT_INLINE_NODEBUG bool operator==(const String& other) const noexcept { return equals(other); } + ASMJIT_INLINE_NODEBUG bool operator!=(const String& other) const noexcept { return !equals(other); } //! \} //! \name Accessors //! \{ - inline bool isLarge() const noexcept { return _type >= kTypeLarge; } - inline bool isExternal() const noexcept { return _type == kTypeExternal; } + ASMJIT_INLINE_NODEBUG bool isExternal() const noexcept { return _type == kTypeExternal; } + ASMJIT_INLINE_NODEBUG bool isLargeOrExternal() const noexcept { return _type >= kTypeLarge; } //! Tests whether the string is empty. - inline bool empty() const noexcept { return size() == 0; } + ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return size() == 0; } //! Returns the size of the string. - inline size_t size() const noexcept { return isLarge() ? size_t(_large.size) : size_t(_type); } + ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return isLargeOrExternal() ? size_t(_large.size) : size_t(_type); } //! Returns the capacity of the string. - inline size_t capacity() const noexcept { return isLarge() ? _large.capacity : size_t(kSSOCapacity); } + ASMJIT_INLINE_NODEBUG size_t capacity() const noexcept { return isLargeOrExternal() ? _large.capacity : size_t(kSSOCapacity); } //! Returns the data of the string. - inline char* data() noexcept { return isLarge() ? _large.data : _small.data; } + ASMJIT_INLINE_NODEBUG char* data() noexcept { return isLargeOrExternal() ? _large.data : _small.data; } //! \overload - inline const char* data() const noexcept { return isLarge() ? _large.data : _small.data; } + ASMJIT_INLINE_NODEBUG const char* data() const noexcept { return isLargeOrExternal() ? _large.data : _small.data; } - inline char* start() noexcept { return data(); } - inline const char* start() const noexcept { return data(); } + ASMJIT_INLINE_NODEBUG char* start() noexcept { return data(); } + ASMJIT_INLINE_NODEBUG const char* start() const noexcept { return data(); } - inline char* end() noexcept { return data() + size(); } - inline const char* end() const noexcept { return data() + size(); } + ASMJIT_INLINE_NODEBUG char* end() noexcept { return data() + size(); } + ASMJIT_INLINE_NODEBUG const char* end() const noexcept { return data() + size(); } //! \} @@ -206,22 +199,22 @@ public: //! \{ //! Swaps the content of this string with `other`. - inline void swap(String& other) noexcept { + ASMJIT_INLINE_NODEBUG void swap(String& other) noexcept { std::swap(_raw, other._raw); } //! Clears the content of the string. ASMJIT_API Error clear() noexcept; - ASMJIT_API char* prepare(uint32_t op, size_t size) noexcept; + ASMJIT_API char* prepare(ModifyOp op, size_t size) noexcept; - ASMJIT_API Error _opString(uint32_t op, const char* str, size_t size = SIZE_MAX) noexcept; - ASMJIT_API Error _opChar(uint32_t op, char c) noexcept; - ASMJIT_API Error _opChars(uint32_t op, char c, size_t n) noexcept; - ASMJIT_API Error _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept; - ASMJIT_API Error _opHex(uint32_t op, const void* data, size_t size, char separator = '\0') noexcept; - ASMJIT_API Error _opFormat(uint32_t op, const char* fmt, ...) noexcept; - ASMJIT_API Error _opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept; + ASMJIT_API Error _opString(ModifyOp op, const char* str, size_t size = SIZE_MAX) noexcept; + ASMJIT_API Error _opChar(ModifyOp op, char c) noexcept; + ASMJIT_API Error _opChars(ModifyOp op, char c, size_t n) noexcept; + ASMJIT_API Error _opNumber(ModifyOp op, uint64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept; + ASMJIT_API Error _opHex(ModifyOp op, const void* data, size_t size, char separator = '\0') noexcept; + ASMJIT_API Error _opFormat(ModifyOp op, const char* fmt, ...) noexcept; + ASMJIT_API Error _opVFormat(ModifyOp op, const char* fmt, va_list ap) noexcept; //! Replaces the current of the string with `data` of the given `size`. //! @@ -229,92 +222,92 @@ public: ASMJIT_API Error assign(const char* data, size_t size = SIZE_MAX) noexcept; //! Replaces the current of the string with `other` string. - inline Error assign(const String& other) noexcept { + ASMJIT_INLINE_NODEBUG Error assign(const String& other) noexcept { return assign(other.data(), other.size()); } //! Replaces the current of the string by a single `c` character. - inline Error assign(char c) noexcept { - return _opChar(kOpAssign, c); + ASMJIT_INLINE_NODEBUG Error assign(char c) noexcept { + return _opChar(ModifyOp::kAssign, c); } //! Replaces the current of the string by a `c` character, repeated `n` times. - inline Error assignChars(char c, size_t n) noexcept { - return _opChars(kOpAssign, c, n); + ASMJIT_INLINE_NODEBUG Error assignChars(char c, size_t n) noexcept { + return _opChars(ModifyOp::kAssign, c, n); } //! Replaces the current of the string by a formatted integer `i` (signed). - inline Error assignInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept { - return _opNumber(kOpAssign, uint64_t(i), base, width, flags | kFormatSigned); + ASMJIT_INLINE_NODEBUG Error assignInt(int64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept { + return _opNumber(ModifyOp::kAssign, uint64_t(i), base, width, flags | StringFormatFlags::kSigned); } //! Replaces the current of the string by a formatted integer `i` (unsigned). - inline Error assignUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept { - return _opNumber(kOpAssign, i, base, width, flags); + ASMJIT_INLINE_NODEBUG Error assignUInt(uint64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept { + return _opNumber(ModifyOp::kAssign, i, base, width, flags); } //! Replaces the current of the string by the given `data` converted to a HEX string. - inline Error assignHex(const void* data, size_t size, char separator = '\0') noexcept { - return _opHex(kOpAssign, data, size, separator); + ASMJIT_INLINE_NODEBUG Error assignHex(const void* data, size_t size, char separator = '\0') noexcept { + return _opHex(ModifyOp::kAssign, data, size, separator); } //! Replaces the current of the string by a formatted string `fmt`. template<typename... Args> - inline Error assignFormat(const char* fmt, Args&&... args) noexcept { - return _opFormat(kOpAssign, fmt, std::forward<Args>(args)...); + ASMJIT_INLINE_NODEBUG Error assignFormat(const char* fmt, Args&&... args) noexcept { + return _opFormat(ModifyOp::kAssign, fmt, std::forward<Args>(args)...); } //! Replaces the current of the string by a formatted string `fmt` (va_list version). - inline Error assignVFormat(const char* fmt, va_list ap) noexcept { - return _opVFormat(kOpAssign, fmt, ap); + ASMJIT_INLINE_NODEBUG Error assignVFormat(const char* fmt, va_list ap) noexcept { + return _opVFormat(ModifyOp::kAssign, fmt, ap); } //! Appends `str` having the given size `size` to the string. //! //! Null terminated strings can set `size` to `SIZE_MAX`. - inline Error append(const char* str, size_t size = SIZE_MAX) noexcept { - return _opString(kOpAppend, str, size); + ASMJIT_INLINE_NODEBUG Error append(const char* str, size_t size = SIZE_MAX) noexcept { + return _opString(ModifyOp::kAppend, str, size); } //! Appends `other` string to this string. - inline Error append(const String& other) noexcept { + ASMJIT_INLINE_NODEBUG Error append(const String& other) noexcept { return append(other.data(), other.size()); } //! Appends a single `c` character. - inline Error append(char c) noexcept { - return _opChar(kOpAppend, c); + ASMJIT_INLINE_NODEBUG Error append(char c) noexcept { + return _opChar(ModifyOp::kAppend, c); } //! Appends `c` character repeated `n` times. - inline Error appendChars(char c, size_t n) noexcept { - return _opChars(kOpAppend, c, n); + ASMJIT_INLINE_NODEBUG Error appendChars(char c, size_t n) noexcept { + return _opChars(ModifyOp::kAppend, c, n); } //! Appends a formatted integer `i` (signed). - inline Error appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept { - return _opNumber(kOpAppend, uint64_t(i), base, width, flags | kFormatSigned); + ASMJIT_INLINE_NODEBUG Error appendInt(int64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept { + return _opNumber(ModifyOp::kAppend, uint64_t(i), base, width, flags | StringFormatFlags::kSigned); } //! Appends a formatted integer `i` (unsigned). - inline Error appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept { - return _opNumber(kOpAppend, i, base, width, flags); + ASMJIT_INLINE_NODEBUG Error appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept { + return _opNumber(ModifyOp::kAppend, i, base, width, flags); } //! Appends the given `data` converted to a HEX string. - inline Error appendHex(const void* data, size_t size, char separator = '\0') noexcept { - return _opHex(kOpAppend, data, size, separator); + ASMJIT_INLINE_NODEBUG Error appendHex(const void* data, size_t size, char separator = '\0') noexcept { + return _opHex(ModifyOp::kAppend, data, size, separator); } //! Appends a formatted string `fmt` with `args`. template<typename... Args> - inline Error appendFormat(const char* fmt, Args&&... args) noexcept { - return _opFormat(kOpAppend, fmt, std::forward<Args>(args)...); + ASMJIT_INLINE_NODEBUG Error appendFormat(const char* fmt, Args&&... args) noexcept { + return _opFormat(ModifyOp::kAppend, fmt, std::forward<Args>(args)...); } //! Appends a formatted string `fmt` (va_list version). - inline Error appendVFormat(const char* fmt, va_list ap) noexcept { - return _opVFormat(kOpAppend, fmt, ap); + ASMJIT_INLINE_NODEBUG Error appendVFormat(const char* fmt, va_list ap) noexcept { + return _opVFormat(ModifyOp::kAppend, fmt, ap); } ASMJIT_API Error padEnd(size_t n, char c = ' ') noexcept; @@ -322,8 +315,16 @@ public: //! Truncate the string length into `newSize`. ASMJIT_API Error truncate(size_t newSize) noexcept; - ASMJIT_API bool eq(const char* other, size_t size = SIZE_MAX) const noexcept; - inline bool eq(const String& other) const noexcept { return eq(other.data(), other.size()); } + ASMJIT_API bool equals(const char* other, size_t size = SIZE_MAX) const noexcept; + ASMJIT_INLINE_NODEBUG bool equals(const String& other) const noexcept { return equals(other.data(), other.size()); } + +#if !defined(ASMJIT_NO_DEPRECATED) + ASMJIT_DEPRECATED("Use String::equals() instead") + ASMJIT_INLINE_NODEBUG bool eq(const char* other, size_t size = SIZE_MAX) const noexcept { return equals(other, size); } + + ASMJIT_DEPRECATED("Use String::equals() instead") + ASMJIT_INLINE_NODEBUG bool eq(const String& other) const noexcept { return equals(other.data(), other.size()); } +#endif // !ASMJIT_NO_DEPRECATED //! \} @@ -332,46 +333,28 @@ public: //! Resets string to embedded and makes it empty (zero length, zero first char) //! - //! \note This is always called internally after an external buffer was released - //! as it zeroes all bytes used by String's embedded storage. + //! \note This is always called internally after an external buffer was released as it zeroes all bytes + //! used by String's embedded storage. inline void _resetInternal() noexcept { for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_raw.uptr); i++) _raw.uptr[i] = 0; } inline void _setSize(size_t newSize) noexcept { - if (isLarge()) + if (isLargeOrExternal()) _large.size = newSize; else _small.type = uint8_t(newSize); } //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use assign() instead of assignString()") - inline Error assignString(const char* data, size_t size = SIZE_MAX) noexcept { return assign(data, size); } - - ASMJIT_DEPRECATED("Use assign() instead of assignChar()") - inline Error assignChar(char c) noexcept { return assign(c); } - - ASMJIT_DEPRECATED("Use append() instead of appendString()") - inline Error appendString(const char* data, size_t size = SIZE_MAX) noexcept { return append(data, size); } - - ASMJIT_DEPRECATED("Use append() instead of appendChar()") - inline Error appendChar(char c) noexcept { return append(c); } -#endif // !ASMJIT_NO_DEPRECATED }; -// ============================================================================ -// [asmjit::StringTmp] -// ============================================================================ - //! Temporary string builder, has statically allocated `N` bytes. template<size_t N> class StringTmp : public String { public: - ASMJIT_NONCOPYABLE(StringTmp<N>) + ASMJIT_NONCOPYABLE(StringTmp) //! Embedded data. char _embeddedData[Support::alignUp(N + 1, sizeof(size_t))]; @@ -379,7 +362,7 @@ public: //! \name Construction & Destruction //! \{ - inline StringTmp() noexcept { + ASMJIT_INLINE_NODEBUG StringTmp() noexcept { _resetToTemporary(); } |