/// \ref fennec::nullptr_t "nullptr_t"
diff --git a/include/fennec/math/matrix.h b/include/fennec/math/matrix.h
index a6fb0f8..7611825 100644
--- a/include/fennec/math/matrix.h
+++ b/include/fennec/math/matrix.h
@@ -324,7 +324,7 @@ struct matrix
///
/// \copydetails matrix::operator[](size_t) const
constexpr column_t& operator[](size_t i)
- { assert(i < columns); return data[i]; }
+ { assert(i < columns, "Array Out of Bounds"); return data[i]; }
///
/// \brief returns the column at index \f$i\f$
@@ -333,20 +333,20 @@ struct matrix
/// \param i the index
/// \returns the column at index \f$i\f$
constexpr const column_t& operator[](size_t i) const
- { assert(i < columns); return data[i]; }
+ { assert(i < columns, "Array Out of Bounds"); return data[i]; }
///
/// \copydetails matrix::operator()(size_t, size_t) const
- constexpr scalar_t& operator()(size_t i, size_t j)
- { assert(i < columns && j < rows); return data[i][j]; }
+ constexpr scalar_t& operator[](size_t i, size_t j)
+ { assert(i < columns && j < rows, "Array Out of Bounds"); return data[i][j]; }
///
/// \brief returns the cell in row \p j column \p i
/// \param i the column
/// \param j the row
/// \returns the cell at the specified index.
- constexpr scalar_t operator()(size_t i, size_t j) const
- { assert(i < columns && j < rows); return data[i][j]; }
+ constexpr scalar_t operator[](size_t i, size_t j) const
+ { assert(i < columns && j < rows, "Array Out of Bounds"); return data[i][j]; }
/// @}
diff --git a/include/fennec/math/vector.h b/include/fennec/math/vector.h
index 2036f45..20b5e21 100644
--- a/include/fennec/math/vector.h
+++ b/include/fennec/math/vector.h
@@ -710,7 +710,7 @@ struct vector : detail::vector_base_type
/// \brief unary boolean not operator
///
/// \details
- /// \param v the vector
+ /// \param x the vector
/// \returns A \ref fennec_math_vector "vector" \a v such that, \f$v_i=!x_i\f$
constexpr friend vector_t operator!(const vector_t& x)
{ return vector_t(!x[IndicesV] ...); }
diff --git a/include/fennec/memory/allocator.h b/include/fennec/memory/allocator.h
index b1b5d36..8b3e21e 100644
--- a/include/fennec/memory/allocator.h
+++ b/include/fennec/memory/allocator.h
@@ -22,6 +22,7 @@
#include
#include
+#include
#include
#include
#include
@@ -64,7 +65,7 @@ private:
struct __diff> { using type = typename AllocT::diff_t; };
template
- struct __size : std::make_unsigned {};
+ struct __size : make_unsigned {};
template
struct __size> { using type = typename AllocT::size_t; };
@@ -188,7 +189,17 @@ 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
constexpr allocation(size_t n) noexcept
- : _data(_alloc.al), _capacity(n) {}
+ : _data(nullptr), _capacity(0)
+ { allocate(n); }
+
+ ///
+ /// \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)
+ : allocation(n)
+ { fennec::memcpy(_data, data, n); }
///
/// \brief Allocator Constructor
@@ -205,7 +216,20 @@ public:
///
/// \details This constructor should be used when the type `AllocT` needs internal data.
constexpr allocation(size_t n, const alloc_t& alloc) noexcept
- : _alloc(alloc), _data(nullptr), _capacity(0) {}
+ : _alloc(alloc), _data(nullptr), _capacity(0)
+ { allocate(n); }
+
+ ///
+ /// \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, const alloc_t& alloc)
+ : allocation(n, alloc)
+ { fennec::memcpy(_data, data, n); }
///
/// \brief Copy Constructor, creates an allocation of equal size and performs a byte-wise copy
@@ -227,6 +251,35 @@ public:
/// \brief Default Destructor, releases the memory block if still present
constexpr ~allocation() noexcept { if (_data) _alloc.deallocate(_data); }
+ ///
+ /// \brief Copy Assignment Operator
+ /// \param alloc the allocation to copy
+ /// \returns a reference to `this`
+ constexpr allocation& operator=(const allocation& alloc)
+ {
+ allocation::allocate(alloc.capacity());
+ fennec::memcpy(_data, alloc, size());
+ return *this;
+ }
+
+ ///
+ /// \brief Move Assignment Operator
+ /// \param alloc the allocation to copy
+ /// \returns a reference to `this`
+ constexpr allocation& operator=(allocation&& alloc) noexcept
+ {
+ // Copy contents
+ _alloc = alloc._alloc;
+ _data = alloc._data;
+ _capacity = alloc._capacity;
+
+ // Cleanup alloc
+ alloc._data = nullptr;
+ alloc._capacity = 0;
+
+ return *this;
+ }
+
///
/// \brief Allocate a block of memory for the allocation.
/// If there is already an allocated block of memory, the previous allocation is released.
@@ -236,7 +289,7 @@ public:
if (_data)
_alloc.deallocate(_data);
- _data = alloc_t::allocate(_capacity = n);
+ _data = _alloc.allocate(_capacity = n);
}
///
@@ -245,6 +298,7 @@ public:
{
if (_data)
_alloc.deallocate(_data);
+
_data = nullptr;
_capacity = 0;
}
@@ -258,7 +312,7 @@ public:
return _alloc.allocate(_capacity = n);
value_t* old = _data;
- _data = alloc_t::allocate(n);
+ _data = _alloc.allocate(n);
fennec::memcpy(_data, old, min(_capacity, n) * sizeof(T));
_alloc.deallocate(old);
_capacity = n;
diff --git a/include/fennec/memory/detail/__memory.h b/include/fennec/memory/detail/__string.h
similarity index 53%
rename from include/fennec/memory/detail/__memory.h
rename to include/fennec/memory/detail/__string.h
index 906091f..5bf33d2 100644
--- a/include/fennec/memory/detail/__memory.h
+++ b/include/fennec/memory/detail/__string.h
@@ -21,46 +21,32 @@
#include
-namespace fennec
-{
-namespace detail
-{
-constexpr size_t __memcpy_8(void* dst, const void* src)
- { *static_cast(dst) = *static_cast(src); return 1; }
+// deprecated, switched to ISO C implementation
+// see https://git.mslockbo.org/mslockbo/fennec/src/commit/0eeb7ae3cff9d78e98dc5d9fc09bcb98b10986b9 for previous
+// implementation
-// helper for copying 2 bytes at once
-constexpr size_t __memcpy_16(void* dst, const void* src)
- { *static_cast(dst) = *static_cast(src); return 2; }
+#if _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4117)
+#endif
-// helper for copying 4 bytes at once
-constexpr size_t __memcpy_32(void* dst, const void* src)
- { *static_cast(dst) = *static_cast(src); return 4; }
+#if __GNUC__
+#define __OPTIMIZE__
+#endif
-// helper for copying 8 bytes at once
-constexpr size_t __memcpy_64(void* dst, const void* src)
- { *static_cast(dst) = *static_cast(src); return 8; }
+#pragma push_macro("__cplusplus")
+#undef __cplusplus
+#include
+#pragma pop_macro("__cplusplus")
-constexpr size_t __memcpy(void* dst, const void* src, size_t n)
-{
- switch (n)
- {
- case 0:
- return 0;
- case 1:
- return __memcpy_8(dst, src);
- case 2: case 3:
- return __memcpy_16(dst, src);
- case 4: case 5: case 6: case 7:
- return __memcpy_32(dst, src);
- default:
- return __memcpy_64(dst, src);
- }
-}
+#if __GNUC__
+#undef __OPTIMIZE__
+#endif
-}
-
-}
+#if _MSC_VER
+#pragma warning(pop)
+#endif
#endif // FENNEC_MEMORY_DETAIL_MEMORY_H
diff --git a/include/fennec/memory/memory.h b/include/fennec/memory/memory.h
index be0f5b8..ae45709 100644
--- a/include/fennec/memory/memory.h
+++ b/include/fennec/memory/memory.h
@@ -21,7 +21,7 @@
#define FENNEC_MEMORY_H
#include
-#include
+#include
namespace fennec
{
@@ -34,27 +34,14 @@ namespace fennec
template
constexpr TypeT* addressof(TypeT& obj) { return FENNEC_BUILTIN_ADDRESSOF(obj); }
-///
-/// \copydetails fennec::memchr(const void*, int, size_t)
-constexpr void* memchr(void* arr, int ch, size_t n)
-{
- uint8_t* a = static_cast(arr);
- while (n-- && *a++ != ch) {}
- return n ? a : nullptr;
-}
-
///
/// \brief Finds the first occurence of ```static_cast(ch)``` in the first \f$n\f$ bytes
/// \param arr Pointer to the object, interpreted as an array of bytes
/// \param ch The byte to search for
/// \param n The number of bytes to search
/// \returns A pointer to the location of \f$ch\f$, otherwise \f$nullptr\f$ if \f$ch\f$ is not found.
-constexpr const void* memchr(const void* arr, int ch, size_t n)
-{
- const uint8_t* a = static_cast(arr);
- while (n-- && *a++ != ch) {}
- return n ? a : nullptr;
-}
+using ::memchr;
+using ::wmemchr;
///
/// \brief Compares the bytes of \f$lhs\f$ with \f$rhs\f$.
@@ -63,13 +50,8 @@ constexpr const void* memchr(const void* arr, int ch, size_t n)
/// \param n The number of bytes to parse
/// \returns \f$0\f$ if the first \f$n\f$ bytes of \f$lhs\f$ and \f$rhs\f$ are equivalent. Otherwise, returns \f$1\f$
/// for the first byte \f$b\f$ where \f$lhs[b] > \f$ rhs[b]\f$, and \f$-1\f$ for \f$
-constexpr int memcmp(const void* lhs, const void* rhs, size_t n)
-{
- const uint8_t* lhs_ = static_cast(lhs);
- const uint8_t* rhs_ = static_cast(rhs);
- while (n-- && *lhs_++ == *rhs_++) {}
- return n ? *lhs_ - *rhs_ : 0;
-}
+using ::memcmp;
+using ::wmemcmp;
///
/// \brief Safe version of memcmp
@@ -91,19 +73,8 @@ constexpr int memcmp_s(const void* lhs, size_t n0, const void* rhs, size_t n1)
/// \f$src\f$ will be repeated in \f$dst\f$ with a period of \f$k\f$.
///
/// A full mathematical proof of this function is possible in Set Theory.
-constexpr void* memcpy(void* dst, const void* src, size_t n)
-{
- if (dst == src) return dst;
- uint8_t* d = static_cast(dst);
- const uint8_t* s = static_cast(src);
-
- while (n > 0) {
- size_t step = detail::__memcpy(d, s, n);
- d += step; s += step; n -= step;
- }
-
- return dst;
-}
+using ::memcpy;
+using ::wmemcpy;
///
/// \brief Safe version of memcpy
@@ -119,27 +90,8 @@ constexpr void* memcpy_s(void* dst, size_t n0, const void* src, size_t n1)
/// \param src The source object, interpreted as an array of bytes
/// \param n The number of bytes to copy
/// \returns \f$dst\f$
-constexpr void* memmove(void* dst, const void* src, size_t n)
-{
- if (dst == src) return dst;
- uint8_t* d = static_cast(dst);
- const uint8_t* s = static_cast(src);
-
- if (d < s) {
- while (n > 0) {
- size_t step = detail::__memcpy(d, s, n);
- d += step; s += step; n -= step;
- }
- }
- else {
- d += n - 1; s += n - 1;
- while (n > 0) {
- size_t step = detail::__memcpy(d, s, n);
- d -= step; s -= step; n -= step;
- }
- }
- return dst;
-}
+using ::memmove;
+using ::wmemmove;
///
/// \brief Safe version of memmove
@@ -155,18 +107,8 @@ constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1)
/// \param ch The value, interpreted as an \f$uint8_t\f$
/// \param n The number of bytes to set
/// \returns \f$dst\f$
-constexpr void* memset(void* dst, int ch, size_t n)
-{
- uint8_t* d = static_cast(dst);
- uint8_t val[8] = { static_cast(ch) };
-
- while (n > 0) {
- size_t step = detail::__memcpy(d, val, n);
- d += step; n -= step;
- }
-
- return dst;
-}
+using ::memset;
+using ::wmemset;
}
diff --git a/include/fennec/memory/new.h b/include/fennec/memory/new.h
index dd714c0..315811e 100644
--- a/include/fennec/memory/new.h
+++ b/include/fennec/memory/new.h
@@ -20,8 +20,6 @@
#ifndef FENNEC_MEMORY_NEW_H
#define FENNEC_MEMORY_NEW_H
-#include
-
#include
#include
diff --git a/source/debug/assert_impl.cpp b/source/debug/assert_impl.cpp
index 3675252..7d5d647 100644
--- a/source/debug/assert_impl.cpp
+++ b/source/debug/assert_impl.cpp
@@ -16,7 +16,16 @@
// along with this program. If not, see .
// =====================================================================================================================
-void __assert_callback(const char*, const char*, int, const char*)
-{
+#include
+void __assert_callback(const char* expression, const char* file, int line, const char* function, const char* description)
+{
+ // Skip
+ // __assert_callback
+ // __assert_impl
+ printf("Assert failed: \"%s\" \n"
+ "At %s:%d in %s \n"
+ "Description: %s \n",
+ expression, file, line, function, description);
+ cpptrace::generate_trace(2).print();
}
\ No newline at end of file
diff --git a/source/lang/assert.cpp b/source/lang/assert.cpp
index aa02e7e..12ed477 100644
--- a/source/lang/assert.cpp
+++ b/source/lang/assert.cpp
@@ -20,13 +20,13 @@
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);
+extern 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)
+void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* description)
{
- __assert_callback(expression, file, line, function);
+ __assert_callback(expression, file, line, function, description);
#ifndef NDEBUG
- abort();
+ ::abort();
#endif
}
\ No newline at end of file
diff --git a/source/memory/new.cpp b/source/memory/new.cpp
index e685da1..495d722 100644
--- a/source/memory/new.cpp
+++ b/source/memory/new.cpp
@@ -29,10 +29,10 @@
#else
// 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); }
+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
@@ -46,31 +46,31 @@ inline void* operator new[](fennec::size_t size, fennec::align_t align)
inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast(align), size); }
inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return _aligned_malloc(static_cast(align), size); }
#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, 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) noexcept { ::free(ptr); }
+inline void operator delete[](void* ptr) 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 new (fennec::size_t size, fennec::align_t align) { return aligned_alloc(static_cast(align), size); }
-inline void* operator new[](fennec::size_t size, fennec::align_t align) { return aligned_alloc(static_cast(align), size); }
-inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return aligned_alloc(static_cast(align), size); }
-inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return aligned_alloc(static_cast(align), size); }
+inline void* operator new (fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast(align), size); }
+inline void* operator new[](fennec::size_t size, fennec::align_t align) { return ::aligned_alloc(static_cast(align), size); }
+inline void* operator new (fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast(align), size); }
+inline void* operator new[](fennec::size_t size, fennec::align_t align, const fennec::nothrow_t&) { return ::aligned_alloc(static_cast(align), size); }
#endif
// Aligned deallocation functions
-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::align_t) noexcept { ::free(ptr); }
+inline void operator delete[](void* ptr, fennec::align_t) noexcept { ::free(ptr); }
// Sized 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, 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) 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, 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, 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); }
#endif
\ No newline at end of file
diff --git a/test/test.h b/test/test.h
index 6cca29a..8b8f750 100644
--- a/test/test.h
+++ b/test/test.h
@@ -51,9 +51,6 @@ inline std::ostream& operator<<(std::ostream& os, const matrix(std::ostream& os, index_sequence) {
- // ((os << fennec::row(m, i) << " "), ...);
- //}(os, make_index_sequence{});
os << "]";
return os;
}
@@ -97,7 +94,7 @@ inline void __fennec_test_run(const std::string& expression, const ResultT resul
std::cout << std::endl;
// Assert to halt and get some debug info
- assert(passed);
+ assert(passed, "Test Failed");
}
}
|