- Removed a bug with attempt to include pure c headers
- Added some more information about the license - fennec::file implementation
This commit is contained in:
@@ -21,40 +21,13 @@
|
||||
|
||||
#include <fennec/fproc/strings/string.h>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
inline string getcwd() {
|
||||
char cstr[MAX_PATH];
|
||||
if (GetCurrentDirectory(sizeof(str), str) == 0) {
|
||||
return string("");
|
||||
}
|
||||
return string(cstr);
|
||||
}
|
||||
string getcwd();
|
||||
string absolute(const cstring& path);
|
||||
string absolute(const string& path);
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <linux/limits.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
inline string getcwd() {
|
||||
char cstr[PATH_MAX];
|
||||
if (::getcwd(cstr, sizeof(cstr)) == NULL) {
|
||||
return string("");
|
||||
}
|
||||
return string(cstr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_FPROC_IO_COMMON_H
|
||||
|
||||
@@ -19,18 +19,6 @@
|
||||
#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 <stdio.h>
|
||||
#pragma pop_macro("__cplusplus")
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_FPROC_STRINGS_DETAIL_CTYPE_H
|
||||
|
||||
@@ -19,77 +19,259 @@
|
||||
#ifndef FENNEC_FPROC_IO_FILE_H
|
||||
#define FENNEC_FPROC_IO_FILE_H
|
||||
|
||||
#include <asm-generic/errno-base.h>
|
||||
|
||||
#include <fennec/fproc/strings/cstring.h>
|
||||
#include <fennec/fproc/strings/string.h>
|
||||
|
||||
struct FILE;
|
||||
#include <fennec/fproc/strings/wstring.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Mode flags for opening a file
|
||||
enum fmode : uint8_t
|
||||
///
|
||||
/// fmode_binary and fmode_wide are independent of the other modes
|
||||
///
|
||||
/// \details Valid Flag Combinations
|
||||
/// <table width="100%" class="fieldtable" id="table_fennec_fproc_io_fmode">
|
||||
/// <tr><th style="vertical-align: top">Flags
|
||||
/// <th style="vertical-align: top">Description
|
||||
///
|
||||
/// <tr><td style="vertical-align: top">`read`
|
||||
/// <td style="vertical-align: top">Opens file as read-only, reading from start
|
||||
///
|
||||
/// <tr><td style="vertical-align: top">`write`
|
||||
/// <td style="vertical-align: top">Opens file as write-only, writing to end
|
||||
///
|
||||
/// <tr><td style="vertical-align: top">`read | write`
|
||||
/// <td style="vertical-align: top">Opens file as read-write, reading from start
|
||||
///
|
||||
/// <tr><td style="vertical-align: top">`write | trunc`
|
||||
/// <td style="vertical-align: top">Opens file as write-only, destroying contents
|
||||
///
|
||||
/// <tr><td style="vertical-align: top">`read | write | trunc`
|
||||
/// <td style="vertical-align: top">Opens file as read-write, destroying contents
|
||||
/// </table>
|
||||
enum fmode_ : uint8_t
|
||||
{
|
||||
read = 0b00000001
|
||||
, write = 0b00000010
|
||||
, append = 0b00000100
|
||||
, noexists = 0b00001000
|
||||
fmode_read = 0b00000001 ///< Opens file for reading
|
||||
, fmode_write = 0b00000010 ///< Opens file for writing
|
||||
, fmode_trunc = 0b00000100 ///< Contents of the file will be destroyed, only compatible with write enabled modes
|
||||
, fmode_exclusive = 0b00001000 ///< Generates an error if the opened file is not empty
|
||||
, fmode_binary = 0b00010000 ///< Open in binary mode
|
||||
, fmode_wide = 0b00100000 ///< Opens a file in wide mode
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Structure for handling streams of data
|
||||
///
|
||||
/// \details operations, when errored, will return a corresponding error.
|
||||
/// Use file::get_error() to check if an error is present and return a corresponding string.
|
||||
/// Use file::clear_error() to clear the errored state.
|
||||
/// Some operations, specifically file::rename() and file::copy().
|
||||
class file
|
||||
{
|
||||
public:
|
||||
/// \brief value of an invalid position
|
||||
static constexpr size_t npos = -1;
|
||||
|
||||
///
|
||||
/// \brief Check if the provided mode bitflags are a valid combination
|
||||
/// \param mode the bitfield
|
||||
/// \returns true if the combination of flags is valid, false otherwise
|
||||
static constexpr bool is_valid(uint8_t mode) {
|
||||
bool t = mode & fmode_trunc;
|
||||
bool x = mode & fmode_exclusive;
|
||||
bool w = mode & fmode_write;
|
||||
|
||||
// when x is true, t must be true
|
||||
// when t is true, w must be true
|
||||
return (t && x && w)
|
||||
|| (t && w)
|
||||
|| !(t || x);
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns the c stdout
|
||||
static file& cout();
|
||||
|
||||
///
|
||||
/// \returns the c stdin
|
||||
static file& cin();
|
||||
|
||||
///
|
||||
/// \returns the c stderr
|
||||
static file& cerr();
|
||||
|
||||
///
|
||||
/// \brief default constructor, initializes an empty stream
|
||||
file();
|
||||
|
||||
///
|
||||
/// \brief default destructor, cleans up an open stream
|
||||
~file();
|
||||
|
||||
///
|
||||
/// \brief Opens a file at the provided path using the provided mode
|
||||
/// \param path the path to the provided file
|
||||
/// \param mode the flags for opening the file
|
||||
file(const cstring& path, fmode mode);
|
||||
file(const string& path, fmode mode);
|
||||
/// \brief move constructor
|
||||
/// \param file the stream to take ownership of
|
||||
file(file&& file) noexcept;
|
||||
|
||||
file(file&& file);
|
||||
file& operator=(file&& file) noexcept;
|
||||
|
||||
// don't allow copying streams
|
||||
file(const file&) = delete;
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
|
||||
///
|
||||
/// \returns the path the stream
|
||||
const string& path() const {
|
||||
return _path;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns the mode of the stream
|
||||
uint8_t mode() const {
|
||||
return _mode;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns true if there is a valid, open stream.
|
||||
bool is_open() const {
|
||||
return _handle != nullptr;
|
||||
}
|
||||
|
||||
|
||||
// File Access =========================================================================================================
|
||||
|
||||
void open(const cstring& filename, fmode mode);
|
||||
void open(const string& filename, fmode mode);
|
||||
void close();
|
||||
void commit();
|
||||
///
|
||||
/// \brief open a file
|
||||
/// \param path the path to the file
|
||||
/// \param mode the mode flags to open the file with
|
||||
/// \returns false on success, true on error
|
||||
bool open(const cstring& path, uint8_t mode);
|
||||
|
||||
///
|
||||
/// \brief open a file
|
||||
/// \param path the path to the file
|
||||
/// \param mode the mode flags to open the file with
|
||||
/// \returns false on success, true on error
|
||||
bool open(const string& path, uint8_t mode);
|
||||
|
||||
///
|
||||
/// \brief close a stream
|
||||
/// \returns false on success, true on error
|
||||
bool close();
|
||||
|
||||
///
|
||||
/// \brief commit the streams buffer to the file
|
||||
/// \returns false on success, true on error
|
||||
bool commit();
|
||||
|
||||
|
||||
// File Operations =====================================================================================================
|
||||
|
||||
void erase();
|
||||
void rename(const cstring& str);
|
||||
void rename(const string& str);
|
||||
///
|
||||
/// \brief closes the stream and erases the file
|
||||
/// \returns false on success, true on error
|
||||
bool erase();
|
||||
|
||||
///
|
||||
/// \brief rebinds the stream, copying contents to path, and erasing the old file
|
||||
/// \param path the new path
|
||||
/// \returns false on success, true on error
|
||||
///
|
||||
/// \details attempts to open a write-only stream at path,
|
||||
/// attempts to reopen this file as read-only,
|
||||
/// copies the contents of this file to the new stream,
|
||||
/// reopen the new stream with the flags of this file and binds to it,
|
||||
/// closes the old file.
|
||||
bool rename(const cstring& path);
|
||||
|
||||
///
|
||||
/// \brief rebinds the stream, copying contents to path, and erasing the old file
|
||||
/// \param path the new path
|
||||
/// \returns false on success, true on error
|
||||
///
|
||||
/// \details attempts to open a write-only stream at path,
|
||||
/// attempts to reopen this file as read-only,
|
||||
/// copies the contents of this file to the new stream,
|
||||
/// reopen the new stream with the flags of this file and binds to it,
|
||||
/// closes the old file.
|
||||
bool rename(const string& path);
|
||||
|
||||
///
|
||||
/// \brief copies the contents of this file to path.
|
||||
/// \param path the path to copy to
|
||||
/// \returns a file at the new path with the copied contents
|
||||
file copy(const cstring& path);
|
||||
|
||||
///
|
||||
/// \brief copies the contents of this file to path.
|
||||
/// \param path the path to copy to
|
||||
/// \returns a file at the new path with the copied contents
|
||||
file copy(const string& path);
|
||||
|
||||
|
||||
// File Positioning ====================================================================================================
|
||||
|
||||
size_t get_pos();
|
||||
void set_pos(size_t i);
|
||||
void rewind();
|
||||
size_t get_pos() const;
|
||||
bool set_pos(size_t i);
|
||||
bool rewind();
|
||||
bool eof() const;
|
||||
|
||||
|
||||
// Read Operations =====================================================================================================
|
||||
|
||||
char getc();
|
||||
wchar_t getwc();
|
||||
|
||||
size_t read(void* data, size_t size, size_t n);
|
||||
|
||||
template<typename T>
|
||||
size_t read(T* data, size_t n) {
|
||||
return read(static_cast<void*>(data), sizeof(T), n);
|
||||
}
|
||||
|
||||
template<typename T, size_t n>
|
||||
size_t read(T (&data)[n]) {
|
||||
return read(static_cast<void*>(data), sizeof(T), n);
|
||||
}
|
||||
|
||||
string getline();
|
||||
wstring getwline();
|
||||
|
||||
|
||||
// Write Operations ====================================================================================================
|
||||
|
||||
bool putc(char c);
|
||||
bool putwc(wchar_t c);
|
||||
|
||||
size_t write(const void* data, size_t size, size_t n);
|
||||
|
||||
template<typename T>
|
||||
size_t write(const T* data, size_t n) {
|
||||
return write(static_cast<const void*>(data), sizeof(T), n);
|
||||
}
|
||||
|
||||
template<typename T, size_t n>
|
||||
size_t write(const T (&data)[n]) {
|
||||
return write(static_cast<const void*>(data), sizeof(T), n);
|
||||
}
|
||||
|
||||
|
||||
// Error Handling ======================================================================================================
|
||||
|
||||
bool check_error();
|
||||
string get_error();
|
||||
void clear_error();
|
||||
|
||||
|
||||
//
|
||||
const char* get_error() const { return _error; }
|
||||
void clear_error() { _error = nullptr; }
|
||||
|
||||
private:
|
||||
FILE* _handle;
|
||||
string _path;
|
||||
fmode _mode;
|
||||
uint8_t _mode;
|
||||
char* _error;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -19,18 +19,7 @@
|
||||
#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 <ctype.h>
|
||||
#pragma pop_macro("__cplusplus")
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include <wctype.h>
|
||||
|
||||
#endif // FENNEC_FPROC_STRINGS_DETAIL_CTYPE_H
|
||||
|
||||
@@ -19,18 +19,6 @@
|
||||
#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
|
||||
|
||||
@@ -75,7 +75,33 @@ public:
|
||||
/// \details adds additional character for null termination.
|
||||
constexpr _string(char c, size_t n)
|
||||
: _str(n + 1) {
|
||||
fennec::memset(_str, c, n); _str[n] = '\0';
|
||||
fennec::memset(_str.data(), c, n); _str[n] = '\0';
|
||||
}
|
||||
///
|
||||
/// \brief Buffer Copy Constructor
|
||||
/// \param str the buffer to copy
|
||||
/// \param len number of characters in the buffer
|
||||
///
|
||||
/// \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.
|
||||
template<size_t n>
|
||||
constexpr _string(const char str[n])
|
||||
: _str(str, n + 1) {
|
||||
::strncpy(_str.data(), str, n);
|
||||
_str[n] = '\0';
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Buffer Copy Constructor
|
||||
/// \param str the buffer to copy
|
||||
/// \param len number of characters in the buffer
|
||||
///
|
||||
/// \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.
|
||||
constexpr _string(const char* str, size_t n)
|
||||
: _str(str, n + 1) {
|
||||
::strncpy(_str.data(), str, n);
|
||||
_str[n] = '\0';
|
||||
}
|
||||
|
||||
///
|
||||
@@ -94,7 +120,7 @@ public:
|
||||
/// \brief String Copy Constructor
|
||||
/// \param str the string to copy
|
||||
constexpr _string(const string& str)
|
||||
: _string(str, str.size() - 1) {
|
||||
: _string(str, str.size()) {
|
||||
}
|
||||
|
||||
constexpr _string(_string&& str) noexcept
|
||||
@@ -112,6 +138,10 @@ public:
|
||||
return _str.capacity() - 1;
|
||||
}
|
||||
|
||||
constexpr bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
|
||||
@@ -187,16 +217,16 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \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()`
|
||||
/// \brief Finds the index of the first occurrence of `c` in the string
|
||||
/// \param c the character to find
|
||||
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t find(char c, size_t i = 0) const {
|
||||
if (i >= size()) { // bounds check
|
||||
return size();
|
||||
}
|
||||
|
||||
const char* loc = ::strchr(_str + i, c); // get location using strchr
|
||||
return loc ? loc - _str : size(); // return size if not found
|
||||
const char* loc = ::strchr(_str.data() + i, c); // get location using strchr
|
||||
return loc ? loc - _str.data() : size(); // return size if not found
|
||||
}
|
||||
|
||||
///
|
||||
@@ -293,7 +323,18 @@ public:
|
||||
constexpr void resize(size_t n) {
|
||||
size_t i = size();
|
||||
_str.reallocate(n + 1);
|
||||
if (n > i) fennec::memset(*_str + i, '\0', n - i);
|
||||
if (n > i) fennec::memset(_str.data() + i, '\0', n - i);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Assignment Operator
|
||||
/// \param str the string to copy
|
||||
/// \returns a reference to `this`
|
||||
constexpr string& operator=(const cstring& str) {
|
||||
resize(str.size());
|
||||
fennec::memcpy(_str.data(), str, str.size());
|
||||
_str[str.size()] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -301,8 +342,8 @@ public:
|
||||
/// \param str the string to copy
|
||||
/// \returns a reference to `this`
|
||||
constexpr string& operator=(const string& str) {
|
||||
if (str.size() > size()) resize(str.size());
|
||||
fennec::memcpy(_str, str, str.size());
|
||||
resize(str.size());
|
||||
fennec::memcpy(_str.data(), str, str.size());
|
||||
_str[str.size()] = '\0';
|
||||
return *this;
|
||||
}
|
||||
@@ -321,10 +362,12 @@ public:
|
||||
/// \param i the start index
|
||||
/// \param n the number of characters
|
||||
/// \return
|
||||
constexpr string substring(size_t i, size_t n = size()) const {
|
||||
assert(i < size(), "Array Out of Bounds");
|
||||
constexpr string substring(size_t i, size_t n = npos) const {
|
||||
if (i >= size()) {
|
||||
return string("");
|
||||
}
|
||||
n = min(n, size() - i);
|
||||
return string(&_str[i], n);
|
||||
return string(_str.data() + i, n);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -340,14 +383,14 @@ public:
|
||||
|
||||
constexpr string operator+(const cstring& str) const {
|
||||
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[0], _str.data(), size()); // Copy the contents of this
|
||||
fennec::memcpy(&res[size()], str, str.size()); // Append the contents of str
|
||||
return res;
|
||||
}
|
||||
|
||||
constexpr string operator+(const string& str) const {
|
||||
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[0], _str.data(), size()); // Copy the contents of this
|
||||
fennec::memcpy(&res[size()], str, str.size()); // Append the contents of str
|
||||
return res;
|
||||
}
|
||||
|
||||
309
include/fennec/fproc/strings/wcstring.h
Normal file
309
include/fennec/fproc/strings/wcstring.h
Normal file
@@ -0,0 +1,309 @@
|
||||
// =====================================================================================================================
|
||||
// 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_wcstring_H
|
||||
#define FENNEC_FPROC_STRINGS_wcstring_H
|
||||
|
||||
#include <fennec/fproc/strings/detail/__ctype.h>
|
||||
#include <fennec/memory/detail/__string.h>
|
||||
|
||||
#include <fennec/lang/assert.h>
|
||||
|
||||
#include <fennec/math/common.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
// TODO: Document
|
||||
|
||||
using ::iswalnum;
|
||||
using ::iswalpha;
|
||||
using ::iswlower;
|
||||
using ::iswupper;
|
||||
using ::iswdigit;
|
||||
using ::iswxdigit;
|
||||
using ::iswcntrl;
|
||||
using ::iswgraph;
|
||||
using ::iswspace;
|
||||
using ::iswblank;
|
||||
using ::iswprint;
|
||||
using ::iswpunct;
|
||||
|
||||
using ::towlower;
|
||||
using ::towupper;
|
||||
|
||||
using ::towctrans;
|
||||
using ::wctrans;
|
||||
|
||||
///
|
||||
/// \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 wcstring
|
||||
{
|
||||
public:
|
||||
static constexpr size_t npos = -1;
|
||||
|
||||
// Constructors ========================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Default Constructor, initializes with nullptr
|
||||
constexpr wcstring()
|
||||
: _str(nullptr), _size(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 wcstring(wchar_t* str, size_t n)
|
||||
: _str(str)
|
||||
, _size(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 wcstring(wchar_t(&str)[n])
|
||||
: _str(str)
|
||||
, _size(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 wcstring(const wchar_t* str, size_t n)
|
||||
: _cstr(str)
|
||||
, _size(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 wcstring(const wchar_t(&str)[n])
|
||||
: _cstr(str)
|
||||
, _size(n - 1)
|
||||
, _const(true) {
|
||||
assert(_cstr[n - 1] == '\0', "Invalid NTBS.");
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Move Constructor
|
||||
/// \param str object to move
|
||||
constexpr wcstring(wcstring&& str) noexcept
|
||||
: _cstr(str._cstr)
|
||||
, _size(str._size)
|
||||
, _const(str._const) {
|
||||
str._cstr = nullptr;
|
||||
str._size = 0;
|
||||
str._const = true;
|
||||
}
|
||||
|
||||
// TODO: Document
|
||||
constexpr wcstring(const wcstring&) = delete;
|
||||
constexpr ~wcstring() = default;
|
||||
|
||||
// TODO: Document
|
||||
template<size_t n>
|
||||
constexpr wcstring& operator=(wchar_t(&str)[n]) {
|
||||
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
||||
_str = str; _size = n - 1; _const = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: Document
|
||||
template<size_t n>
|
||||
constexpr wcstring& operator=(const wchar_t(&str)[n]) {
|
||||
assert(str[n - 1] == '\0', "Invalid NTBS.");
|
||||
_cstr = str; _size = n - 1; _const = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: Document
|
||||
constexpr wcstring& operator=(wcstring&& str) noexcept {
|
||||
_cstr = str._cstr; str._cstr = nullptr;
|
||||
_size = str._size; str._size = 0;
|
||||
_const = str._const; str._const = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
|
||||
///
|
||||
/// \returns the size of the string excluding its null terminator, i.e. `(*str)[size()] == '\0'`
|
||||
constexpr size_t size() const { return _size; }
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Array Access Operator
|
||||
/// \param i the index to access
|
||||
/// \returns a reference to the character
|
||||
constexpr wchar_t& operator[](size_t i) {
|
||||
assertd(not _const, "Attempted to Access Const-Qualified Memory as Non-Const");
|
||||
assertd(i < size(), "Array Out of Bounds");
|
||||
return _str[i];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Const-Array Access Operator
|
||||
/// \param i the index to access
|
||||
/// \returns a copy of the character
|
||||
constexpr wchar_t operator[](size_t i) const {
|
||||
assertd(i < size(), "Array Out of Bounds");
|
||||
return _cstr[i];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Dereference Operator
|
||||
/// \returns A const qualified pointer to the underlying allocation
|
||||
constexpr const wchar_t* operator*() const {
|
||||
return _cstr;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Implicit Dereference Cast
|
||||
constexpr operator const wchar_t*() const {
|
||||
return _cstr;
|
||||
}
|
||||
|
||||
|
||||
// Examination =========================================================================================================
|
||||
|
||||
///
|
||||
/// \returns The length of the string to the first null-terminator
|
||||
constexpr size_t length() const {
|
||||
return find(L'\0');
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief String Comparison
|
||||
/// \param str 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 wcstring& str, size_t i = 0, size_t n = npos) const {
|
||||
if (i >= _size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = min(n, max(_size, str._size) + 1);
|
||||
return ::wcsncmp(_cstr + i, str, n);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief String Equality
|
||||
/// \param str the string to compare against
|
||||
/// \returns True if all characters are equal, false otherwise
|
||||
constexpr bool operator==(const wcstring& str) const {
|
||||
return compare(str) == 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the first occurrence of `c` in the string
|
||||
/// \param c the character to find
|
||||
/// \param i the index to start at
|
||||
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t find(wchar_t c, size_t i = 0) const {
|
||||
if (i >= _size) { // bounds check
|
||||
return _size;
|
||||
}
|
||||
|
||||
const wchar_t* loc = ::wcschr(_cstr + i, c); // get location using strchr
|
||||
return loc ? loc - _cstr : _size; // return size if not found
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the first occurrence of `str` in the string.
|
||||
/// \param str the string to find
|
||||
/// \param i the index to start at
|
||||
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t find(const wcstring& str, size_t i = 0) const {
|
||||
if (i + str._size > _size) { // bounds check
|
||||
return _size;
|
||||
}
|
||||
|
||||
const wchar_t* loc = ::wcsstr(_cstr + i, str); // get location using strstr
|
||||
return loc ? loc - _cstr : _size; // return size if not found
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the last occurrence of `c` in the string.
|
||||
/// \param c the string to find
|
||||
/// \param i the index to start at
|
||||
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t rfind(wchar_t c, size_t i = npos) const {
|
||||
if (_size == 0) {
|
||||
return _size;
|
||||
}
|
||||
|
||||
i = min(i, _size - 1); // clamp i to bounds
|
||||
do {
|
||||
if (_cstr[i] == c) return i; // loop backwards looking for c
|
||||
} while (i--);
|
||||
return _size; // base case
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the last occurrence of `str` in the string.
|
||||
/// \param str the string to find
|
||||
/// \param i the index to start at
|
||||
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t rfind(const wcstring& str, size_t i = npos) const {
|
||||
if (_size == 0) {
|
||||
return _size;
|
||||
}
|
||||
|
||||
const wchar_t first = str[0];
|
||||
i = min(i, _size - str._size);
|
||||
do {
|
||||
if(_cstr[i] == first) {
|
||||
if (compare(str, i, str._size - 1) == 0) {
|
||||
return i;
|
||||
}
|
||||
} // loop backwards looking for str
|
||||
} while (i--);
|
||||
return _size; // base case
|
||||
}
|
||||
|
||||
private:
|
||||
union { // hack to allow both const qualified and non-const strings
|
||||
wchar_t* _str;
|
||||
const wchar_t* _cstr;
|
||||
};
|
||||
size_t _size;
|
||||
bool _const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_FPROC_STRINGS_wcstring_H
|
||||
426
include/fennec/fproc/strings/wstring.h
Normal file
426
include/fennec/fproc/strings/wstring.h
Normal file
@@ -0,0 +1,426 @@
|
||||
// =====================================================================================================================
|
||||
// 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_wstringS_wstring_H
|
||||
#define FENNEC_FPROC_wstringS_wstring_H
|
||||
|
||||
#include <fennec/fproc/strings/detail/__ctype.h>
|
||||
#include <fennec/fproc/strings/wcstring.h>
|
||||
|
||||
#include <fennec/lang/assert.h>
|
||||
|
||||
#include <fennec/memory/allocator.h>
|
||||
#include <fennec/memory/common.h>
|
||||
|
||||
#include <fennec/math/common.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
// Forward def
|
||||
template<typename AllocT = allocator<wchar_t>> struct _wstring;
|
||||
|
||||
// Alias for default allocator
|
||||
using wstring = _wstring<>;
|
||||
|
||||
///
|
||||
/// \brief Struct for wrapping c-style strings
|
||||
///
|
||||
/// \details behaviour guarantees that the underlying string is null-terminated
|
||||
template<typename AllocT>
|
||||
struct _wstring
|
||||
{
|
||||
public:
|
||||
static constexpr size_t npos = -1;
|
||||
using alloc_t = allocation<wchar_t, AllocT>;
|
||||
|
||||
|
||||
// Constructors ========================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Default Constructor, initializes empty string
|
||||
constexpr _wstring()
|
||||
: _str() {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Sized Constructor, initializes a null-terminated string of size `n` with null wchar_tacters
|
||||
/// \param n the number of wchar_tacters
|
||||
///
|
||||
/// \details adds additional wchar_tacter for null termination.
|
||||
constexpr _wstring(size_t n)
|
||||
: _wstring('\0', n) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Sized Constructor, initializes a null-terminated string of size `n` filled with the wchar_tacter `c`
|
||||
/// \param c the wchar_tacter to fill with
|
||||
/// \param n the number of wchar_tacters
|
||||
///
|
||||
/// \details adds additional wchar_tacter for null termination.
|
||||
constexpr _wstring(wchar_t c, size_t n)
|
||||
: _str(n + 1) {
|
||||
fennec::wmemset(_str.data(), c, n); _str[n] = '\0';
|
||||
}
|
||||
///
|
||||
/// \brief Buffer Copy Constructor
|
||||
/// \param str the buffer to copy
|
||||
/// \param len number of wchar_tacters in the buffer
|
||||
///
|
||||
/// \details adds additional wchar_tacter for null termination. Ignores whether str is null-terminated.
|
||||
/// This constructor makes the assumption that `len` is the intended number of wchar_tacters.
|
||||
template<size_t n>
|
||||
constexpr _wstring(const wchar_t str[n])
|
||||
: _str(str, n + 1) {
|
||||
::wcsncpy(_str.data(), str, n);
|
||||
_str[n] = '\0';
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Buffer Copy Constructor
|
||||
/// \param str the buffer to copy
|
||||
/// \param len number of wchar_tacters in the buffer
|
||||
///
|
||||
/// \details adds additional wchar_tacter for null termination. Ignores whether str is null-terminated.
|
||||
/// This constructor makes the assumption that `len` is the intended number of wchar_tacters.
|
||||
constexpr _wstring(const wchar_t* str, size_t n)
|
||||
: _str(str, n + 1) {
|
||||
::wcsncpy(_str.data(), str, n);
|
||||
_str[n] = '\0';
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Buffer Copy Constructor
|
||||
/// \param str the buffer to copy
|
||||
/// \param len number of wchar_tacters in the buffer
|
||||
///
|
||||
/// \details adds additional wchar_tacter for null termination. Ignores whether str is null-terminated.
|
||||
/// This constructor makes the assumption that `len` is the intended number of wchar_tacters.
|
||||
constexpr _wstring(const wcstring& str)
|
||||
: _str(str, str.size() + 1) {
|
||||
_str[str.size()] = '\0';
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief String Copy Constructor
|
||||
/// \param str the string to copy
|
||||
constexpr _wstring(const wstring& str)
|
||||
: _wstring(str, str.size() - 1) {
|
||||
}
|
||||
|
||||
constexpr _wstring(_wstring&& str) noexcept
|
||||
: _str(fennec::move(str._str)) { }
|
||||
|
||||
///
|
||||
/// \brief String Destructor, cleans up the underlying allocation
|
||||
constexpr ~_wstring() = default; // allocation cleans up itself
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
|
||||
///
|
||||
/// \returns The size of the string excluding null terminator
|
||||
constexpr size_t size() const {
|
||||
return _str.capacity() - 1;
|
||||
}
|
||||
|
||||
constexpr bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Array Access Operator
|
||||
/// \param i the index to access
|
||||
/// \returns a reference to the wchar_tacter
|
||||
constexpr wchar_t& operator[](int i) {
|
||||
return _str[i];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Const-Array Access Operator
|
||||
/// \param i the index to access
|
||||
/// \returns a copy of the wchar_tacter
|
||||
constexpr wchar_t operator[](int i) const {
|
||||
assertd(i >= 0 && i < size(), "Array Out of Bounds");
|
||||
return _str[i];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Dereference Operator
|
||||
/// \returns A const qualified pointer to the underlying allocation
|
||||
constexpr const wchar_t* operator*() const {
|
||||
return _str.data();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Implicit Dereference Cast
|
||||
constexpr operator const wchar_t*() const {
|
||||
return _str.data();
|
||||
}
|
||||
|
||||
|
||||
// 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 wcstring& str, size_t i = 0, size_t n = npos) const {
|
||||
if (i >= size()) { // bounds check
|
||||
return -1;
|
||||
}
|
||||
n = fennec::min(n, fennec::max(_str, str.size()) + 1);
|
||||
|
||||
return ::wcsncmp(_str.data() + i, str, n);
|
||||
}
|
||||
|
||||
///
|
||||
/// \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 wstring& str, size_t i = 0, size_t n = npos) const {
|
||||
if (i >= size()) { // bounds check
|
||||
return -1;
|
||||
}
|
||||
n = min(n, max(size(), str.size()) + 1);
|
||||
|
||||
return ::wcsncmp(_str.data() + i, str, n);
|
||||
}
|
||||
|
||||
constexpr bool operator==(const _wstring& str) const {
|
||||
return compare(str) == 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the first occurrence of `c` in the string
|
||||
/// \param c the wchar_tacter to find
|
||||
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t find(wchar_t c, size_t i = 0) const {
|
||||
if (i >= size()) { // bounds check
|
||||
return size();
|
||||
}
|
||||
|
||||
const wchar_t* loc = ::wcschr(_str.data() + i, c); // get location using strchr
|
||||
return loc ? loc - _str.data() : size(); // return size if not found
|
||||
}
|
||||
|
||||
///
|
||||
/// \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 wstring& str, size_t i = 0) const { // bounds check
|
||||
if (i >= size()) { // bounds check
|
||||
return size();
|
||||
}
|
||||
|
||||
const wchar_t* loc = ::wcsstr(_str, str);
|
||||
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 wcstring& str, size_t i = 0) const {
|
||||
if (i + str.size() > size()) { // bounds check
|
||||
return size();
|
||||
}
|
||||
|
||||
const wchar_t* loc = ::wcsstr(_str + i, str); // get location using strstr
|
||||
return loc ? loc - _str : size(); // return size if not found
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the last occurrence of `c` in the string.
|
||||
/// \param c the string to find
|
||||
/// \param i the index to start at
|
||||
/// \returns The index of `c` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t rfind(wchar_t c, size_t i = npos) const {
|
||||
if (size() == 0) {
|
||||
return size();
|
||||
}
|
||||
i = min(i, size() - 1); // clamp i to bounds
|
||||
do {
|
||||
if (_str[i] == c) { // loop backwards looking for c
|
||||
return i;
|
||||
}
|
||||
} while (i--);
|
||||
return size(); // base case
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the last occurrence of `str` in the string.
|
||||
/// \param str the string to find
|
||||
/// \param i the index to start at
|
||||
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t rfind(const wcstring& str, size_t i = npos) const {
|
||||
if (size() == 0) {
|
||||
return size();
|
||||
}
|
||||
const wchar_t first = str[0];
|
||||
i = min(i, size() - str.size());
|
||||
do {
|
||||
if(_str[i] == first) {
|
||||
if (compare(str, i) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} while (i--);
|
||||
return size(); // base case
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the index of the last occurrence of `str` in the string.
|
||||
/// \param str the string to find
|
||||
/// \param i the index to start at
|
||||
/// \returns The index of `str` if it occurs in the string, otherwise returns `size()`
|
||||
constexpr size_t rfind(const wstring& str, size_t i = npos) const {
|
||||
if (size() == 0) {
|
||||
return size();
|
||||
}
|
||||
const wchar_t first = str[0];
|
||||
i = min(i, size() - str.size());
|
||||
do {
|
||||
if(_str[i] == first) {
|
||||
if (compare(str, i) == 0) { // loop backwards looking for str
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} while (i--);
|
||||
return size(); // base case
|
||||
}
|
||||
|
||||
// Manipulation ========================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Resize the string, filling additional bytes with `'\0'`
|
||||
/// \param n the new size of the string
|
||||
constexpr void resize(size_t n) {
|
||||
size_t i = size();
|
||||
_str.reallocate(n + 1);
|
||||
if (n > i) fennec::wmemset(_str.data() + i, L'\0', n - i);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Assignment Operator
|
||||
/// \param str the string to copy
|
||||
/// \returns a reference to `this`
|
||||
constexpr wstring& operator=(const wcstring& str) {
|
||||
if (str.size() > size()) resize(str.size());
|
||||
fennec::wmemcpy(_str.data(), str, str.size());
|
||||
_str[str.size()] = L'\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Assignment Operator
|
||||
/// \param str the string to copy
|
||||
/// \returns a reference to `this`
|
||||
constexpr wstring& operator=(const wstring& str) {
|
||||
if (str.size() > size()) resize(str.size());
|
||||
fennec::wmemcpy(_str.data(), str, str.size());
|
||||
_str[str.size()] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Move Assignment Operator
|
||||
/// \param str the string to move
|
||||
/// \returns a reference to `this`
|
||||
constexpr wstring& operator=(wstring&& str) noexcept {
|
||||
_str = fennec::move(str._str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Retrieve a substring of a string
|
||||
/// \param i the start index
|
||||
/// \param n the number of wchar_tacters
|
||||
/// \return
|
||||
constexpr wstring substring(size_t i, size_t n = npos) const {
|
||||
if (i >= size()) {
|
||||
return wstring("");
|
||||
}
|
||||
n = min(n, size() - i);
|
||||
return wstring(_str.data() + i, n);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Returns a string with `c` appended to it
|
||||
/// \param c
|
||||
/// \returns
|
||||
constexpr wstring operator+(wchar_t c) const {
|
||||
// Copy contents with one additional byte.
|
||||
wstring res(_str, _str.size());
|
||||
res[size()] = c; // Set the last wchar_tacter to c
|
||||
return res;
|
||||
}
|
||||
|
||||
constexpr wstring operator+(const wcstring& str) const {
|
||||
wstring res(size() + str.size()); // Make a new string with the size of this + str
|
||||
fennec::wmemcpy(&res[0], _str.data(), size()); // Copy the contents of this
|
||||
fennec::wmemcpy(&res[size()], str, str.size()); // Append the contents of str
|
||||
return res;
|
||||
}
|
||||
|
||||
constexpr wstring operator+(const wstring& str) const {
|
||||
wstring res(size() + str.size()); // Make a new string with the size of this + str
|
||||
fennec::wmemcpy(&res[0], _str.data(), size()); // Copy the contents of this
|
||||
fennec::wmemcpy(&res[size()], str, str.size()); // Append the contents of str
|
||||
return res;
|
||||
}
|
||||
|
||||
constexpr wstring& operator+=(wchar_t c) {
|
||||
size_t x = size();
|
||||
resize(x + 1);
|
||||
_str[x] = c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr wstring& operator+=(const wcstring& str) {
|
||||
size_t x = size();
|
||||
resize(x + str.size());
|
||||
fennec::wmemcpy(&_str[x], str, str.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr wstring& operator+=(const wstring& str) {
|
||||
size_t x = size();
|
||||
resize(x + str.size());
|
||||
fennec::wmemcpy(&_str[x], str, str.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
alloc_t _str;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // FENNEC_FPROC_wstringS_wstring_H
|
||||
@@ -26,14 +26,7 @@
|
||||
#define __PTRDIFF_TYPE__ ptrdiff_t
|
||||
#endif
|
||||
|
||||
#pragma push_macro("__cplusplus")
|
||||
#undef __cplusplus
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#pragma pop_macro("__cplusplus")
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_LANG_DETAIL_INT_H
|
||||
|
||||
@@ -19,20 +19,6 @@
|
||||
#ifndef FENNEC_LANG_DETAIL_STDLIB_H
|
||||
#define FENNEC_LANG_DETAIL_STDLIB_H
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4117)
|
||||
#endif
|
||||
|
||||
#pragma push_macro("__cplusplus")
|
||||
#undef __cplusplus
|
||||
extern "C" {
|
||||
#include <stdlib.h>
|
||||
}
|
||||
#pragma pop_macro("__cplusplus")
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_LANG_DETAIL_STDLIB_H
|
||||
|
||||
@@ -19,20 +19,11 @@
|
||||
#ifndef FENNEC_MATH_DETAIL_MATH_H
|
||||
#define FENNEC_MATH_DETAIL_MATH_H
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4117)
|
||||
#endif
|
||||
|
||||
#pragma push_macro("__cplusplus")
|
||||
#undef __cplusplus
|
||||
#include <math.h>
|
||||
#pragma pop_macro("__cplusplus")
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#undef div
|
||||
#undef acos
|
||||
#undef asin
|
||||
|
||||
@@ -691,8 +691,4 @@ template<typename genType> constexpr genType log_phi() { return
|
||||
|
||||
}
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_MATH_EXT_CONSTANTS_H
|
||||
|
||||
@@ -615,8 +615,4 @@ struct vector_storage<4, SwizzleGenT, DataT>
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_MATH_VECTOR_STORAGE_H
|
||||
|
||||
@@ -508,12 +508,7 @@ public:
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
constexpr const value_t operator[](size_t i) const requires requires { is_fundamental_v<value_t> == true; } {
|
||||
assertd(i < size(), "Array Out of Bounds");
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
constexpr const value_t& operator[](size_t i) const requires requires { is_fundamental_v<value_t> == false; } {
|
||||
constexpr const value_t operator[](size_t i) const {
|
||||
assertd(i < size(), "Array Out of Bounds");
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
@@ -23,27 +23,15 @@
|
||||
// see https://git.mslockbo.org/mslockbo/fennec/src/commit/0eeb7ae3cff9d78e98dc5d9fc09bcb98b10986b9 for previous
|
||||
// implementation
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4117)
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define __OPTIMIZE__
|
||||
#endif
|
||||
|
||||
#pragma push_macro("__cplusplus")
|
||||
#undef __cplusplus
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#pragma pop_macro("__cplusplus")
|
||||
|
||||
#if __GNUC__
|
||||
#undef __OPTIMIZE__
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // FENNEC_MEMORY_DETAIL_MEMORY_H
|
||||
|
||||
@@ -102,37 +102,4 @@ void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noe
|
||||
void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept;
|
||||
|
||||
|
||||
// Platform specific code
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
inline size_T pagesize() {
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetSystemInfo(&sysInfo);
|
||||
return sysInfo.dwPageSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
inline size_t pagesize() {
|
||||
return sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // FENNEC_MEMORY_NEW_H
|
||||
|
||||
Reference in New Issue
Block a user