Browse Source

vfs and rendering scaffolds

devel
Ludovic 'Archivist' Lagouardette 4 years ago
parent
commit
2c6dea516a
28 changed files with 1569 additions and 217 deletions
  1. +2
    -2
      Makefile
  2. +20
    -0
      include/gp/algorithm/foreach.hpp
  3. +11
    -1
      include/gp/algorithm/min_max.hpp
  4. +26
    -0
      include/gp/algorithm/min_of.hpp
  5. +26
    -0
      include/gp/algorithm/rotate.hpp
  6. +1
    -1
      include/gp/algorithm/tmp_manip.hpp
  7. +1
    -1
      include/gp/allocator/buddy.hpp
  8. +78
    -12
      include/gp/array.hpp
  9. +18
    -13
      include/gp/function.hpp
  10. +130
    -0
      include/gp/indexed_array.hpp
  11. +116
    -21
      include/gp/iterator.hpp
  12. +167
    -0
      include/gp/math.hpp
  13. +196
    -0
      include/gp/math/fp_math.hpp
  14. +0
    -0
      include/gp/math/integer_math.hpp
  15. +0
    -0
      include/gp/math/q_math.hpp
  16. +37
    -15
      include/gp/optional.hpp
  17. +76
    -0
      include/gp/rendering/renderer.hpp
  18. +20
    -21
      include/gp/variant.hpp
  19. +385
    -0
      include/gp/vfs/vfs.hpp
  20. +22
    -35
      include/gp_config.hpp
  21. +0
    -2
      include/indexed_array.hpp
  22. +25
    -20
      include/rc6_generic.hpp
  23. +1
    -1
      include/stored_indexed_array.hpp
  24. +8
    -3
      tests.cpp
  25. +16
    -0
      tests/allocator.hpp
  26. +116
    -14
      tests/gp_test.cpp
  27. +47
    -0
      tests/math.cpp
  28. +24
    -55
      tests/rc6_generic.cpp

+ 2
- 2
Makefile View File

@ -1,8 +1,8 @@
CXX= clang++-8
CXXFLAGS= --std=c++17 -O0 -pthread -DFUZZ_STRENGTH=500000 -pedantic -Werror \
-fsanitize=address -fno-omit-frame-pointer \
CXXFLAGS= --std=c++17 -O0 -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -pedantic -Werror \
-Wno-unknown-attributes \
-g -fprofile-instr-generate -fcoverage-mapping
# -fsanitize=address -fno-omit-frame-pointer
all: tests
tests: bin/tests

+ 20
- 0
include/gp/algorithm/foreach.hpp View File

@ -0,0 +1,20 @@
#pragma once
#include <stddef.h>
namespace gp{
template <typename range, typename F>
void indexed_foreach(range n, F f) {
for(size_t idx = 0; idx < n.size(); ++idx)
{
f(idx, n[idx]);
}
}
template <typename range, typename F>
void foreach(range n, F f) {
for(auto& elem : n)
{
f(elem);
}
}
}

+ 11
- 1
include/gp/algorithm/min_max.hpp View File

@ -27,6 +27,8 @@ namespace gp{
}
}
template<typename T>
constexpr T clamp(T first, T value, T last)
{
@ -34,4 +36,12 @@ namespace gp{
if(value > last) return last;
return value;
}
}
}

+ 26
- 0
include/gp/algorithm/min_of.hpp View File

@ -0,0 +1,26 @@
#pragma once
#include "gp_config.hpp"
#include "gp/algorithm/move.hpp"
namespace gp{
template<typename T>
T identity(T v){return v;}
template<typename T>
T& identity(T& v){return v;}
template<typename it, typename transform>
auto&& min_of(it beg, it end, transform fn = identity) {
gp_config::assertion(beg == end, "min_of provided with empty range");
auto fn_v = fn(*beg);
++beg;
while(beg != end) {
auto n_fn_v = fn(*beg);
if(n_fn_v < fn_v) {
fn_v = n_fn_v;
}
++beg;
}
return gp::move(fn_v);
}
}

+ 26
- 0
include/gp/algorithm/rotate.hpp View File

@ -0,0 +1,26 @@
#pragma once
#include "gp/algorithm/move.hpp"
namespace gp {
template<typename iterator>
iterator rotate(iterator first, iterator new_first, iterator last)
{
if(first == new_first) return last;
if(new_first == last) return first;
iterator in = new_first;
iterator out = first;
iterator mv = first;
while(in != last) {
if(out == mv) mv = in;
gp::swap((*out++), (*in++));
}
// rotate the remaining sequence into place
(rotate)(out, mv, last);
return out;
}
}

+ 1
- 1
include/gp/algorithm/tmp_manip.hpp View File

@ -109,7 +109,7 @@ namespace gp{
else
{
return max_size<
either<
k">typename either<
( sizeof(T) > sizeof(U) ),
T,
U

+ 1
- 1
include/gp/allocator/buddy.hpp View File

@ -2,7 +2,7 @@
#include "gp_config.hpp"
#include "gp/buffer.hpp"
#include "gp/array.hpp"
#include "gp/integer_math.hpp"
#include "gp/math.hpp"
#include <type_traits>
#include <gp/algorithm/tmp_manip.hpp>
#include <gp/algorithm/modifiers.hpp>

+ 78
- 12
include/gp/array.hpp View File

@ -5,28 +5,74 @@
namespace gp{
template<typename T, std::size_t sz>
class array{
T ary[sz];
public:
using associated_iterator = pointer_iterator<T>;
using associated_const_iterator = pointer_iterator<T>;
T ary[sz];
using associated_iterator = pointer_iterator<T, 1>;
using associated_const_iterator = const_pointer_iterator<T, 1>;
using associated_riterator = pointer_iterator<T, -1>;
using associated_const_riterator = const_pointer_iterator<T, -1>;
array()
: ary()
{}
array(const array& oth)
{
auto it_l = begin();
auto it_o = oth.cbegin();
for(size_t i = 0; i < sz; ++i)
{
new(&*(it_l++)) T(*(it_o++));
}
}
template<typename ...U>
array(U&& ...v)
: ary{gp::forward(v...)}
array(U&& ...values)
: ary{gp::move((T&&)values)...}
{}
array(array&& values)
{
gp::move_uninitialized<T>(
values,
*this
);
}
template<>
array<T[sz]>(T (& oth)[sz]) {
gp::move_uninitialized<T>(
gp::nameless_range(oth, oth+sz),
gp::nameless_range(begin(), end())
);
}
template<>
array<T[sz]>(T (&& oth)[sz]) {
gp::move_uninitialized(
gp::nameless_range(oth, oth+sz),
gp::nameless_range(*this)
gp::nameless_range(n">begin(), end())
);
}
array& operator=(array& oth)
{
for(size_t i = 0; i < sz; ++i)
{
ary[i]=oth[i];
}
return *this;
}
array& operator=(array&& oth)
{
for(size_t i = 0; i < sz; ++i)
{
ary[i]=gp::move(oth[i]);
}
return *this;
}
constexpr T& operator[] (size_t off)
{
if constexpr (gp_config::has_buffer_bounds)
@ -49,24 +95,44 @@ namespace gp{
return sz;
}
constexpr associated_iterator begin()
constexpr pointer_iterator<T, 1> begin()
{
return associated_iterator(&ary[0]);
}
constexpr associated_iterator end()
constexpr pointer_iterator<T, 1> end()
{
return associated_iterator(&ary[sz]);
}
constexpr associated_const_iterator cbegin() const
constexpr const_pointer_iterator<T, 1> cbegin() const
{
return associated_const_iterator(&ary[0]);
}
constexpr const_pointer_iterator<T, 1> cend() const
{
return associated_const_iterator(&ary[sz]);
}
constexpr pointer_iterator<T, -1> rbegin()
{
return associated_riterator(&ary[sz-1]);
}
constexpr pointer_iterator<T, -1> rend()
{
return associated_riterator(ary-1);
}
constexpr const_pointer_iterator<T, -1> crbegin() const
{
return ary;
return f">associated_const_riterator(&ary[sz-1]);
}
constexpr associated_const_iterator cend() const
constexpr const_pointer_iterator<T, -1> crend() const
{
return ary+sz;
return f">associated_const_riterator(ary-1);
}
constexpr bool operator==(const array& oth) const

+ 18
- 13
include/gp/function.hpp View File

@ -18,13 +18,13 @@ namespace gp{
class callable : virtual_callable{
fn internal_representation;
public:
callable(const fn& func)
callable(const fn func)
: internal_representation{func}
{}
virtual ~callable() override = default;
ret operator() (args... arg_list)
ret operator() (args... arg_list) override
{
return internal_representation(arg_list...);
}
@ -37,7 +37,7 @@ namespace gp{
SOO = 2
};
state_t state = 0;
state_t state{};
union{
virtual_callable* functor = nullptr;
char inplace[12];
@ -61,27 +61,32 @@ namespace gp{
if constexpr (sizeof(callable<T>) <= sizeof(self))
{
new((void*)&self) callable(t);
state = ACTIVE | SOO;
state = p">(state_t)(ACTIVE | SOO);
}
else
{
self = new callable(t);
state = ACTIVE | NO_SOO;
state = p">(state_t)(ACTIVE | NO_SOO);
}
}
function()
{
state = INACTIVE;
}
template <typename T>
function(T t)
{
if constexpr (sizeof(callable<T>) <= sizeof(self))
{
new((void*)&self) callable(t);
state = ACTIVE | SOO;
new((void*)&self) callableo"><T>(t);
state = p">(state_t)(ACTIVE | SOO);
}
else
{
self = new callable(t);
state = ACTIVE | NO_SOO;
self = new callableo"><T>(t);
state = p">(state_t)(ACTIVE | NO_SOO);
}
}
@ -90,13 +95,13 @@ namespace gp{
{
if constexpr (sizeof(callable<T>) <= sizeof(self))
{
new((void*)&self) callable(t);
state = ACTIVE | SOO;
new((void*)&self) callableo"><T>(t);
state = p">(state_t)(ACTIVE | SOO);
}
else
{
self = new callable(t);
state = ACTIVE | NO_SOO;
self = new callableo"><T>(t);
state = p">(state_t)(ACTIVE | NO_SOO);
}
}

+ 130
- 0
include/gp/indexed_array.hpp View File

@ -0,0 +1,130 @@
#pragma once
#include <stddef.h>
#include "gp_config.hpp"
#include "gp/algorithm/move.hpp"
#include "gp/iterator.hpp"
namespace gp{
template<typename T, size_t _capacity>
class indexed_array{
size_t data_top = 0;
size_t available_indexes_top = 0;
size_t remove_top = 0;
T data_table[_capacity];
size_t available_indexes[_capacity];
size_t translation_table[_capacity];
size_t reverse_translation_table[_capacity];
size_t remove_table[_capacity];
public:
indexed_array() {}
size_t push(T&& value) {
size_t index;
gp_config::assertion(data_top+1 != _capacity, "Indexed array capacity exceeded");
if(available_indexes_top) {
available_indexes_top--;
index = available_indexes[available_indexes_top];
} else {
index = data_top;
}
new(&data_table[data_top]) T(gp::move(value));
translation_table[index] = data_top;
reverse_translation_table[data_top] = index;
++data_top;
return index;
}
void pop(size_t idx) {
size_t v_idx = translation_table[idx];
available_indexes[available_indexes_top] = idx;
++available_indexes_top;
translation_table[idx] = -1;
--data_top;
if(v_idx < data_top) {
size_t u_idx = reverse_translation_table[data_top];
data_table[v_idx] = gp::move(data_table[data_top]);
::operator delete(&data_table[data_top], &data_table[data_top]);
data_table[data_top].~T();
translation_table[u_idx] = v_idx;
reverse_translation_table[v_idx] = u_idx;
}
}
void reset() {
auto it = data_table;
auto end = data_table+data_top;
while(it != end) {
::operator delete(it, it);
++it;
}
data_top = 0;
available_indexes_top = 0;
remove_top = 0;
}
void mark_internal_for_removal(size_t i_idx) {
remove_table[remove_top] = reverse_translation_table[i_idx];
++remove_top;
}
void mark_for_removal(size_t idx) {
remove_table[remove_top] = idx;
++remove_top;
}
void sweep_removed() {
auto it = remove_table;
auto end = remove_table+remove_top;
while(it != end) {
pop(*it);
++it;
}
}
bool has(size_t idx) {
if(idx > data_top) return false;
if(translation_table[idx] == -1) return false;
return true;
}
pointer_iterator<T> begin()
{
return data_table;
}
pointer_iterator<T> end()
{
return data_table+data_top;
}
const_pointer_iterator<T> cbegin()
{
return data_table;
}
const_pointer_iterator<T> cend()
{
return data_table+data_top;
}
size_t size() {
return data_top;
}
size_t capacity() {
return _capacity;
}
T& operator[](size_t idx) {
gp_config::assertion(idx < data_top, "Bad indexed array access");
return data_table[translation_table[idx]];
}
};
}

+ 116
- 21
include/gp/iterator.hpp View File

@ -8,7 +8,7 @@ enum class iterator_type_t{
lazy_iterator
};
template<typename T>
template<typename Tp">, int sign = 1>
struct pointer_iterator final
{
T* data;
@ -24,76 +24,171 @@ struct pointer_iterator final
: data{ptr}
{}
constexpr k">operator T&()
constexpr n">T& operator*()
{
return *data;
}
constexpr T& operator*(){
return *data;
}
constexpr pointer_iterator operator++()
constexpr pointer_iterator& operator++()
{
return pointer_iterator{++data};
data += sign;
return *this;
}
constexpr pointer_iterator operator++(int)
{
return pointer_iterator{data++};
auto p = *this;
data += sign;
return p;
}
constexpr pointer_iterator operator--()
constexpr pointer_iterator& operator--()
{
return pointer_iterator{--data};
data -= sign;
return *this;
}
constexpr pointer_iterator operator--(int)
{
return pointer_iterator{data--};
auto p = *this;
data -= sign;
return p;
}
constexpr pointer_iterator operator+(const std::size_t offset)
{
return pointer_iterator{data+offset};
return pointer_iterator{data+sign*offset};
}
constexpr pointer_iterator operator+(const int offset)
{
return pointer_iterator{data+offset};
return pointer_iterator{data+sign*offset};
}
constexpr pointer_iterator operator-(const std::size_t offset)
{
return pointer_iterator{data-offset};
return pointer_iterator{data-sign*offset};
}
constexpr pointer_iterator operator-(const int offset)
{
return pointer_iterator{data-offset};
return pointer_iterator{data-sign*offset};
}
constexpr difference_type operator-(const pointer_iterator& oth) const
{
return (T*)data-(T*)oth.data;
return ((T*)data-(T*)oth.data)*sign;
}
constexpr bool operator==(const pointer_iterator oth)
{
return data==oth.data;
}
constexpr bool operator!=(pointer_iterator oth)
{
return data!=oth.data;
}
constexpr bool before_or_equal(const pointer_iterator oth)
{
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data);
}
constexpr bool operator<=(const pointer_iterator oth)
{
return before_or_equal(oth);
}
};
template<typename T, int sign = 1>
struct const_pointer_iterator final
{
const T* data;
typedef T value_type;
typedef std::size_t difference_type;
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator;
constexpr const_pointer_iterator(const const_pointer_iterator& oth)
: data{oth.data}
{}
constexpr const_pointer_iterator(const T* ptr)
: data{ptr}
{}
constexpr const T& operator*()
{
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)
{
return const_pointer_iterator{data+sign*offset};
}
constexpr const_pointer_iterator operator+(const int offset)
{
return const_pointer_iterator{data+sign*offset};
}
constexpr const_pointer_iterator operator-(const std::size_t offset)
{
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 pointer_iterator& oth)
constexpr bool operator==(const const_pointer_iterator oth)
{
return data==oth.data;
}
constexpr bool operator!=(pointer_iterator& oth)
constexpr bool operator!=(const_pointer_iterator oth)
{
return data!=oth.data;
}
constexpr bool before_or_equal(const pointer_iterator& oth)
constexpr bool before_or_equal(const const_pointer_iterator oth)
{
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data);
}
constexpr bool operator<=(const pointer_iterator& oth)
constexpr bool operator<=(const const_pointer_iterator oth)
{
return before_or_equal(oth);
}

+ 167
- 0
include/gp/math.hpp View File

@ -0,0 +1,167 @@
#pragma once
#include "gp_config.hpp"
#include "gp/math/integer_math.hpp"
#include "gp/math/q_math.hpp"
#if !defined(NO_FP_MATH)
# include "gp/math/fp_math.hpp"
#endif
namespace gp {
template<typename T = gp_config::rendering::default_type>
struct vec2_g {
T x;
T 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 oth) {
return {x+oth.x, y+oth.y};
}
vec2_g normalize() {
T ilen = fast_isqrt(x*x+y*y);
return {x*ilen, y*ilen};
}
};
template<typename T = gp_config::rendering::default_type>
struct vec3_g {
T x;
T y;
T 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 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};
}
};
template<typename T = gp_config::rendering::default_type>
struct vec4_g {
T x;
T y;
T z;
T 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 oth) {
return {x+oth.x, y+oth.y, z+oth.z, w+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};
}
};
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;
}
}

+ 196
- 0
include/gp/math/fp_math.hpp View File

@ -0,0 +1,196 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <limits>
#include "gp/algorithm/repeat.hpp"
namespace gp{
template<typename T>
constexpr T pi;
template<>
constexpr float pi<float> = 3.1415926535897932384626433832795028841971693993751058209749445923078164062;
template<>
constexpr double pi<double> = 3.1415926535897932384626433832795028841971693993751058209749445923078164062;
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 >= std::numeric_limits<int32_t>::max()
|| 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 >= std::numeric_limits<int64_t>::max()
|| 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<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;
}
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;
}
float sin(float v) {
v += pi<float>;
v = v - 2*pi<float>*floor(v/(2*pi<float>));
v -= pi<float>;
float s = sign(v);
v *= s;
return sin_taylor<10>(v)*s;
}
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<float>/2);
}
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;
}
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;
}
float fast_isqrt(float v) {return isqrt<1>(v);}
double fast_isqrt(double v) {return isqrt<1>(v);}
}

include/gp/integer_math.hpp → include/gp/math/integer_math.hpp View File


+ 0
- 0
include/gp/math/q_math.hpp View File


+ 37
- 15
include/gp/optional.hpp View File

@ -3,37 +3,51 @@
#include "gp_config.hpp"
#include "gp/exception.hpp"
#include "gp/algorithm/move.hpp"
#include "gp/algorithm/modifiers.hpp"
namespace gp{
struct nullopt_t{};
constexpr nullopt_t nullopt;
// TODO: Add allocators to the template
template<typename T, bool B = std::is_final<T>::value || std::is_fundamental<T>::value>
template<
typename T,
typename allocator = gp_config::memory_module::default_allocator,
bool copy_allocator = false,
bool B = std::is_final<T>::value || std::is_fundamental<T>::value
>
class optional;
template<typename T>
class optional<T,true>{
template<typename Tp">, typename allocator, bool copy_allocator>
class optional<T, allocator, copy_allocator, true>{
bool ready = false;
char buffer[sizeof(T)];
typename gp::either<
copy_allocator,
allocator,
gp::reference_wrapper<allocator>
>::type alloc;
public:
constexpr optional()
constexpr optional(n">allocator p = allocator{})
: ready{false}
, alloc(p)
{}
constexpr optional(nullopt_t)
constexpr optional(nullopt_t, allocator p = allocator{})
: ready{false}
, alloc(p)
{}
constexpr optional(T& value)
constexpr optional(T& value, allocator p = allocator{})
: ready{true}
, alloc(p)
{
new(buffer) T(value);
}
constexpr optional(T&& value)
constexpr optional(T&& value, allocator p = allocator{})
: ready{true}
, alloc(p)
{
new(buffer) T(gp::move(value));
}
@ -87,30 +101,38 @@ namespace gp{
}
};
// TODO: Add allocators to the template
template<typename T>
class optional<T,false>{
template<typename T, typename allocator, bool copy_allocator>
class optional<T, allocator, copy_allocator, false>{
bool ready = false;
T* ptr;
typename gp::either<
copy_allocator,
allocator,
gp::reference_wrapper<allocator>
>::type alloc;
public:
constexpr optional()
constexpr optional(n">allocator p = allocator{})
: ready{false}
, alloc(p)
{}
constexpr optional(nullopt_t)
constexpr optional(nullopt_t, allocator p = allocator{})
: ready{false}
, alloc(p)
{}
template<typename U>
constexpr optional(U& value)
constexpr optional(U& value, allocator p = allocator{})
: ready{true}
, alloc(p)
{
ptr = new U(value); // TODO: Use allocators
}
template<typename U>
constexpr optional(U&& value)
constexpr optional(U&& value, allocator p = allocator{})
: ready{true}
, alloc(p)
{
ptr = new U(gp::move(value)); // TODO: Use allocators
}

+ 76
- 0
include/gp/rendering/renderer.hpp View File

@ -0,0 +1,76 @@
#pragma once
#include "gp_config.hpp"
#include "gp/math.hpp"
#include "gp/function.hpp"
#include "gp/algorithm/min_of.hpp"
#include "gp/indexed_array.hpp"
using vec2 = gp::vec2_g<>;
using vec3 = gp::vec3_g<>;
using vec4 = gp::vec4_g<>;
struct camera{
vec3 position;
vec3 normal;
};
using index_t = size_t;
using distance_t = gp_config::rendering::default_type;
using color_t = GP_CONFIG__RENDERING__COLOR_T;
struct render_point{
distance_t distance;
index_t material;
bool operator<(const render_point& rhs) {
return distance < rhs.distance;
}
};
using sdf_t = gp::function<render_point(vec3)>;
using material_t = gp::function<color_t(vec3)>;
class renderer {
using g_t = gp_config::rendering::default_type;
constexpr static auto epsilon = gp_config::rendering::epsilon;
public:
gp::indexed_array<sdf_t, 4096> scene_elements;
gp::indexed_array<material_t, 4096> materials;
material_t sky_box = [](vec3) -> color_t { return vec4{0,0,0,0};};
vec2 _resolution{128,64};
camera _camera{{0, 0, -1}, {0, 0, 0}};
vec2 _fov{90, 45};
distance_t projection_start = 1;
distance_t projection_end = 50;
size_t passes = 12;
renderer() = default;
color_t render(vec2 pixel) {
g_t depth = projection_start;
vec3 target{0,0,0};
target = target.normalize();
vec3 render_target{_camera.position};
for(int i = 0; i < passes; ++i) {
render_target = _camera.position+depth*target;
render_point distance = gp::min_of(
scene_elements.begin(),
scene_elements.end(),
[&](auto& p){
return p(render_target);
}
);
if(distance.distance < epsilon) {
return materials[distance.material](render_target);
}
depth += distance.distance;
if(depth >= projection_end) {
break;
}
}
return sky_box(render_target);
}
};

+ 20
- 21
include/gp/variant.hpp View File

@ -10,17 +10,15 @@
namespace gp{
template< typename Enable, typename ...T>
class variant;
template<typename ...T>
class variant<typename std::enable_if<!gp_config::memory_module::is_ok && all_of_fixed_size<T...>::value,int>::type, T...>{
class fixed_variant{
std::size_t index = std::numeric_limits<std::size_t>::max();
char buffer[max_size<T...>];
char buffer[max_size<T...>()];
gp::function<void(void*)> dtor = [](void*){};
static_assert(all_of_fixed_size<T...>::value, "not fixed");
public:
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
constexpr variant(U& value)
constexpr fixed_variant(U& value)
: index{r_index_of<U, T...>::value}
{
new(buffer) U(value);
@ -28,7 +26,7 @@ namespace gp{
}
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
constexpr variant(U&& value)
constexpr fixed_variant(U&& value)
: index{r_index_of<U, T...>::value}
{
new(buffer) U(std::move(value));
@ -61,7 +59,7 @@ namespace gp{
dtor = gp::function([](void* thing){((U*)thing)->~U();});
}
~variant()
~fixed_variant()
{
if(index != std::numeric_limits<std::size_t>::max())
{
@ -96,26 +94,27 @@ namespace gp{
}
};
template<typename ...T>
class varianto"><typename std::enable_if<gp_config::memory_module::is_ok,default_memory_allocator<>>::type, T...>{
template<typename n">allocator_t = gp_config::memory_module::default_allocator, typename ...T>
class variant{
std::size_t index = std::numeric_limits<std::size_t>::max();
void* ptr;
gp::function<void(void*)> dtor = [](void*){};
allocator_t allocator;
public:
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
constexpr variant(U& value)
: index{r_index_of<U, T...>::value}
{
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(value);
dtor = gp::function([](void* thing){((U*)thing)->~U();});
ptr = (void*)new(allocator.allocate(sizeof(U))) U(value);
dtor = gp::function([](void* thing){((U*)thing)->~U();}); // TODO:replae with delete(p,t)
}
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
constexpr variant(U&& value)
: index{r_index_of<U, T...>::value}
{
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(std::move(value));
dtor = gp::function([](void* thing){((U*)thing)->~U();});
ptr = (void*)new(allocator.allocate(sizeof(U))) U(std::move(value));
dtor = gp::function([](void* thing){((U*)thing)->~U();}); // TODO:replae with delete(p,t)
}
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
@ -124,11 +123,11 @@ namespace gp{
if(index != std::numeric_limits<std::size_t>::max())
{
dtor(ptr);
default_memory_allocator<>{}.deallocate(ptr);
allocator.deallocate(ptr);
}
index = r_index_of<U, T...>::value;
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(value);
dtor = gp::function([](void* thing){((U*)thing)->~U();});
ptr = (void*)new(allocator.allocate(sizeof(U))) U(value);
dtor = gp::function([](void* thing){((U*)thing)->~U();}); // TODO:replae with delete(p,t)
}
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
@ -137,11 +136,11 @@ namespace gp{
if(index != std::numeric_limits<std::size_t>::max())
{
dtor(ptr);
default_memory_allocator<>{}.deallocate(ptr);
allocator.deallocate(ptr);
}
index = r_index_of<U, T...>::value;
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(std::move(value));
dtor = gp::function([](void* thing){((U*)thing)->~U();});
ptr = (void*)new(allocator.allocate(sizeof(U))) U(std::move(value));
dtor = gp::function([](void* thing){((U*)thing)->~U();}); // TODO: replace with delete(p, t)
}
~variant()
@ -149,7 +148,7 @@ namespace gp{
if(index != std::numeric_limits<std::size_t>::max())
{
dtor(ptr);
default_memory_allocator<>{}.deallocate(ptr);
allocator.deallocate(ptr);
}
}

+ 385
- 0
include/gp/vfs/vfs.hpp View File

@ -0,0 +1,385 @@
#pragma once
#include <stddef.h>
#include "gp_config.hpp"
#include "gp/variant.hpp"
#include "gp/optional.hpp"
#include "gp/buffer.hpp"
#include "gp/allocator/aggregator.hpp"
namespace gp {
class vfs {
public:
struct bad_file final {
static constexpr auto _what = "bad_file";
constexpr auto what() {
return _what;
}
};
struct faulty_buffer final {
static constexpr auto _what = "faulty_buffer";
constexpr auto what() {
return _what;
}
};
struct interrupted final {
static constexpr auto _what = "interrupted";
constexpr auto what() {
return _what;
}
};
struct io_error final {
static constexpr auto _what = "io_error";
constexpr auto what() {
return _what;
}
};
struct is_directory final {
static constexpr auto _what = "is_directory";
constexpr auto what() {
return _what;
}
};
struct try_again final {
static constexpr auto _what = "try_again";
constexpr auto what() {
return _what;
}
};
struct not_connected final {
static constexpr auto _what = "not_connected";
constexpr auto what() {
return _what;
}
};
struct impossible_io final {
static constexpr auto _what = "impossible_io";
constexpr auto what() {
return _what;
}
};
struct negative_offset final {
static constexpr auto _what = "negative_offset";
constexpr auto what() {
return _what;
}
};
struct is_pipe final {
static constexpr auto _what = "is_pipe";
constexpr auto what() {
return _what;
}
};
struct buffer_too_big final {
static constexpr auto _what = "buffer_too_big";
constexpr auto what() {
return _what;
}
};
struct path_not_directory final {
static constexpr auto _what = "path_not_directory";
constexpr auto what() {
return _what;
}
};
struct name_too_long final {
static constexpr auto _what = "name_too_long";
constexpr auto what() {
return _what;
}
};
struct does_not_exist final {
static constexpr auto _what = "does_not_exist";
constexpr auto what() {
return _what;
}
};
struct may_loop final {
static constexpr auto _what = "may_loop";
constexpr auto what() {
return _what;
}
};
struct invalid_flags final {
static constexpr auto _what = "invalid_flags";
constexpr auto what() {
return _what;
}
};
struct is_read_only final {
static constexpr auto _what = "is_read_only";
constexpr auto what() {
return _what;
}
};
struct fd_limit_reached final {
static constexpr auto _what = "fd_limit_reached";
constexpr auto what() {
return _what;
}
};
struct file_limit_reached final {
static constexpr auto _what = "file_limit_reached";
constexpr auto what() {
return _what;
}
};
struct no_locking final {
static constexpr auto _what = "no_locking";
constexpr auto what() {
return _what;
}
};
struct would_block final {
static constexpr auto _what = "would_block";
constexpr auto what() {
return _what;
}
};
struct no_inodes final {
static constexpr auto _what = "no_inodes";
constexpr auto what() {
return _what;
}
};
struct no_space final {
static constexpr auto _what = "no_space";
constexpr auto what() {
return _what;
}
};
struct quota_reached final {
static constexpr auto _what = "quota_reached";
constexpr auto what() {
return _what;
}
};
struct cannot_write_shared_text final {
static constexpr auto _what = "cannot_write_shared_text";
constexpr auto what() {
return _what;
}
};
struct faulty_filename final {
static constexpr auto _what = "faulty_filename";
constexpr auto what() {
return _what;
}
};
struct exists_already final {
static constexpr auto _what = "exists_already";
constexpr auto what() {
return _what;
}
};
struct is_append_only final {
static constexpr auto _what = "is_append_only";
constexpr auto what() {
return _what;
}
};
struct unimplemented_operation final {
static constexpr auto _what = "unimplemented_operation";
constexpr auto what() {
return _what;
}
};
struct is_busy final {
static constexpr auto _what = "is_busy";
constexpr auto what() {
return _what;
}
};
struct bad_relative_path final {
static constexpr auto _what = "bad_relative_path";
constexpr auto what() {
return _what;
}
};
struct no_permissions final {
static constexpr auto _what = "no_permissions";
constexpr auto what() {
return _what;
}
};
struct success final {
static constexpr auto _what = "success";
constexpr auto what() {
return _what;
}
};
struct too_big final {
static constexpr auto _what = "too_big";
constexpr auto what() {
return _what;
}
};
struct network_down final {
static constexpr auto _what = "network_down";
constexpr auto what() {
return _what;
}
};
struct destination_not_available final {
static constexpr auto _what = "destination_not_available";
constexpr auto what() {
return _what;
}
};
struct insufficient_buffer_space final {
static constexpr auto _what = "insufficient_buffer_space";
constexpr auto what() {
return _what;
}
};
using read_return = gp::fixed_variant<
typename buffer<char>::associated_iterator, // iterator to last element read
bad_file,
faulty_buffer,
interrupted,
io_error,
is_directory,
try_again,
not_connected,
impossible_io,
negative_offset,
is_pipe,
buffer_too_big
>;
using open_return = gp::fixed_variant<
gp_config::file_descriptor_t,
path_not_directory,
name_too_long,
does_not_exist,
may_loop,
is_directory,
invalid_flags,
is_read_only,
fd_limit_reached,
file_limit_reached,
impossible_io,
interrupted,
no_locking,
would_block,
no_space,
no_inodes,
quota_reached,
io_error,
cannot_write_shared_text,
faulty_filename,
exists_already,
is_append_only,
unimplemented_operation,
is_busy,
bad_relative_path,
no_permissions
>;
using close_return = gp::fixed_variant<
success,
bad_file,
interrupted,
io_error
>;
using write_return = gp::fixed_variant<
typename buffer<char>::associated_iterator,
bad_file,
no_space,
quota_reached,
too_big,
interrupted,
io_error,
faulty_buffer,
is_pipe,
try_again,
network_down,
destination_not_available,
impossible_io,
buffer_too_big,
negative_offset,
insufficient_buffer_space
>;
class file_flags{};
class file_permissions{};
private:
struct virtual_fs
{
virtual ~virtual_fs() = default;
virtual open_return open(buffer<char>, file_flags, file_permissions) = 0;
virtual read_return read(gp_config::file_descriptor_t, buffer<char>) = 0;
virtual write_return write(gp_config::file_descriptor_t, buffer<char>, size_t) = 0;
virtual close_return close(gp_config::file_descriptor_t) = 0;
};
template<typename concrete>
class abstract_fs final : public virtual_fs{
concrete internal_representation;
public:
abstract_fs(abstract_fs& v) = delete;
abstract_fs(abstract_fs&& v)
: internal_representation{v.internal_representation}
{}
abstract_fs(concrete& v) = delete;
abstract_fs(concrete&& v)
: internal_representation{v}
{}
virtual ~abstract_fs() override = default;
virtual open_return open(buffer<char> path, file_flags flags, file_permissions perms) override {
return internal_representation.open(path, flags, perms);
}
virtual read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) override {
return internal_representation.read(fd, buff);
}
virtual write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) override {
return internal_representation.write(fd, buff, offset);
}
virtual close_return close(gp_config::file_descriptor_t fd) override {
return internal_representation.close(fd);
}
};
reference_wrapper<aggregator> allocator;
virtual_fs* file_system;
public:
template<typename T>
vfs(T&& v, reference_wrapper<aggregator> _ref)
: allocator{_ref}
, file_system{new(allocator.get().allocate(sizeof(T))) T(gp::move(v))}
{}
open_return open(buffer<char> path, file_flags flags, file_permissions perms) {
return file_system->open(path, flags, perms);
}
read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) {
return file_system->read(fd, buff);
}
write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) {
return file_system->write(fd, buff, offset);
}
close_return close(gp_config::file_descriptor_t fd) {
return file_system->close(fd);
}
~vfs() {
file_system->~virtual_fs();
allocator.get().deallocate(file_system);
}
};
}

+ 22
- 35
include/gp_config.hpp View File

@ -4,46 +4,33 @@
#include <cstdlib>
#include <type_traits>
namespace gp_config{
namespace memory_module{
enum class memory_mode_t{
other,
clib,
buffer,
arena_buffer
};
constexpr memory_mode_t memory_mode = memory_mode_t::clib;
template<memory_mode_t T = memory_mode_t::other>
constexpr void*(*memory_allocator)(std::size_t)=nullptr;
template<memory_mode_t T = memory_mode_t::other>
constexpr void(*memory_deallocator)(void*)=nullptr;
// C Standard library memory usage
template<>
constexpr void*(*memory_allocator<memory_mode_t::clib>)(std::size_t) = malloc;
template<>
constexpr void(*memory_deallocator<memory_mode_t::clib>)(void*) = free;
#ifdef GP_TESTS
class static_mapper;
#else
namespace gp {
class c_allocator;
}
#endif
// Buffer memory usage only
template<>
constexpr void*(*memory_allocator<memory_mode_t::buffer>)(std::size_t) = nullptr;
template<>
constexpr void(*memory_deallocator<memory_mode_t::buffer>)(void*) = nullptr;
namespace gp_config{
namespace rendering {
using default_type = float;
constexpr default_type epsilon = 0.001;
#define GP_CONFIG__RENDERING__COLOR_T vec4
}
// Buffer of arena memory usage
template<>
constexpr void*(*memory_allocator<memory_mode_t::arena_buffer>)(std::size_t) = nullptr;
template<>
constexpr void(*memory_deallocator<memory_mode_t::arena_buffer>)(void*) = nullptr;
namespace memory_module{
#ifdef GP_TESTS
using default_allocator = static_mapper;
#else
using default_allocator = gp::c_allocator;
#endif
constexpr bool is_ok =
( memory_allocator<memory_mode> != nullptr )
&& ( memory_deallocator<memory_mode> != nullptr );
constexpr bool is_ok = true;
}
typedef uint32_t file_descriptor_t;
constexpr bool has_exceptions = true;
constexpr bool has_buffer_bounds = true;

+ 0
- 2
include/indexed_array.hpp View File

@ -1,2 +0,0 @@
#pragma once
// UNIMPLEMENTED: see filename

+ 25
- 20
include/rc6_generic.hpp View File

@ -1,13 +1,14 @@
#pragma once
#include <stdint.h>
#include <iostream>
#include <stddef.h>
#include <gp/integer_math.hpp>
#include <algorithm>
#include <array>
#include <gp/math.hpp>
#include <gp/array.hpp>
#include <gp/algorithm/rotate.hpp>
// BUG: A proper investigation is required to fix this file so that it gives the correct output.
template<typename word_t = uint32_t, size_t r = 20, size_t b = 128, word_t P = 0xb7e15163L, word_t Q = 0x9e3779b9L>
template<typename word_t = uint32_t, size_t r = 20, size_t b = 128, word_t P = 0xb7e15163, word_t Q = 0x9e3779b9>
class RC6 {
static constexpr size_t word_size = 8*sizeof(word_t);
@ -21,17 +22,17 @@ class RC6 {
class RC6_KeySched {
using sched_t = std::array<word_t, 2*r+4>;
using sched_t = gp::array<word_t, 2*r+4>;
public:
static constexpr size_t c = (b+word_size-1)/word_size;
static constexpr size_t v_3 = std::max(c, 2*r+4);
static constexpr size_t v_3 = gp::max(c, 2*r+4);
static constexpr size_t v = v_3*3;
private:
sched_t S;
sched_t S{};
public:
constexpr RC6_KeySched(std::array<word_t, c> L)
constexpr RC6_KeySched(gp::array<word_t, c> L)
{
n">assert(r_l(r_r(13,13),13) == 13);
k">static_assert(r_l(r_r(13,13),13) == 13);
auto it = S.begin();
*(it++) = P;
@ -43,16 +44,20 @@ class RC6 {
word_t B = 0;
word_t i = 0;
word_t j = 0;
for(size_t s = 0; s < v; ++s)
size_t s = 0;
while(true)
{
A = S[i] = r_l( S[i] + A + B, 3 );
B = L[j] = r_l( L[j] + A + B, (A + B)%(word_size));
B += A;
B = L[j] = r_l( L[j] + B, B%(word_size));
++s;
if(s >= v) break;
i = s % S.size();
j = s % L.size();
}
}
const auto cbegin()
{
@ -79,14 +84,14 @@ class RC6 {
public:
typedef std::array<word_t, RC6_KeySched::c> key_type;
typedef std::array<word_t, 4> block_type;
typedef gp::array<word_t, RC6_KeySched::c> key_type;
typedef gp::array<word_t, 4> block_type;
constexpr RC6(const key_type& key)
: S(key)
{}
constexpr block_type encrypt(block_type plaintext) {
constexpr block_type&& encrypt(block_type plaintext) {
using namespace gp::math;
auto& A = plaintext[0];
auto& B = plaintext[1];
@ -104,13 +109,13 @@ public:
auto t = r_l( B * ( 2 * B + 1 ), msb(word_size));
A = r_l((A ^ t), u % word_size) + *(it++);
C = r_l((C ^ u), t % word_size) + *(it++);
std::rotate(plaintext.begin(), plaintext.begin()+1, plaintext.end());
gp::rotate(plaintext.begin(), plaintext.begin()+1, plaintext.end());
}
A += *(it++);
C += *(it++);
assert(it == S.cend());
return plaintext;
return std::move(plaintext);
}
constexpr block_type decrypt(block_type plaintext) {
@ -126,7 +131,7 @@ public:
for(size_t i = 0; i < r; ++i)
{
std::rotate(plaintext.begin(), plaintext.end()-1, plaintext.end());
gp::rotate(plaintext.begin(), plaintext.end()-1, plaintext.end());
auto u = r_l( D * ( 2 * D + 1 ), msb(word_size));
auto t = r_l( B * ( 2 * B + 1 ), msb(word_size));
C = r_r( (C - *(it++)) , t % word_size) ^ u ;
@ -136,7 +141,7 @@ public:
D -= *(it++);
B -= *(it++);
assert(it == S.crend());
return plaintext;
return std::move(plaintext);
}
};

+ 1
- 1
include/stored_indexed_array.hpp View File

@ -1,2 +1,2 @@
#pragma once
// UNIMPLEMENTED: see filename
// UNIMPLEMENTED: see filename

+ 8
- 3
tests.cpp View File

@ -1,4 +1,5 @@
#include "test_scaffold.h"
#include "allocator.hpp"
#include "gp_config.hpp"
#include "meta_test.cpp"
#include "shared_fd.cpp"
@ -6,8 +7,12 @@
#include "gp_test.cpp"
#include "bloomfilter.cpp"
#include "quotient_filter.cpp"
#include "math.cpp"
#include <iostream>
alignas(2048) gp::array<char, 4096> static_mapper::store;
gp::buddy<> static_mapper::impl = gp::buddy<>{store.begin().data, store.size()};
int main()
{
uint failed = 0;
@ -16,13 +21,13 @@ int main()
{
++runned;
int value;
c1">//try{
k">try{
value = test->run();
if(value)
{
std::cout << std::dec << test->name << " failed with "<< value << std::endl;
}
cm">/*} catch (gp::runtime_error err) {
p">} catch (gp::runtime_error err) {
std::cout << test->name << " failed with an exception: " << err.what() << std::endl;
value = -1;
} catch (gp_config::assert_failure err) {
@ -31,7 +36,7 @@ int main()
} catch (...) {
std::cout << test->name << " failed with an exception" << std::endl;
value = -1;
}*/
}
failed += (value != 0);
}
std::cout << std::dec << "Runned "<<runned<<" tests with "<<failed<<" failures" << std::endl;

+ 16
- 0
tests/allocator.hpp View File

@ -0,0 +1,16 @@
#pragma once
#include "gp/allocator/buddy.hpp"
#include "gp/allocator/dummy.hpp"
struct static_mapper {
static gp::array<char, 4096> store;
static gp::buddy<> impl;
void* allocate(size_t sz) {
return impl.allocate(sz);
}
bool deallocate(void* ptr) {
return impl.deallocate(ptr);
}
};

+ 116
- 14
tests/gp_test.cpp View File

@ -1,9 +1,12 @@
#include "test_scaffold.h"
#include "allocator.hpp"
#include "gp/array.hpp"
#include "gp/indexed_array.hpp"
#include "gp/allocator/aggregator.hpp"
#include "gp/allocator/buddy.hpp"
#include "gp/allocator/dummy.hpp"
#include "gp/algorithm/repeat.hpp"
#include "gp/algorithm/rotate.hpp"
#include "gp/ring_list.hpp"
#include <thread>
#include <chrono>
@ -16,6 +19,7 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include "gp/vfs/vfs.hpp"
@ -28,20 +32,6 @@
constexpr bool time_fuzzes = true;
struct static_mapper {
static gp::array<char, 4096> store;
static gp::buddy<> impl;
void* allocate(size_t sz) {
return impl.allocate(sz);
}
bool deallocate(void* ptr) {
return impl.deallocate(ptr);
}
};
alignas(2048) gp::array<char, 4096> static_mapper::store;
gp::buddy<> static_mapper::impl = gp::buddy<>{store.begin().data, store.size()};
struct arraysum_test : public test_scaffold {
arraysum_test() {
@ -430,3 +420,115 @@ struct aggregator_test : public test_scaffold {
};
append_test dummy_8ijfsd658(new aggregator_test{});
struct array_test : public test_scaffold {
array_test() {
name = __FILE__ ":7";
}
virtual int run() {
int res = 0;
gp::array<int, 8> store;
{
int i = 0;
for(auto& p : store)
{
p = i++;
}
for(auto it = store.rbegin(); it != store.rend(); ++it)
{
gp_config::assertion(*it == --i, "array error");
}
for(const auto& p : store)
{
gp_config::assertion(p == i++, "array error");
}
for(auto it = store.crbegin(); it != store.crend(); ++it)
{
gp_config::assertion(*it == --i, "array error");
}
size_t cnt = 0;
for(const auto& p : store)
{
cnt++;
}
gp_config::assertion(cnt == store.size(), "array error");
cnt = 0;
for(auto& p : store)
{
cnt++;
}
gp_config::assertion(cnt == store.size(), "array error");
cnt = 0;
for(auto it = store.crbegin(); it != store.crend(); ++it)
{
cnt++;
}
gp_config::assertion(cnt == store.size(), "array error");
cnt = 0;
for(auto it = store.rbegin(); it != store.rend(); ++it)
{
cnt++;
}
gp_config::assertion(cnt == store.size(), "array error");
gp::rotate(store.begin(), store.begin()+1, store.end());
gp::array<int, 8> rotated({1,2,3,4,5,6,7,0});
gp_config::assertion(store == rotated, "rotate error");
gp::rotate(store.begin(), store.end()-1, store.end());
gp_config::assertion(store[0] == 0, "rotate error");
}
return res;
}
};
append_test dummy_ajcurgsd3(new array_test{});
struct indexed_array_test : public test_scaffold {
indexed_array_test() {
name = __FILE__ ":7";
}
virtual int run() {
int res = 0;
{
gp::indexed_array<int, 8> store;
size_t idx = store.push (112);
store.push (113);
store.push (114);
gp_config::assertion(store[idx] == 112, "Bad value in indexed array");
store.mark_for_removal(idx);
store.sweep_removed();
for(auto& p : store) {
if(p == 112) res++;
}
gp_config::assertion(store.size() == 2, "Bad size of indexed array");
}
{
gp::indexed_array<std::string, 8> store;
size_t idx = store.push ("112");
store.push ("113");
store.push ("114");
gp_config::assertion(store[idx] == "112", "Bad value in indexed array");
store.mark_for_removal(idx);
store.sweep_removed();
for(auto& p : store) {
if(p == "112") res++;
}
gp_config::assertion(store.size() == 2, "Bad size of indexed array");
{
// TODO: write a concrete implementation and test it
// gp::vfs fs;
}
}
return res;
}
};
append_test dummy_khxurgsd3(new indexed_array_test{});

+ 47
- 0
tests/math.cpp View File

@ -0,0 +1,47 @@
#include "test_scaffold.h"
#include "gp/math.hpp"
#include "gp/rendering/renderer.hpp"
#include <cmath>
struct sin_test : public test_scaffold {
sin_test() {
name = __FILE__ ":1";
}
virtual int run() {
int res = 0;
for(float i = 0; i < 100; i += 0.1) {
float v = gp::sin(i);
float ref = sin(i);
res += 0.3 < gp::abs<float>(ref - v)*100.0/(gp::abs(ref+0.00000001));
}
for(float i = 0; i < 100; i += 0.1) {
float v = gp::cos(i);
float ref = cos(i);
res += 0.3 < gp::abs<float>(ref - v)*100.0/(gp::abs(ref+0.00000001));
}
return res;
}
};
append_test dummy_mldffh6f(new sin_test{});
struct render_test : public test_scaffold {
render_test() {
name = __FILE__ ":2";
}
virtual int run() {
int res = 0;
renderer a;
return res;
}
};
append_test dummy_ml8576f(new render_test{});

+ 24
- 55
tests/rc6_generic.cpp View File

@ -10,33 +10,24 @@ struct RC6test : public test_scaffold {
virtual int run() {
using rc = RC6<>;
rc::key_type key = {0,0,0,0};
rc::block_type plaintext = {0,0,0,0};
rc::block_type expected = {0x8fc3a536,0x56b1f778,0xc129df4e,0x9848a41e};
/*
std::cout<<"plain:";
for(auto a : plaintext)
std::cout << std::hex << a;
*/
auto cipher = rc{key};
plaintext = cipher.encrypt(plaintext);
/*std::cout<<"\nkey__:";
for(auto a : key)
std::cout << std::hex << a;
std::cout<<"\nciphe:";
for(auto a : plaintext)
std::cout << std::hex << a;
std::cout<<"\nexpec:";
for(auto a : expected)
std::cout << std::hex << a;
std::cout << std::endl;
*/
return plaintext != expected;
auto res = 0;
{
rc::key_type key = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
rc::block_type plaintext = {0,0,0,0};
rc::block_type expected = {0x8fc3a536,0x56b1f778,0xc129df4e,0x9848a41e};
auto cipher = rc{key};
plaintext = cipher.encrypt(plaintext);
res += plaintext != expected;
}
{
rc::key_type key = {0x80000000, 0x00000000, 0x00000000, 0x00000000};
rc::block_type plaintext = {0,0,0,0};
rc::block_type expected = {0x1AD578A0, 0x2A081628, 0x50A15A15, 0x52A17AD4};
auto cipher = rc{key};
plaintext = cipher.encrypt(plaintext);
res += plaintext != expected;
}
return res;
}
};
@ -50,38 +41,16 @@ struct RC6test2 : public test_scaffold {
virtual int run() {
using rc = RC6<>;
rc::key_type key = {0,0,0,0};
rc::block_type plaintext = {0,0,0,0};
rc::block_type expected = {0,0,0,0};
rc::key_type key{0,0,0,0};
rc::block_type plaintext{0,0,0,0};
rc::block_type expected{0,0,0,0};
/*
std::cout<<"plain:";
for(auto a : plaintext)
std::cout << std::hex << a;
*/
auto cipher = rc{key};
plaintext = cipher.encrypt(plaintext);
/*std::cout<<"\nkey__:";
for(auto a : key)
std::cout << std::hex << a;
std::cout<<"\nciphe:";
for(auto a : plaintext)
std::cout << std::hex << a;
*/
plaintext = cipher.decrypt(plaintext);
auto plaintext2 = cipher.encrypt(plaintext);
/*std::cout<<"\ncidec:";
for(auto a : plaintext)
std::cout << std::hex << a;
auto plaintext3 = cipher.decrypt(plaintext2);
std::cout<<"\nexpec:";
for(auto a : expected)
std::cout << std::hex << a;
std::cout << std::endl;
*/
return plaintext != expected;
return plaintext3 != expected;
}
};

Loading…
Cancel
Save