@ -1,3 +1,3 @@ | |||||
src:gp/vfs/scheduler.hpp | |||||
src:gp/vfs/platforms/gcc-x86_64.hpp | |||||
src:gp/system/scheduler.hpp | |||||
src:gp/system/platforms/gcc-x86_64.hpp | |||||
fun:gp::specifics::platform_data::push(void*) | fun:gp::specifics::platform_data::push(void*) |
@ -1,8 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/algorithm/move.hpp> | |||||
#include <gp/algorithm/cvref.hpp> | |||||
#include <gp/algorithm/reference.hpp> | |||||
#include <gp/algorithms/move.hpp> | |||||
#include <gp/algorithms/cvref.hpp> | |||||
#include <gp/algorithms/reference.hpp> | |||||
#include <type_traits> | #include <type_traits> | ||||
@ -1,8 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/algorithm/tmp_manip.hpp" | |||||
#include "gp/algorithm/cvref.hpp" | |||||
#include "gp/range.hpp" | |||||
#include "gp/algorithms/tmp_manip.hpp" | |||||
#include "gp/algorithms/cvref.hpp" | |||||
#include "gp/utils/range.hpp" | |||||
namespace gp{ | namespace gp{ | ||||
template<typename T> | template<typename T> |
@ -1,7 +1,7 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/algorithm/move.hpp> | |||||
#include <gp/algorithm/cvref.hpp> | |||||
#include <gp/algorithms/move.hpp> | |||||
#include <gp/algorithms/cvref.hpp> | |||||
namespace gp{ | namespace gp{ |
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/algorithm/move.hpp" | |||||
#include "gp/algorithms/move.hpp" | |||||
namespace gp { | namespace gp { | ||||
template<typename iterator> | template<typename iterator> |
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/buffer.hpp> | |||||
#include <gp/containers/buffer.hpp> | |||||
#include <initializer_list> | #include <initializer_list> | ||||
@ -1,10 +1,10 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/algorithm/move.hpp> | |||||
#include <gp/function.hpp> | |||||
#include <gp/algorithms/move.hpp> | |||||
#include <gp/functional/function.hpp> | |||||
#include <gp/exception.hpp> | #include <gp/exception.hpp> | ||||
#include <gp/iterator.hpp> | |||||
#include <gp/optional.hpp> | |||||
#include <gp/utils/iterator.hpp> | |||||
#include <gp/functional/optional.hpp> | |||||
#include <cstddef> | #include <cstddef> | ||||
#include <cstdint> | #include <cstdint> |
@ -1,6 +1,6 @@ | |||||
#pragma one | #pragma one | ||||
#include <gp/array.hpp> | |||||
#include <gp/containers/array.hpp> | |||||
#include <gp/integer_math.hpp> | #include <gp/integer_math.hpp> | ||||
#include <gp/iterator.hpp> | #include <gp/iterator.hpp> | ||||
// UNIMPLEMENTED: see filename | // UNIMPLEMENTED: see filename |
@ -1,8 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/algorithm/foreach.hpp> | |||||
#include <gp/algorithm/tmp_manip.hpp> | |||||
#include <gp/array.hpp> | |||||
#include <gp/algorithms/foreach.hpp> | |||||
#include <gp/algorithms/tmp_manip.hpp> | |||||
#include <gp/containers/array.hpp> | |||||
#include <atomic> | #include <atomic> | ||||
@ -1,8 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/algorithm/foreach.hpp> | |||||
#include <gp/algorithm/tmp_manip.hpp> | |||||
#include <gp/array.hpp> | |||||
#include <gp/algorithms/foreach.hpp> | |||||
#include <gp/algorithms/tmp_manip.hpp> | |||||
#include <gp/containers/array.hpp> | |||||
#include <gp/exception.hpp> | #include <gp/exception.hpp> | ||||
#include <atomic> | #include <atomic> |
@ -1,7 +1,7 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/buffer.hpp> | |||||
#include <gp/allocator/allocator.hpp> | |||||
#include <gp/containers/buffer.hpp> | |||||
#include <gp/utils/allocators/allocator.hpp> | |||||
#include <initializer_list> | #include <initializer_list> | ||||
@ -1,11 +1,11 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/exception.hpp" | #include "gp/exception.hpp" | ||||
#include "gp/algorithm/modifiers.hpp" | |||||
#include "gp/algorithm/move.hpp" | |||||
#include "gp/algorithm/tmp_manip.hpp" | |||||
#include "gp/allocator/allocator.hpp" | |||||
#include "gp/optional.hpp" | |||||
#include "gp/algorithms/modifiers.hpp" | |||||
#include "gp/algorithms/move.hpp" | |||||
#include "gp/algorithms/tmp_manip.hpp" | |||||
#include "gp/utils/allocators/allocator.hpp" | |||||
#include "gp/functional/optional.hpp" | |||||
namespace gp{ | namespace gp{ | ||||
@ -1,11 +1,11 @@ | |||||
#pragma once | #pragma once | ||||
#include <gp/algorithm/repeat.hpp> | |||||
#include <gp/bitops.hpp> | |||||
#include <gp/optional.hpp> | |||||
#include <gp/pair.hpp> | |||||
#include <gp/variant.hpp> | |||||
#include <gp/vector.hpp> | |||||
#include <gp/algorithms/repeat.hpp> | |||||
#include <gp/math/boolean/bitops.hpp> | |||||
#include <gp/functional/optional.hpp> | |||||
#include <gp/utils/pair.hpp> | |||||
#include <gp/functional/variant.hpp> | |||||
#include <gp/containers/vector.hpp> | |||||
namespace gp { | namespace gp { |
@ -1,8 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/buffer.hpp" | |||||
#include "gp/vector.hpp" | |||||
#include "gp/vfs/file_description.hpp" | |||||
#include "gp/containers/buffer.hpp" | |||||
#include "gp/containers/vector.hpp" | |||||
#include "gp/ipc/file_description.hpp" | |||||
namespace gp{ | namespace gp{ | ||||
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/array.hpp" | |||||
#include "gp/containers/array.hpp" | |||||
#include <cstddef> | #include <cstddef> | ||||
#include <cstdint> | #include <cstdint> |
@ -1,237 +0,0 @@ | |||||
#pragma once | |||||
#include <cstddef> | |||||
#include <cstdint> | |||||
// BUG: none of this is in a namespace | |||||
// TODO: Specify the concept of an iterator | |||||
/** | |||||
* @brief An enumeration that may be used to determine iterator categories | |||||
* | |||||
*/ | |||||
enum class iterator_type_t{ | |||||
contiguous_iterator, /**< Defines an iterator for something that is continuous and random access */ | |||||
non_contiguous_iterator, /**< Defines an iterator for a non contiguous datastructure, for example an iterator over a hashmap or a tree*/ | |||||
lazy_iterator /**< Defines an iterator for which the actual data layout and availability are still unknown*/ | |||||
}; | |||||
/** | |||||
* @brief An abstraction of a pointer to iterate against, in both normal and reverse order | |||||
* | |||||
* @tparam T The type of data pointed by the iterator | |||||
* @tparam sign the direction in which data is scrutinized, should be either 1 or -1, behaviour for other value is left undefined | |||||
*/ | |||||
template<typename T, int sign = 1> | |||||
struct pointer_iterator final | |||||
{ | |||||
T* data; /**< the only data field of the class */ | |||||
typedef T value_type; /**< The type of which a reference will be returned on dereferencing */ | |||||
typedef std::size_t difference_type; /**< The type of the substraction of two pointers */ | |||||
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see iterator_type_t */ | |||||
/** | |||||
* @brief Generates an empty iterator | |||||
*/ | |||||
constexpr pointer_iterator() | |||||
: data{nullptr} | |||||
{} | |||||
constexpr pointer_iterator(const pointer_iterator& oth) | |||||
: data{oth.data} | |||||
{} | |||||
/** | |||||
* @brief Generates an iterator from any pointer | |||||
*/ | |||||
constexpr pointer_iterator(T* ptr) | |||||
: data{ptr} | |||||
{} | |||||
/** | |||||
* @brief Dereference unary operator | |||||
* | |||||
* @return constexpr T& returns a reference to the pointed value | |||||
*/ | |||||
constexpr T& operator*() const | |||||
{ | |||||
return *data; | |||||
} | |||||
constexpr pointer_iterator& operator++() | |||||
{ | |||||
data += sign; | |||||
return *this; | |||||
} | |||||
constexpr pointer_iterator operator++(int) | |||||
{ | |||||
auto p = *this; | |||||
data += sign; | |||||
return p; | |||||
} | |||||
constexpr pointer_iterator& operator--() | |||||
{ | |||||
data -= sign; | |||||
return *this; | |||||
} | |||||
constexpr pointer_iterator operator--(int) | |||||
{ | |||||
auto p = *this; | |||||
data -= sign; | |||||
return p; | |||||
} | |||||
constexpr pointer_iterator operator+(const std::size_t offset) const | |||||
{ | |||||
return pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr pointer_iterator operator+(const int offset) const | |||||
{ | |||||
return pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr pointer_iterator operator-(const std::size_t offset) const | |||||
{ | |||||
return pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr pointer_iterator operator-(const int offset) const | |||||
{ | |||||
return pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr difference_type operator-(const pointer_iterator& oth) const | |||||
{ | |||||
return ((T*)data-(T*)oth.data)*sign; | |||||
} | |||||
constexpr bool operator==(const pointer_iterator oth) const | |||||
{ | |||||
return data==oth.data; | |||||
} | |||||
constexpr bool operator!=(pointer_iterator oth) const | |||||
{ | |||||
return data!=oth.data; | |||||
} | |||||
constexpr bool before_or_equal(const pointer_iterator oth) const | |||||
{ | |||||
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data); | |||||
} | |||||
constexpr bool operator<=(const pointer_iterator oth) const | |||||
{ | |||||
return before_or_equal(oth); | |||||
} | |||||
}; | |||||
/** | |||||
* @brief An identical twin to the pointer_iterator, but which dereference to a const reference | |||||
* | |||||
* @see pointer_iterator | |||||
* @tparam T @see pointer_iterator | |||||
* @tparam sign @see pointer_iterator | |||||
*/ | |||||
template<typename T, int sign = 1> | |||||
struct const_pointer_iterator final | |||||
{ | |||||
const T* data; /**< @see pointer_iterator */ | |||||
typedef T value_type; /**< @see pointer_iterator */ | |||||
typedef std::size_t difference_type; /**< @see pointer_iterator */ | |||||
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see pointer_iterator */ | |||||
constexpr const_pointer_iterator(const const_pointer_iterator& oth) | |||||
: data{oth.data} | |||||
{} | |||||
/** | |||||
* @brief @see pointer_iterator | |||||
*/ | |||||
constexpr const_pointer_iterator(const T* ptr) | |||||
: data{ptr} | |||||
{} | |||||
/** | |||||
* @brief Dereferencing returns a const version of what a pointer_iterator would return | |||||
*/ | |||||
constexpr const T& operator*() const | |||||
{ | |||||
return *data; | |||||
} | |||||
constexpr const_pointer_iterator& operator++() | |||||
{ | |||||
data += sign; | |||||
return *this; | |||||
} | |||||
constexpr const_pointer_iterator operator++(int) | |||||
{ | |||||
auto p = data; | |||||
data += sign; | |||||
return const_pointer_iterator{p}; | |||||
} | |||||
constexpr const_pointer_iterator& operator--() | |||||
{ | |||||
data -= sign; | |||||
return *this; | |||||
} | |||||
constexpr const_pointer_iterator operator--(int) | |||||
{ | |||||
auto p = data; | |||||
data -= sign; | |||||
return const_pointer_iterator{p}; | |||||
} | |||||
constexpr const_pointer_iterator operator+(const std::size_t offset) const | |||||
{ | |||||
return const_pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr const_pointer_iterator operator+(const int offset) const | |||||
{ | |||||
return const_pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr const_pointer_iterator operator-(const std::size_t offset) const | |||||
{ | |||||
return const_pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr const_pointer_iterator operator-(const int offset) | |||||
{ | |||||
return const_pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr difference_type operator-(const const_pointer_iterator& oth) const | |||||
{ | |||||
return ((T*)data-(T*)oth.data)*sign; | |||||
} | |||||
constexpr bool operator==(const const_pointer_iterator oth) const | |||||
{ | |||||
return data==oth.data; | |||||
} | |||||
constexpr bool operator!=(const_pointer_iterator oth) const | |||||
{ | |||||
return data!=oth.data; | |||||
} | |||||
constexpr bool before_or_equal(const const_pointer_iterator oth) const | |||||
{ | |||||
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data); | |||||
} | |||||
constexpr bool operator<=(const const_pointer_iterator oth) const | |||||
{ | |||||
return before_or_equal(oth); | |||||
} | |||||
}; |
@ -0,0 +1,35 @@ | |||||
#pragma once | |||||
namespace gp { | |||||
namespace math { | |||||
template<typename T> | |||||
constexpr T pi; | |||||
template<typename T> | |||||
T abs(T); | |||||
template<typename word_t> | |||||
word_t log2(word_t v); | |||||
/** | |||||
* @brief Returns \f$n\f$ so that it is the smallest value that matches for \f$v\leq{}log2(2^n)\f$ | |||||
* | |||||
* @tparam word_t | |||||
* @param v | |||||
* @return constexpr word_t | |||||
*/ | |||||
template<typename word_t> | |||||
constexpr word_t msb(word_t v); | |||||
/** | |||||
* @brief Reads the sign of a value | |||||
* | |||||
* @tparam T | |||||
* @return -1 if the value is negative | |||||
* @return 0 if the value is 0 or not a number | |||||
* @return 1 if the value is positive | |||||
*/ | |||||
template<typename T> | |||||
T sign(T); | |||||
} | |||||
} |
@ -1,267 +0,0 @@ | |||||
#pragma once | |||||
#include "gp/algorithm/repeat.hpp" | |||||
#include <limits> | |||||
#include <stddef.h> | |||||
#include <stdint.h> | |||||
namespace gp{ | |||||
template<typename T> | |||||
constexpr T pi; | |||||
template<> | |||||
constexpr float pi<float> = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; | |||||
template<> | |||||
constexpr double pi<double> = 3.1415926535897932384626433832795028841971693993751058209749445923078164062L; | |||||
template<typename T> | |||||
T abs(T); | |||||
template<> | |||||
float abs<float>(float value) { | |||||
static_assert(sizeof(float) == 4, "bad float size"); | |||||
union { | |||||
float fp; | |||||
uint32_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFF; | |||||
return p.fp; | |||||
} | |||||
template<> | |||||
double abs<double>(double value) { | |||||
static_assert(sizeof(double) == 8, "bad double size"); | |||||
union { | |||||
double fp; | |||||
uint64_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFFffFFffFF; | |||||
return p.fp; | |||||
} | |||||
template<typename T> | |||||
T floor(T); | |||||
template<> | |||||
float floor<float>(float value) { | |||||
static_assert(sizeof(float) == 4, "bad float size"); | |||||
if( | |||||
value >= 16777216 | |||||
|| value <= std::numeric_limits<int32_t>::min() | |||||
|| value != value | |||||
) { | |||||
return value; | |||||
} | |||||
int32_t ret = value; | |||||
float ret_d = ret; | |||||
if(value == ret_d || value >= 0) { | |||||
return ret; | |||||
} else { | |||||
return ret-1; | |||||
} | |||||
} | |||||
template<> | |||||
double floor<double>(double value) { | |||||
static_assert(sizeof(double) == 8, "bad double size"); | |||||
if( | |||||
value >= 9007199254740992 | |||||
|| value <= std::numeric_limits<int64_t>::min() | |||||
|| value != value | |||||
) { | |||||
return value; | |||||
} | |||||
int64_t ret = value; | |||||
double ret_d = ret; | |||||
if(value == ret_d || value >= 0) { | |||||
return ret; | |||||
} else { | |||||
return ret-1; | |||||
} | |||||
} | |||||
/** | |||||
* @brief Reads the sign of a value | |||||
* | |||||
* @tparam T | |||||
* @return -1 if the value is negative | |||||
* @return 0 if the value is 0 or not a number | |||||
* @return 1 if the value is positive | |||||
*/ | |||||
template<typename T> | |||||
T sign(T); | |||||
template<> | |||||
float sign<float>(float value) { | |||||
static_assert(sizeof(float) == 4, "bad float size"); | |||||
if(!value) return 0; | |||||
union { | |||||
float fp; | |||||
uint32_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFF; | |||||
return value/p.fp; | |||||
} | |||||
template<> | |||||
double sign<double>(double value) { | |||||
static_assert(sizeof(double) == 8, "bad double size"); | |||||
if(!value) return 0; | |||||
union { | |||||
double fp; | |||||
uint64_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFFffFFffFF; | |||||
return value/p.fp; | |||||
} | |||||
/** | |||||
* @brief Calculate the sin of a value using Taylor's method | |||||
* | |||||
* @tparam steps The number of steps to do at the maximum | |||||
* @tparam T the type of value and the return type expected | |||||
* @tparam accuracy the maximum accuracy to shoot for (early stopping) | |||||
* @param value The value to calculate the sin of. Works better for values close to 0. | |||||
* @return T the sin of the value (the sign may be off idk I don't remember) | |||||
*/ | |||||
template<size_t steps, typename T, size_t accuracy = 1000000> | |||||
T sin_taylor(T value) { | |||||
const T acc = T{1}/T{accuracy}; | |||||
T B = value; | |||||
T C = 1; | |||||
T ret = B/C; | |||||
for(size_t i = 1; (i < steps) && (abs<>(B/C) > acc); ++i) { | |||||
B *= -1*value*value; | |||||
C *= 2*i*(2*i+1); | |||||
ret += B/C; | |||||
} | |||||
return ret; | |||||
} | |||||
/** | |||||
* @brief General purpose sin function | |||||
* | |||||
* @param v | |||||
* @return float | |||||
*/ | |||||
float sin(float v) { | |||||
// limit the range between -pi and +pi | |||||
v += pi<float>; | |||||
v = v - 2*pi<float>*floor(v/(2*pi<float>)); | |||||
v -= pi<float>; | |||||
float s = sign(v); | |||||
v *= s; | |||||
// use taylor's method on the value | |||||
return sin_taylor<10>(v)*s; | |||||
} | |||||
/** | |||||
* @brief General purpose sin function | |||||
* | |||||
* @param v | |||||
* @return double | |||||
*/ | |||||
double sin(double v) { | |||||
v += pi<double>; | |||||
v = v - 2*pi<double>*floor(v/(2*pi<double>)); | |||||
v -= pi<double>; | |||||
float s = sign(v); | |||||
v *= s; | |||||
return sin_taylor<10>(v)*s; | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
float cos(float v) { | |||||
return sin(v+pi<float>/2); | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
double cos(double v) { | |||||
return sin(v+pi<double>/2); | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
float tan(float v) { | |||||
return sin(v)/cos(v); | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
double tan(double v) { | |||||
return sin(v)/cos(v); | |||||
} | |||||
/** | |||||
* @brief Quake isqrt (x) -> 1/sqrt(x) | |||||
* | |||||
* @tparam cycles the number of newton method cycles to apply | |||||
* @param v the value to apply the function on | |||||
* @return float \f$\frac{1}{\sqrt{v}}\f$ | |||||
*/ | |||||
template<size_t cycles = 5> | |||||
float isqrt(float v) { | |||||
int32_t i; | |||||
float x2, y; | |||||
constexpr float threehalfs = 1.5F; | |||||
x2 = v * 0.5F; | |||||
y = v; | |||||
i = * ( int32_t * ) &y; | |||||
i = 0x5F375A86 - ( i >> 1 ); | |||||
y = * ( float * ) &i; | |||||
gp::repeat(cycles, [&](){ | |||||
y = y * ( threehalfs - ( x2 * y * y ) ); | |||||
}); | |||||
return y; | |||||
} | |||||
/** | |||||
* @brief Quake isqrt (x) -> 1/sqrt(x) but for doubles | |||||
* | |||||
* @tparam cycles the number of newton method cycles to apply | |||||
* @param v the value to apply the function on | |||||
* @return double \f$\frac{1}{\sqrt{v}}\f$ | |||||
*/ | |||||
template<size_t cycles = 5> | |||||
double isqrt(double v) { | |||||
int64_t i; | |||||
double x2, y; | |||||
constexpr double threehalfs = 1.5F; | |||||
x2 = v * 0.5F; | |||||
y = v; | |||||
i = * ( int64_t * ) &y; | |||||
i = 0x5FE6EB50C7B537A9 - ( i >> 1 ); | |||||
y = * ( double * ) &i; | |||||
gp::repeat(cycles, [&](){ | |||||
y = y * ( threehalfs - ( x2 * y * y ) ); | |||||
}); | |||||
return y; | |||||
} | |||||
/** | |||||
* @brief A faster version of the Quake isqrt (actually the same but with defined cycles) | |||||
* | |||||
* @param v | |||||
* @return float | |||||
*/ | |||||
float fast_isqrt(float v) {return isqrt<1>(v);} | |||||
/** | |||||
* @brief A faster version of the Quake isqrt (actually the same but with defined cycles) | |||||
* | |||||
* @param v | |||||
* @return double | |||||
*/ | |||||
double fast_isqrt(double v) {return isqrt<1>(v);} | |||||
} |
@ -0,0 +1,68 @@ | |||||
#pragma once | |||||
#include "gp_config.hpp" | |||||
#include "gp/algorithms/repeat.hpp" | |||||
namespace gp { | |||||
template<typename T> | |||||
T lerp(T input, T low, T high) { | |||||
return low + (high - low) * input; | |||||
} | |||||
template<typename T> | |||||
T lextrap(T input, T low, T high) { | |||||
return (input - low) / (high - low); | |||||
} | |||||
template<typename T, size_t fixed_passes = 16> | |||||
T fixed_sqrt(T value) { | |||||
gp_config::assertion(value >= 0, "trying to compute square root of negative number"); | |||||
if(value == 0) return 0; | |||||
T ret = value / 2; | |||||
T tmp; | |||||
gp::repeat(fixed_passes, [&](){ | |||||
tmp = ret; | |||||
ret = (value / tmp + tmp) / 2; | |||||
}); | |||||
return ret; | |||||
} | |||||
template<typename T, size_t cap_passes = 16> | |||||
T epsilon_sqrt(T value) { | |||||
gp_config::assertion(value >= 0, "trying to compute square root of negative number"); | |||||
if(value == 0) return 0; | |||||
T ret = value / 2; | |||||
T tmp; | |||||
constexpr T epsilon = gp_config::rendering::epsilon; | |||||
size_t cnt = 0; | |||||
while( | |||||
!( | |||||
(ret+epsilon)*ret > value | |||||
&& (ret-epsilon)*ret < value | |||||
) | |||||
&& cnt < cap_passes | |||||
){ | |||||
tmp = ret; | |||||
ret = (value / tmp + tmp) / 2; | |||||
++cnt; | |||||
}; | |||||
return ret; | |||||
} | |||||
template<typename T, size_t cap_passes = 16> | |||||
T stable_sqrt(T value) { | |||||
gp_config::assertion(value >= 0, "trying to compute square root of negative number"); | |||||
if(value == 0) return 0; | |||||
T ret = value / 2; | |||||
T tmp; | |||||
while(ret != tmp){ | |||||
tmp = ret; | |||||
ret = (value / tmp + tmp) / 2; | |||||
}; | |||||
return ret; | |||||
} | |||||
} |
@ -0,0 +1,3 @@ | |||||
#pragma once | |||||
#include "gp/math/ieee754/fp_math.hpp" |
@ -0,0 +1,255 @@ | |||||
#pragma once | |||||
#include "gp/algorithms/repeat.hpp" | |||||
#include "gp/math/details/math_definitions.hpp" | |||||
#include <limits> | |||||
#include <stddef.h> | |||||
#include <stdint.h> | |||||
namespace gp{ | |||||
namespace math{ | |||||
template<> | |||||
constexpr float pi<float> = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; | |||||
template<> | |||||
constexpr double pi<double> = 3.1415926535897932384626433832795028841971693993751058209749445923078164062L; | |||||
template<> | |||||
float abs<float>(float value) { | |||||
static_assert(sizeof(float) == 4, "bad float size"); | |||||
union { | |||||
float fp; | |||||
uint32_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFF; | |||||
return p.fp; | |||||
} | |||||
template<> | |||||
double abs<double>(double value) { | |||||
static_assert(sizeof(double) == 8, "bad double size"); | |||||
union { | |||||
double fp; | |||||
uint64_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFFffFFffFF; | |||||
return p.fp; | |||||
} | |||||
template<typename T> | |||||
T floor(T); | |||||
template<> | |||||
float floor<float>(float value) { | |||||
static_assert(sizeof(float) == 4, "bad float size"); | |||||
if( | |||||
value >= 16777216 | |||||
|| value <= std::numeric_limits<int32_t>::min() | |||||
|| value != value | |||||
) { | |||||
return value; | |||||
} | |||||
int32_t ret = value; | |||||
float ret_d = ret; | |||||
if(value == ret_d || value >= 0) { | |||||
return ret; | |||||
} else { | |||||
return ret-1; | |||||
} | |||||
} | |||||
template<> | |||||
double floor<double>(double value) { | |||||
static_assert(sizeof(double) == 8, "bad double size"); | |||||
if( | |||||
value >= 9007199254740992 | |||||
|| value <= std::numeric_limits<int64_t>::min() | |||||
|| value != value | |||||
) { | |||||
return value; | |||||
} | |||||
int64_t ret = value; | |||||
double ret_d = ret; | |||||
if(value == ret_d || value >= 0) { | |||||
return ret; | |||||
} else { | |||||
return ret-1; | |||||
} | |||||
} | |||||
template<> | |||||
float sign<float>(float value) { | |||||
static_assert(sizeof(float) == 4, "bad float size"); | |||||
if(!value) return 0; | |||||
union { | |||||
float fp; | |||||
uint32_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFF; | |||||
return value/p.fp; | |||||
} | |||||
template<> | |||||
double sign<double>(double value) { | |||||
static_assert(sizeof(double) == 8, "bad double size"); | |||||
if(!value) return 0; | |||||
union { | |||||
double fp; | |||||
uint64_t ab; | |||||
} p; | |||||
p.fp = value; | |||||
p.ab &= 0x7fFFffFFffFFffFF; | |||||
return value/p.fp; | |||||
} | |||||
/** | |||||
* @brief Calculate the sin of a value using Taylor's method | |||||
* | |||||
* @tparam steps The number of steps to do at the maximum | |||||
* @tparam T the type of value and the return type expected | |||||
* @tparam accuracy the maximum accuracy to shoot for (early stopping) | |||||
* @param value The value to calculate the sin of. Works better for values close to 0. | |||||
* @return T the sin of the value (the sign may be off idk I don't remember) | |||||
*/ | |||||
template<size_t steps, typename T, size_t accuracy = 1000000> | |||||
T sin_taylor(T value) { | |||||
const T acc = T{1}/T{accuracy}; | |||||
T B = value; | |||||
T C = 1; | |||||
T ret = B/C; | |||||
for(size_t i = 1; (i < steps) && (abs<>(B/C) > acc); ++i) { | |||||
B *= -1*value*value; | |||||
C *= 2*i*(2*i+1); | |||||
ret += B/C; | |||||
} | |||||
return ret; | |||||
} | |||||
/** | |||||
* @brief General purpose sin function | |||||
* | |||||
* @param v | |||||
* @return float | |||||
*/ | |||||
inline float sin(float v) { | |||||
// limit the range between -pi and +pi | |||||
v += pi<float>; | |||||
v = v - 2*pi<float>*floor(v/(2*pi<float>)); | |||||
v -= pi<float>; | |||||
float s = sign(v); | |||||
v *= s; | |||||
// use taylor's method on the value | |||||
return sin_taylor<10>(v)*s; | |||||
} | |||||
/** | |||||
* @brief General purpose sin function | |||||
* | |||||
* @param v | |||||
* @return double | |||||
*/ | |||||
inline double sin(double v) { | |||||
v += pi<double>; | |||||
v = v - 2*pi<double>*floor(v/(2*pi<double>)); | |||||
v -= pi<double>; | |||||
float s = sign(v); | |||||
v *= s; | |||||
return sin_taylor<10>(v)*s; | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
inline float cos(float v) { | |||||
return sin(v+pi<float>/2); | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
inline double cos(double v) { | |||||
return sin(v+pi<double>/2); | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
inline float tan(float v) { | |||||
return sin(v)/cos(v); | |||||
} | |||||
// TODO: replace with an actual implementation | |||||
inline double tan(double v) { | |||||
return sin(v)/cos(v); | |||||
} | |||||
/** | |||||
* @brief Quake isqrt (x) -> 1/sqrt(x) | |||||
* | |||||
* @tparam cycles the number of newton method cycles to apply | |||||
* @param v the value to apply the function on | |||||
* @return float \f$\frac{1}{\sqrt{v}}\f$ | |||||
*/ | |||||
template<size_t cycles = 5> | |||||
float isqrt(float v) { | |||||
int32_t i; | |||||
float x2, y; | |||||
constexpr float threehalfs = 1.5F; | |||||
x2 = v * 0.5F; | |||||
y = v; | |||||
i = * ( int32_t * ) &y; | |||||
i = 0x5F375A86 - ( i >> 1 ); | |||||
y = * ( float * ) &i; | |||||
gp::repeat(cycles, [&](){ | |||||
y = y * ( threehalfs - ( x2 * y * y ) ); | |||||
}); | |||||
return y; | |||||
} | |||||
/** | |||||
* @brief Quake isqrt (x) -> 1/sqrt(x) but for doubles | |||||
* | |||||
* @tparam cycles the number of newton method cycles to apply | |||||
* @param v the value to apply the function on | |||||
* @return double \f$\frac{1}{\sqrt{v}}\f$ | |||||
*/ | |||||
template<size_t cycles = 5> | |||||
double isqrt(double v) { | |||||
int64_t i; | |||||
double x2, y; | |||||
constexpr double threehalfs = 1.5F; | |||||
x2 = v * 0.5F; | |||||
y = v; | |||||
i = * ( int64_t * ) &y; | |||||
i = 0x5FE6EB50C7B537A9 - ( i >> 1 ); | |||||
y = * ( double * ) &i; | |||||
gp::repeat(cycles, [&](){ | |||||
y = y * ( threehalfs - ( x2 * y * y ) ); | |||||
}); | |||||
return y; | |||||
} | |||||
/** | |||||
* @brief A faster version of the Quake isqrt (actually the same but with defined cycles) | |||||
* | |||||
* @param v | |||||
* @return float | |||||
*/ | |||||
inline float fast_isqrt(float v) {return isqrt<1>(v);} | |||||
/** | |||||
* @brief A faster version of the Quake isqrt (actually the same but with defined cycles) | |||||
* | |||||
* @param v | |||||
* @return double | |||||
*/ | |||||
inline double fast_isqrt(double v) {return isqrt<1>(v);} | |||||
} | |||||
} |
@ -0,0 +1,3 @@ | |||||
#pragma once | |||||
#include "gp/math/integral/logarithms.hpp" |
@ -0,0 +1,3 @@ | |||||
#pragma once | |||||
// UNIMPLEMENTED |
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/array.hpp" | |||||
#include "gp/containers/array.hpp" | |||||
using display_char = gp::array<uint8_t, 8>; | using display_char = gp::array<uint8_t, 8>; | ||||
@ -0,0 +1,290 @@ | |||||
#pragma once | |||||
#include "gp_config.hpp" | |||||
#include "gp/algorithms/min_max.hpp" | |||||
#include "gp/algorithms/repeat.hpp" | |||||
#include "gp/math.hpp" | |||||
namespace gp{ | |||||
namespace math { | |||||
template<typename T = gp_config::rendering::default_type> | |||||
struct vec2_g { | |||||
T x; | |||||
T y; | |||||
vec2_g() | |||||
: x{} | |||||
, y{} | |||||
{} | |||||
vec2_g( | |||||
T _x, | |||||
T _y | |||||
) | |||||
: x{_x} | |||||
, y{_y} | |||||
{} | |||||
vec2_g operator/(vec2_g rhs) { | |||||
return { | |||||
x / rhs.x, | |||||
y / rhs.y | |||||
}; | |||||
} | |||||
vec2_g operator*(vec2_g rhs) { | |||||
return { | |||||
x * rhs.x, | |||||
y * rhs.y | |||||
}; | |||||
} | |||||
vec2_g operator+(vec2_g oth) { | |||||
return {x+oth.x, y+oth.y}; | |||||
} | |||||
vec2_g operator-(vec2_g oth) { | |||||
return {x-oth.x, y-oth.y}; | |||||
} | |||||
vec2_g normalize() { | |||||
T ilen = fast_isqrt(x*x+y*y); | |||||
return {x*ilen, y*ilen}; | |||||
} | |||||
T length() { | |||||
return fixed_sqrt(x*x+y*y); | |||||
} | |||||
}; | |||||
template<typename T = gp_config::rendering::default_type> | |||||
struct vec3_g { | |||||
T x; | |||||
T y; | |||||
T z; | |||||
T& r(){ | |||||
return x; | |||||
} | |||||
T& g(){ | |||||
return y; | |||||
} | |||||
T& b(){ | |||||
return z; | |||||
} | |||||
vec3_g() | |||||
: x{} | |||||
, y{} | |||||
, z{} | |||||
{} | |||||
vec3_g( | |||||
T _x, | |||||
T _y, | |||||
T _z | |||||
) | |||||
: x{_x} | |||||
, y{_y} | |||||
, z{_z} | |||||
{} | |||||
vec3_g(vec2_g<T> left, T right) | |||||
: x{left.x} | |||||
, y{left.y} | |||||
, z{right} | |||||
{} | |||||
vec3_g(T left, vec2_g<T> right) | |||||
: x{left} | |||||
, y{right.x} | |||||
, z{right.y} | |||||
{} | |||||
vec3_g operator/(vec3_g rhs) { | |||||
return { | |||||
x / rhs.x, | |||||
y / rhs.y, | |||||
z / rhs.z | |||||
}; | |||||
} | |||||
vec3_g operator*(vec3_g rhs) { | |||||
return { | |||||
x * rhs.x, | |||||
y * rhs.y, | |||||
z * rhs.z | |||||
}; | |||||
} | |||||
vec3_g operator+(vec3_g oth) { | |||||
return {x+oth.x, y+oth.y, z+oth.z}; | |||||
} | |||||
vec3_g operator-(vec3_g oth) { | |||||
return {x-oth.x, y-oth.y, z-oth.z}; | |||||
} | |||||
vec3_g normalize() { | |||||
T ilen = fast_isqrt(x*x+y*y+z*z); | |||||
return {x*ilen, y*ilen, z*ilen}; | |||||
} | |||||
T length() { | |||||
return fixed_sqrt(x*x+y*y+z*z); | |||||
} | |||||
}; | |||||
template<typename T = gp_config::rendering::default_type> | |||||
struct vec4_g { | |||||
T x; | |||||
T y; | |||||
T z; | |||||
T w; | |||||
T& r(){ | |||||
return x; | |||||
} | |||||
T& g(){ | |||||
return y; | |||||
} | |||||
T& b(){ | |||||
return z; | |||||
} | |||||
T& a(){ | |||||
return w; | |||||
} | |||||
vec4_g() | |||||
: x{} | |||||
, y{} | |||||
, z{} | |||||
, w{} | |||||
{} | |||||
vec4_g( | |||||
T _x, | |||||
T _y, | |||||
T _z, | |||||
T _w | |||||
) | |||||
: x{_x} | |||||
, y{_y} | |||||
, z{_z} | |||||
, w{_w} | |||||
{} | |||||
vec4_g(T left, vec3_g<> right) | |||||
: x{left} | |||||
, y{right.x} | |||||
, z{right.y} | |||||
, w{right.z} | |||||
{} | |||||
vec4_g(vec3_g<> left, T right) | |||||
: x{left.x} | |||||
, y{left.y} | |||||
, z{left.z} | |||||
, w{right} | |||||
{} | |||||
vec4_g operator/(vec4_g rhs) { | |||||
return { | |||||
x / rhs.x, | |||||
y / rhs.y, | |||||
z / rhs.z, | |||||
w / rhs.w | |||||
}; | |||||
} | |||||
vec4_g operator*(vec4_g rhs) { | |||||
return { | |||||
x * rhs.x, | |||||
y * rhs.y, | |||||
z * rhs.z, | |||||
w * rhs.w | |||||
}; | |||||
} | |||||
vec4_g operator+(vec4_g oth) { | |||||
return {x+oth.x, y+oth.y, z+oth.z, w+oth.w}; | |||||
} | |||||
vec4_g operator-(vec4_g oth) { | |||||
return {x-oth.x, y-oth.y, z-oth.w, z-oth.w}; | |||||
} | |||||
vec4_g normalize() { | |||||
T ilen = fast_isqrt(x*x+y*y+z*z+w*w); | |||||
return {x*ilen, y*ilen, z*ilen, w*ilen}; | |||||
} | |||||
T length() { | |||||
return fixed_sqrt(x*x+y*y+z*z+w*w); | |||||
} | |||||
}; | |||||
template<typename T> | |||||
auto sphere_sdf(vec3_g<T> center, T radius) { | |||||
return [=](vec3_g<T> position) -> T const { | |||||
auto p = position - center; | |||||
return p.length() - radius; | |||||
}; | |||||
} | |||||
template<typename T, typename lhs, typename rhs> | |||||
auto union_sdf(lhs _l, rhs _r) { | |||||
return [=](vec3_g<T> position) -> T const { | |||||
return gp::min(_l(position), _r(position)); | |||||
}; | |||||
} | |||||
template<typename T, typename lhs, typename rhs> | |||||
auto intersect_sdf(lhs _l, rhs _r) { | |||||
return [=](vec3_g<T> position) -> T const { | |||||
return gp::max(_l(position), _r(position)); | |||||
}; | |||||
} | |||||
template<typename T, typename lhs, typename rhs> | |||||
auto difference_sdf(lhs _l, rhs _r) { | |||||
return [=](vec3_g<T> position) -> T const { | |||||
return gp::max(_l(position), -_r(position)); | |||||
}; | |||||
} | |||||
template<typename T> | |||||
vec2_g<T> operator*(vec2_g<T> p, T v) { | |||||
return {p.x*v, p.y*v}; | |||||
} | |||||
template<typename T> | |||||
vec3_g<T> operator*(vec3_g<T> p, T v) { | |||||
return {p.x*v, p.y*v, p.z*v}; | |||||
} | |||||
template<typename T> | |||||
vec4_g<T> operator*(vec4_g<T> p, T v) { | |||||
return {p.x*v, p.y*v, p.z*v, p.w*v}; | |||||
} | |||||
template<typename T> | |||||
vec2_g<T> operator*(T v, vec2_g<T> p) { | |||||
return p*v; | |||||
} | |||||
template<typename T> | |||||
vec3_g<T> operator*(T v, vec3_g<T> p) { | |||||
return p*v; | |||||
} | |||||
template<typename T> | |||||
vec4_g<T> operator*(T v, vec4_g<T> p) { | |||||
return p*v; | |||||
} | |||||
} | |||||
} | |||||
static_assert(sizeof(gp::math::vec3_g<int>) == sizeof(int)*3, "vec3_g has strange alignment"); | |||||
static_assert(sizeof(gp::math::vec4_g<int>) == sizeof(int)*4, "vec4_g has strange alignment"); |
@ -1,64 +0,0 @@ | |||||
#pragma once | |||||
#include "gp_config.hpp" | |||||
#include "gp/algorithm/move.hpp" | |||||
#include "gp/allocator/allocator.hpp" | |||||
#include "gp/exception.hpp" | |||||
#include <type_traits> | |||||
// XXX: THIS FILE SHOULD BE REMOVED, AS SHOULD ALL DEPENDENCIES ON THE C-ALLOCATOR AS IS | |||||
/* | |||||
namespace gp{ | |||||
template<class T, typename I = std::enable_if_t<gp_config::memory_module::is_ok,int>> | |||||
class default_memory_allocator | |||||
{ | |||||
public: | |||||
using pointer_type = T*; | |||||
using reference_type = T&; | |||||
using const_pointer_type = const T*; | |||||
using const_reference_type = const T&; | |||||
pointer_type allocate(size_t sz) | |||||
{ | |||||
return reinterpret_cast <pointer_type> (gp_config::memory_module::memory_allocator<gp_config::memory_module::memory_mode>(sizeof(T) * sz)); | |||||
} | |||||
void deallocate(pointer_type ptr) | |||||
{ | |||||
gp_config::memory_module::memory_deallocator<gp_config::memory_module::memory_mode>(ptr); | |||||
} | |||||
template<typename ...params> | |||||
pointer_type construct(pointer_type ptr, params... args) | |||||
{ | |||||
new(ptr) T(args...); | |||||
return ptr; | |||||
} | |||||
void destroy(pointer_type v) | |||||
{ | |||||
v->~T(); | |||||
} | |||||
}; | |||||
} | |||||
void* operator new(size_t sz) | |||||
{ | |||||
auto ptr = gp_config::memory_module::memory_allocator<gp_config::memory_module::memory_mode>(sz); | |||||
if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
if(!ptr) | |||||
{ | |||||
throw gp::bad_alloc{}; | |||||
} | |||||
} | |||||
return ptr; | |||||
} | |||||
void operator delete (void* ptr) noexcept | |||||
{ | |||||
gp_config::memory_module::memory_deallocator<gp_config::memory_module::memory_mode>(ptr); | |||||
} | |||||
*/ |
@ -1,29 +0,0 @@ | |||||
#pragma once | |||||
#include <gp/buffer.hpp> | |||||
#include <stddef.h> | |||||
#include <stdint.h> | |||||
// UNIMPLEMENTED: see filename | |||||
template<typename T> | |||||
struct subtree_iterator final | |||||
{ | |||||
gp::buffer<T> target; | |||||
size_t idx; | |||||
public: | |||||
subtree_iterator() | |||||
: target{} | |||||
, idx{0} | |||||
{} | |||||
subtree_iterator(gp::buffer<T> data, size_t itr_idx) | |||||
: target{data} | |||||
, idx{itr_idx} | |||||
{} | |||||
template<typename func> | |||||
void climb_traversal(func& traverser) { | |||||
} | |||||
}; |
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/buffer.hpp" | |||||
#include "gp/containers/buffer.hpp" | |||||
#include <cstdint> | #include <cstdint> | ||||
@ -1,11 +1,11 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp_config.hpp" | #include "gp_config.hpp" | ||||
#include "gp/function.hpp" | |||||
#include "gp/indexed_array.hpp" | |||||
#include "gp/pointers.hpp" | |||||
#include "gp/vfs/file_description.hpp" | |||||
#include "gp/vfs/platforms/platform_autopicker.hpp" | |||||
#include "gp/functional/function.hpp" | |||||
#include "gp/containers/indexed_array.hpp" | |||||
#include "gp/utils/pointers.hpp" | |||||
#include "gp/ipc/file_description.hpp" | |||||
#include "gp/system/platforms/platform_autopicker.hpp" | |||||
#include <atomic> | #include <atomic> | ||||
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/vfs/process_data.hpp" | |||||
#include "gp/system/process_data.hpp" | |||||
#include <atomic> | #include <atomic> | ||||
#include <new> | #include <new> |
@ -1,8 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/indexed_array.hpp" | |||||
#include "gp/vfs/process_data.hpp" | |||||
#include "gp/vfs/runqueue.hpp" | |||||
#include "gp/containers/indexed_array.hpp" | |||||
#include "gp/system/process_data.hpp" | |||||
#include "gp/system/runqueue.hpp" | |||||
namespace gp{ | namespace gp{ | ||||
@ -1,5 +1,5 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/vfs/system.hpp" | |||||
#include "gp/system/system.hpp" | |||||
namespace gp{ | namespace gp{ | ||||
@ -1,13 +1,13 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/algorithm/foreach.hpp" | |||||
#include "gp/algorithm/reference.hpp" | |||||
#include "gp/allocator/allocator.hpp" | |||||
#include "gp/vector.hpp" | |||||
#include "gp/vfs/file_description.hpp" | |||||
#include "gp/vfs/filesystem.hpp" | |||||
#include "gp/vfs/runqueue.hpp" | |||||
#include "gp/vfs/scheduler.hpp" | |||||
#include "gp/algorithms/foreach.hpp" | |||||
#include "gp/algorithms/reference.hpp" | |||||
#include "gp/utils/allocators/allocator.hpp" | |||||
#include "gp/containers/vector.hpp" | |||||
#include "gp/ipc/file_description.hpp" | |||||
#include "gp/ipc/filesystem.hpp" | |||||
#include "gp/system/runqueue.hpp" | |||||
#include "gp/system/scheduler.hpp" | |||||
namespace gp{ | namespace gp{ |
@ -0,0 +1,5 @@ | |||||
#pragma once | |||||
#include "gp/utils/allocators/aggregator.hpp" | |||||
#include "gp/utils/allocators/arena.hpp" | |||||
#include "gp/utils/allocators/buddy.hpp" | |||||
#include "gp/utils/allocators/dummy.hpp" |
@ -1,7 +1,7 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/ring_list.hpp" | |||||
#include "gp/allocator/allocator.hpp" | |||||
#include "gp/containers/ring_list.hpp" | |||||
#include "gp/utils/allocators/allocator.hpp" | |||||
#include <stddef.h> | #include <stddef.h> | ||||
@ -1,7 +1,7 @@ | |||||
#pragma once | #pragma once | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include "gp/allocator/allocator.hpp" | |||||
#include "gp/utils/allocators/allocator.hpp" | |||||
namespace gp { | namespace gp { | ||||
struct dummy_allocator : public allocator { | struct dummy_allocator : public allocator { |
@ -0,0 +1,240 @@ | |||||
#pragma once | |||||
#include <cstddef> | |||||
#include <cstdint> | |||||
// BUG: none of this is in a namespace | |||||
// TODO: Specify the concept of an iterator | |||||
namespace gp { | |||||
/** | |||||
* @brief An enumeration that may be used to determine iterator categories | |||||
* | |||||
*/ | |||||
enum class iterator_type_t{ | |||||
contiguous_iterator, /**< Defines an iterator for something that is continuous and random access */ | |||||
non_contiguous_iterator, /**< Defines an iterator for a non contiguous datastructure, for example an iterator over a hashmap or a tree*/ | |||||
lazy_iterator /**< Defines an iterator for which the actual data layout and availability are still unknown*/ | |||||
}; | |||||
/** | |||||
* @brief An abstraction of a pointer to iterate against, in both normal and reverse order | |||||
* | |||||
* @tparam T The type of data pointed by the iterator | |||||
* @tparam sign the direction in which data is scrutinized, should be either 1 or -1, behaviour for other value is left undefined | |||||
*/ | |||||
template<typename T, int sign = 1> | |||||
struct pointer_iterator final | |||||
{ | |||||
T* data; /**< the only data field of the class */ | |||||
typedef T value_type; /**< The type of which a reference will be returned on dereferencing */ | |||||
typedef std::size_t difference_type; /**< The type of the substraction of two pointers */ | |||||
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see iterator_type_t */ | |||||
/** | |||||
* @brief Generates an empty iterator | |||||
*/ | |||||
constexpr pointer_iterator() | |||||
: data{nullptr} | |||||
{} | |||||
constexpr pointer_iterator(const pointer_iterator& oth) | |||||
: data{oth.data} | |||||
{} | |||||
/** | |||||
* @brief Generates an iterator from any pointer | |||||
*/ | |||||
constexpr pointer_iterator(T* ptr) | |||||
: data{ptr} | |||||
{} | |||||
/** | |||||
* @brief Dereference unary operator | |||||
* | |||||
* @return constexpr T& returns a reference to the pointed value | |||||
*/ | |||||
constexpr T& operator*() const | |||||
{ | |||||
return *data; | |||||
} | |||||
constexpr pointer_iterator& operator++() | |||||
{ | |||||
data += sign; | |||||
return *this; | |||||
} | |||||
constexpr pointer_iterator operator++(int) | |||||
{ | |||||
auto p = *this; | |||||
data += sign; | |||||
return p; | |||||
} | |||||
constexpr pointer_iterator& operator--() | |||||
{ | |||||
data -= sign; | |||||
return *this; | |||||
} | |||||
constexpr pointer_iterator operator--(int) | |||||
{ | |||||
auto p = *this; | |||||
data -= sign; | |||||
return p; | |||||
} | |||||
constexpr pointer_iterator operator+(const std::size_t offset) const | |||||
{ | |||||
return pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr pointer_iterator operator+(const int offset) const | |||||
{ | |||||
return pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr pointer_iterator operator-(const std::size_t offset) const | |||||
{ | |||||
return pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr pointer_iterator operator-(const int offset) const | |||||
{ | |||||
return pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr difference_type operator-(const pointer_iterator& oth) const | |||||
{ | |||||
return ((T*)data-(T*)oth.data)*sign; | |||||
} | |||||
constexpr bool operator==(const pointer_iterator oth) const | |||||
{ | |||||
return data==oth.data; | |||||
} | |||||
constexpr bool operator!=(pointer_iterator oth) const | |||||
{ | |||||
return data!=oth.data; | |||||
} | |||||
constexpr bool before_or_equal(const pointer_iterator oth) const | |||||
{ | |||||
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data); | |||||
} | |||||
constexpr bool operator<=(const pointer_iterator oth) const | |||||
{ | |||||
return before_or_equal(oth); | |||||
} | |||||
}; | |||||
/** | |||||
* @brief An identical twin to the pointer_iterator, but which dereference to a const reference | |||||
* | |||||
* @see pointer_iterator | |||||
* @tparam T @see pointer_iterator | |||||
* @tparam sign @see pointer_iterator | |||||
*/ | |||||
template<typename T, int sign = 1> | |||||
struct const_pointer_iterator final | |||||
{ | |||||
const T* data; /**< @see pointer_iterator */ | |||||
typedef T value_type; /**< @see pointer_iterator */ | |||||
typedef std::size_t difference_type; /**< @see pointer_iterator */ | |||||
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see pointer_iterator */ | |||||
constexpr const_pointer_iterator(const const_pointer_iterator& oth) | |||||
: data{oth.data} | |||||
{} | |||||
/** | |||||
* @brief @see pointer_iterator | |||||
*/ | |||||
constexpr const_pointer_iterator(const T* ptr) | |||||
: data{ptr} | |||||
{} | |||||
/** | |||||
* @brief Dereferencing returns a const version of what a pointer_iterator would return | |||||
*/ | |||||
constexpr const T& operator*() const | |||||
{ | |||||
return *data; | |||||
} | |||||
constexpr const_pointer_iterator& operator++() | |||||
{ | |||||
data += sign; | |||||
return *this; | |||||
} | |||||
constexpr const_pointer_iterator operator++(int) | |||||
{ | |||||
auto p = data; | |||||
data += sign; | |||||
return const_pointer_iterator{p}; | |||||
} | |||||
constexpr const_pointer_iterator& operator--() | |||||
{ | |||||
data -= sign; | |||||
return *this; | |||||
} | |||||
constexpr const_pointer_iterator operator--(int) | |||||
{ | |||||
auto p = data; | |||||
data -= sign; | |||||
return const_pointer_iterator{p}; | |||||
} | |||||
constexpr const_pointer_iterator operator+(const std::size_t offset) const | |||||
{ | |||||
return const_pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr const_pointer_iterator operator+(const int offset) const | |||||
{ | |||||
return const_pointer_iterator{data+sign*offset}; | |||||
} | |||||
constexpr const_pointer_iterator operator-(const std::size_t offset) const | |||||
{ | |||||
return const_pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr const_pointer_iterator operator-(const int offset) | |||||
{ | |||||
return const_pointer_iterator{data-sign*offset}; | |||||
} | |||||
constexpr difference_type operator-(const const_pointer_iterator& oth) const | |||||
{ | |||||
return ((T*)data-(T*)oth.data)*sign; | |||||
} | |||||
constexpr bool operator==(const const_pointer_iterator oth) const | |||||
{ | |||||
return data==oth.data; | |||||
} | |||||
constexpr bool operator!=(const_pointer_iterator oth) const | |||||
{ | |||||
return data!=oth.data; | |||||
} | |||||
constexpr bool before_or_equal(const const_pointer_iterator oth) const | |||||
{ | |||||
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data); | |||||
} | |||||
constexpr bool operator<=(const const_pointer_iterator oth) const | |||||
{ | |||||
return before_or_equal(oth); | |||||
} | |||||
}; | |||||
} |
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/algorithm/move.hpp" | |||||
#include "gp/algorithms/move.hpp" | |||||
namespace gp{ | namespace gp{ | ||||
template<typename T1, typename T2> | template<typename T1, typename T2> |
@ -1,9 +1,9 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/algorithm/modifiers.hpp" | |||||
#include "gp/algorithm/move.hpp" | |||||
#include "gp/buffer.hpp" | |||||
#include "gp/function.hpp" | |||||
#include "gp/algorithms/modifiers.hpp" | |||||
#include "gp/algorithms/move.hpp" | |||||
#include "gp/containers/buffer.hpp" | |||||
#include "gp/functional/function.hpp" | |||||
namespace gp { | namespace gp { | ||||
@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "gp/algorithm/tmp_manip.hpp" | |||||
#include "gp/algorithms/tmp_manip.hpp" | |||||
namespace gp{ | namespace gp{ | ||||
/*template<typename T> | /*template<typename T> |