mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 12:42:34 +01:00
StringView constexpr. (#351)
This commit is contained in:
committed by
GitHub
parent
0e221f9844
commit
808aa150f8
@@ -171,6 +171,13 @@ namespace bx
|
||||
return __builtin_bit_cast(Ty, _from);
|
||||
}
|
||||
|
||||
template<typename Ty, typename FromT>
|
||||
inline constexpr bool narrowCastTest(Ty* _out, const FromT& _from)
|
||||
{
|
||||
*_out = static_cast<Ty>(_from);
|
||||
return static_cast<FromT>(*_out) == _from;
|
||||
}
|
||||
|
||||
template<typename Ty, typename FromT>
|
||||
inline Ty narrowCast(const FromT& _from, Location _location)
|
||||
{
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace bx
|
||||
}
|
||||
|
||||
template<int32_t SizeT>
|
||||
inline constexpr StringLiteral::StringLiteral(const char (&str)[SizeT])
|
||||
: m_ptr(str)
|
||||
inline constexpr StringLiteral::StringLiteral(const char (&_str)[SizeT])
|
||||
: m_ptr(_str)
|
||||
, m_len(SizeT - 1)
|
||||
{
|
||||
BX_ASSERT('\0' == m_ptr[SizeT - 1], "Must be 0 terminated.");
|
||||
@@ -61,20 +61,21 @@ namespace bx
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline void StringLiteral::clear()
|
||||
inline constexpr void StringLiteral::clear()
|
||||
{
|
||||
m_ptr = "";
|
||||
m_len = 0;
|
||||
}
|
||||
|
||||
inline bool StringLiteral::isEmpty() const
|
||||
inline constexpr bool StringLiteral::isEmpty() const
|
||||
{
|
||||
return 0 == m_len;
|
||||
}
|
||||
|
||||
inline StringView::StringView()
|
||||
inline constexpr StringView::StringView()
|
||||
{
|
||||
clear();
|
||||
m_ptr = "";
|
||||
m_len = 0;
|
||||
}
|
||||
|
||||
inline constexpr StringView::StringView(const StringLiteral& _str)
|
||||
@@ -84,49 +85,49 @@ namespace bx
|
||||
{
|
||||
}
|
||||
|
||||
inline StringView::StringView(const StringView& _rhs)
|
||||
inline constexpr StringView::StringView(const StringView& _rhs)
|
||||
{
|
||||
set(_rhs);
|
||||
}
|
||||
|
||||
inline StringView::StringView(const StringView& _rhs, int32_t _start, int32_t _len)
|
||||
inline constexpr StringView::StringView(const StringView& _rhs, int32_t _start, int32_t _len)
|
||||
{
|
||||
set(_rhs, _start, _len);
|
||||
}
|
||||
|
||||
inline StringView& StringView::operator=(const char* _rhs)
|
||||
inline constexpr StringView& StringView::operator=(const char* _rhs)
|
||||
{
|
||||
set(_rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline StringView& StringView::operator=(const StringView& _rhs)
|
||||
inline constexpr StringView& StringView::operator=(const StringView& _rhs)
|
||||
{
|
||||
set(_rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline StringView::StringView(const char* _ptr)
|
||||
inline constexpr StringView::StringView(const char* _ptr)
|
||||
{
|
||||
set(_ptr, INT32_MAX);
|
||||
}
|
||||
|
||||
inline StringView::StringView(const char* _ptr, int32_t _len)
|
||||
inline constexpr StringView::StringView(const char* _ptr, int32_t _len)
|
||||
{
|
||||
set(_ptr, _len);
|
||||
}
|
||||
|
||||
inline StringView::StringView(const char* _ptr, const char* _term)
|
||||
inline constexpr StringView::StringView(const char* _ptr, const char* _term)
|
||||
{
|
||||
set(_ptr, _term);
|
||||
}
|
||||
|
||||
inline void StringView::set(const char* _ptr)
|
||||
inline constexpr void StringView::set(const char* _ptr)
|
||||
{
|
||||
set(_ptr, INT32_MAX);
|
||||
}
|
||||
|
||||
inline void StringView::set(const char* _ptr, int32_t _len)
|
||||
inline constexpr void StringView::set(const char* _ptr, int32_t _len)
|
||||
{
|
||||
clear();
|
||||
|
||||
@@ -138,68 +139,99 @@ namespace bx
|
||||
}
|
||||
}
|
||||
|
||||
inline void StringView::set(const char* _ptr, const char* _term)
|
||||
inline constexpr void StringView::set(const char* _ptr, const char* _term)
|
||||
{
|
||||
set(_ptr, int32_t(_term-_ptr) );
|
||||
}
|
||||
|
||||
inline void StringView::set(const StringView& _str)
|
||||
inline constexpr void StringView::set(const StringView& _str)
|
||||
{
|
||||
set(_str, 0, INT32_MAX);
|
||||
}
|
||||
|
||||
inline void StringView::set(const StringView& _str, int32_t _start, int32_t _len)
|
||||
inline constexpr void StringView::set(const StringView& _str, int32_t _start, int32_t _len)
|
||||
{
|
||||
const int32_t start = min(_start, _str.m_len);
|
||||
const int32_t len = clamp(_str.m_len - start, 0, min(_len, _str.m_len) );
|
||||
set(_str.m_ptr + start, len);
|
||||
}
|
||||
|
||||
inline void StringView::clear()
|
||||
inline constexpr void StringView::clear()
|
||||
{
|
||||
m_ptr = "";
|
||||
m_len = 0;
|
||||
m_0terminated = true;
|
||||
}
|
||||
|
||||
inline const char* StringView::getPtr() const
|
||||
inline constexpr const char* StringView::getPtr() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline const char* StringView::getTerm() const
|
||||
inline constexpr const char* StringView::getTerm() const
|
||||
{
|
||||
return m_ptr + m_len;
|
||||
}
|
||||
|
||||
inline bool StringView::isEmpty() const
|
||||
inline constexpr bool StringView::isEmpty() const
|
||||
{
|
||||
return 0 == m_len;
|
||||
}
|
||||
|
||||
inline int32_t StringView::getLength() const
|
||||
inline constexpr int32_t StringView::getLength() const
|
||||
{
|
||||
return m_len;
|
||||
}
|
||||
|
||||
inline bool StringView::is0Terminated() const
|
||||
inline constexpr bool StringView::is0Terminated() const
|
||||
{
|
||||
return m_0terminated;
|
||||
}
|
||||
|
||||
inline bool operator==(const StringView& _lhs, const StringView& _rhs)
|
||||
inline constexpr bool operator==(const StringView& _lhs, const StringView& _rhs)
|
||||
{
|
||||
return 0 == strCmp(_lhs, _rhs);
|
||||
const int32_t len = _lhs.getLength();
|
||||
|
||||
if (len != _rhs.getLength() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == len)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* lhs = _lhs.getPtr();
|
||||
const char* rhs = _rhs.getPtr();
|
||||
|
||||
if constexpr (!isConstantEvaluated() )
|
||||
{
|
||||
// note: comparison of addresses of literals has unspecified value
|
||||
if (lhs == rhs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t ii = 0, num = len-1
|
||||
; ii < num && *lhs == *rhs
|
||||
; ++ii, ++lhs, ++rhs
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
return *lhs == *rhs;
|
||||
}
|
||||
|
||||
inline bool overlap(const StringView& _a, const StringView& _b)
|
||||
inline constexpr bool overlap(const StringView& _a, const StringView& _b)
|
||||
{
|
||||
return _a.getTerm() > _b.getPtr()
|
||||
&& _b.getTerm() > _a.getPtr()
|
||||
;
|
||||
}
|
||||
|
||||
inline bool contain(const StringView& _a, const StringView& _b)
|
||||
inline constexpr bool contain(const StringView& _a, const StringView& _b)
|
||||
{
|
||||
return _a.getPtr() <= _b.getPtr()
|
||||
&& _a.getTerm() >= _b.getTerm()
|
||||
@@ -207,76 +239,76 @@ namespace bx
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline FixedStringT<MaxCapacityT>::FixedStringT()
|
||||
inline constexpr FixedStringT<MaxCapacityT>::FixedStringT()
|
||||
: m_len(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline FixedStringT<MaxCapacityT>::FixedStringT(const char* _str)
|
||||
inline constexpr FixedStringT<MaxCapacityT>::FixedStringT(const char* _str)
|
||||
: FixedStringT<MaxCapacityT>()
|
||||
{
|
||||
set(_str);
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline FixedStringT<MaxCapacityT>::FixedStringT(const StringView& _str)
|
||||
inline constexpr FixedStringT<MaxCapacityT>::FixedStringT(const StringView& _str)
|
||||
: FixedStringT<MaxCapacityT>()
|
||||
{
|
||||
set(_str);
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline FixedStringT<MaxCapacityT>::~FixedStringT()
|
||||
inline constexpr FixedStringT<MaxCapacityT>::~FixedStringT()
|
||||
{
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline void FixedStringT<MaxCapacityT>::set(const char* _str)
|
||||
inline constexpr void FixedStringT<MaxCapacityT>::set(const char* _str)
|
||||
{
|
||||
set(StringView(_str) );
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline void FixedStringT<MaxCapacityT>::set(const StringView& _str)
|
||||
inline constexpr void FixedStringT<MaxCapacityT>::set(const StringView& _str)
|
||||
{
|
||||
int32_t copied = strCopy(m_storage, MaxCapacityT, _str);
|
||||
m_len = copied;
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline void FixedStringT<MaxCapacityT>::append(const StringView& _str)
|
||||
inline constexpr void FixedStringT<MaxCapacityT>::append(const StringView& _str)
|
||||
{
|
||||
m_len += strCopy(&m_storage[m_len], MaxCapacityT-m_len, _str);
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline void FixedStringT<MaxCapacityT>::clear()
|
||||
inline constexpr void FixedStringT<MaxCapacityT>::clear()
|
||||
{
|
||||
m_len = 0;
|
||||
m_storage[0] = '\0';
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline bool FixedStringT<MaxCapacityT>::isEmpty() const
|
||||
inline constexpr bool FixedStringT<MaxCapacityT>::isEmpty() const
|
||||
{
|
||||
return 0 == m_len;
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline int32_t FixedStringT<MaxCapacityT>::getLength() const
|
||||
inline constexpr int32_t FixedStringT<MaxCapacityT>::getLength() const
|
||||
{
|
||||
return m_len;
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline const char* FixedStringT<MaxCapacityT>::getCPtr() const
|
||||
inline constexpr const char* FixedStringT<MaxCapacityT>::getCPtr() const
|
||||
{
|
||||
return m_storage;
|
||||
}
|
||||
|
||||
template<uint16_t MaxCapacityT>
|
||||
inline FixedStringT<MaxCapacityT>::operator StringView() const
|
||||
inline constexpr FixedStringT<MaxCapacityT>::operator StringView() const
|
||||
{
|
||||
return StringView(m_storage, m_len);
|
||||
}
|
||||
@@ -438,11 +470,23 @@ namespace bx
|
||||
return m_line;
|
||||
}
|
||||
|
||||
inline int32_t strLen(const StringView& _str, int32_t _max)
|
||||
inline constexpr int32_t strLen(const StringView& _str, int32_t _max)
|
||||
{
|
||||
return min(_str.getLength(), _max);
|
||||
}
|
||||
|
||||
inline constexpr int32_t strLen(const char* _str, int32_t _max)
|
||||
{
|
||||
if (NULL == _str)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* ptr = _str;
|
||||
for (; 0 < _max && *ptr != '\0'; ++ptr, --_max) {};
|
||||
return int32_t(ptr - _str);
|
||||
}
|
||||
|
||||
inline bool hasPrefix(const StringView& _str, const StringView& _prefix)
|
||||
{
|
||||
const int32_t len = _prefix.getLength();
|
||||
@@ -479,4 +523,76 @@ namespace bx
|
||||
return _str;
|
||||
}
|
||||
|
||||
inline bool fromString(int8_t* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(uint8_t* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(int16_t* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(uint16_t* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(int32_t* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(uint32_t* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(long* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(unsigned long* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
inline bool fromString(unsigned long long* _out, const StringView& _str)
|
||||
{
|
||||
long long tmp;
|
||||
fromString(&tmp, _str);
|
||||
|
||||
return narrowCastTest(_out, tmp);
|
||||
}
|
||||
|
||||
} // namespace bx
|
||||
|
||||
@@ -452,9 +452,9 @@
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
static_assert(__cplusplus >= BX_LANGUAGE_CPP17, "\n\n"
|
||||
static_assert(__cplusplus >= BX_LANGUAGE_CPP20, "\n\n"
|
||||
"\t** IMPORTANT! **\n\n"
|
||||
"\tC++17 standard support is required to build.\n"
|
||||
"\tC++20 standard support is required to build.\n"
|
||||
"\t\n");
|
||||
|
||||
// https://releases.llvm.org/
|
||||
|
||||
@@ -282,6 +282,14 @@ namespace bx
|
||||
/// Write C string.
|
||||
int32_t write(WriterI* _writer, const char* _str, Error* _err);
|
||||
|
||||
///
|
||||
template<typename Ty>
|
||||
inline int32_t write(WriterI* _writer, const Ty& _value, Error* _err);
|
||||
|
||||
///
|
||||
template<>
|
||||
int32_t write(WriterI* _writer, const StringView& _str, Error* _err);
|
||||
|
||||
/// Write formatted string.
|
||||
int32_t write(WriterI* _writer, const StringView& _format, va_list _argList, Error* _err);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace bx
|
||||
/// Construct string literal from C-style string literal.
|
||||
///
|
||||
template<int32_t SizeT>
|
||||
constexpr StringLiteral(const char (&str)[SizeT]);
|
||||
constexpr StringLiteral(const char (&_str)[SizeT]);
|
||||
|
||||
/// Returns string length.
|
||||
///
|
||||
@@ -43,11 +43,11 @@ namespace bx
|
||||
constexpr const char* getCPtr() const;
|
||||
|
||||
///
|
||||
void clear();
|
||||
constexpr void clear();
|
||||
|
||||
/// Returns `true` if string is empty.
|
||||
///
|
||||
bool isEmpty() const;
|
||||
constexpr bool isEmpty() const;
|
||||
|
||||
private:
|
||||
const char* m_ptr;
|
||||
@@ -61,75 +61,75 @@ namespace bx
|
||||
public:
|
||||
/// Construct default/empty string view.
|
||||
///
|
||||
StringView();
|
||||
constexpr StringView();
|
||||
|
||||
/// Construct string view from string literal.
|
||||
///
|
||||
constexpr StringView(const StringLiteral& _str);
|
||||
|
||||
///
|
||||
StringView(const StringView& _rhs);
|
||||
constexpr StringView(const StringView& _rhs);
|
||||
|
||||
///
|
||||
StringView(const StringView& _rhs, int32_t _start, int32_t _len);
|
||||
constexpr StringView(const StringView& _rhs, int32_t _start, int32_t _len);
|
||||
|
||||
///
|
||||
StringView& operator=(const char* _rhs);
|
||||
constexpr StringView& operator=(const char* _rhs);
|
||||
|
||||
///
|
||||
StringView& operator=(const StringView& _rhs);
|
||||
constexpr StringView& operator=(const StringView& _rhs);
|
||||
|
||||
///
|
||||
StringView(const char* _ptr);
|
||||
constexpr StringView(const char* _ptr);
|
||||
|
||||
///
|
||||
StringView(const char* _ptr, int32_t _len);
|
||||
constexpr StringView(const char* _ptr, int32_t _len);
|
||||
|
||||
///
|
||||
StringView(const char* _ptr, const char* _term);
|
||||
constexpr StringView(const char* _ptr, const char* _term);
|
||||
|
||||
///
|
||||
void set(const char* _ptr);
|
||||
constexpr void set(const char* _ptr);
|
||||
|
||||
///
|
||||
void set(const char* _ptr, int32_t _len);
|
||||
constexpr void set(const char* _ptr, int32_t _len);
|
||||
|
||||
///
|
||||
void set(const char* _ptr, const char* _term);
|
||||
constexpr void set(const char* _ptr, const char* _term);
|
||||
|
||||
///
|
||||
void set(const StringView& _str);
|
||||
constexpr void set(const StringView& _str);
|
||||
|
||||
///
|
||||
void set(const StringView& _str, int32_t _start, int32_t _len);
|
||||
constexpr void set(const StringView& _str, int32_t _start, int32_t _len);
|
||||
|
||||
///
|
||||
void clear();
|
||||
constexpr void clear();
|
||||
|
||||
/// Returns pointer to non-terminated string.
|
||||
///
|
||||
/// @attention Use of this pointer in standard C/C++ functions is not safe. You must use it
|
||||
/// in conjunction with `getTerm()` or getLength()`.
|
||||
///
|
||||
const char* getPtr() const;
|
||||
constexpr const char* getPtr() const;
|
||||
|
||||
/// Returns pointer past last character in string view.
|
||||
///
|
||||
/// @attention Dereferencing this pointer is not safe.
|
||||
///
|
||||
const char* getTerm() const;
|
||||
constexpr const char* getTerm() const;
|
||||
|
||||
/// Returns `true` if string is empty.
|
||||
///
|
||||
bool isEmpty() const;
|
||||
constexpr bool isEmpty() const;
|
||||
|
||||
/// Returns string length.
|
||||
///
|
||||
int32_t getLength() const;
|
||||
constexpr int32_t getLength() const;
|
||||
|
||||
/// Returns `true` if string is zero terminated.
|
||||
///
|
||||
bool is0Terminated() const;
|
||||
constexpr bool is0Terminated() const;
|
||||
|
||||
protected:
|
||||
const char* m_ptr;
|
||||
@@ -138,13 +138,13 @@ namespace bx
|
||||
};
|
||||
|
||||
/// Compare two string views.
|
||||
bool operator==(const StringView& _lhs, const StringView& _rhs);
|
||||
constexpr bool operator==(const StringView& _lhs, const StringView& _rhs);
|
||||
|
||||
/// Returns true if two string views overlap.
|
||||
bool overlap(const StringView& _a, const StringView& _b);
|
||||
constexpr bool overlap(const StringView& _a, const StringView& _b);
|
||||
|
||||
/// Returns true if string view `_a` contains string view `_b`.
|
||||
bool contain(const StringView& _a, const StringView& _b);
|
||||
constexpr bool contain(const StringView& _a, const StringView& _b);
|
||||
|
||||
/// Fixed capacity string.
|
||||
///
|
||||
@@ -153,44 +153,44 @@ namespace bx
|
||||
{
|
||||
public:
|
||||
///
|
||||
FixedStringT();
|
||||
constexpr FixedStringT();
|
||||
|
||||
///
|
||||
FixedStringT(const char* _str);
|
||||
constexpr FixedStringT(const char* _str);
|
||||
|
||||
///
|
||||
FixedStringT(const StringView& _str);
|
||||
constexpr FixedStringT(const StringView& _str);
|
||||
|
||||
///
|
||||
~FixedStringT();
|
||||
constexpr ~FixedStringT();
|
||||
|
||||
///
|
||||
void set(const char* _str);
|
||||
constexpr void set(const char* _str);
|
||||
|
||||
///
|
||||
void set(const StringView& _str);
|
||||
constexpr void set(const StringView& _str);
|
||||
|
||||
///
|
||||
void append(const StringView& _str);
|
||||
constexpr void append(const StringView& _str);
|
||||
|
||||
///
|
||||
void clear();
|
||||
constexpr void clear();
|
||||
|
||||
/// Returns `true` if string is empty.
|
||||
///
|
||||
bool isEmpty() const;
|
||||
constexpr bool isEmpty() const;
|
||||
|
||||
/// Returns string length.
|
||||
///
|
||||
int32_t getLength() const;
|
||||
constexpr int32_t getLength() const;
|
||||
|
||||
/// Returns zero-terminated C string pointer.
|
||||
///
|
||||
const char* getCPtr() const;
|
||||
constexpr const char* getCPtr() const;
|
||||
|
||||
/// Implicitly converts FixedStringT to StringView.
|
||||
///
|
||||
operator StringView() const;
|
||||
constexpr operator StringView() const;
|
||||
|
||||
private:
|
||||
char m_storage[MaxCapacityT];
|
||||
@@ -342,10 +342,10 @@ namespace bx
|
||||
int32_t strCmpV(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX);
|
||||
|
||||
/// Get string length.
|
||||
int32_t strLen(const char* _str, int32_t _max = INT32_MAX);
|
||||
constexpr int32_t strLen(const char* _str, int32_t _max = INT32_MAX);
|
||||
|
||||
/// Get string length.
|
||||
int32_t strLen(const StringView& _str, int32_t _max = INT32_MAX);
|
||||
constexpr int32_t strLen(const StringView& _str, int32_t _max = INT32_MAX);
|
||||
|
||||
/// Copy _num characters from string _src to _dst buffer of maximum _dstSize capacity
|
||||
/// including zero terminator. Copy will be terminated with '\0'.
|
||||
@@ -480,12 +480,36 @@ namespace bx
|
||||
/// Converts string to double value.
|
||||
bool fromString(double* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 8-bit integer value.
|
||||
bool fromString(int8_t* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 8-bit unsigned integer value.
|
||||
bool fromString(uint8_t* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 8-bit integer value.
|
||||
bool fromString(int16_t* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 8-bit unsigned integer value.
|
||||
bool fromString(uint16_t* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 32-bit integer value.
|
||||
bool fromString(int32_t* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 32-bit unsigned integer value.
|
||||
bool fromString(uint32_t* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to
|
||||
bool fromString(long* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to
|
||||
bool fromString(unsigned long* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 64-bit long long value.
|
||||
bool fromString(long long* _out, const StringView& _str);
|
||||
|
||||
/// Converts string to 64-bit unsigned long long value.
|
||||
bool fromString(unsigned long long* _out, const StringView& _str);
|
||||
|
||||
///
|
||||
class LineReader
|
||||
{
|
||||
|
||||
10
src/dtoa.cpp
10
src/dtoa.cpp
@@ -1093,7 +1093,7 @@ namespace bx
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fromString(int32_t* _out, const StringView& _str)
|
||||
bool fromString(long long* _out, const StringView& _str)
|
||||
{
|
||||
StringView str = strLTrimSpace(_str);
|
||||
|
||||
@@ -1113,7 +1113,7 @@ namespace bx
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t result = 0;
|
||||
long long result = 0;
|
||||
|
||||
for (ch = *ptr++; isNumeric(ch) && ptr <= term; ch = *ptr++)
|
||||
{
|
||||
@@ -1125,10 +1125,4 @@ namespace bx
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fromString(uint32_t* _out, const StringView& _str)
|
||||
{
|
||||
fromString( (int32_t*)_out, _str);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace bx
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace bx
|
||||
|
||||
typedef char (*CharFn)(char _ch);
|
||||
|
||||
inline char toNoop(char _ch)
|
||||
inline constexpr char toNoop(char _ch)
|
||||
{
|
||||
return _ch;
|
||||
}
|
||||
@@ -290,18 +290,6 @@ namespace bx
|
||||
);
|
||||
}
|
||||
|
||||
int32_t strLen(const char* _str, int32_t _max)
|
||||
{
|
||||
if (NULL == _str)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* ptr = _str;
|
||||
for (; 0 < _max && *ptr != '\0'; ++ptr, --_max) {};
|
||||
return int32_t(ptr - _str);
|
||||
}
|
||||
|
||||
inline int32_t strCopy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num)
|
||||
{
|
||||
BX_ASSERT(NULL != _dst, "_dst can't be NULL!");
|
||||
|
||||
@@ -13,41 +13,6 @@
|
||||
|
||||
bx::AllocatorI* g_allocator;
|
||||
|
||||
TEST_CASE("StringLiteral", "[string]")
|
||||
{
|
||||
constexpr bx::StringLiteral tmp[] = { "1389", "abvgd", "mac", "pod" };
|
||||
|
||||
REQUIRE(bx::isSorted(tmp, BX_COUNTOF(tmp) ) );
|
||||
|
||||
STATIC_REQUIRE(4 == tmp[0].getLength() );
|
||||
REQUIRE(4 == bx::strLen(tmp[0]) );
|
||||
REQUIRE(0 == bx::strCmp("1389", tmp[0]) );
|
||||
|
||||
STATIC_REQUIRE(5 == tmp[1].getLength() );
|
||||
REQUIRE(5 == bx::strLen(tmp[1]) );
|
||||
REQUIRE(0 == bx::strCmp("abvgd", tmp[1]) );
|
||||
|
||||
STATIC_REQUIRE(3 == tmp[2].getLength() );
|
||||
REQUIRE(3 == bx::strLen(tmp[2]) );
|
||||
REQUIRE(0 == bx::strCmp("mac", tmp[2]) );
|
||||
|
||||
STATIC_REQUIRE(3 == tmp[3].getLength() );
|
||||
REQUIRE(3 == bx::strLen(tmp[3]) );
|
||||
REQUIRE(0 == bx::strCmp("pod", tmp[3]) );
|
||||
|
||||
constexpr bx::StringLiteral copy(tmp[0]);
|
||||
|
||||
STATIC_REQUIRE(4 == copy.getLength() );
|
||||
REQUIRE(4 == bx::strLen(copy) );
|
||||
REQUIRE(0 == bx::strCmp("1389", copy) );
|
||||
|
||||
constexpr bx::StringView sv(tmp[1]);
|
||||
|
||||
REQUIRE(5 == sv.getLength() );
|
||||
REQUIRE(5 == bx::strLen(sv) );
|
||||
REQUIRE("abvgd" == sv);
|
||||
}
|
||||
|
||||
TEST_CASE("stringPrintfTy", "[string]")
|
||||
{
|
||||
std::string test;
|
||||
@@ -492,6 +457,47 @@ TEST_CASE("fromString int32_t", "[string]")
|
||||
REQUIRE(testFromString(-21, "-021") );
|
||||
}
|
||||
|
||||
TEST_CASE("StringLiteral", "[string]")
|
||||
{
|
||||
constexpr bx::StringLiteral tmp[] = { "1389", "abvgd", "mac", "pod" };
|
||||
|
||||
REQUIRE(bx::isSorted(tmp, BX_COUNTOF(tmp) ) );
|
||||
|
||||
STATIC_REQUIRE(4 == tmp[0].getLength() );
|
||||
STATIC_REQUIRE(4 == bx::strLen(tmp[0]) );
|
||||
REQUIRE(0 == bx::strCmp("1389", tmp[0]) );
|
||||
|
||||
STATIC_REQUIRE(5 == tmp[1].getLength() );
|
||||
STATIC_REQUIRE(5 == bx::strLen(tmp[1]) );
|
||||
REQUIRE(0 == bx::strCmp("abvgd", tmp[1]) );
|
||||
|
||||
STATIC_REQUIRE(3 == tmp[2].getLength() );
|
||||
STATIC_REQUIRE(3 == bx::strLen(tmp[2]) );
|
||||
REQUIRE(0 == bx::strCmp("mac", tmp[2]) );
|
||||
|
||||
STATIC_REQUIRE(3 == tmp[3].getLength() );
|
||||
STATIC_REQUIRE(3 == bx::strLen(tmp[3]) );
|
||||
REQUIRE(0 == bx::strCmp("pod", tmp[3]) );
|
||||
|
||||
constexpr bx::StringLiteral copy(tmp[0]);
|
||||
STATIC_REQUIRE(4 == copy.getLength() );
|
||||
REQUIRE(4 == bx::strLen(copy) );
|
||||
REQUIRE(0 == bx::strCmp("1389", copy) );
|
||||
|
||||
constexpr bx::StringView sv(tmp[1]);
|
||||
STATIC_REQUIRE(5 == sv.getLength() );
|
||||
STATIC_REQUIRE(5 == bx::strLen(sv) );
|
||||
STATIC_REQUIRE("abvgd" == sv);
|
||||
}
|
||||
|
||||
TEST_CASE("StringView constexpr", "[string]")
|
||||
{
|
||||
constexpr bx::StringView sv("1389");
|
||||
|
||||
STATIC_REQUIRE(sv == "1389");
|
||||
STATIC_REQUIRE(4 == bx::strLen(sv) );
|
||||
}
|
||||
|
||||
TEST_CASE("StringView", "[string]")
|
||||
{
|
||||
bx::StringView sv("test");
|
||||
|
||||
Reference in New Issue
Block a user