diff --git a/deps/ox/src/ox/model/desctypes.hpp b/deps/ox/src/ox/model/desctypes.hpp index 2273beff..0432f944 100644 --- a/deps/ox/src/ox/model/desctypes.hpp +++ b/deps/ox/src/ox/model/desctypes.hpp @@ -15,9 +15,9 @@ namespace ox { -using String = BString<100>; -using FieldName = String; -using TypeName = String; +using ModelString = BString<100>; +using FieldName = ModelString; +using TypeName = ModelString; enum class PrimitiveType: uint8_t { UnsignedInteger = 0, @@ -170,6 +170,6 @@ Error modelRead(T *io, DescriptorField *field) { return err; } -using TypeStore = ox::HashMap; +using TypeStore = ox::HashMap; } diff --git a/deps/ox/src/ox/std/CMakeLists.txt b/deps/ox/src/ox/std/CMakeLists.txt index a5400cf0..eade5aa5 100644 --- a/deps/ox/src/ox/std/CMakeLists.txt +++ b/deps/ox/src/ox/std/CMakeLists.txt @@ -8,6 +8,7 @@ add_library( random.cpp substitutes.cpp stacktrace.cpp + string.cpp strops.cpp trace.cpp ) diff --git a/deps/ox/src/ox/std/bstring.hpp b/deps/ox/src/ox/std/bstring.hpp new file mode 100644 index 00000000..0368f8fc --- /dev/null +++ b/deps/ox/src/ox/std/bstring.hpp @@ -0,0 +1,197 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "memops.hpp" +#include "strops.hpp" +#include "typetraits.hpp" + +namespace ox { + +// Bounded String +template +class BString { + private: + char m_buff[buffLen + 1]; + + public: + constexpr BString() noexcept; + + constexpr BString(const char *str) noexcept; + + constexpr const BString &operator=(const char *str) noexcept; + + constexpr const BString &operator=(char *str) noexcept; + + constexpr const BString &operator=(int64_t i) noexcept; + + constexpr const BString &operator+=(const char *str) noexcept; + + constexpr const BString &operator+=(char *str) noexcept; + + constexpr const BString &operator+=(int64_t i) noexcept; + + constexpr bool operator==(const BString &other) noexcept; + + constexpr bool operator!=(const BString &other) noexcept; + + constexpr char operator[](std::size_t i) const noexcept; + + constexpr char &operator[](std::size_t i) noexcept; + + constexpr char *data() noexcept; + + constexpr const char *c_str() const noexcept; + + /** + * Returns the number of characters in this string. + */ + constexpr std::size_t len() const noexcept; + + /** + * Returns the number of bytes used for this string. + */ + constexpr std::size_t bytes() const noexcept; + + /** + * Returns the capacity of bytes for this string. + */ + constexpr std::size_t cap() const noexcept; +}; + +template +constexpr BString::BString() noexcept { + m_buff[0] = 0; +} + +template +constexpr BString::BString(const char *str) noexcept { + *this = str; +} + +template +constexpr const BString &BString::operator=(int64_t i) noexcept { + char str[65] = {}; + ox_itoa(i, str); + return this->operator=(str); +} + +template +constexpr const BString &BString::operator=(const char *str) noexcept { + std::size_t strLen = ox_strlen(str) + 1; + if (cap() < strLen) { + strLen = cap(); + } + ox_memcpy(m_buff, str, strLen); + // make sure last element is a null terminator + m_buff[cap() - 1] = 0; + return *this; +} + +template +constexpr const BString &BString::operator=(char *str) noexcept { + return *this = static_cast(str); +} + +template +constexpr const BString &BString::operator+=(const char *str) noexcept { + std::size_t strLen = ox_strlen(str) + 1; + auto currentLen = len(); + if (cap() < currentLen + strLen) { + strLen = cap() - currentLen; + } + ox_memcpy(m_buff + currentLen, str, strLen); + // make sure last element is a null terminator + m_buff[currentLen + strLen] = 0; + return *this; +} + +template +constexpr const BString &BString::operator+=(char *str) noexcept { + return *this += static_cast(str); +} + +template +constexpr const BString &BString::operator+=(int64_t i) noexcept { + char str[65] = {}; + ox_itoa(i, str); + return this->operator+=(str); +} + +template +constexpr bool BString::operator==(const BString &other) noexcept { + bool retval = true; + std::size_t i = 0; + while (i < buffLen && (m_buff[i] || other.m_buff[i])) { + if (m_buff[i] != other.m_buff[i]) { + retval = false; + break; + } + i++; + } + return retval; +} + +template +constexpr bool BString::operator!=(const BString &other) noexcept { + return !operator==(other); +} + +template +constexpr char BString::operator[](std::size_t i) const noexcept { + return m_buff[i]; +} + +template +constexpr char &BString::operator[](std::size_t i) noexcept { + return m_buff[i]; +} + +template +constexpr char *BString::data() noexcept { + return static_cast(m_buff); +} + +template +constexpr const char *BString::c_str() const noexcept { + return static_cast(m_buff); +} + + +template +constexpr std::size_t BString::len() const noexcept { + std::size_t length = 0; + for (std::size_t i = 0; i < buffLen; i++) { + uint8_t b = static_cast(m_buff[i]); + if (b) { + if ((b & 128) == 0) { // normal ASCII character + length++; + } else if ((b & (256 << 6)) == (256 << 6)) { // start of UTF-8 character + length++; + } + } else { + break; + } + } + return length; +} + +template +constexpr std::size_t BString::bytes() const noexcept { + std::size_t i = 0; + for (i = 0; i < buffLen && m_buff[i]; i++); + return i + 1; // add one for null terminator +} + +template +constexpr std::size_t BString::cap() const noexcept { + return buffLen; +} + +} diff --git a/deps/ox/src/ox/std/string.cpp b/deps/ox/src/ox/std/string.cpp new file mode 100644 index 00000000..c341fec6 --- /dev/null +++ b/deps/ox/src/ox/std/string.cpp @@ -0,0 +1,118 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "string.hpp" + +namespace ox { + +String::String() noexcept { + m_buff.push_back(0); +} + +String::String(const char *str) noexcept { + m_buff.push_back(0); + *this = str; +} + +const String &String::operator=(int64_t i) noexcept { + char str[65] = {}; + ox_itoa(i, str); + return this->operator=(str); +} + +const String &String::operator=(const char *str) noexcept { + std::size_t strLen = ox_strlen(str) + 1; + m_buff.resize(strLen + 1); + memcpy(m_buff.data(), str, strLen); + // make sure last element is a null terminator + m_buff[m_buff.size() - 1] = 0; + return *this; +} + +const String &String::operator=(char *str) noexcept { + return *this = static_cast(str); +} + +const String &String::operator+=(const char *str) noexcept { + std::size_t strLen = ox_strlen(str); + auto currentLen = len(); + m_buff.resize(m_buff.size() + strLen); + memcpy(&m_buff[currentLen], str, strLen); + // make sure last element is a null terminator + m_buff[currentLen + strLen] = 0; + return *this; +} + +const String &String::operator+=(char *str) noexcept { + return *this += static_cast(str); +} + +const String &String::operator+=(int64_t i) noexcept { + char str[65] = {}; + ox_itoa(i, str); + return this->operator+=(str); +} + +bool String::operator==(const String &other) noexcept { + bool retval = true; + std::size_t i = 0; + while (i < m_buff.size() && (m_buff[i] || other.m_buff[i])) { + if (m_buff[i] != other.m_buff[i]) { + retval = false; + break; + } + i++; + } + return retval; +} + +bool String::operator!=(const String &other) noexcept { + return !operator==(other); +} + +char String::operator[](std::size_t i) const noexcept { + return m_buff[i]; +} + +char &String::operator[](std::size_t i) noexcept { + return m_buff[i]; +} + +char *String::data() noexcept { + return m_buff.data(); +} + +const char *String::c_str() const noexcept { + return static_cast(m_buff.data()); +} + + +std::size_t String::len() const noexcept { + std::size_t length = 0; + for (std::size_t i = 0; i < m_buff.size(); i++) { + uint8_t b = static_cast(m_buff[i]); + if (b) { + if ((b & 128) == 0) { // normal ASCII character + length++; + } else if ((b & (256 << 6)) == (256 << 6)) { // start of UTF-8 character + length++; + } + } else { + break; + } + } + return length; +} + +std::size_t String::bytes() const noexcept { + std::size_t i = 0; + for (i = 0; i < m_buff.size() && m_buff[i]; i++); + return i + 1; // add one for null terminator +} + +} diff --git a/deps/ox/src/ox/std/string.hpp b/deps/ox/src/ox/std/string.hpp index 0368f8fc..af4934e3 100644 --- a/deps/ox/src/ox/std/string.hpp +++ b/deps/ox/src/ox/std/string.hpp @@ -8,190 +8,58 @@ #pragma once +#include "bstring.hpp" #include "memops.hpp" #include "strops.hpp" #include "typetraits.hpp" +#include "vector.hpp" namespace ox { // Bounded String -template -class BString { +class String { private: - char m_buff[buffLen + 1]; + Vector m_buff; public: - constexpr BString() noexcept; + String() noexcept; - constexpr BString(const char *str) noexcept; + String(const char *str) noexcept; - constexpr const BString &operator=(const char *str) noexcept; + const String &operator=(const char *str) noexcept; - constexpr const BString &operator=(char *str) noexcept; + const String &operator=(char *str) noexcept; - constexpr const BString &operator=(int64_t i) noexcept; + const String &operator=(int64_t i) noexcept; - constexpr const BString &operator+=(const char *str) noexcept; + const String &operator+=(const char *str) noexcept; - constexpr const BString &operator+=(char *str) noexcept; + const String &operator+=(char *str) noexcept; - constexpr const BString &operator+=(int64_t i) noexcept; + const String &operator+=(int64_t i) noexcept; - constexpr bool operator==(const BString &other) noexcept; + bool operator==(const String &other) noexcept; - constexpr bool operator!=(const BString &other) noexcept; + bool operator!=(const String &other) noexcept; - constexpr char operator[](std::size_t i) const noexcept; + char operator[](std::size_t i) const noexcept; - constexpr char &operator[](std::size_t i) noexcept; + char &operator[](std::size_t i) noexcept; - constexpr char *data() noexcept; + char *data() noexcept; - constexpr const char *c_str() const noexcept; + const char *c_str() const noexcept; /** * Returns the number of characters in this string. */ - constexpr std::size_t len() const noexcept; + std::size_t len() const noexcept; /** * Returns the number of bytes used for this string. */ - constexpr std::size_t bytes() const noexcept; + std::size_t bytes() const noexcept; - /** - * Returns the capacity of bytes for this string. - */ - constexpr std::size_t cap() const noexcept; }; -template -constexpr BString::BString() noexcept { - m_buff[0] = 0; -} - -template -constexpr BString::BString(const char *str) noexcept { - *this = str; -} - -template -constexpr const BString &BString::operator=(int64_t i) noexcept { - char str[65] = {}; - ox_itoa(i, str); - return this->operator=(str); -} - -template -constexpr const BString &BString::operator=(const char *str) noexcept { - std::size_t strLen = ox_strlen(str) + 1; - if (cap() < strLen) { - strLen = cap(); - } - ox_memcpy(m_buff, str, strLen); - // make sure last element is a null terminator - m_buff[cap() - 1] = 0; - return *this; -} - -template -constexpr const BString &BString::operator=(char *str) noexcept { - return *this = static_cast(str); -} - -template -constexpr const BString &BString::operator+=(const char *str) noexcept { - std::size_t strLen = ox_strlen(str) + 1; - auto currentLen = len(); - if (cap() < currentLen + strLen) { - strLen = cap() - currentLen; - } - ox_memcpy(m_buff + currentLen, str, strLen); - // make sure last element is a null terminator - m_buff[currentLen + strLen] = 0; - return *this; -} - -template -constexpr const BString &BString::operator+=(char *str) noexcept { - return *this += static_cast(str); -} - -template -constexpr const BString &BString::operator+=(int64_t i) noexcept { - char str[65] = {}; - ox_itoa(i, str); - return this->operator+=(str); -} - -template -constexpr bool BString::operator==(const BString &other) noexcept { - bool retval = true; - std::size_t i = 0; - while (i < buffLen && (m_buff[i] || other.m_buff[i])) { - if (m_buff[i] != other.m_buff[i]) { - retval = false; - break; - } - i++; - } - return retval; -} - -template -constexpr bool BString::operator!=(const BString &other) noexcept { - return !operator==(other); -} - -template -constexpr char BString::operator[](std::size_t i) const noexcept { - return m_buff[i]; -} - -template -constexpr char &BString::operator[](std::size_t i) noexcept { - return m_buff[i]; -} - -template -constexpr char *BString::data() noexcept { - return static_cast(m_buff); -} - -template -constexpr const char *BString::c_str() const noexcept { - return static_cast(m_buff); -} - - -template -constexpr std::size_t BString::len() const noexcept { - std::size_t length = 0; - for (std::size_t i = 0; i < buffLen; i++) { - uint8_t b = static_cast(m_buff[i]); - if (b) { - if ((b & 128) == 0) { // normal ASCII character - length++; - } else if ((b & (256 << 6)) == (256 << 6)) { // start of UTF-8 character - length++; - } - } else { - break; - } - } - return length; -} - -template -constexpr std::size_t BString::bytes() const noexcept { - std::size_t i = 0; - for (i = 0; i < buffLen && m_buff[i]; i++); - return i + 1; // add one for null terminator -} - -template -constexpr std::size_t BString::cap() const noexcept { - return buffLen; -} - } diff --git a/deps/ox/src/ox/std/test/CMakeLists.txt b/deps/ox/src/ox/std/test/CMakeLists.txt index 6e9b0875..81079e32 100644 --- a/deps/ox/src/ox/std/test/CMakeLists.txt +++ b/deps/ox/src/ox/std/test/CMakeLists.txt @@ -12,5 +12,6 @@ add_test("Test\\ ox_memcmp\\ HIJKLMN\\ !=\\ ABCDEFG" StdTest "HIJKLMN != ABCDEFG add_test("Test\\ ox_memcmp\\ ABCDEFG\\ ==\\ ABCDEFG" StdTest "ABCDEFG == ABCDEFG") add_test("Test\\ ox_memcmp\\ ABCDEFGHI\\ ==\\ ABCDEFG" StdTest "ABCDEFGHI == ABCDEFG") add_test("Test\\ BString" StdTest "BString") +add_test("Test\\ String" StdTest "String") add_test("Test\\ Vector" StdTest "Vector") add_test("Test\\ HashMap" StdTest "HashMap") diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index f5521ee7..dad60511 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -40,12 +40,30 @@ map> tests = { { "BString", []() { - ox::BString<100> s; + ox::BString<5> s; s += "A"; s += "B"; s += 9; s += "C"; oxAssert(s == "AB9C", "BString append broken"); + s = "asdf"; + oxAssert(s == "asdf", "String assign broken"); + return OxError(0); + } + }, + { + "String", + []() { + ox::String s; + s += "A"; + s += "B"; + s += 9; + s += "C"; + oxAssert(s == "AB9C", "String append broken"); + s = "asdf"; + oxAssert(s == "asdf", "String assign broken"); + s += "aoeu"; + oxAssert(s == "asdfaoeu", "String append broken"); return OxError(0); } }, diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index 126a8e7a..45c86eb5 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -8,6 +8,7 @@ #pragma once +#include "new.hpp" #include "types.hpp" #include "utility.hpp" @@ -54,6 +55,8 @@ class Vector { T *data(); + const T *data() const; + bool contains(T) const noexcept; template @@ -197,6 +200,11 @@ T *Vector::data() { return m_items; } +template +const T *Vector::data() const { + return m_items; +} + template bool Vector::contains(T v) const noexcept { for (std::size_t i = 0; i < m_size; i++) {