- Setup Basic Implementation for String Library
This commit is contained in:
@@ -121,6 +121,9 @@ add_library(fennec STATIC
|
|||||||
include/fennec/fproc/strings/string.h
|
include/fennec/fproc/strings/string.h
|
||||||
|
|
||||||
include/fennec/fproc/strings/detail/__ctype.h
|
include/fennec/fproc/strings/detail/__ctype.h
|
||||||
|
include/fennec/fproc/strings/cstring.h
|
||||||
|
include/fennec/fproc/strings/locale.h
|
||||||
|
include/fennec/fproc/io/file.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled
|
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled
|
||||||
@@ -139,7 +142,7 @@ endif()
|
|||||||
|
|
||||||
target_compile_options(fennec PUBLIC "-mavx" "-mavx2" "-mavx512f") # SIMD Instructions, automatic vectorization will occur
|
target_compile_options(fennec PUBLIC "-mavx" "-mavx2" "-mavx512f") # SIMD Instructions, automatic vectorization will occur
|
||||||
|
|
||||||
target_link_options(fennec PRIVATE "-nostdlib -nodefaultlibs -fno-exceptions") # Do not compile base fennec library with c++ stdlib
|
target_link_options(fennec PRIVATE "-nostdlib -nodefaultlibs -fno-exceptions -fdiagnostics-all-candidates") # Do not compile base fennec library with c++ stdlib
|
||||||
# fennec does not use the C++ stdlib because it is bloated, difficult to read, and implementation defined.
|
# fennec does not use the C++ stdlib because it is bloated, difficult to read, and implementation defined.
|
||||||
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
|
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
|
||||||
|
|
||||||
|
|||||||
46
include/fennec/fproc/io/file.h
Normal file
46
include/fennec/fproc/io/file.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_FPROC_IO_FILE_H
|
||||||
|
#define FENNEC_FPROC_IO_FILE_H
|
||||||
|
|
||||||
|
#include <fennec/fproc/strings/cstring.h>
|
||||||
|
|
||||||
|
struct FILE;
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
class file
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
file();
|
||||||
|
~file();
|
||||||
|
|
||||||
|
file(const file&) = delete;
|
||||||
|
|
||||||
|
void open(const cstring& filename, const cstring& mode);
|
||||||
|
void close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE* _handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_FPROC_IO_FILE_H
|
||||||
222
include/fennec/fproc/strings/cstring.h
Normal file
222
include/fennec/fproc/strings/cstring.h
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_FPROC_STRINGS_CSTRING_H
|
||||||
|
#define FENNEC_FPROC_STRINGS_CSTRING_H
|
||||||
|
|
||||||
|
#include <fennec/fproc/strings/detail/__ctype.h>
|
||||||
|
#include <fennec/memory/detail/__string.h>
|
||||||
|
|
||||||
|
#include <fennec/lang/assert.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
// TODO: Document
|
||||||
|
|
||||||
|
using ::isalnum;
|
||||||
|
using ::isalpha;
|
||||||
|
using ::islower;
|
||||||
|
using ::isupper;
|
||||||
|
using ::isdigit;
|
||||||
|
using ::isxdigit;
|
||||||
|
using ::iscntrl;
|
||||||
|
using ::isgraph;
|
||||||
|
using ::isspace;
|
||||||
|
using ::isblank;
|
||||||
|
using ::isprint;
|
||||||
|
using ::ispunct;
|
||||||
|
|
||||||
|
using ::tolower;
|
||||||
|
using ::toupper;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief This struct wraps c-style strings
|
||||||
|
///
|
||||||
|
/// \details Requires that the string is null-terminated.
|
||||||
|
/// Prevents const qualified memory blocks from being manipulated.
|
||||||
|
/// This struct should be used when fennec::string would make unnecessary dynamic buffers.
|
||||||
|
struct cstring
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Default Constructor, initializes with nullptr
|
||||||
|
constexpr cstring()
|
||||||
|
: _str(nullptr), _len(0), _const(true)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Buffer Constructor, wraps the provided C-Style string
|
||||||
|
/// \param str the buffer to wrap
|
||||||
|
/// \param n the number of characters in the buffer plus the null terminator
|
||||||
|
constexpr cstring(char* str, size_t n)
|
||||||
|
: _str(str), _len(n - 1), _const(false)
|
||||||
|
{ assert(_str[n - 1] == '\0', "Invalid NTBS."); }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Buffer Constructor, wraps the provided C-Style string
|
||||||
|
/// \param str the buffer to wrap
|
||||||
|
/// \tparam n the number of characters in the buffer plus the null terminator
|
||||||
|
template<size_t n>
|
||||||
|
constexpr cstring(char(&str)[n])
|
||||||
|
: _str(str), _len(n - 1), _const(false)
|
||||||
|
{ assert(_str[n - 1] == '\0', "Invalid NTBS."); }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const Buffer Constructor, wraps the provided C-Style string
|
||||||
|
/// \param str the buffer to wrap
|
||||||
|
/// \param n the number of characters in the buffer plus the null terminator
|
||||||
|
constexpr cstring(const char* str, size_t n)
|
||||||
|
: _cstr(str), _len(n - 1), _const(true)
|
||||||
|
{ assert(_cstr[n - 1] == '\0', "Invalid NTBS."); }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Buffer Constructor, wraps the provided C-Style string
|
||||||
|
/// \param str the buffer to wrap
|
||||||
|
/// \tparam n the number of characters in the buffer plus the null terminator
|
||||||
|
template<size_t n>
|
||||||
|
constexpr cstring(const char(&str)[n])
|
||||||
|
: _cstr(str), _len(n - 1), _const(true)
|
||||||
|
{ assert(_cstr[n - 1] == '\0', "Invalid NTBS."); }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Move Constructor
|
||||||
|
/// \param str object to move
|
||||||
|
constexpr cstring(cstring&& str)
|
||||||
|
: _cstr(str._cstr), _len(str._len)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
constexpr cstring(const cstring&) = delete;
|
||||||
|
constexpr ~cstring() = default;
|
||||||
|
|
||||||
|
template<size_t n>
|
||||||
|
constexpr cstring& operator=(char(&str)[n]) {
|
||||||
|
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
||||||
|
_str = str; _len = n - 1; _const = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t n>
|
||||||
|
constexpr cstring& operator=(const char(&str)[n]) {
|
||||||
|
assert(str[n - 1] == '\0', "Invalid NTBS.");
|
||||||
|
_cstr = str; _len = n - 1; _const = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Properties ==========================================================================================================
|
||||||
|
|
||||||
|
constexpr size_t size() const { return _len; }
|
||||||
|
|
||||||
|
|
||||||
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Array Access Operator
|
||||||
|
/// \param i the index to access
|
||||||
|
/// \returns a reference to the character
|
||||||
|
constexpr char& operator[](size_t i) {
|
||||||
|
assert(i < size(), "Array Out of Bounds");
|
||||||
|
assert(not _const, "Attempted to Access Const-Qualified Memory as Non-Const");
|
||||||
|
return _str[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Const-Array Access Operator
|
||||||
|
/// \param i the index to access
|
||||||
|
/// \returns a copy of the character
|
||||||
|
constexpr char operator[](size_t i) const {
|
||||||
|
assert(i < size(), "Array Out of Bounds");
|
||||||
|
return _cstr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Dereference Operator
|
||||||
|
/// \returns A const qualified pointer to the underlying allocation
|
||||||
|
constexpr const char* operator*() const { return _cstr; }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Implicit Dereference Cast
|
||||||
|
constexpr operator const char*() const { return _cstr; }
|
||||||
|
|
||||||
|
|
||||||
|
// Examination =========================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns The length of the string to the first null-terminator
|
||||||
|
constexpr size_t length() const
|
||||||
|
{ return find('\0'); }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief String Comparison
|
||||||
|
/// \param ostr the string to compare against
|
||||||
|
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
|
||||||
|
/// current locale, otherwise a positive value.
|
||||||
|
constexpr int compare(const cstring& str) const
|
||||||
|
{ return ::strcoll(_cstr, str); }
|
||||||
|
|
||||||
|
constexpr bool operator==(const cstring& str) const
|
||||||
|
{ return compare(str) == 0; }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Finds the index of the first occurrence of `x` in the string
|
||||||
|
/// \param x the character to find
|
||||||
|
/// \returns The index of `x` if it occurs in the string, otherwise returns `size()`
|
||||||
|
constexpr size_t find(char x) const
|
||||||
|
{
|
||||||
|
const char* loc = ::strchr(_cstr, x);
|
||||||
|
return loc ? loc - _cstr : size();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||||
|
/// \param str the string to find
|
||||||
|
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||||
|
constexpr size_t find(const cstring& str) const
|
||||||
|
{
|
||||||
|
const char* loc = ::strstr(_cstr, str);
|
||||||
|
return loc ? loc - _cstr : size();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Finds the index of the last occurrence of `x` in the string.
|
||||||
|
/// \param x the string to find
|
||||||
|
/// \returns The index of `x` if it occurs in the string, otherwise returns `size()`
|
||||||
|
constexpr size_t rfind(char x) const
|
||||||
|
{
|
||||||
|
const char* loc = ::strrchr(_cstr, x);
|
||||||
|
return loc ? loc - _cstr : size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: constexpr size_t rfind(const string& str) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
union {
|
||||||
|
char* _str;
|
||||||
|
const char* _cstr;
|
||||||
|
};
|
||||||
|
size_t _len;
|
||||||
|
bool _const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_FPROC_STRINGS_CSTRING_H
|
||||||
@@ -22,8 +22,6 @@
|
|||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4117)
|
#pragma warning(disable:4117)
|
||||||
|
|
||||||
#define __PTRDIFF_TYPE__ ptrdiff_t
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma push_macro("__cplusplus")
|
#pragma push_macro("__cplusplus")
|
||||||
|
|||||||
36
include/fennec/fproc/strings/detail/__locale.h
Normal file
36
include/fennec/fproc/strings/detail/__locale.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_FPROC_STRINGS_DETAIL_CTYPE_H
|
||||||
|
#define FENNEC_FPROC_STRINGS_DETAIL_CTYPE_H
|
||||||
|
|
||||||
|
#if _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4117)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma push_macro("__cplusplus")
|
||||||
|
#undef __cplusplus
|
||||||
|
#include <locale.h>
|
||||||
|
#pragma pop_macro("__cplusplus")
|
||||||
|
|
||||||
|
#if _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // FENNEC_FPROC_STRINGS_DETAIL_CTYPE_H
|
||||||
44
include/fennec/fproc/strings/locale.h
Normal file
44
include/fennec/fproc/strings/locale.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_FPROC_STRINGS_LOCALE_H
|
||||||
|
#define FENNEC_FPROC_STRINGS_LOCALE_H
|
||||||
|
|
||||||
|
#include <fennec/fproc/strings/detail/__locale.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
enum locale : int
|
||||||
|
{
|
||||||
|
lc_all = LC_ALL
|
||||||
|
, lc_collate = LC_COLLATE
|
||||||
|
, lc_ctype = LC_CTYPE
|
||||||
|
, lc_monetary = LC_MONETARY
|
||||||
|
, lc_numeric = LC_NUMERIC
|
||||||
|
, lc_time = LC_TIME
|
||||||
|
};
|
||||||
|
|
||||||
|
using ::lconv;
|
||||||
|
|
||||||
|
using ::setlocale;
|
||||||
|
using ::localeconv;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_FPROC_STRINGS_LOCALE_H
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#ifndef FENNEC_FPROC_STRINGS_STRING_H
|
#ifndef FENNEC_FPROC_STRINGS_STRING_H
|
||||||
#define FENNEC_FPROC_STRINGS_STRING_H
|
#define FENNEC_FPROC_STRINGS_STRING_H
|
||||||
|
|
||||||
|
#include <fennec/fproc/strings/cstring.h>
|
||||||
#include <fennec/fproc/strings/detail/__ctype.h>
|
#include <fennec/fproc/strings/detail/__ctype.h>
|
||||||
|
|
||||||
#include <fennec/lang/assert.h>
|
#include <fennec/lang/assert.h>
|
||||||
@@ -28,35 +29,19 @@
|
|||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO: Document
|
|
||||||
|
|
||||||
using ::isalnum;
|
|
||||||
using ::isalpha;
|
|
||||||
using ::islower;
|
|
||||||
using ::isupper;
|
|
||||||
using ::isdigit;
|
|
||||||
using ::isxdigit;
|
|
||||||
using ::iscntrl;
|
|
||||||
using ::isgraph;
|
|
||||||
using ::isspace;
|
|
||||||
using ::isblank;
|
|
||||||
using ::isprint;
|
|
||||||
using ::ispunct;
|
|
||||||
|
|
||||||
using ::tolower;
|
|
||||||
using ::toupper;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Struct for wrapping c-style strings
|
/// \brief Struct for wrapping c-style strings
|
||||||
///
|
///
|
||||||
/// \details fennec will use this class over `const char*` for memory safety.
|
/// \details behaviour guarantees that the underlying string is null-terminated
|
||||||
/// behaviour guarantees that the underlying string is null-terminated
|
|
||||||
template<typename AllocT = allocator<char>>
|
template<typename AllocT = allocator<char>>
|
||||||
struct string
|
struct string
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using alloc_t = allocation<char, AllocT>;
|
using alloc_t = allocation<char, AllocT>;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors ========================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes empty string
|
/// \brief Default Constructor, initializes empty string
|
||||||
constexpr string()
|
constexpr string()
|
||||||
@@ -89,22 +74,9 @@ public:
|
|||||||
///
|
///
|
||||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
||||||
/// This constructor makes the assumption that `len` is the intended number of characters.
|
/// This constructor makes the assumption that `len` is the intended number of characters.
|
||||||
constexpr string(const char* str, size_t len)
|
constexpr string(const cstring& str)
|
||||||
: _str(str, len + 1)
|
: _str(str, str.size() + 1)
|
||||||
{ _str[len] = '\0'; }
|
{ _str[str.size()] = '\0'; }
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief Array Copy Constructor
|
|
||||||
/// \tparam N the number of characters
|
|
||||||
/// \param str the array to copy
|
|
||||||
///
|
|
||||||
/// \details if str is not null-terminated, adds additional character for null-termination.
|
|
||||||
template<size_t N>
|
|
||||||
constexpr string(const char str[N])
|
|
||||||
{
|
|
||||||
if (str[N - 1] == '\0') string(str, N - 1);
|
|
||||||
else string(str, N);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Copy Constructor
|
/// \brief String Copy Constructor
|
||||||
@@ -155,7 +127,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Implicit Dereference Cast
|
/// \brief Implicit Dereference Cast
|
||||||
constexpr operator const char*() const { return _str; }
|
constexpr operator const char*() const { return _str; }
|
||||||
|
|
||||||
|
|
||||||
// Examination =========================================================================================================
|
// Examination =========================================================================================================
|
||||||
@@ -193,6 +165,16 @@ public:
|
|||||||
return loc ? loc - _str : size();
|
return loc ? loc - _str : size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||||
|
/// \param str the string to find
|
||||||
|
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||||
|
constexpr size_t find(const cstring& str) const
|
||||||
|
{
|
||||||
|
const char* loc = ::strstr(_str, str);
|
||||||
|
return loc ? loc - _str : size();
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Finds the index of the last occurrence of `x` in the string.
|
/// \brief Finds the index of the last occurrence of `x` in the string.
|
||||||
/// \param x the string to find
|
/// \param x the string to find
|
||||||
@@ -271,6 +253,14 @@ public:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr string operator+(const cstring& str)
|
||||||
|
{
|
||||||
|
string res(size() + str.size()); // Make a new string with the size of this + str
|
||||||
|
fennec::memcpy(res, _str, size()); // Copy the contents of this
|
||||||
|
fennec::memcpy(&res[size()], str, str.size()); // Append the contents of str
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr string& operator+=(char c)
|
constexpr string& operator+=(char c)
|
||||||
{
|
{
|
||||||
size_t x = size();
|
size_t x = size();
|
||||||
@@ -287,6 +277,14 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr string& operator+=(const cstring& str)
|
||||||
|
{
|
||||||
|
size_t x = size();
|
||||||
|
resize(x + str.size());
|
||||||
|
fennec::memcpy(&_str[x], str, str.size());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alloc_t _str;
|
alloc_t _str;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ template<> struct __is_void<void> : true_type {};
|
|||||||
template<typename> struct __is_bool : false_type {};
|
template<typename> struct __is_bool : false_type {};
|
||||||
template<> struct __is_bool<bool_t> : true_type {};
|
template<> struct __is_bool<bool_t> : true_type {};
|
||||||
|
|
||||||
|
template<typename> struct __is_null_pointer : false_type {};
|
||||||
|
template<> struct __is_null_pointer<nullptr_t> : true_type {};
|
||||||
|
|
||||||
// Provides definitions for all builtin int types
|
// Provides definitions for all builtin int types
|
||||||
template<typename> struct __is_integral : false_type {};
|
template<typename> struct __is_integral : false_type {};
|
||||||
template<> struct __is_integral<bool_t> : true_type {};
|
template<> struct __is_integral<bool_t> : true_type {};
|
||||||
|
|||||||
@@ -126,6 +126,22 @@
|
|||||||
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 0
|
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics
|
||||||
|
#if __has_builtin(__is_array)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_ARRAY 1
|
||||||
|
# define FENNEC_BUILTIN_IS_ARRAY(arg) __is_array(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_ARRAY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics
|
||||||
|
#if __has_builtin(__is_class)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_CLASS 1
|
||||||
|
# define FENNEC_BUILTIN_IS_CLASS(arg) __is_class(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_CLASS
|
||||||
|
#endif
|
||||||
|
|
||||||
// Difficult and Inconsistent without intrinsics
|
// Difficult and Inconsistent without intrinsics
|
||||||
#if __has_builtin(__is_constructible)
|
#if __has_builtin(__is_constructible)
|
||||||
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
|
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
|
||||||
@@ -159,6 +175,22 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics.
|
||||||
|
#if __has_builtin(__is_enum)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_ENUM 1
|
||||||
|
# define FENNEC_BUILTIN_IS_ENUM(arg) __is_enum(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_ENUM 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics
|
||||||
|
#if __has_builtin(__is_final)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
|
||||||
|
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
// Inconsistent without intrinsics
|
// Inconsistent without intrinsics
|
||||||
#if __has_builtin(__is_polymorphic)
|
#if __has_builtin(__is_polymorphic)
|
||||||
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 1
|
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 1
|
||||||
|
|||||||
@@ -148,6 +148,74 @@ template<typename T> constexpr bool_t is_bool_v
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fennec::is_null_pointer =============================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief check if \p T is of type nullptr_t
|
||||||
|
///
|
||||||
|
/// \details Stores a boolean value in `is_null_pointer::value`, representing whether the provided type is of base type nullptr_t.
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> struct is_null_pointer
|
||||||
|
: detail::__is_null_pointer<remove_cvr_t<T>>{};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief shorthand for ```is_null_pointer<T>::value```
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> constexpr bool_t is_null_pointer_v
|
||||||
|
= is_null_pointer<T>::value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fennec::is_array ====================================================================================================
|
||||||
|
|
||||||
|
#if FENNEC_HAS_BUILTIN_IS_ARRAY
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief check if \p T is of an array type
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> struct is_array
|
||||||
|
: bool_constant<FENNEC_BUILTIN_IS_ARRAY(T)> {};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief check if \p T is of an array type
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> struct is_array
|
||||||
|
: false_type {};
|
||||||
|
|
||||||
|
// overload for a sized array type
|
||||||
|
template<typename T, size_t N> struct is_array<T[N]>
|
||||||
|
: true_type {};
|
||||||
|
|
||||||
|
// overload for a generic array type
|
||||||
|
template<typename T> struct is_array<T[]>
|
||||||
|
: true_type {};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief shorthand for ```is_array<T>::value```
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> constexpr bool_t is_array_v
|
||||||
|
= is_array<T>::value;
|
||||||
|
|
||||||
|
// fennec::is_class ====================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief check if \p T is a class
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> struct is_class
|
||||||
|
: bool_constant<FENNEC_BUILTIN_IS_CLASS(T)> {};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief check if \p T is a class
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> constexpr size_t is_class_v
|
||||||
|
= is_class<T>::value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Integral Types ======================================================================================================
|
// Integral Types ======================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ void __assert_impl(const char* expression, const char* file, int line, const cha
|
|||||||
__assert_callback(expression, file, line, function, description);
|
__assert_callback(expression, file, line, function, description);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
||||||
::abort();
|
::abort();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,9 @@ add_executable(fennec-test main.cpp
|
|||||||
tests/math/test_exponential.h
|
tests/math/test_exponential.h
|
||||||
tests/math/test_relational.h
|
tests/math/test_relational.h
|
||||||
tests/math/test_trigonometric.h
|
tests/math/test_trigonometric.h
|
||||||
|
tests/fproc/test_strings.h
|
||||||
|
tests/fproc/strings/test_cstring.h
|
||||||
|
tests/test_fproc.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(fennec-test PRIVATE
|
target_link_libraries(fennec-test PRIVATE
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "tests/test_memory.h"
|
#include "tests/test_memory.h"
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
#include "tests/test_fproc.h"
|
||||||
|
|
||||||
|
|
||||||
int main(int, char **)
|
int main(int, char **)
|
||||||
@@ -41,5 +42,10 @@ int main(int, char **)
|
|||||||
fennec::test::fennec_test_math();
|
fennec::test::fennec_test_math();
|
||||||
fennec_test_spacer(3);
|
fennec_test_spacer(3);
|
||||||
|
|
||||||
|
fennec_test_header("format processing library");
|
||||||
|
fennec_test_spacer(2);
|
||||||
|
fennec::test::fennec_test_fproc();
|
||||||
|
fennec_test_spacer(3);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ inline std::ostream& operator<<(std::ostream& os, const matrix<ScalarT, RowsV, C
|
|||||||
|
|
||||||
// Core test function
|
// Core test function
|
||||||
template<typename ResultT>
|
template<typename ResultT>
|
||||||
inline void __fennec_test_run(const std::string& expression, const ResultT result, const ResultT expected)
|
inline void __fennec_test_run(const std::string& expression, const ResultT& result, const ResultT& expected)
|
||||||
{
|
{
|
||||||
// Print out the expression as a string and the resulting value
|
// Print out the expression as a string and the resulting value
|
||||||
std::cout << std::boolalpha;
|
std::cout << std::boolalpha;
|
||||||
|
|||||||
57
test/tests/fproc/strings/test_cstring.h
Normal file
57
test/tests/fproc/strings/test_cstring.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_TEST_FPROC_STRINGS_CSTRING_H
|
||||||
|
#define FENNEC_TEST_FPROC_STRINGS_CSTRING_H
|
||||||
|
|
||||||
|
#include <fennec/fproc/strings/cstring.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
|
||||||
|
static char test_string[] = "Hello World!";
|
||||||
|
static const char test_string_const[] = "Hello World!";
|
||||||
|
|
||||||
|
inline void fennec_test_fproc_strings_cstring()
|
||||||
|
{
|
||||||
|
cstring str = test_string;
|
||||||
|
const cstring cstr = test_string_const;
|
||||||
|
|
||||||
|
fennec_test_run(str, cstr);
|
||||||
|
fennec_test_run(cstr, str);
|
||||||
|
|
||||||
|
fennec_test_spacer(1);
|
||||||
|
|
||||||
|
fennec_test_run(str.length(), size_t(12));
|
||||||
|
fennec_test_run(str.compare(cstr), 0);
|
||||||
|
fennec_test_run(str.find('W'), size_t(6));
|
||||||
|
fennec_test_run(str.find("World"), size_t(6));
|
||||||
|
fennec_test_run(str.rfind('o'), size_t(7));
|
||||||
|
|
||||||
|
fennec_test_spacer(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_TEST_FPROC_STRINGS_CSTRING_H
|
||||||
44
test/tests/fproc/test_strings.h
Normal file
44
test/tests/fproc/test_strings.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_TEST_FPROC_STRINGS_H
|
||||||
|
#define FENNEC_TEST_FPROC_STRINGS_H
|
||||||
|
|
||||||
|
#include "../../test.h"
|
||||||
|
#include "./strings/test_cstring.h"
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void fennec_test_fproc_strings()
|
||||||
|
{
|
||||||
|
fennec_test_subheader("cstring");
|
||||||
|
fennec_test_spacer(2);
|
||||||
|
fennec_test_fproc_strings_cstring();
|
||||||
|
fennec_test_spacer(3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_TEST_FPROC_STRINGS_H
|
||||||
44
test/tests/test_fproc.h
Normal file
44
test/tests/test_fproc.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_TEST_FPROC_H
|
||||||
|
#define FENNEC_TEST_FPROC_H
|
||||||
|
|
||||||
|
#include "../test.h"
|
||||||
|
#include "./fproc/test_strings.h"
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void fennec_test_fproc()
|
||||||
|
{
|
||||||
|
fennec_test_header("strings");
|
||||||
|
fennec_test_spacer(2);
|
||||||
|
fennec_test_fproc_strings();
|
||||||
|
fennec_test_spacer(3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_TEST_FPROC_H
|
||||||
Reference in New Issue
Block a user