@ -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*) |
@ -1,8 +1,8 @@ | |||
#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> | |||
@ -1,8 +1,8 @@ | |||
#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{ | |||
template<typename T> |
@ -1,7 +1,7 @@ | |||
#pragma once | |||
#include <gp/algorithm/move.hpp> | |||
#include <gp/algorithm/cvref.hpp> | |||
#include <gp/algorithms/move.hpp> | |||
#include <gp/algorithms/cvref.hpp> | |||
namespace gp{ |
@ -1,6 +1,6 @@ | |||
#pragma once | |||
#include "gp/algorithm/move.hpp" | |||
#include "gp/algorithms/move.hpp" | |||
namespace gp { | |||
template<typename iterator> |
@ -1,6 +1,6 @@ | |||
#pragma once | |||
#include <gp/buffer.hpp> | |||
#include <gp/containers/buffer.hpp> | |||
#include <initializer_list> | |||
@ -1,10 +1,10 @@ | |||
#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/iterator.hpp> | |||
#include <gp/optional.hpp> | |||
#include <gp/utils/iterator.hpp> | |||
#include <gp/functional/optional.hpp> | |||
#include <cstddef> | |||
#include <cstdint> |
@ -1,6 +1,6 @@ | |||
#pragma one | |||
#include <gp/array.hpp> | |||
#include <gp/containers/array.hpp> | |||
#include <gp/integer_math.hpp> | |||
#include <gp/iterator.hpp> | |||
// UNIMPLEMENTED: see filename |
@ -1,8 +1,8 @@ | |||
#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> | |||
@ -1,8 +1,8 @@ | |||
#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 <atomic> |
@ -1,7 +1,7 @@ | |||
#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> | |||
@ -1,11 +1,11 @@ | |||
#pragma once | |||
#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{ | |||
@ -1,11 +1,11 @@ | |||
#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 { |
@ -1,8 +1,8 @@ | |||
#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{ | |||
@ -1,6 +1,6 @@ | |||
#pragma once | |||
#include "gp/array.hpp" | |||
#include "gp/containers/array.hpp" | |||
#include <cstddef> | |||
#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 | |||
#include "gp/array.hpp" | |||
#include "gp/containers/array.hpp" | |||
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 | |||
#include "gp/buffer.hpp" | |||
#include "gp/containers/buffer.hpp" | |||
#include <cstdint> | |||
@ -1,11 +1,11 @@ | |||
#pragma once | |||
#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> | |||
@ -1,6 +1,6 @@ | |||
#pragma once | |||
#include "gp/vfs/process_data.hpp" | |||
#include "gp/system/process_data.hpp" | |||
#include <atomic> | |||
#include <new> |
@ -1,8 +1,8 @@ | |||
#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{ | |||
@ -1,5 +1,5 @@ | |||
#pragma once | |||
#include "gp/vfs/system.hpp" | |||
#include "gp/system/system.hpp" | |||
namespace gp{ | |||
@ -1,13 +1,13 @@ | |||
#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{ |
@ -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 | |||
#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> | |||
@ -1,7 +1,7 @@ | |||
#pragma once | |||
#include <stddef.h> | |||
#include "gp/allocator/allocator.hpp" | |||
#include "gp/utils/allocators/allocator.hpp" | |||
namespace gp { | |||
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 | |||
#include "gp/algorithm/move.hpp" | |||
#include "gp/algorithms/move.hpp" | |||
namespace gp{ | |||
template<typename T1, typename T2> |
@ -1,9 +1,9 @@ | |||
#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 { | |||
@ -1,6 +1,6 @@ | |||
#pragma once | |||
#include "gp/algorithm/tmp_manip.hpp" | |||
#include "gp/algorithms/tmp_manip.hpp" | |||
namespace gp{ | |||
/*template<typename T> |