- Fixed a bunch of compilation errors and warnings
- Added frameworks for retrieving specific filesystem information for a target platform
This commit is contained in:
@@ -75,8 +75,9 @@ add_library(fennec STATIC
|
|||||||
# MEMORY ===============================================================================================================
|
# MEMORY ===============================================================================================================
|
||||||
include/fennec/memory/new.h source/memory/new.cpp
|
include/fennec/memory/new.h source/memory/new.cpp
|
||||||
|
|
||||||
include/fennec/memory/allocator.h
|
|
||||||
include/fennec/memory/common.h
|
include/fennec/memory/common.h
|
||||||
|
include/fennec/memory/allocator.h
|
||||||
|
include/fennec/memory/memory.h
|
||||||
include/fennec/memory/pointers.h
|
include/fennec/memory/pointers.h
|
||||||
include/fennec/memory/ptr_traits.h
|
include/fennec/memory/ptr_traits.h
|
||||||
|
|
||||||
@@ -118,15 +119,17 @@ add_library(fennec STATIC
|
|||||||
# FPROC ================================================================================================================
|
# FPROC ================================================================================================================
|
||||||
|
|
||||||
# Strings
|
# Strings
|
||||||
|
include/fennec/fproc/strings/cstring.h
|
||||||
|
include/fennec/fproc/strings/locale.h
|
||||||
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
|
# IO
|
||||||
include/fennec/fproc/io/file.h
|
include/fennec/fproc/io/file.h source/fproc/io/file.cpp
|
||||||
source/fproc/io/file.cpp
|
include/fennec/fproc/io/common.h
|
||||||
include/fennec/fproc/filesystem/path.h
|
source/fproc/io/common.cpp
|
||||||
include/fennec/memory/memory.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
|
||||||
|
|||||||
45
PLANNING.md
45
PLANNING.md
@@ -63,7 +63,7 @@ This however can be achieved using events at different stages of those engines t
|
|||||||
- 2D Physics (`physics2d`)
|
- 2D Physics (`physics2d`)
|
||||||
- 2D & 3D Audio (`audio`)
|
- 2D & 3D Audio (`audio`)
|
||||||
|
|
||||||
### Security Ramblings:
|
### File Security Ramblings:
|
||||||
|
|
||||||
Windows is starting to piss me off, so I am considering dropping official support for MSVC. MinGW and Cygwin
|
Windows is starting to piss me off, so I am considering dropping official support for MSVC. MinGW and Cygwin
|
||||||
will still work for compiling on Windows if this ends up being the case. The reason for this is that there are
|
will still work for compiling on Windows if this ends up being the case. The reason for this is that there are
|
||||||
@@ -85,7 +85,7 @@ This issue can be solved using `fopen("<file>", "w+")`, however this specific be
|
|||||||
learning how to work with file systems. We can attempt to abstract this away with another wrapper, or simply write
|
learning how to work with file systems. We can attempt to abstract this away with another wrapper, or simply write
|
||||||
the file structure to handle this behaviour properly. The downside to this method overall is that it will break
|
the file structure to handle this behaviour properly. The downside to this method overall is that it will break
|
||||||
common conventions of how humans interpret filesystems and the related control flow logic. What we can do is force the
|
common conventions of how humans interpret filesystems and the related control flow logic. What we can do is force the
|
||||||
`'+'` flag to always be present for write operations, and raise an error, when desired, if the file is not empty. This
|
`'+'` flag to always be present for write operations, and raise an error when desired, if the file is not empty. This
|
||||||
unfortunately would have the downside of being unable to open a file as write only.
|
unfortunately would have the downside of being unable to open a file as write only.
|
||||||
|
|
||||||
Using `"wx"` in this instance would not be sufficient since it would require a second call to fopen, which would
|
Using `"wx"` in this instance would not be sufficient since it would require a second call to fopen, which would
|
||||||
@@ -99,6 +99,38 @@ debugging it, and testing for vulnerabilities. As stated above, this implementat
|
|||||||
so we would not have to entirely drop support for Windows. However, MSVC is the most widely used compiler for Windows
|
so we would not have to entirely drop support for Windows. However, MSVC is the most widely used compiler for Windows
|
||||||
applications and is native to Visual Studio and VSCode.
|
applications and is native to Visual Studio and VSCode.
|
||||||
|
|
||||||
|
What is probably the best solution is to wrap everything in a file interface that does not allow the direct setting of
|
||||||
|
these flags. Then we set our own usage type for the file that informs which flags should be used.
|
||||||
|
|
||||||
|
We need to be able to handle the following types of files:
|
||||||
|
- Assets, such as scenes, audio, textures, metadata, meshes, etc.
|
||||||
|
- Save files, setting files, etc.
|
||||||
|
|
||||||
|
One of the nice things about the assets is that they are guaranteed to be read-only once an application is installed
|
||||||
|
on the computer of the end-user. Therefore, this issue only arises with save files and custom file formats.
|
||||||
|
|
||||||
|
When the editor is run, all these files should be opened in read/write mode.
|
||||||
|
|
||||||
|
Naming conventions should exist for the types of files and how they are read. For example, in release mode,
|
||||||
|
most assets should be opened once, and then closed immediately. However, this does not make sense for formats
|
||||||
|
that are continuous and too large to be kept around in memory, such as video formats.
|
||||||
|
|
||||||
|
Perhaps the following conventions:
|
||||||
|
- Static Asset
|
||||||
|
- Stream Asset
|
||||||
|
- Resource
|
||||||
|
|
||||||
|
We can turn this into an object-oriented approach by having different formats inherit these base types. We may still
|
||||||
|
have a base file type that wraps C functionality, but discourage developers from using the interface.
|
||||||
|
|
||||||
|
We could also declare the file interface extern so that only internal files know the implementation. However, I would
|
||||||
|
not be satisfied by doing this since it would prevent developers from implementing custom file type implementations.
|
||||||
|
|
||||||
|
Conserving memory is not really an issue here as long as we are smart about our implementation. Files should only be
|
||||||
|
open when necessary and be closed when it is no longer necessary to have them open.
|
||||||
|
|
||||||
|
When built in release mode, we also need to pack static assets into some sort of archive that is mountable to reduce
|
||||||
|
disk space consumption of a program. I am considering encryption for archives, but there likely is not much of a point.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -186,6 +218,10 @@ fennec should be able to use Doxygen and LaTeX externally. Consider including bi
|
|||||||
- Spreadsheets & Tables
|
- Spreadsheets & Tables
|
||||||
- ODS
|
- ODS
|
||||||
- CSV
|
- CSV
|
||||||
|
- Audio Formats
|
||||||
|
- MP3
|
||||||
|
- WAV
|
||||||
|
- AAC
|
||||||
- Graphics Formats
|
- Graphics Formats
|
||||||
- Textures
|
- Textures
|
||||||
- BMP
|
- BMP
|
||||||
@@ -200,6 +236,11 @@ fennec should be able to use Doxygen and LaTeX externally. Consider including bi
|
|||||||
- Models
|
- Models
|
||||||
- FBX
|
- FBX
|
||||||
- Wavefront OBJ
|
- Wavefront OBJ
|
||||||
|
- Video Formats
|
||||||
|
- MP4
|
||||||
|
- AVI
|
||||||
|
- MPG
|
||||||
|
- MOV
|
||||||
|
|
||||||
**TODO LATER**
|
**TODO LATER**
|
||||||
* Compilation (`fproc/code`)
|
* Compilation (`fproc/code`)
|
||||||
|
|||||||
66
README.md
66
README.md
@@ -65,24 +65,24 @@ fennec Standards:
|
|||||||
called `detail`. Helper functions should be documented with C-Style comments, however it is not necessary to provide
|
called `detail`. Helper functions should be documented with C-Style comments, however it is not necessary to provide
|
||||||
Doxygen documentation.
|
Doxygen documentation.
|
||||||
|
|
||||||
- **DO NOT USE C++ EXCEPTIONS** they will not be supported because they are shit. No, I won't elaborate.[[1]](#f1)
|
- **DO NOT USE C++ EXCEPTIONS** they will not be supported because they are shit. No, I won't elaborate.<sup>[[1]](#f1)</sup>
|
||||||
|
|
||||||
* Most behaviours should be type independent. Specifically interactions with the core systems of the engine.
|
* Most behaviours should be type independent. Specifically interactions with the core systems of the engine.
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<a id="f1"></a>
|
<a id="f1"></a>
|
||||||
[1] Okay, I will elaborate. If we were to use the exception paradigm for all erroneous behaviour, we couldn't
|
<sup>[1]</sup> Okay, I will elaborate. If we were to use the exception paradigm for all erroneous behaviour, we couldn't
|
||||||
guarantee that the state will not be corrupted when an exception is thrown. The behaviour afterward is
|
guarantee that the state will not be corrupted when an exception is thrown. The behaviour afterward is
|
||||||
undefined because of this, and we also don't really know when, how, or where that exception will be handled.
|
undefined because of this, and we also don't really know when, how, or where that exception will be handled.
|
||||||
The assertion paradigm is better at handling this because you are defining erroneous behaviour in the code and how
|
The assertion paradigm is better at handling this because you are defining erroneous behaviour in the code and how
|
||||||
it is handled. In a debug build we can immediately halt the program, we don't care about the state afterward, only
|
it is handled. In a debug build we can immediately halt the program, we don't care about the state afterward, only
|
||||||
beforehand. Now for a release build, this is first and foremost a game engine, so we want to crash as gracefully as
|
beforehand. Now for a release build, this is first and foremost a game engine, so we want to crash as gracefully as
|
||||||
possible, prevent data loss, and get some debug information for it. fennec defines its own `assert` macro to
|
possible, prevent data loss, and get some debug information for it. fennec defines its own `assert` macro to
|
||||||
be used, defining a hook in the private version of the function. This hook is used to clean up any state information
|
be used, defining a hook in the private version of the function. This hook is used to clean up any state information
|
||||||
within the engine and may be used to send immediate events to listeners so that outside functionality may decide
|
within the engine and may be used to send immediate events to listeners so that outside functionality may decide
|
||||||
how to handle the impending crash. In Debug Mode there is nothing that can be done to stop the crash, as soon as the branch
|
how to handle the impending crash. In Debug Mode there is nothing that can be done to stop the crash, as soon
|
||||||
finishes, `abort()` will be called.
|
as the branch finishes, `abort()` will be called.
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@@ -199,6 +199,44 @@ information displayed is correct.
|
|||||||
<a id="usage"></a>
|
<a id="usage"></a>
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|
||||||
|
### Licensing
|
||||||
|
|
||||||
|
The following statement is not legal advice, nor is it legally binding, and nor does it change the terms of the license.
|
||||||
|
|
||||||
|
fennec is licensed under GPLv3. The primary reason for the choice of license is to dissuade corporations from modifying
|
||||||
|
fennec and using it in a commercial manner. This of course does not bar them from using fennec commercially, however
|
||||||
|
it will prevent them from being able to make the derivative work proprietary. You are free to use and redistribute
|
||||||
|
fennec however you wish according to the terms of the license, which does not bar you from commercializing software
|
||||||
|
based on fennec.
|
||||||
|
|
||||||
|
I encourage those who wish to commercialize derivative works crowdfund rather than use a sales model. I also ask
|
||||||
|
that you kindly support me as a developer, I will set up a Buy Me a Coffee link at some point.
|
||||||
|
|
||||||
|
GPLv3 is bound by fair use; here is the clause, 17 U.S. Code § 107:
|
||||||
|
|
||||||
|
```
|
||||||
|
107. Limitations on exclusive rights: Fair use
|
||||||
|
|
||||||
|
Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by
|
||||||
|
reproduction in copies or phonorecords or by any other means specified by that section, for purposes such as criticism,
|
||||||
|
comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an
|
||||||
|
infringement of copyright. In determining whether the use made of a work in any particular case is a fair use the
|
||||||
|
factors to be considered shall include—
|
||||||
|
|
||||||
|
(1) the purpose and character of the use, including whether such use is of a commercial nature or is for nonprofit
|
||||||
|
educational purposes;
|
||||||
|
(2) the nature of the copyrighted work;
|
||||||
|
(3) the amount and substantiality of the portion used in relation to the copyrighted work as a whole; and
|
||||||
|
(4) the effect of the use upon the potential market for or value of the copyrighted work.
|
||||||
|
|
||||||
|
The fact that a work is unpublished shall not itself bar a finding of fair use if such finding is made upon
|
||||||
|
consideration of all the above factors.
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have any questions or concerns, please seek legal council. If you believe someone else has violated the terms
|
||||||
|
of this license, please contact me at [mslockbo@gmail.com](mailto:mslockbo@gmail.com).
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -207,5 +245,5 @@ information displayed is correct.
|
|||||||
|
|
||||||
There are some principles to keep in mind when contributing to fennec.
|
There are some principles to keep in mind when contributing to fennec.
|
||||||
|
|
||||||
1. You must follow the style guide provided by the [GNU Coding Standard](https://www.gnu.org/prep/standards/html_node/Writing-C.html).
|
1. You must follow the [standards provided above](#coding-standards).
|
||||||
2. Any changes must allow all projects to be forward compatible with newer engine verisons.
|
2. Any changes must allow all projects to be forward compatible with newer engine versions.
|
||||||
|
|||||||
31
include/fennec/fproc/io/common.h
Normal file
31
include/fennec/fproc/io/common.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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_COMMON_H
|
||||||
|
#define FENNEC_FPROC_IO_COMMON_H
|
||||||
|
|
||||||
|
#include <fennec/fproc/strings/string.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
string getcwd();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_FPROC_IO_COMMON_H
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <fennec/fproc/strings/cstring.h>
|
#include <fennec/fproc/strings/cstring.h>
|
||||||
#include <fennec/fproc/strings/string.h>
|
#include <fennec/fproc/strings/string.h>
|
||||||
#include <fennec/fproc/filesystem/path.h>
|
|
||||||
|
|
||||||
struct FILE;
|
struct FILE;
|
||||||
|
|
||||||
@@ -32,10 +31,10 @@ namespace fennec
|
|||||||
/// \brief Mode flags for opening a file
|
/// \brief Mode flags for opening a file
|
||||||
enum fmode : uint8_t
|
enum fmode : uint8_t
|
||||||
{
|
{
|
||||||
read = 0b00000001
|
read = 0b00000001
|
||||||
, write = 0b00000010
|
, write = 0b00000010
|
||||||
, append = 0b00000100
|
, append = 0b00000100
|
||||||
, no_overwrite = 0b00001000
|
, noexists = 0b00001000
|
||||||
};
|
};
|
||||||
|
|
||||||
class file
|
class file
|
||||||
@@ -50,7 +49,8 @@ public:
|
|||||||
/// \param mode the flags for opening the file
|
/// \param mode the flags for opening the file
|
||||||
file(const cstring& path, fmode mode);
|
file(const cstring& path, fmode mode);
|
||||||
file(const string& path, fmode mode);
|
file(const string& path, fmode mode);
|
||||||
file(const path& path, fmode mode);
|
|
||||||
|
file(file&& file);
|
||||||
|
|
||||||
file(const file&) = delete;
|
file(const file&) = delete;
|
||||||
|
|
||||||
@@ -59,7 +59,6 @@ public:
|
|||||||
|
|
||||||
void open(const cstring& filename, fmode mode);
|
void open(const cstring& filename, fmode mode);
|
||||||
void open(const string& filename, fmode mode);
|
void open(const string& filename, fmode mode);
|
||||||
void open(const path& filename, fmode mode);
|
|
||||||
void close();
|
void close();
|
||||||
void commit();
|
void commit();
|
||||||
|
|
||||||
@@ -89,6 +88,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
FILE* _handle;
|
FILE* _handle;
|
||||||
|
string _path;
|
||||||
|
fmode _mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#include <fennec/lang/assert.h>
|
#include <fennec/lang/assert.h>
|
||||||
|
|
||||||
|
#include <fennec/math/common.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ using string = _string<>;
|
|||||||
/// \brief Struct for wrapping c-style strings
|
/// \brief Struct for wrapping c-style strings
|
||||||
///
|
///
|
||||||
/// \details behaviour guarantees that the underlying string is null-terminated
|
/// \details behaviour guarantees that the underlying string is null-terminated
|
||||||
template<typename AllocT = allocator<char>>
|
template<typename AllocT>
|
||||||
struct _string
|
struct _string
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -120,7 +120,6 @@ public:
|
|||||||
/// \param i the index to access
|
/// \param i the index to access
|
||||||
/// \returns a reference to the character
|
/// \returns a reference to the character
|
||||||
constexpr char& operator[](int i) {
|
constexpr char& operator[](int i) {
|
||||||
assertd(i >= 0 && i < size(), "Array Out of Bounds");
|
|
||||||
return _str[i];
|
return _str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +283,7 @@ public:
|
|||||||
/// \param str the string to copy
|
/// \param str the string to copy
|
||||||
/// \returns a reference to `this`
|
/// \returns a reference to `this`
|
||||||
constexpr string& operator=(const string& str) {
|
constexpr string& operator=(const string& str) {
|
||||||
if (str.size() > size()) string::resize(str.size());
|
if (str.size() > size()) resize(str.size());
|
||||||
fennec::memcpy(_str, str, str.size());
|
fennec::memcpy(_str, str, str.size());
|
||||||
_str[str.size()] = '\0';
|
_str[str.size()] = '\0';
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
using assert_handler = void (*)(const char *, const char *, int , const char *);
|
using assert_handler = void (*)(const char *, const char *, int , const char *);
|
||||||
|
|
||||||
extern void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc);
|
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc);
|
||||||
|
|
||||||
// flagged unlikely to optimize branch prediction
|
// flagged unlikely to optimize branch prediction
|
||||||
#define assert(expression, description) \
|
#define assert(expression, description) \
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#pragma push_macro("__cplusplus")
|
#pragma push_macro("__cplusplus")
|
||||||
#undef __cplusplus
|
#undef __cplusplus
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#pragma pop_macro("__cplusplus")
|
#pragma pop_macro("__cplusplus")
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace fennec
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename> struct __make_unsigned : undefined_t {};
|
template<typename> struct __make_unsigned : type_transform<undefined_t> {};
|
||||||
|
|
||||||
template<> struct __make_unsigned<char_t> : type_transform<uchar_t> {};
|
template<> struct __make_unsigned<char_t> : type_transform<uchar_t> {};
|
||||||
template<> struct __make_unsigned<uchar_t> : type_transform<uchar_t> {};
|
template<> struct __make_unsigned<uchar_t> : type_transform<uchar_t> {};
|
||||||
@@ -43,7 +43,7 @@ template<> struct __make_unsigned<llong_t> : type_transform<ullong_t> {};
|
|||||||
template<> struct __make_unsigned<ullong_t> : type_transform<ullong_t> {};
|
template<> struct __make_unsigned<ullong_t> : type_transform<ullong_t> {};
|
||||||
|
|
||||||
|
|
||||||
template<typename> struct __make_signed : undefined_t {};
|
template<typename> struct __make_signed : type_transform<undefined_t> {};
|
||||||
|
|
||||||
template<> struct __make_signed<char_t> : type_transform<schar_t> {};
|
template<> struct __make_signed<char_t> : type_transform<schar_t> {};
|
||||||
template<> struct __make_signed<uchar_t> : type_transform<schar_t> {};
|
template<> struct __make_signed<uchar_t> : type_transform<schar_t> {};
|
||||||
|
|||||||
@@ -191,6 +191,14 @@
|
|||||||
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
|
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent with dynamic intrinsics, requires a massive table for static intrinsics
|
||||||
|
#if __has_builtin(__is_fundamental)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_FUNDAMENTAL 1
|
||||||
|
# define FENNEC_BUILTIN_IS_FUNDAMENTAL(arg) __is_fundamental(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_FUNDAMENTAL 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
|
||||||
|
|||||||
@@ -288,6 +288,21 @@ template<typename T> struct is_arithmetic
|
|||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T> constexpr bool_t is_arithmetic_v = is_arithmetic<T>::value;
|
template<typename T> constexpr bool_t is_arithmetic_v = is_arithmetic<T>::value;
|
||||||
|
|
||||||
|
|
||||||
|
// fennec::is_fundamental ==============================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief check if \p T is a fundamental type, i.e. arithmetic, void, or nullptr_t
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> struct is_fundamental
|
||||||
|
: bool_constant<is_arithmetic_v<T> || is_void_v<T> || is_null_pointer_v<T>>{};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief shorthand for ```is_fundamental<T>::value```
|
||||||
|
/// \tparam T type to check
|
||||||
|
template<typename T> constexpr bool_t is_fundamental_v = is_fundamental<T>::value;
|
||||||
|
|
||||||
|
|
||||||
// fennec::is_same =====================================================================================================
|
// fennec::is_same =====================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -306,7 +321,7 @@ template<typename T> struct is_same<T, T> : true_type {};
|
|||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {};
|
template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {};
|
||||||
|
|
||||||
// fennec::can_convert =================================================================================================
|
// fennec::is_convertible ==============================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief check if type `T0` can be converted `T1`
|
/// \brief check if type `T0` can be converted `T1`
|
||||||
|
|||||||
@@ -203,6 +203,8 @@
|
|||||||
|
|
||||||
#include <fennec/lang/detail/__int.h>
|
#include <fennec/lang/detail/__int.h>
|
||||||
|
|
||||||
|
#include <fennec/lang/conditional_types.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
// Basic Types =========================================================================================================
|
// Basic Types =========================================================================================================
|
||||||
@@ -253,12 +255,7 @@ namespace fennec
|
|||||||
template<typename...> using void_t = void; ///< \brief Void type used for SFINAE
|
template<typename...> using void_t = void; ///< \brief Void type used for SFINAE
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
}
|
|
||||||
|
|
||||||
#include <fennec/lang/conditional_types.h>
|
|
||||||
|
|
||||||
namespace fennec
|
|
||||||
{
|
|
||||||
|
|
||||||
// Sized Arithmetic Types ==============================================================================================
|
// Sized Arithmetic Types ==============================================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -271,6 +271,8 @@
|
|||||||
|
|
||||||
#include <fennec/math/detail/__math.h>
|
#include <fennec/math/detail/__math.h>
|
||||||
|
|
||||||
|
#include <fennec/lang/limits.h>
|
||||||
|
|
||||||
#include <fennec/math/vector.h>
|
#include <fennec/math/vector.h>
|
||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
@@ -462,7 +464,7 @@ constexpr vector<genType, i...> trunc(const vector<genType, i...>& x) {
|
|||||||
/// \param x input value
|
/// \param x input value
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
constexpr genType roundEven(genType x) {
|
constexpr genType roundEven(genType x) {
|
||||||
static const genType e = std::numeric_limits<genType>::epsilon();
|
static const genType e = numeric_limits<genType>::epsilon();
|
||||||
int I = static_cast<int>(x);
|
int I = static_cast<int>(x);
|
||||||
genType i = static_cast<genType>(I);
|
genType i = static_cast<genType>(I);
|
||||||
genType f = x - i;
|
genType f = x - i;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
2// =====================================================================================================================
|
// =====================================================================================================================
|
||||||
// fennec, a free and open source game engine
|
// fennec, a free and open source game engine
|
||||||
// Copyright (C) 2025 Medusa Slockbower
|
// Copyright (C) 2025 Medusa Slockbower
|
||||||
//
|
//
|
||||||
@@ -33,15 +33,22 @@
|
|||||||
#define FENNEC_MEMORY_ALLOCATOR_H
|
#define FENNEC_MEMORY_ALLOCATOR_H
|
||||||
|
|
||||||
#include <fennec/memory/ptr_traits.h>
|
#include <fennec/memory/ptr_traits.h>
|
||||||
|
#include <fennec/memory/new.h>
|
||||||
|
|
||||||
#include <fennec/lang/conditional_types.h>
|
#include <fennec/lang/conditional_types.h>
|
||||||
#include <fennec/lang/numeric_transforms.h>
|
#include <fennec/lang/numeric_transforms.h>
|
||||||
#include <fennec/lang/types.h>
|
#include <fennec/lang/types.h>
|
||||||
#include <fennec/lang/type_traits.h>
|
#include <fennec/lang/type_traits.h>
|
||||||
|
|
||||||
|
#include <fennec/math/ext/constants.h>
|
||||||
#include <fennec/math/common.h>
|
#include <fennec/math/common.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wchanges-meaning"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
@@ -177,14 +184,92 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
||||||
constexpr T* allocate(size_t n) {
|
constexpr T* allocate(size_t n) {
|
||||||
return ::operator new(n * sizeof(T));
|
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
||||||
|
constexpr T* allocate(size_t n, align_t align) {
|
||||||
|
return static_cast<T*>(::operator new(n * sizeof(T), align));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Deallocate a block of memory with type `T`
|
/// \brief Deallocate a block of memory with type `T`
|
||||||
constexpr void deallocate(T* ptr) {
|
constexpr void deallocate(T* ptr) {
|
||||||
return ::operator delete(ptr);
|
return ::operator delete(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Deallocate a block of memory with type `T`
|
||||||
|
constexpr void deallocate(T* ptr, align_t align) {
|
||||||
|
return ::operator delete(ptr, align);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Allocator implementation, uses `new` and `delete` operators.
|
||||||
|
/// \tparam T The data type to allocate
|
||||||
|
template<typename T>
|
||||||
|
class allocator<T[]>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// \brief Alias for the data type used for metaprogramming
|
||||||
|
using value_t = T;
|
||||||
|
|
||||||
|
/// \brief Metaprogramming utility to rebind an allocator to a different data type
|
||||||
|
template<typename R> using rebind = allocator<R>;
|
||||||
|
|
||||||
|
/// \brief Default Constructor
|
||||||
|
constexpr allocator() = default;
|
||||||
|
|
||||||
|
/// \brief Default Destructor
|
||||||
|
constexpr ~allocator() = default;
|
||||||
|
|
||||||
|
/// \brief Copy Constructor
|
||||||
|
constexpr allocator(const allocator&) = default;
|
||||||
|
|
||||||
|
/// \brief Copy Assignment
|
||||||
|
constexpr allocator& operator=(const allocator&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Equality operator
|
||||||
|
constexpr bool_t operator==(const allocator&) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Inequality operator
|
||||||
|
constexpr bool_t operator!=(const allocator&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Equality operator for allocators of same type but with different data type
|
||||||
|
template<typename U> constexpr bool_t operator==(const allocator<U>&) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Inequality operator for allocators of same type but with different data type
|
||||||
|
template<typename U> constexpr bool_t operator!=(const allocator<U>&) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
||||||
|
constexpr T* allocate(size_t n) {
|
||||||
|
return static_cast<T*>(::operator new[](n * sizeof(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
||||||
|
constexpr T* allocate(size_t n, align_t align) {
|
||||||
|
return static_cast<T*>(::operator new[](n * sizeof(T), align));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Deallocate a block of memory with type `T`
|
||||||
|
constexpr void deallocate(T* ptr) {
|
||||||
|
return ::operator delete[](ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Deallocate a block of memory with type `T`
|
||||||
|
constexpr void deallocate(T* ptr, align_t align) {
|
||||||
|
return ::operator delete[](ptr, align);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -211,6 +296,9 @@ public:
|
|||||||
/// \brief diff type definition for ptr_traits
|
/// \brief diff type definition for ptr_traits
|
||||||
using diff_t = ptrdiff_t;
|
using diff_t = ptrdiff_t;
|
||||||
|
|
||||||
|
|
||||||
|
// Cosntructors ========================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Default Constructor, initializes internal data to `null` and the capacity to `0`
|
/// \brief Default Constructor, initializes internal data to `null` and the capacity to `0`
|
||||||
constexpr allocation() noexcept
|
constexpr allocation() noexcept
|
||||||
@@ -235,6 +323,24 @@ public:
|
|||||||
fennec::memcpy(_data, data, n);
|
fennec::memcpy(_data, data, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Sized Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes
|
||||||
|
/// \param n The number of elements of type `T` to allocate for
|
||||||
|
constexpr allocation(size_t n, align_t align) noexcept
|
||||||
|
: _data(nullptr), _capacity(0), _alignment(zero<align_t>()) {
|
||||||
|
allocate(n, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Buffer Copy Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes.
|
||||||
|
/// Then, the contents of data are copied into the allocation.
|
||||||
|
/// \param data the buffer to copy
|
||||||
|
/// \param n the number of elements
|
||||||
|
constexpr allocation(const T* data, size_t n, align_t align)
|
||||||
|
: allocation(n, align) {
|
||||||
|
fennec::memcpy(_data, data, n);
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Allocator Constructor
|
/// \brief Allocator Constructor
|
||||||
/// \param alloc The allocation object to copy.
|
/// \param alloc The allocation object to copy.
|
||||||
@@ -268,6 +374,30 @@ public:
|
|||||||
fennec::memcpy(_data, data, n);
|
fennec::memcpy(_data, data, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Sized Allocator Constructor
|
||||||
|
/// \param n The number of elements of type `T` to allocate for
|
||||||
|
/// \param alloc The allocation object to copy.
|
||||||
|
///
|
||||||
|
/// \details This constructor should be used when the type `AllocT` needs internal data.
|
||||||
|
constexpr allocation(size_t n, align_t align, const alloc_t& alloc) noexcept
|
||||||
|
: _alloc(alloc), _data(nullptr), _capacity(0), _alignment(zero<align_t>()) {
|
||||||
|
allocate(n, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Buffer Copy Allocator Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes.
|
||||||
|
/// Then, the contents of data are copied into the allocation.
|
||||||
|
/// \param data the buffer to copy
|
||||||
|
/// \param n the number of elements
|
||||||
|
/// \param alloc The allocation object to copy.
|
||||||
|
///
|
||||||
|
/// \details This constructor should be used when the type `AllocT` needs internal data.
|
||||||
|
constexpr allocation(const T* data, size_t n, align_t align, const alloc_t& alloc)
|
||||||
|
: allocation(n, align, alloc) {
|
||||||
|
fennec::memcpy(_data, data, n);
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Copy Constructor, creates an allocation of equal size and performs a byte-wise copy
|
/// \brief Copy Constructor, creates an allocation of equal size and performs a byte-wise copy
|
||||||
/// \param alloc The allocation to copy
|
/// \param alloc The allocation to copy
|
||||||
@@ -292,6 +422,9 @@ public:
|
|||||||
if (_data) _alloc.deallocate(_data);
|
if (_data) _alloc.deallocate(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Assignment ==========================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Copy Assignment Operator
|
/// \brief Copy Assignment Operator
|
||||||
/// \param alloc the allocation to copy
|
/// \param alloc the allocation to copy
|
||||||
@@ -319,37 +452,45 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Allocation and Deallocation =========================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Allocate a block of memory for the allocation.
|
/// \brief Allocate a block of memory for the allocation.
|
||||||
/// If there is already an allocated block of memory, the previous allocation is released.
|
/// If there is already an allocated block of memory, the previous allocation is released.
|
||||||
/// \param n The number of elements of type `T` to allocate for
|
/// \param n The number of elements of type `T` to allocate for
|
||||||
constexpr void allocate(size_t n) noexcept {
|
constexpr void allocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
if (_data) {
|
deallocate();
|
||||||
_alloc.deallocate(_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
_data = _alloc.allocate(_capacity = n);
|
if (_alignment != zero<align_t>()) {
|
||||||
|
_data = _alloc.allocate(_capacity = n, _alignment = align);
|
||||||
|
} else {
|
||||||
|
_data = _alloc.allocate(_capacity = n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Release the block of memory.
|
/// \brief Release the block of memory.
|
||||||
constexpr void release() noexcept
|
constexpr void deallocate() noexcept {
|
||||||
{
|
|
||||||
if (_data) {
|
if (_data) {
|
||||||
_alloc.deallocate(_data);
|
if (_alignment != zero<align_t>()) {
|
||||||
|
_alloc.deallocate(_data, _alignment);
|
||||||
|
} else {
|
||||||
|
_alloc.deallocate(_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_data = nullptr;
|
_data = nullptr;
|
||||||
_capacity = 0;
|
_capacity = 0;
|
||||||
|
_alignment = zero<align_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Reallocate the block with a new size.
|
/// \brief Reallocate the block with a new size.
|
||||||
/// Contents are copied to the new allocation.
|
/// Contents are copied to the new allocation.
|
||||||
constexpr void reallocate(size_t n) noexcept
|
constexpr void reallocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
{
|
|
||||||
if (_data == nullptr) {
|
if (_data == nullptr) {
|
||||||
return _alloc.allocate(_capacity = n);
|
allocate(n, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t* old = _data;
|
value_t* old = _data;
|
||||||
@@ -359,6 +500,27 @@ public:
|
|||||||
_capacity = n;
|
_capacity = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Access ==============================================================================================================
|
||||||
|
|
||||||
|
constexpr value_t& operator[](size_t i) {
|
||||||
|
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> == 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; } {
|
||||||
|
assertd(i < size(), "Array Out of Bounds");
|
||||||
|
return _data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Modification ========================================================================================================
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Clear the block of memory, setting all bytes to 0.
|
/// \brief Clear the block of memory, setting all bytes to 0.
|
||||||
constexpr void clear() noexcept {
|
constexpr void clear() noexcept {
|
||||||
@@ -387,11 +549,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alloc_t _alloc; // Allocator object
|
alloc_t _alloc; // Allocator object
|
||||||
value_t* _data; // Handle for the memory block
|
value_t* _data; // Handle for the memory block
|
||||||
size_t _capacity; // Capacity of the memory block in elements.
|
size_t _capacity; // Capacity of the memory block in elements.
|
||||||
|
align_t _alignment; // Alignment information
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FENNEC_MEMORY_ALLOCATOR_H
|
#endif // FENNEC_MEMORY_ALLOCATOR_H
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ struct __ptr_get_element : first_element<ClassT> { }; // Default case, return th
|
|||||||
|
|
||||||
// overload for types that have a member `ClassT::element_t`
|
// overload for types that have a member `ClassT::element_t`
|
||||||
template<typename ClassT> requires requires { typename ClassT::element_t; }
|
template<typename ClassT> requires requires { typename ClassT::element_t; }
|
||||||
struct __ptr_get_element { using type = typename ClassT::element_t; };
|
struct __ptr_get_element<ClassT, ClassT> { using type = typename ClassT::element_t; };
|
||||||
|
|
||||||
// helper for generating `pointer_to`
|
// helper for generating `pointer_to`
|
||||||
template<typename PtrT, typename ElemT, bool_t = is_void_v<ElemT>>
|
template<typename PtrT, typename ElemT, bool_t = is_void_v<ElemT>>
|
||||||
|
|||||||
@@ -19,10 +19,6 @@
|
|||||||
#ifndef FENNEC_MEMORY_DETAIL_MEMORY_H
|
#ifndef FENNEC_MEMORY_DETAIL_MEMORY_H
|
||||||
#define FENNEC_MEMORY_DETAIL_MEMORY_H
|
#define FENNEC_MEMORY_DETAIL_MEMORY_H
|
||||||
|
|
||||||
#include <fennec/lang/types.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// deprecated, switched to ISO C implementation
|
// deprecated, switched to ISO C implementation
|
||||||
// see https://git.mslockbo.org/mslockbo/fennec/src/commit/0eeb7ae3cff9d78e98dc5d9fc09bcb98b10986b9 for previous
|
// see https://git.mslockbo.org/mslockbo/fennec/src/commit/0eeb7ae3cff9d78e98dc5d9fc09bcb98b10986b9 for previous
|
||||||
// implementation
|
// implementation
|
||||||
@@ -39,6 +35,7 @@
|
|||||||
#pragma push_macro("__cplusplus")
|
#pragma push_macro("__cplusplus")
|
||||||
#undef __cplusplus
|
#undef __cplusplus
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
#pragma pop_macro("__cplusplus")
|
#pragma pop_macro("__cplusplus")
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ struct nothrow_t
|
|||||||
explicit nothrow_t() noexcept { }
|
explicit nothrow_t() noexcept { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns the page size for the current environment
|
||||||
|
size_t pagesize();
|
||||||
|
|
||||||
template<typename TypeT> void construct(TypeT* ptr) {
|
template<typename TypeT> void construct(TypeT* ptr) {
|
||||||
ptr->TypeT();
|
ptr->TypeT();
|
||||||
}
|
}
|
||||||
@@ -71,4 +75,31 @@ template<typename TypeT> void destruct(TypeT* ptr) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* operator new (fennec::size_t size);
|
||||||
|
void* operator new[](fennec::size_t size);
|
||||||
|
void* operator new (fennec::size_t size, const fennec::nothrow_t&);
|
||||||
|
void* operator new[](fennec::size_t size, const fennec::nothrow_t&);
|
||||||
|
void* operator new (fennec::size_t size, fennec::align_t align);
|
||||||
|
void* operator new[](fennec::size_t size, fennec::align_t align);
|
||||||
|
void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&);
|
||||||
|
void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&);
|
||||||
|
|
||||||
|
|
||||||
|
void operator delete (void* ptr) noexcept;
|
||||||
|
void operator delete[](void* ptr) noexcept;
|
||||||
|
void operator delete (void* ptr, fennec::size_t) noexcept;
|
||||||
|
void operator delete[](void* ptr, fennec::size_t) noexcept;
|
||||||
|
void operator delete (void* ptr, const fennec::nothrow_t&) noexcept;
|
||||||
|
void operator delete[](void* ptr, const fennec::nothrow_t&) noexcept;
|
||||||
|
void operator delete (void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept;
|
||||||
|
void operator delete[](void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept;
|
||||||
|
|
||||||
|
void operator delete (void* ptr, fennec::align_t) noexcept;
|
||||||
|
void operator delete[](void* ptr, fennec::align_t) noexcept;
|
||||||
|
void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept;
|
||||||
|
void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept;
|
||||||
|
void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept;
|
||||||
|
void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept;
|
||||||
|
|
||||||
|
|
||||||
#endif // FENNEC_MEMORY_NEW_H
|
#endif // FENNEC_MEMORY_NEW_H
|
||||||
|
|||||||
56
source/fproc/io/common.cpp
Normal file
56
source/fproc/io/common.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#include <fennec/fproc/io/common.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
string getcwd() {
|
||||||
|
char cstr[MAX_PATH];
|
||||||
|
if (GetCurrentDirectory(sizeof(str), str) == 0) {
|
||||||
|
return string("");
|
||||||
|
}
|
||||||
|
string result(cstr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
string getcwd() {
|
||||||
|
char cstr[PATH_MAX];
|
||||||
|
if (::getcwd(cstr, sizeof(cstr)) == NULL) {
|
||||||
|
return string("");
|
||||||
|
}
|
||||||
|
string result(cstr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
using assert_handler = void (*)(const char *, const char *, int , const char *);
|
using assert_handler = void (*)(const char *, const char *, int , const char *);
|
||||||
|
|
||||||
extern void __assert_callback(const char* expression, const char* file, int line, const char* function, const char* description);
|
void __assert_callback(const char* expression, const char* file, int line, const char* function, const char* description);
|
||||||
|
|
||||||
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* description)
|
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* description)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,16 +28,14 @@
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Allocation functions
|
// Windows does not define ISO C aligned allocation functions
|
||||||
inline void* operator new (fennec::size_t size) { return ::malloc(size); }
|
|
||||||
inline void* operator new[](fennec::size_t size) { return ::malloc(size); }
|
|
||||||
inline void* operator new (fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); }
|
|
||||||
inline void* operator new[](fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); }
|
|
||||||
|
|
||||||
// Aligned allocation & deallocation functions
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
inline void operator delete (void* ptr) noexcept { _aligned_free(ptr); }
|
inline void operator delete (void* ptr) noexcept { _aligned_free(ptr); }
|
||||||
inline void operator delete[](void* ptr) noexcept { _aligned_free(ptr); }
|
inline void operator delete[](void* ptr) noexcept { _aligned_free(ptr); }
|
||||||
|
inline void operator delete (void* ptr, fennec::align_t) noexcept { ::_aligned_free(ptr); }
|
||||||
|
inline void operator delete[](void* ptr, fennec::align_t) noexcept { ::_aligned_free(ptr); }
|
||||||
|
inline void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept { ::_aligned_free(ptr); }
|
||||||
|
inline void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept { ::_aligned_free(ptr); }
|
||||||
inline void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); }
|
inline void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); }
|
||||||
inline void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); }
|
inline void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { _aligned_free(ptr); }
|
||||||
|
|
||||||
@@ -45,9 +43,15 @@ inline void* operator new (fennec::size_t size, fennec::align_t align)
|
|||||||
inline void* operator new[](fennec::size_t size, fennec::align_t align) { return _aligned_malloc(static_cast<size_t>(align), size); }
|
inline void* operator new[](fennec::size_t size, fennec::align_t align) { return _aligned_malloc(static_cast<size_t>(align), size); }
|
||||||
inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast<size_t>(align), size); }
|
inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast<size_t>(align), size); }
|
||||||
inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast<size_t>(align), size); }
|
inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast<size_t>(align), size); }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
inline void operator delete (void* ptr) noexcept { ::free(ptr); }
|
inline void operator delete (void* ptr) noexcept { ::free(ptr); }
|
||||||
inline void operator delete[](void* ptr) noexcept { ::free(ptr); }
|
inline void operator delete[](void* ptr) noexcept { ::free(ptr); }
|
||||||
|
inline void operator delete (void* ptr, fennec::align_t) noexcept { ::free(ptr); }
|
||||||
|
inline void operator delete[](void* ptr, fennec::align_t) noexcept { ::free(ptr); }
|
||||||
|
inline void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); }
|
||||||
|
inline void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); }
|
||||||
inline void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
inline void operator delete (void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
||||||
inline void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
inline void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
||||||
|
|
||||||
@@ -55,22 +59,54 @@ inline void* operator new (fennec::size_t size, fennec::align_t align)
|
|||||||
inline void* operator new[](fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast<fennec::size_t>(align), size); }
|
inline void* operator new[](fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast<fennec::size_t>(align), size); }
|
||||||
inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast<fennec::size_t>(align), size); }
|
inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast<fennec::size_t>(align), size); }
|
||||||
inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast<fennec::size_t>(align), size); }
|
inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast<fennec::size_t>(align), size); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Aligned deallocation functions
|
// Allocation functions
|
||||||
inline void operator delete (void* ptr, fennec::align_t) noexcept { ::free(ptr); }
|
inline void* operator new (fennec::size_t size) { return ::malloc(size); }
|
||||||
inline void operator delete[](void* ptr, fennec::align_t) noexcept { ::free(ptr); }
|
inline void* operator new[](fennec::size_t size) { return ::malloc(size); }
|
||||||
|
inline void* operator new (fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); }
|
||||||
|
inline void* operator new[](fennec::size_t size, const fennec::nothrow_t&) { return ::malloc(size); }
|
||||||
|
|
||||||
// Sized deallocation functions
|
// Deallocation Functions
|
||||||
inline void operator delete (void* ptr, fennec::size_t) noexcept { ::free(ptr); }
|
inline void operator delete (void* ptr, fennec::size_t) noexcept { ::free(ptr); }
|
||||||
inline void operator delete[](void* ptr, fennec::size_t) noexcept { ::free(ptr); }
|
inline void operator delete[](void* ptr, fennec::size_t) noexcept { ::free(ptr); }
|
||||||
inline void operator delete (void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); }
|
|
||||||
inline void operator delete[](void* ptr, fennec::size_t, fennec::align_t) noexcept { ::free(ptr); }
|
|
||||||
|
|
||||||
// Non-throwing deallocation functions
|
|
||||||
inline void operator delete (void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
inline void operator delete (void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
||||||
inline void operator delete[](void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
inline void operator delete[](void* ptr, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
||||||
inline void operator delete (void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
inline void operator delete (void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
||||||
inline void operator delete[](void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
inline void operator delete[](void* ptr, fennec::size_t, const fennec::nothrow_t&) noexcept { ::free(ptr); }
|
||||||
|
|
||||||
|
|
||||||
|
// Platform specific code
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
size_T pagesize() {
|
||||||
|
SYSTEM_INFO sysInfo;
|
||||||
|
GetSystemInfo(&sysInfo);
|
||||||
|
return sysInfo.dwPageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
size_t pagesize() {
|
||||||
|
return sysconf(_SC_PAGESIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user