- Component-Wise Functions for Quaternions

- Fixed Allocation Bug with Strings
This commit is contained in:
2025-07-17 21:56:37 -04:00
parent 86286e84d7
commit ab1c7d94be
17 changed files with 514 additions and 89 deletions

View File

@@ -108,7 +108,11 @@ add_library(fennec STATIC
include/fennec/math/trigonometric.h
include/fennec/math/relational.h
include/fennec/math/ext/common.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/__math.h
@@ -128,8 +132,6 @@ add_library(fennec STATIC
# Filesystem
include/fennec/fproc/filesystem/file.h source/fproc/filesystem/file.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

View File

@@ -52,42 +52,62 @@ public:
///
/// \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.
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.
dynarray(size_t n) : _alloc(n), _size(n)
dynarray(size_t n)
: _alloc(n)
, _size(n)
{
element_t* addr = _alloc.data();
for(; n > 0; --n, ++addr) { fennec::construct(addr); }
for(; n > 0; --n, ++addr) {
fennec::construct(addr);
}
}
///
/// \brief
/// \param n
/// \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();
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 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();
for(; n > 0; --n, ++addr) { fennec::construct(addr, val); }
for(; n > 0; --n, ++addr) {
fennec::construct(addr, val);
}
}
template<typename...ArgsT>
dynarray(size_t n, ArgsT&&...args) {
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() {
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 {

View File

@@ -81,9 +81,9 @@ public:
/// \param mode the bitfield
/// \returns true if the combination of flags is valid, false otherwise
static constexpr bool is_valid(uint8_t mode) {
bool t = mode & fmode_trunc;
bool x = mode & fmode_exclusive;
bool w = mode & fmode_write;
const bool t = mode & fmode_trunc;
const bool x = mode & fmode_exclusive;
const bool w = mode & fmode_write;
// when x is true, t must be true
// when t is true, w must be true
@@ -151,21 +151,21 @@ public:
/// \param path the path to the file
/// \param mode the mode flags to open the file with
/// \returns false on success, true on error
bool open(const cstring& p, uint8_t mode);
bool open(const cstring& path, uint8_t mode);
///
/// \brief open a file
/// \param path the path to the file
/// \param mode the mode flags to open the file with
/// \returns false on success, true on error
bool open(const string& p, uint8_t mode);
bool open(const string& path, uint8_t mode);
///
/// \brief open a file
/// \param path the path to the file
/// \param mode the mode flags to open the file with
/// \returns false on success, true on error
bool open(const path& p, uint8_t mode);
bool open(const path& path, uint8_t mode);
///
/// \brief close a stream
@@ -195,7 +195,7 @@ public:
/// copies the contents of this file to the new stream,
/// reopen the new stream with the flags of this file and binds to it,
/// closes the old file.
bool rename(const cstring& p);
bool rename(const cstring& path);
///
/// \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,
/// reopen the new stream with the flags of this file and binds to it,
/// 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
@@ -219,25 +219,25 @@ public:
/// copies the contents of this file to the new stream,
/// reopen the new stream with the flags of this file and binds to it,
/// closes the old file.
bool rename(const path& p);
bool rename(const path& path);
///
/// \brief copies the contents of this file to path.
/// \param path the path to copy to
/// \returns a file at the new path with the copied contents
file copy(const cstring& p);
file copy(const cstring& path);
///
/// \brief copies the contents of this file to path.
/// \param path the path to copy to
/// \returns a file at the new path with the copied contents
file copy(const string& p);
file copy(const string& path);
///
/// \brief copies the contents of this file to path.
/// \param path the path to copy to
/// \returns a file at the new path with the copied contents
file copy(const path& p);
file copy(const path& path);
// File Positioning ====================================================================================================

View File

@@ -53,7 +53,8 @@ public:
///
/// \brief C-String Conversion Constructor
/// \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] == '/') {
_str = _str.substring(0, str.size() - 1);
}
@@ -62,7 +63,8 @@ public:
///
/// \brief String Conversion Constructor
/// \param str the string to convert
path(const string& str) : _str(str) {
path(const string& str)
: _str(str) {
while (_str[_str.size() - 1] == '/') {
_str = _str.substring(0, str.size() - 1);
}
@@ -71,7 +73,9 @@ public:
///
/// \brief Path Copy Constructor
/// \param p the path to copy
path(const path& p) : _str(p._str) { }
path(const path& p)
: _str(p._str) {
}
///
/// \brief Path Move Constructor
@@ -144,10 +148,11 @@ public:
bool empty() {
size_t size = _str.size();
if (size == 0) return true;
#ifdef _WIN32
return (_str[1] == ':' && size == 3) || size == 0;
return (_str[1] == ':' && size == 3);
#else
return (_str[0] == '/' && size == 1) || size == 0;
return (_str[0] == '/' && size == 1);
#endif
}
@@ -213,7 +218,7 @@ public:
if (parse.empty()) break;
// Push the path
size_t loc = parse._str.find('/');
const size_t loc = parse._str.find('/');
working._str += '/';
working._str += parse._str.substring(0, loc);
parse._str = parse._str.substring(loc + 1);

View File

@@ -206,6 +206,8 @@ public:
///
/// \brief String Comparison
/// \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
/// current locale, otherwise a positive value.
constexpr int compare(const cstring& str, size_t i = 0, size_t n = npos) const {

View File

@@ -75,52 +75,46 @@ public:
/// \details adds additional character for null termination.
constexpr _string(char c, size_t n)
: _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
/// \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.
/// This constructor makes the assumption that `len` is the intended number of characters.
template<size_t n>
constexpr _string(const char str[n])
: _str(str, n + 1) {
::strncpy(_str.data(), str, n);
_str[n] = '\0';
}
///
/// \brief Buffer Copy Constructor
/// \param str the buffer to copy
/// \param len number of characters in the buffer
/// \param n 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.
/// This constructor makes the assumption that `n` is the intended number of characters.
constexpr _string(const char* str, size_t n)
: _str(str, n + 1) {
::strncpy(_str.data(), str, n);
_str[n] = '\0';
}
///
/// \brief Buffer Copy Constructor
/// \param str the buffer to copy
/// \param len number of characters in the buffer
///
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
/// This constructor makes the assumption that `len` is the intended number of characters.
constexpr _string(const cstring& str)
: _str(str, str.size() + 1) {
_str[str.size()] = '\0';
}
///
/// \brief String Copy Constructor
/// \param str the string to copy
constexpr _string(const string& str)
: _string(str, str.size()) {
constexpr _string(const _string& str)
: _str(str._str) {
}
constexpr _string(_string&& str) noexcept

View File

@@ -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);
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;
}
@@ -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);
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;
}
@@ -207,7 +207,7 @@ constexpr void* bit_xor(void* arr, const void* mask, size_t n) {
uint8_t* d = static_cast<uint8_t*>(arr);
const uint8_t* s = static_cast<const uint8_t*>(mask);
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;
}

View File

@@ -805,7 +805,7 @@ constexpr genType ldexp(genType x, genIType exp) {
// Vector Specializations ----------------------------------------------------------------------------------------------
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])...);
}

View 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

View File

@@ -19,7 +19,6 @@
#ifndef FENNEC_MATH_EXT_QUATERNION_H
#define FENNEC_MATH_EXT_QUATERNION_H
#include <fennec/math/trigonometric.h>
#include <fennec/math/vector_base.h>
namespace fennec
@@ -27,16 +26,18 @@ namespace fennec
template<typename ScalarT> struct quaternion;
template<typename genType> using qua = quaternion<genType>;
using quat = quaternion<float>;
using dquat = quaternion<double>;
using quat = qua<float>;
using dquat = qua<double>;
///
/// \brief Dot Function
/// \param q The Quaternion
/// \returns The square sum of all components.
/// \param x the first quaternion
/// \param y the second quaternion
/// \returns The sum of component products.
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;
}
@@ -45,7 +46,7 @@ constexpr genType dot(const quaternion<genType>& x, const quaternion<genType>& y
/// \param q The Quaternion
/// \returns The square sum of all components.
template<typename genType>
constexpr genType sqnorm(const quaternion<genType>& q) {
constexpr genType sqnorm(const qua<genType>& q) {
return fennec::dot(q, q);
}
@@ -54,7 +55,7 @@ constexpr genType sqnorm(const quaternion<genType>& q) {
/// \param q The Quaternion
/// \returns The Hamilton Tensor of `q`
template<typename genType>
constexpr genType norm(const quaternion<genType>& q) {
constexpr genType norm(const qua<genType>& q) {
return fennec::sqrt(sqnorm(q));
}
@@ -63,7 +64,7 @@ constexpr genType norm(const quaternion<genType>& q) {
/// \param q The Quaternion
/// \returns A Quaternion of `q` with norm `1`
template<typename genType>
constexpr quaternion<genType> unit(const quaternion<genType>& q) {
constexpr qua<genType> unit(const qua<genType>& q) {
genType n = fennec::norm(q);
return q * (genType(1) / n);
}
@@ -73,23 +74,10 @@ constexpr quaternion<genType> unit(const quaternion<genType>& q) {
/// \param q The Quaternion
/// \returns The quaternion \f${q}^{-1}\f$
template<typename genType>
constexpr quaternion<genType> reciprocal(const quaternion<genType>& q) {
constexpr qua<genType> reciprocal(const qua<genType>& 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>
struct quaternion : detail::vector_base_type<ScalarT, 4>

View File

@@ -22,6 +22,7 @@
#include <fennec/math/matrix.h>
#include <fennec/math/trigonometric.h>
#include <fennec/math/ext/constants.h>
#include <fennec/math/ext/quaternion.h>
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
enum rot_
{

View 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

View File

@@ -169,7 +169,7 @@ constexpr genType radians(genType degrees) {
template<typename genType, size_t...i>
constexpr vector<genType, i...> radians(const vector<genType, i...>& degrees) {
return genType(degrees * 0.01745329251994329576923690768489);
return vector<genType, i...>(degrees * 0.01745329251994329576923690768489);
}

View File

@@ -326,6 +326,7 @@ public:
///
/// \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 align The alignment of the allocation
constexpr allocation(size_t n, align_t align) noexcept
: _data(nullptr)
, _capacity(0)
@@ -338,6 +339,7 @@ public:
/// Then, the contents of data are copied into the allocation.
/// \param data the buffer to copy
/// \param n the number of elements
/// \param align The alignment of the allocation
constexpr allocation(const T* data, size_t n, align_t align)
: allocation(n, align) {
fennec::memcpy(_data, data, n);
@@ -383,6 +385,7 @@ public:
///
/// \brief Sized Allocator Constructor
/// \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.
///
/// \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.
/// \param data the buffer to copy
/// \param n the number of elements
/// \param align The alignment of the allocation
/// \param alloc The allocation object to copy.
///
/// \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 {
deallocate();
if (_alignment != zero<align_t>()) {
if (align != zero<align_t>()) {
_data = _alloc.allocate(_capacity = n, _alignment = align);
} else {
_data = _alloc.allocate(_capacity = n);
@@ -521,7 +525,7 @@ public:
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");
return _data[i];
}

View File

@@ -69,7 +69,8 @@ using ::wmemcmp;
///
/// \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 n1 The size, in bytes, of rhs
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
/// \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 n1 The size, in bytes, of src
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
/// \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 n1 The size, in bytes, of src
constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1) {

View File

@@ -307,7 +307,7 @@ bool file::erase() {
}
// Close the file
path path = move(_path);
const path path = move(_path);
if (close()) {
return true;
}
@@ -512,7 +512,7 @@ bool file::rename(const path& p) {
}
// Validate path
path fpath = p.absolute();
const path fpath = p.absolute();
if (_path == fpath) {
return false;
}
@@ -783,7 +783,7 @@ file file::copy(const path& p) {
}
// Validate path
path fpath = p.absolute();
const path fpath = p.absolute();
if (_path == fpath) {
return file();
}
@@ -951,7 +951,7 @@ size_t file::read(void* data, size_t size, size_t n) {
return 0;
}
size_t read = fread(data, size, n, _handle);
const size_t read = fread(data, size, n, _handle);
if (read != size && ferror(_handle)) {
_error = strerror(errno);
}
@@ -971,7 +971,7 @@ string file::getline() {
// Read the next line;
char* line = nullptr;
size_t size = 0;
size_t read = ::getline(&line, &size, _handle);
const size_t read = ::getline(&line, &size, _handle);
if (read == npos && ferror(_handle)) {
_error = strerror(errno);
if (line) free(line);
@@ -1053,7 +1053,7 @@ size_t file::write(const void* data, size_t size, size_t n) {
return 0;
}
size_t r = fwrite(data, size, n, _handle);
const size_t r = fwrite(data, size, n, _handle);
if (r != size && ferror(_handle)) {
_error = strerror(errno);

View File

@@ -27,11 +27,11 @@ namespace fennec
namespace test
{
static char test_string[] = "Hello World!";
static const char test_string_const[] = "Hello World!";
inline void fennec_test_fproc_strings_cstring()
{
static char test_string[] = "Hello World!";
static const char test_string_const[] = "Hello World!";
cstring str = test_string;
const cstring cstr = test_string_const;
@@ -40,12 +40,12 @@ inline void fennec_test_fproc_strings_cstring()
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.find('W'), size_t(6));
fennec_test_run(str.find("World"), size_t(6));
fennec_test_run(str.rfind('o'), size_t(7));
fennec_test_run(str.rfind("World"), size_t(6));
fennec_test_run(str.find('W'), static_cast<size_t>(6));
fennec_test_run(str.find("World"), static_cast<size_t>(6));
fennec_test_run(str.rfind('o'), static_cast<size_t>(7));
fennec_test_run(str.rfind("World"), static_cast<size_t>(6));
fennec_test_spacer(2);