- Component-Wise Functions for Quaternions
- Fixed Allocation Bug with Strings
This commit is contained in:
@@ -108,7 +108,11 @@ add_library(fennec STATIC
|
|||||||
include/fennec/math/trigonometric.h
|
include/fennec/math/trigonometric.h
|
||||||
include/fennec/math/relational.h
|
include/fennec/math/relational.h
|
||||||
|
|
||||||
|
include/fennec/math/ext/common.h
|
||||||
include/fennec/math/ext/constants.h
|
include/fennec/math/ext/constants.h
|
||||||
|
include/fennec/math/ext/quaternion.h
|
||||||
|
include/fennec/math/ext/transform.h
|
||||||
|
include/fennec/math/ext/trigonometric.h
|
||||||
|
|
||||||
include/fennec/math/detail/__fwd.h
|
include/fennec/math/detail/__fwd.h
|
||||||
include/fennec/math/detail/__math.h
|
include/fennec/math/detail/__math.h
|
||||||
@@ -128,8 +132,6 @@ add_library(fennec STATIC
|
|||||||
# Filesystem
|
# Filesystem
|
||||||
include/fennec/fproc/filesystem/file.h source/fproc/filesystem/file.cpp
|
include/fennec/fproc/filesystem/file.h source/fproc/filesystem/file.cpp
|
||||||
include/fennec/fproc/filesystem/path.h source/fproc/filesystem/path.cpp
|
include/fennec/fproc/filesystem/path.h source/fproc/filesystem/path.cpp
|
||||||
include/fennec/math/ext/transform.h
|
|
||||||
include/fennec/math/ext/quaternion.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
|
||||||
|
|||||||
@@ -52,42 +52,62 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Alloc Constructor, initialize empty allocation with allocator instance.
|
/// \brief Alloc Constructor, initialize empty allocation with allocator instance.
|
||||||
/// \param alloc An allocator object to copy, for instances where the allocator needs to be initialized with some data.
|
/// \param alloc An allocator object to copy, for instances where the allocator needs to be initialized with some data.
|
||||||
dynarray(const alloc_t& alloc) : _alloc(8, alloc), _size(0) {}
|
dynarray(const alloc_t& alloc)
|
||||||
|
: _alloc(8, alloc)
|
||||||
|
, _size(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Sized Allocation, create an allocation with a size of `n` elements, initialized with the default constructor.
|
/// \brief Sized Allocation, create an allocation with a size of `n` elements, initialized with the default constructor.
|
||||||
dynarray(size_t n) : _alloc(n), _size(n)
|
dynarray(size_t n)
|
||||||
|
: _alloc(n)
|
||||||
|
, _size(n)
|
||||||
{
|
{
|
||||||
element_t* addr = _alloc.data();
|
element_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) { fennec::construct(addr); }
|
for(; n > 0; --n, ++addr) {
|
||||||
|
fennec::construct(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief
|
/// \brief
|
||||||
/// \param n
|
/// \param n
|
||||||
/// \param alloc
|
/// \param alloc
|
||||||
dynarray(size_t n, const alloc_t& alloc) : _alloc(n, alloc), _size(n) {
|
dynarray(size_t n, const alloc_t& alloc)
|
||||||
|
: _alloc(n, alloc)
|
||||||
|
, _size(n) {
|
||||||
element_t* addr = _alloc.data();
|
element_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) { fennec::construct(addr); }
|
for(; n > 0; --n, ++addr) {
|
||||||
|
fennec::construct(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Create an allocation of size `n`, with each element constructed using the copy constructor
|
/// \brief Create an allocation of size `n`, with each element constructed using the copy constructor
|
||||||
/// \brief n the number of elements
|
/// \brief n the number of elements
|
||||||
dynarray(size_t n, const TypeT& val) {
|
dynarray(size_t n, const TypeT& val)
|
||||||
|
: _alloc(n)
|
||||||
|
, _size(n) {
|
||||||
element_t* addr = _alloc.data();
|
element_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) { fennec::construct(addr, val); }
|
for(; n > 0; --n, ++addr) {
|
||||||
|
fennec::construct(addr, val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename...ArgsT>
|
template<typename...ArgsT>
|
||||||
dynarray(size_t n, ArgsT&&...args) {
|
dynarray(size_t n, ArgsT&&...args) {
|
||||||
element_t* addr = _alloc.data();
|
element_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) { fennec::construct(addr, fennec::forward<ArgsT>(args)...); }
|
for(; n > 0; --n, ++addr) {
|
||||||
|
fennec::construct(addr, fennec::forward<ArgsT>(args)...);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~dynarray() {
|
~dynarray() {
|
||||||
element_t* addr = _alloc.data();
|
element_t* addr = _alloc.data();
|
||||||
for(; n > 0; --n, ++addr) { fennec::destruct(addr); }
|
for(int n = _size; n > 0; --n, ++addr) {
|
||||||
|
fennec::destruct(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ public:
|
|||||||
/// \param mode the bitfield
|
/// \param mode the bitfield
|
||||||
/// \returns true if the combination of flags is valid, false otherwise
|
/// \returns true if the combination of flags is valid, false otherwise
|
||||||
static constexpr bool is_valid(uint8_t mode) {
|
static constexpr bool is_valid(uint8_t mode) {
|
||||||
bool t = mode & fmode_trunc;
|
const bool t = mode & fmode_trunc;
|
||||||
bool x = mode & fmode_exclusive;
|
const bool x = mode & fmode_exclusive;
|
||||||
bool w = mode & fmode_write;
|
const bool w = mode & fmode_write;
|
||||||
|
|
||||||
// when x is true, t must be true
|
// when x is true, t must be true
|
||||||
// when t is true, w must be true
|
// when t is true, w must be true
|
||||||
@@ -151,21 +151,21 @@ public:
|
|||||||
/// \param path the path to the file
|
/// \param path the path to the file
|
||||||
/// \param mode the mode flags to open the file with
|
/// \param mode the mode flags to open the file with
|
||||||
/// \returns false on success, true on error
|
/// \returns false on success, true on error
|
||||||
bool open(const cstring& p, uint8_t mode);
|
bool open(const cstring& path, uint8_t mode);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief open a file
|
/// \brief open a file
|
||||||
/// \param path the path to the file
|
/// \param path the path to the file
|
||||||
/// \param mode the mode flags to open the file with
|
/// \param mode the mode flags to open the file with
|
||||||
/// \returns false on success, true on error
|
/// \returns false on success, true on error
|
||||||
bool open(const string& p, uint8_t mode);
|
bool open(const string& path, uint8_t mode);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief open a file
|
/// \brief open a file
|
||||||
/// \param path the path to the file
|
/// \param path the path to the file
|
||||||
/// \param mode the mode flags to open the file with
|
/// \param mode the mode flags to open the file with
|
||||||
/// \returns false on success, true on error
|
/// \returns false on success, true on error
|
||||||
bool open(const path& p, uint8_t mode);
|
bool open(const path& path, uint8_t mode);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief close a stream
|
/// \brief close a stream
|
||||||
@@ -195,7 +195,7 @@ public:
|
|||||||
/// copies the contents of this file to the new stream,
|
/// copies the contents of this file to the new stream,
|
||||||
/// reopen the new stream with the flags of this file and binds to it,
|
/// reopen the new stream with the flags of this file and binds to it,
|
||||||
/// closes the old file.
|
/// closes the old file.
|
||||||
bool rename(const cstring& p);
|
bool rename(const cstring& path);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief rebinds the stream, copying contents to path, and erasing the old file
|
/// \brief rebinds the stream, copying contents to path, and erasing the old file
|
||||||
@@ -207,7 +207,7 @@ public:
|
|||||||
/// copies the contents of this file to the new stream,
|
/// copies the contents of this file to the new stream,
|
||||||
/// reopen the new stream with the flags of this file and binds to it,
|
/// reopen the new stream with the flags of this file and binds to it,
|
||||||
/// closes the old file.
|
/// closes the old file.
|
||||||
bool rename(const string& p);
|
bool rename(const string& path);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief rebinds the stream, copying contents to path, and erasing the old file
|
/// \brief rebinds the stream, copying contents to path, and erasing the old file
|
||||||
@@ -219,25 +219,25 @@ public:
|
|||||||
/// copies the contents of this file to the new stream,
|
/// copies the contents of this file to the new stream,
|
||||||
/// reopen the new stream with the flags of this file and binds to it,
|
/// reopen the new stream with the flags of this file and binds to it,
|
||||||
/// closes the old file.
|
/// closes the old file.
|
||||||
bool rename(const path& p);
|
bool rename(const path& path);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief copies the contents of this file to path.
|
/// \brief copies the contents of this file to path.
|
||||||
/// \param path the path to copy to
|
/// \param path the path to copy to
|
||||||
/// \returns a file at the new path with the copied contents
|
/// \returns a file at the new path with the copied contents
|
||||||
file copy(const cstring& p);
|
file copy(const cstring& path);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief copies the contents of this file to path.
|
/// \brief copies the contents of this file to path.
|
||||||
/// \param path the path to copy to
|
/// \param path the path to copy to
|
||||||
/// \returns a file at the new path with the copied contents
|
/// \returns a file at the new path with the copied contents
|
||||||
file copy(const string& p);
|
file copy(const string& path);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief copies the contents of this file to path.
|
/// \brief copies the contents of this file to path.
|
||||||
/// \param path the path to copy to
|
/// \param path the path to copy to
|
||||||
/// \returns a file at the new path with the copied contents
|
/// \returns a file at the new path with the copied contents
|
||||||
file copy(const path& p);
|
file copy(const path& path);
|
||||||
|
|
||||||
|
|
||||||
// File Positioning ====================================================================================================
|
// File Positioning ====================================================================================================
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief C-String Conversion Constructor
|
/// \brief C-String Conversion Constructor
|
||||||
/// \param str the cstring to convert
|
/// \param str the cstring to convert
|
||||||
path(const cstring& str) : _str(str) {
|
path(const cstring& str)
|
||||||
|
: _str(str) {
|
||||||
while (not _str.empty() && _str[_str.size() - 1] == '/') {
|
while (not _str.empty() && _str[_str.size() - 1] == '/') {
|
||||||
_str = _str.substring(0, str.size() - 1);
|
_str = _str.substring(0, str.size() - 1);
|
||||||
}
|
}
|
||||||
@@ -62,7 +63,8 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief String Conversion Constructor
|
/// \brief String Conversion Constructor
|
||||||
/// \param str the string to convert
|
/// \param str the string to convert
|
||||||
path(const string& str) : _str(str) {
|
path(const string& str)
|
||||||
|
: _str(str) {
|
||||||
while (_str[_str.size() - 1] == '/') {
|
while (_str[_str.size() - 1] == '/') {
|
||||||
_str = _str.substring(0, str.size() - 1);
|
_str = _str.substring(0, str.size() - 1);
|
||||||
}
|
}
|
||||||
@@ -71,7 +73,9 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Path Copy Constructor
|
/// \brief Path Copy Constructor
|
||||||
/// \param p the path to copy
|
/// \param p the path to copy
|
||||||
path(const path& p) : _str(p._str) { }
|
path(const path& p)
|
||||||
|
: _str(p._str) {
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Path Move Constructor
|
/// \brief Path Move Constructor
|
||||||
@@ -144,10 +148,11 @@ public:
|
|||||||
|
|
||||||
bool empty() {
|
bool empty() {
|
||||||
size_t size = _str.size();
|
size_t size = _str.size();
|
||||||
|
if (size == 0) return true;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return (_str[1] == ':' && size == 3) || size == 0;
|
return (_str[1] == ':' && size == 3);
|
||||||
#else
|
#else
|
||||||
return (_str[0] == '/' && size == 1) || size == 0;
|
return (_str[0] == '/' && size == 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +218,7 @@ public:
|
|||||||
if (parse.empty()) break;
|
if (parse.empty()) break;
|
||||||
|
|
||||||
// Push the path
|
// Push the path
|
||||||
size_t loc = parse._str.find('/');
|
const size_t loc = parse._str.find('/');
|
||||||
working._str += '/';
|
working._str += '/';
|
||||||
working._str += parse._str.substring(0, loc);
|
working._str += parse._str.substring(0, loc);
|
||||||
parse._str = parse._str.substring(loc + 1);
|
parse._str = parse._str.substring(loc + 1);
|
||||||
|
|||||||
@@ -206,6 +206,8 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief String Comparison
|
/// \brief String Comparison
|
||||||
/// \param str the string to compare against
|
/// \param str the string to compare against
|
||||||
|
/// \param i the index to start at
|
||||||
|
/// \param n the number of characters to compare
|
||||||
/// \returns Zero if both strings are equal, otherwise a negative value if lhs appears before rhs according to the
|
/// \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.
|
/// current locale, otherwise a positive value.
|
||||||
constexpr int compare(const cstring& str, size_t i = 0, size_t n = npos) const {
|
constexpr int compare(const cstring& str, size_t i = 0, size_t n = npos) const {
|
||||||
|
|||||||
@@ -75,52 +75,46 @@ public:
|
|||||||
/// \details adds additional character for null termination.
|
/// \details adds additional character for null termination.
|
||||||
constexpr _string(char c, size_t n)
|
constexpr _string(char c, size_t n)
|
||||||
: _str(n + 1) {
|
: _str(n + 1) {
|
||||||
fennec::memset(_str.data(), c, n); _str[n] = '\0';
|
fennec::memset(_str.data(), c, n);
|
||||||
|
_str[n] = '\0';
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
/// \brief Buffer Copy Constructor
|
/// \brief Buffer Copy Constructor
|
||||||
/// \param str the buffer to copy
|
/// \param str the buffer to copy
|
||||||
/// \param len number of characters in the buffer
|
/// \tparam n number of characters in the buffer
|
||||||
///
|
///
|
||||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
||||||
/// This constructor makes the assumption that `len` is the intended number of characters.
|
/// This constructor makes the assumption that `len` is the intended number of characters.
|
||||||
template<size_t n>
|
template<size_t n>
|
||||||
constexpr _string(const char str[n])
|
constexpr _string(const char str[n])
|
||||||
: _str(str, n + 1) {
|
: _str(str, n + 1) {
|
||||||
::strncpy(_str.data(), str, n);
|
|
||||||
_str[n] = '\0';
|
_str[n] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Buffer Copy Constructor
|
/// \brief Buffer Copy Constructor
|
||||||
/// \param str the buffer to copy
|
/// \param str the buffer to copy
|
||||||
/// \param len number of characters in the buffer
|
/// \param n number of characters in the buffer
|
||||||
///
|
///
|
||||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
||||||
/// This constructor makes the assumption that `len` is the intended number of characters.
|
/// This constructor makes the assumption that `n` is the intended number of characters.
|
||||||
constexpr _string(const char* str, size_t n)
|
constexpr _string(const char* str, size_t n)
|
||||||
: _str(str, n + 1) {
|
: _str(str, n + 1) {
|
||||||
::strncpy(_str.data(), str, n);
|
|
||||||
_str[n] = '\0';
|
_str[n] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Buffer Copy Constructor
|
/// \brief Buffer Copy Constructor
|
||||||
/// \param str the buffer to copy
|
/// \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 cstring& str)
|
constexpr _string(const cstring& str)
|
||||||
: _str(str, str.size() + 1) {
|
: _str(str, str.size() + 1) {
|
||||||
_str[str.size()] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief String Copy Constructor
|
/// \brief String Copy Constructor
|
||||||
/// \param str the string to copy
|
/// \param str the string to copy
|
||||||
constexpr _string(const string& str)
|
constexpr _string(const _string& str)
|
||||||
: _string(str, str.size()) {
|
: _str(str._str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr _string(_string&& str) noexcept
|
constexpr _string(_string&& str) noexcept
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ constexpr void* bit_and(void* arr, const void* mask, size_t n) {
|
|||||||
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
||||||
|
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
size_t step = detail::__bit_and(d, s, n);
|
const size_t step = detail::__bit_and(d, s, n);
|
||||||
d += step; s += step; n -= step;
|
d += step; s += step; n -= step;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ constexpr void* bit_or(void* arr, const void* mask, size_t n) {
|
|||||||
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
||||||
while (n > 0)
|
while (n > 0)
|
||||||
{
|
{
|
||||||
size_t step = detail::__bit_or(d, s, n);
|
const size_t step = detail::__bit_or(d, s, n);
|
||||||
d += step; s += step; n -= step;
|
d += step; s += step; n -= step;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ constexpr void* bit_xor(void* arr, const void* mask, size_t n) {
|
|||||||
uint8_t* d = static_cast<uint8_t*>(arr);
|
uint8_t* d = static_cast<uint8_t*>(arr);
|
||||||
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
const uint8_t* s = static_cast<const uint8_t*>(mask);
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
size_t step = detail::__bit_xor(d, s, n);
|
const size_t step = detail::__bit_xor(d, s, n);
|
||||||
d += step; s += step; n -= step;
|
d += step; s += step; n -= step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -805,7 +805,7 @@ constexpr genType ldexp(genType x, genIType exp) {
|
|||||||
// Vector Specializations ----------------------------------------------------------------------------------------------
|
// Vector Specializations ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<typename genType, typename genIType = int_t, size_t...i> requires(is_integral_v<genIType>)
|
template<typename genType, typename genIType = int_t, size_t...i> requires(is_integral_v<genIType>)
|
||||||
constexpr vector<genType, i...> ldexp(const vector<genType, i...>& x, const vector<genType, i...>& exp) {
|
constexpr vector<genType, i...> ldexp(const vector<genType, i...>& x, const vector<genIType, i...>& exp) {
|
||||||
return vector<genType, i...>(fennec::ldexp(x[i], exp[i])...);
|
return vector<genType, i...>(fennec::ldexp(x[i], exp[i])...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
230
include/fennec/math/ext/common.h
Normal file
230
include/fennec/math/ext/common.h
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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_MATH_EXT_COMMON_H
|
||||||
|
#define FENNEC_MATH_EXT_COMMON_H
|
||||||
|
|
||||||
|
#include <fennec/lang/limits.h>
|
||||||
|
|
||||||
|
#include <fennec/math/trigonometric.h>
|
||||||
|
#include <fennec/math/ext/quaternion.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
// Sign Functions ======================================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> sign(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::sign(x.w),
|
||||||
|
fennec::sign(x.x),
|
||||||
|
fennec::sign(x.y),
|
||||||
|
fennec::sign(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> abs(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
x.w * fennec::sign(x.w),
|
||||||
|
x.x * fennec::sign(x.x),
|
||||||
|
x.y * fennec::sign(x.y),
|
||||||
|
x.z * fennec::sign(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Rounding Functions ==================================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> floor(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::floor(x.w),
|
||||||
|
fennec::floor(x.x),
|
||||||
|
fennec::floor(x.y),
|
||||||
|
fennec::floor(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> ceil(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::ceil(x.w),
|
||||||
|
fennec::ceil(x.x),
|
||||||
|
fennec::ceil(x.y),
|
||||||
|
fennec::ceil(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> trunc(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::trunc(x.w),
|
||||||
|
fennec::trunc(x.x),
|
||||||
|
fennec::trunc(x.y),
|
||||||
|
fennec::trunc(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> round(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::round(x.w),
|
||||||
|
fennec::round(x.x),
|
||||||
|
fennec::round(x.y),
|
||||||
|
fennec::round(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> roundEven(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::roundEven(x.w),
|
||||||
|
fennec::roundEven(x.x),
|
||||||
|
fennec::roundEven(x.y),
|
||||||
|
fennec::roundEven(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fractional Functions ================================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> fract(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::fract(x.w),
|
||||||
|
fennec::fract(x.x),
|
||||||
|
fennec::fract(x.y),
|
||||||
|
fennec::fract(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> mod(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::mod(x.w),
|
||||||
|
fennec::mod(x.x),
|
||||||
|
fennec::mod(x.y),
|
||||||
|
fennec::mod(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> modf(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::modf(x.w),
|
||||||
|
fennec::modf(x.x),
|
||||||
|
fennec::modf(x.y),
|
||||||
|
fennec::modf(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> isnan(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::isnan(x.w),
|
||||||
|
fennec::isnan(x.x),
|
||||||
|
fennec::isnan(x.y),
|
||||||
|
fennec::isnan(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> isinf(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::isinf(x.w),
|
||||||
|
fennec::isinf(x.x),
|
||||||
|
fennec::isinf(x.y),
|
||||||
|
fennec::isinf(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> fma(const qua<genType>& a, const qua<genType>& b, const qua<genType>& c) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::fma(a.w, b.w, c.w),
|
||||||
|
fennec::fma(a.x, b.x, c.x),
|
||||||
|
fennec::fma(a.y, b.y, c.y),
|
||||||
|
fennec::fma(a.z, b.z, c.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Comparison Functions ================================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> min(const qua<genType>& x, const qua<genType>& y) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::min(x.w, y.w),
|
||||||
|
fennec::min(x.x, y.x),
|
||||||
|
fennec::min(x.y, y.y),
|
||||||
|
fennec::min(x.z, y.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> max(const qua<genType>& x, const qua<genType>& y) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::max(x.w, y.w),
|
||||||
|
fennec::max(x.x, y.x),
|
||||||
|
fennec::max(x.y, y.y),
|
||||||
|
fennec::max(x.z, y.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> clamp(const qua<genType>& x, genType minVal, genType maxVal) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::clamp(x.w, minVal, maxVal),
|
||||||
|
fennec::clamp(x.x, minVal, maxVal),
|
||||||
|
fennec::clamp(x.y, minVal, maxVal),
|
||||||
|
fennec::clamp(x.z, minVal, maxVal)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> clamp(const qua<genType>& x, const qua<genType>& minVal, const qua<genType>& maxVal) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::clamp(x.w, minVal.w, maxVal.w),
|
||||||
|
fennec::clamp(x.x, minVal.x, maxVal.x),
|
||||||
|
fennec::clamp(x.y, minVal.y, maxVal.y),
|
||||||
|
fennec::clamp(x.z, minVal.z, maxVal.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Curves ==============================================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> mix(const qua<genType>& x, const qua<genType>& y, genType a) {
|
||||||
|
genType cT = fennec::dot(x, y);
|
||||||
|
qua<genType> z = cT < genType(0) ? -y : y;
|
||||||
|
cT = cT < genType(0) ? -cT : cT;
|
||||||
|
|
||||||
|
if (cT > genType(1) - numeric_limits<genType>::epsilon()) {
|
||||||
|
return x * (genType(1) - a) + y * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
genType t = fennec::acos(cT);
|
||||||
|
return (fennec::sin(x * (genType(1) - a) * t) + z * (fennec::sin(a * t))) / fennec::sin(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FENNEC_MATH_EXT_COMMON_H
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
#ifndef FENNEC_MATH_EXT_QUATERNION_H
|
#ifndef FENNEC_MATH_EXT_QUATERNION_H
|
||||||
#define FENNEC_MATH_EXT_QUATERNION_H
|
#define FENNEC_MATH_EXT_QUATERNION_H
|
||||||
|
|
||||||
#include <fennec/math/trigonometric.h>
|
|
||||||
#include <fennec/math/vector_base.h>
|
#include <fennec/math/vector_base.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
@@ -27,16 +26,18 @@ namespace fennec
|
|||||||
|
|
||||||
template<typename ScalarT> struct quaternion;
|
template<typename ScalarT> struct quaternion;
|
||||||
|
|
||||||
|
template<typename genType> using qua = quaternion<genType>;
|
||||||
|
|
||||||
using quat = quaternion<float>;
|
using quat = qua<float>;
|
||||||
using dquat = quaternion<double>;
|
using dquat = qua<double>;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Dot Function
|
/// \brief Dot Function
|
||||||
/// \param q The Quaternion
|
/// \param x the first quaternion
|
||||||
/// \returns The square sum of all components.
|
/// \param y the second quaternion
|
||||||
|
/// \returns The sum of component products.
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
constexpr genType dot(const quaternion<genType>& x, const quaternion<genType>& y) {
|
constexpr genType dot(const qua<genType>& x, const qua<genType>& y) {
|
||||||
return x.w*y.w + x.x*y.x + x.y*y.y + x.z*y.z;
|
return x.w*y.w + x.x*y.x + x.y*y.y + x.z*y.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ constexpr genType dot(const quaternion<genType>& x, const quaternion<genType>& y
|
|||||||
/// \param q The Quaternion
|
/// \param q The Quaternion
|
||||||
/// \returns The square sum of all components.
|
/// \returns The square sum of all components.
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
constexpr genType sqnorm(const quaternion<genType>& q) {
|
constexpr genType sqnorm(const qua<genType>& q) {
|
||||||
return fennec::dot(q, q);
|
return fennec::dot(q, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ constexpr genType sqnorm(const quaternion<genType>& q) {
|
|||||||
/// \param q The Quaternion
|
/// \param q The Quaternion
|
||||||
/// \returns The Hamilton Tensor of `q`
|
/// \returns The Hamilton Tensor of `q`
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
constexpr genType norm(const quaternion<genType>& q) {
|
constexpr genType norm(const qua<genType>& q) {
|
||||||
return fennec::sqrt(sqnorm(q));
|
return fennec::sqrt(sqnorm(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ constexpr genType norm(const quaternion<genType>& q) {
|
|||||||
/// \param q The Quaternion
|
/// \param q The Quaternion
|
||||||
/// \returns A Quaternion of `q` with norm `1`
|
/// \returns A Quaternion of `q` with norm `1`
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
constexpr quaternion<genType> unit(const quaternion<genType>& q) {
|
constexpr qua<genType> unit(const qua<genType>& q) {
|
||||||
genType n = fennec::norm(q);
|
genType n = fennec::norm(q);
|
||||||
return q * (genType(1) / n);
|
return q * (genType(1) / n);
|
||||||
}
|
}
|
||||||
@@ -73,23 +74,10 @@ constexpr quaternion<genType> unit(const quaternion<genType>& q) {
|
|||||||
/// \param q The Quaternion
|
/// \param q The Quaternion
|
||||||
/// \returns The quaternion \f${q}^{-1}\f$
|
/// \returns The quaternion \f${q}^{-1}\f$
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
constexpr quaternion<genType> reciprocal(const quaternion<genType>& q) {
|
constexpr qua<genType> reciprocal(const qua<genType>& q) {
|
||||||
return ~q / fennec::sqnorm(q);
|
return ~q / fennec::sqnorm(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename genType>
|
|
||||||
constexpr quaternion<genType> mix(const quaternion<genType>& x, const quaternion<genType>& y, genType a) {
|
|
||||||
genType cT = fennec::dot(x, y);
|
|
||||||
quaternion<genType> z = cT < genType(0) ? -y : y;
|
|
||||||
cT = cT < genType(0) ? -cT : cT;
|
|
||||||
|
|
||||||
if (cT > genType(1) - numeric_limits<genType>::epsilon()) {
|
|
||||||
return x * (genType(1) - a) + y * a;
|
|
||||||
}
|
|
||||||
|
|
||||||
genType t = fennec::acos(cT);
|
|
||||||
return (fennec::sin(x * (genType(1) - a) * t) + z * (fennec::sin(a * t))) / fennec::sin(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ScalarT>
|
template<typename ScalarT>
|
||||||
struct quaternion : detail::vector_base_type<ScalarT, 4>
|
struct quaternion : detail::vector_base_type<ScalarT, 4>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <fennec/math/matrix.h>
|
#include <fennec/math/matrix.h>
|
||||||
#include <fennec/math/trigonometric.h>
|
#include <fennec/math/trigonometric.h>
|
||||||
#include <fennec/math/ext/constants.h>
|
#include <fennec/math/ext/constants.h>
|
||||||
|
#include <fennec/math/ext/quaternion.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
@@ -125,6 +126,14 @@ constexpr mat<genType, 4, 4> rotation(const vec<genType, 3>& A, genType a) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> rotation(const vec<genType, 3>& axis, genType angle) {
|
||||||
|
vec<genType, 3> a = fennec::normalize(axis);
|
||||||
|
const genType s = fennec::sin(angle);
|
||||||
|
|
||||||
|
return qua<genType>(fennec::cos(angle * genType(0.5)), s * a.x, s * a.y, s * a.z);
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief enum to denote the unit-axis of rotation
|
/// \brief enum to denote the unit-axis of rotation
|
||||||
enum rot_
|
enum rot_
|
||||||
{
|
{
|
||||||
|
|||||||
168
include/fennec/math/ext/trigonometric.h
Normal file
168
include/fennec/math/ext/trigonometric.h
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// 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_MATH_EXT_TRIGONOMETRIC_H
|
||||||
|
#define FENNEC_MATH_EXT_TRIGONOMETRIC_H
|
||||||
|
|
||||||
|
#include <fennec/math/trigonometric.h>
|
||||||
|
#include <fennec/math/ext/quaternion.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
// Angle Conversions ===================================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> radians(const qua<genType>& degrees) {
|
||||||
|
return qua<genType>(degrees * 0.01745329251994329576923690768489);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> degrees(const qua<genType>& radians) {
|
||||||
|
return qua<genType>(radians * 57.29577951308232087679815481410517);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Trigonometric Functions =============================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> sin(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::sin(x.w),
|
||||||
|
fennec::sin(x.x),
|
||||||
|
fennec::sin(x.y),
|
||||||
|
fennec::sin(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> cos(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::cos(x.w),
|
||||||
|
fennec::cos(x.x),
|
||||||
|
fennec::cos(x.y),
|
||||||
|
fennec::cos(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> tan(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::tan(x.w),
|
||||||
|
fennec::tan(x.x),
|
||||||
|
fennec::tan(x.y),
|
||||||
|
fennec::tan(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> asin(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::asin(x.w),
|
||||||
|
fennec::asin(x.x),
|
||||||
|
fennec::asin(x.y),
|
||||||
|
fennec::asin(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> acos(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::acos(x.w),
|
||||||
|
fennec::acos(x.x),
|
||||||
|
fennec::acos(x.y),
|
||||||
|
fennec::acos(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> atan(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::atan(x.w),
|
||||||
|
fennec::atan(x.x),
|
||||||
|
fennec::atan(x.y),
|
||||||
|
fennec::atan(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Hyperbolic Functions ================================================================================================
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> sinh(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::sinh(x.w),
|
||||||
|
fennec::sinh(x.x),
|
||||||
|
fennec::sinh(x.y),
|
||||||
|
fennec::sinh(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> cosh(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::cosh(x.w),
|
||||||
|
fennec::cosh(x.x),
|
||||||
|
fennec::cosh(x.y),
|
||||||
|
fennec::cosh(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> tanh(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::tanh(x.w),
|
||||||
|
fennec::tanh(x.x),
|
||||||
|
fennec::tanh(x.y),
|
||||||
|
fennec::tanh(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> asinh(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::asinh(x.w),
|
||||||
|
fennec::asinh(x.x),
|
||||||
|
fennec::asinh(x.y),
|
||||||
|
fennec::asinh(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> acosh(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::acosh(x.w),
|
||||||
|
fennec::acosh(x.x),
|
||||||
|
fennec::acosh(x.y),
|
||||||
|
fennec::acosh(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
constexpr qua<genType> atanh(const qua<genType>& x) {
|
||||||
|
return qua<genType>(
|
||||||
|
fennec::atanh(x.w),
|
||||||
|
fennec::atanh(x.x),
|
||||||
|
fennec::atanh(x.y),
|
||||||
|
fennec::atanh(x.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_MATH_EXT_TRIGONOMETRIC_H
|
||||||
@@ -169,7 +169,7 @@ constexpr genType radians(genType degrees) {
|
|||||||
|
|
||||||
template<typename genType, size_t...i>
|
template<typename genType, size_t...i>
|
||||||
constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees) {
|
constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees) {
|
||||||
return genType(degrees * 0.01745329251994329576923690768489);
|
return vector<genType, i...>(degrees * 0.01745329251994329576923690768489);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -326,6 +326,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Sized Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes
|
/// \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
|
/// \param n The number of elements of type `T` to allocate for
|
||||||
|
/// \param align The alignment of the allocation
|
||||||
constexpr allocation(size_t n, align_t align) noexcept
|
constexpr allocation(size_t n, align_t align) noexcept
|
||||||
: _data(nullptr)
|
: _data(nullptr)
|
||||||
, _capacity(0)
|
, _capacity(0)
|
||||||
@@ -338,6 +339,7 @@ public:
|
|||||||
/// Then, the contents of data are copied into the allocation.
|
/// Then, the contents of data are copied into the allocation.
|
||||||
/// \param data the buffer to copy
|
/// \param data the buffer to copy
|
||||||
/// \param n the number of elements
|
/// \param n the number of elements
|
||||||
|
/// \param align The alignment of the allocation
|
||||||
constexpr allocation(const T* data, size_t n, align_t align)
|
constexpr allocation(const T* data, size_t n, align_t align)
|
||||||
: allocation(n, align) {
|
: allocation(n, align) {
|
||||||
fennec::memcpy(_data, data, n);
|
fennec::memcpy(_data, data, n);
|
||||||
@@ -383,6 +385,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// \brief Sized Allocator Constructor
|
/// \brief Sized Allocator Constructor
|
||||||
/// \param n The number of elements of type `T` to allocate for
|
/// \param n The number of elements of type `T` to allocate for
|
||||||
|
/// \param align The alignment of the allocation
|
||||||
/// \param alloc The allocation object to copy.
|
/// \param alloc The allocation object to copy.
|
||||||
///
|
///
|
||||||
/// \details This constructor should be used when the type `AllocT` needs internal data.
|
/// \details This constructor should be used when the type `AllocT` needs internal data.
|
||||||
@@ -399,6 +402,7 @@ public:
|
|||||||
/// Then, the contents of data are copied into the allocation.
|
/// Then, the contents of data are copied into the allocation.
|
||||||
/// \param data the buffer to copy
|
/// \param data the buffer to copy
|
||||||
/// \param n the number of elements
|
/// \param n the number of elements
|
||||||
|
/// \param align The alignment of the allocation
|
||||||
/// \param alloc The allocation object to copy.
|
/// \param alloc The allocation object to copy.
|
||||||
///
|
///
|
||||||
/// \details This constructor should be used when the type `AllocT` needs internal data.
|
/// \details This constructor should be used when the type `AllocT` needs internal data.
|
||||||
@@ -475,7 +479,7 @@ public:
|
|||||||
constexpr void allocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
constexpr void allocate(size_t n, align_t align = zero<align_t>()) noexcept {
|
||||||
deallocate();
|
deallocate();
|
||||||
|
|
||||||
if (_alignment != zero<align_t>()) {
|
if (align != zero<align_t>()) {
|
||||||
_data = _alloc.allocate(_capacity = n, _alignment = align);
|
_data = _alloc.allocate(_capacity = n, _alignment = align);
|
||||||
} else {
|
} else {
|
||||||
_data = _alloc.allocate(_capacity = n);
|
_data = _alloc.allocate(_capacity = n);
|
||||||
@@ -521,7 +525,7 @@ public:
|
|||||||
return _data[i];
|
return _data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const value_t operator[](size_t i) const {
|
constexpr const value_t& operator[](size_t i) const {
|
||||||
assertd(i < size(), "Array Out of Bounds");
|
assertd(i < size(), "Array Out of Bounds");
|
||||||
return _data[i];
|
return _data[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ using ::wmemcmp;
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Safe version of memcmp
|
/// \brief Safe version of memcmp
|
||||||
/// \copydoc fennec::memcmp
|
/// \param lhs The first object, interpreted as an array of bytes
|
||||||
|
/// \param rhs The second object, interpreted as an array of bytes
|
||||||
/// \param n0 The size, in bytes, of lhs
|
/// \param n0 The size, in bytes, of lhs
|
||||||
/// \param n1 The size, in bytes, of rhs
|
/// \param n1 The size, in bytes, of rhs
|
||||||
constexpr int memcmp_s(const void* lhs, size_t n0, const void* rhs, size_t n1) {
|
constexpr int memcmp_s(const void* lhs, size_t n0, const void* rhs, size_t n1) {
|
||||||
@@ -93,7 +94,8 @@ using ::wmemcpy;
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Safe version of memcpy
|
/// \brief Safe version of memcpy
|
||||||
/// \copydoc fennec::memcpy
|
/// \param dst The destination object, interpreted as an array of bytes
|
||||||
|
/// \param src The source object, interpreted as an array of bytes
|
||||||
/// \param n0 The size, in bytes, of dst
|
/// \param n0 The size, in bytes, of dst
|
||||||
/// \param n1 The size, in bytes, of src
|
/// \param n1 The size, in bytes, of src
|
||||||
constexpr void* memcpy_s(void* dst, size_t n0, const void* src, size_t n1) {
|
constexpr void* memcpy_s(void* dst, size_t n0, const void* src, size_t n1) {
|
||||||
@@ -111,7 +113,8 @@ using ::wmemmove;
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Safe version of memmove
|
/// \brief Safe version of memmove
|
||||||
/// \copydoc fennec::memmove
|
/// \param dst The destination object, interpreted as an array of bytes
|
||||||
|
/// \param src The source object, interpreted as an array of bytes
|
||||||
/// \param n0 The size, in bytes, of dst
|
/// \param n0 The size, in bytes, of dst
|
||||||
/// \param n1 The size, in bytes, of src
|
/// \param n1 The size, in bytes, of src
|
||||||
constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1) {
|
constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1) {
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ bool file::erase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close the file
|
// Close the file
|
||||||
path path = move(_path);
|
const path path = move(_path);
|
||||||
if (close()) {
|
if (close()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -512,7 +512,7 @@ bool file::rename(const path& p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate path
|
// Validate path
|
||||||
path fpath = p.absolute();
|
const path fpath = p.absolute();
|
||||||
if (_path == fpath) {
|
if (_path == fpath) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -783,7 +783,7 @@ file file::copy(const path& p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate path
|
// Validate path
|
||||||
path fpath = p.absolute();
|
const path fpath = p.absolute();
|
||||||
if (_path == fpath) {
|
if (_path == fpath) {
|
||||||
return file();
|
return file();
|
||||||
}
|
}
|
||||||
@@ -951,7 +951,7 @@ size_t file::read(void* data, size_t size, size_t n) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t read = fread(data, size, n, _handle);
|
const size_t read = fread(data, size, n, _handle);
|
||||||
if (read != size && ferror(_handle)) {
|
if (read != size && ferror(_handle)) {
|
||||||
_error = strerror(errno);
|
_error = strerror(errno);
|
||||||
}
|
}
|
||||||
@@ -971,7 +971,7 @@ string file::getline() {
|
|||||||
// Read the next line;
|
// Read the next line;
|
||||||
char* line = nullptr;
|
char* line = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t read = ::getline(&line, &size, _handle);
|
const size_t read = ::getline(&line, &size, _handle);
|
||||||
if (read == npos && ferror(_handle)) {
|
if (read == npos && ferror(_handle)) {
|
||||||
_error = strerror(errno);
|
_error = strerror(errno);
|
||||||
if (line) free(line);
|
if (line) free(line);
|
||||||
@@ -1053,7 +1053,7 @@ size_t file::write(const void* data, size_t size, size_t n) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t r = fwrite(data, size, n, _handle);
|
const size_t r = fwrite(data, size, n, _handle);
|
||||||
|
|
||||||
if (r != size && ferror(_handle)) {
|
if (r != size && ferror(_handle)) {
|
||||||
_error = strerror(errno);
|
_error = strerror(errno);
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ namespace fennec
|
|||||||
namespace test
|
namespace test
|
||||||
{
|
{
|
||||||
|
|
||||||
static char test_string[] = "Hello World!";
|
|
||||||
static const char test_string_const[] = "Hello World!";
|
|
||||||
|
|
||||||
inline void fennec_test_fproc_strings_cstring()
|
inline void fennec_test_fproc_strings_cstring()
|
||||||
{
|
{
|
||||||
|
static char test_string[] = "Hello World!";
|
||||||
|
static const char test_string_const[] = "Hello World!";
|
||||||
|
|
||||||
cstring str = test_string;
|
cstring str = test_string;
|
||||||
const cstring cstr = test_string_const;
|
const cstring cstr = test_string_const;
|
||||||
|
|
||||||
@@ -40,12 +40,12 @@ inline void fennec_test_fproc_strings_cstring()
|
|||||||
|
|
||||||
fennec_test_spacer(1);
|
fennec_test_spacer(1);
|
||||||
|
|
||||||
fennec_test_run(str.length(), size_t(12));
|
fennec_test_run(str.length(), static_cast<size_t>(12));
|
||||||
fennec_test_run(str.compare(cstr), 0);
|
fennec_test_run(str.compare(cstr), 0);
|
||||||
fennec_test_run(str.find('W'), size_t(6));
|
fennec_test_run(str.find('W'), static_cast<size_t>(6));
|
||||||
fennec_test_run(str.find("World"), size_t(6));
|
fennec_test_run(str.find("World"), static_cast<size_t>(6));
|
||||||
fennec_test_run(str.rfind('o'), size_t(7));
|
fennec_test_run(str.rfind('o'), static_cast<size_t>(7));
|
||||||
fennec_test_run(str.rfind("World"), size_t(6));
|
fennec_test_run(str.rfind("World"), static_cast<size_t>(6));
|
||||||
|
|
||||||
fennec_test_spacer(2);
|
fennec_test_spacer(2);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user