From 2c6dea516af3d70180b54c3fc7738641138f60a9 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Mon, 4 May 2020 23:07:28 +0200 Subject: [PATCH] vfs and rendering scaffolds --- Makefile | 4 +- include/gp/algorithm/foreach.hpp | 20 ++ include/gp/algorithm/min_max.hpp | 12 +- include/gp/algorithm/min_of.hpp | 26 ++ include/gp/algorithm/rotate.hpp | 26 ++ include/gp/algorithm/tmp_manip.hpp | 2 +- include/gp/allocator/buddy.hpp | 2 +- include/gp/array.hpp | 90 +++++- include/gp/function.hpp | 31 +- include/gp/indexed_array.hpp | 130 +++++++++ include/gp/iterator.hpp | 137 +++++++-- include/gp/math.hpp | 167 +++++++++++ include/gp/math/fp_math.hpp | 196 +++++++++++++ include/gp/{ => math}/integer_math.hpp | 0 include/gp/math/q_math.hpp | 0 include/gp/optional.hpp | 52 +++- include/gp/rendering/renderer.hpp | 76 +++++ include/gp/variant.hpp | 41 ++- include/gp/vfs/vfs.hpp | 385 +++++++++++++++++++++++++ include/gp_config.hpp | 57 ++-- include/indexed_array.hpp | 2 - include/rc6_generic.hpp | 45 +-- include/stored_indexed_array.hpp | 2 +- tests.cpp | 11 +- tests/allocator.hpp | 16 + tests/gp_test.cpp | 130 ++++++++- tests/math.cpp | 47 +++ tests/rc6_generic.cpp | 79 ++--- 28 files changed, 1569 insertions(+), 217 deletions(-) create mode 100644 include/gp/algorithm/foreach.hpp create mode 100644 include/gp/algorithm/min_of.hpp create mode 100644 include/gp/algorithm/rotate.hpp create mode 100644 include/gp/indexed_array.hpp create mode 100644 include/gp/math.hpp create mode 100644 include/gp/math/fp_math.hpp rename include/gp/{ => math}/integer_math.hpp (100%) create mode 100644 include/gp/math/q_math.hpp create mode 100644 include/gp/rendering/renderer.hpp create mode 100644 include/gp/vfs/vfs.hpp delete mode 100644 include/indexed_array.hpp create mode 100644 tests/allocator.hpp create mode 100644 tests/math.cpp diff --git a/Makefile b/Makefile index 5e8d9e0..e2a1064 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/include/gp/algorithm/foreach.hpp b/include/gp/algorithm/foreach.hpp new file mode 100644 index 0000000..7b5f482 --- /dev/null +++ b/include/gp/algorithm/foreach.hpp @@ -0,0 +1,20 @@ +#pragma once +#include + +namespace gp{ + template + void indexed_foreach(range n, F f) { + for(size_t idx = 0; idx < n.size(); ++idx) + { + f(idx, n[idx]); + } + } + + template + void foreach(range n, F f) { + for(auto& elem : n) + { + f(elem); + } + } +} \ No newline at end of file diff --git a/include/gp/algorithm/min_max.hpp b/include/gp/algorithm/min_max.hpp index 6bfb560..51b5c54 100644 --- a/include/gp/algorithm/min_max.hpp +++ b/include/gp/algorithm/min_max.hpp @@ -27,6 +27,8 @@ namespace gp{ } } + + template constexpr T clamp(T first, T value, T last) { @@ -34,4 +36,12 @@ namespace gp{ if(value > last) return last; return value; } -} \ No newline at end of file +} + + + + + + + + diff --git a/include/gp/algorithm/min_of.hpp b/include/gp/algorithm/min_of.hpp new file mode 100644 index 0000000..9892052 --- /dev/null +++ b/include/gp/algorithm/min_of.hpp @@ -0,0 +1,26 @@ +#pragma once +#include "gp_config.hpp" +#include "gp/algorithm/move.hpp" + +namespace gp{ + + template + T identity(T v){return v;} + template + T& identity(T& v){return v;} + + template + 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); + } +} \ No newline at end of file diff --git a/include/gp/algorithm/rotate.hpp b/include/gp/algorithm/rotate.hpp new file mode 100644 index 0000000..3bc105d --- /dev/null +++ b/include/gp/algorithm/rotate.hpp @@ -0,0 +1,26 @@ +#pragma once +#include "gp/algorithm/move.hpp" + +namespace gp { + template + 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; + } + +} \ No newline at end of file diff --git a/include/gp/algorithm/tmp_manip.hpp b/include/gp/algorithm/tmp_manip.hpp index 80af38f..cfde14b 100644 --- a/include/gp/algorithm/tmp_manip.hpp +++ b/include/gp/algorithm/tmp_manip.hpp @@ -109,7 +109,7 @@ namespace gp{ else { return max_size< - either< + typename either< ( sizeof(T) > sizeof(U) ), T, U diff --git a/include/gp/allocator/buddy.hpp b/include/gp/allocator/buddy.hpp index 05e9820..a9799c8 100644 --- a/include/gp/allocator/buddy.hpp +++ b/include/gp/allocator/buddy.hpp @@ -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 #include #include diff --git a/include/gp/array.hpp b/include/gp/array.hpp index 8d56c2b..ce09add 100644 --- a/include/gp/array.hpp +++ b/include/gp/array.hpp @@ -5,28 +5,74 @@ namespace gp{ template class array{ - T ary[sz]; public: - using associated_iterator = pointer_iterator; - using associated_const_iterator = pointer_iterator; + T ary[sz]; + using associated_iterator = pointer_iterator; + using associated_const_iterator = const_pointer_iterator; + using associated_riterator = pointer_iterator; + using associated_const_riterator = const_pointer_iterator; 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 - array(U&& ...v) - : ary{gp::forward(v...)} + array(U&& ...values) + : ary{gp::move((T&&)values)...} {} + array(array&& values) + { + gp::move_uninitialized( + values, + *this + ); + } + + template<> + array(T (& oth)[sz]) { + gp::move_uninitialized( + gp::nameless_range(oth, oth+sz), + gp::nameless_range(begin(), end()) + ); + } + template<> array(T (&& oth)[sz]) { gp::move_uninitialized( gp::nameless_range(oth, oth+sz), - gp::nameless_range(*this) + gp::nameless_range(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 begin() { return associated_iterator(&ary[0]); } - constexpr associated_iterator end() + constexpr pointer_iterator end() { return associated_iterator(&ary[sz]); } - constexpr associated_const_iterator cbegin() const + constexpr const_pointer_iterator cbegin() const + { + return associated_const_iterator(&ary[0]); + } + + constexpr const_pointer_iterator cend() const + { + return associated_const_iterator(&ary[sz]); + } + + constexpr pointer_iterator rbegin() + { + return associated_riterator(&ary[sz-1]); + } + + constexpr pointer_iterator rend() + { + return associated_riterator(ary-1); + } + + constexpr const_pointer_iterator crbegin() const { - return ary; + return associated_const_riterator(&ary[sz-1]); } - constexpr associated_const_iterator cend() const + constexpr const_pointer_iterator crend() const { - return ary+sz; + return associated_const_riterator(ary-1); } constexpr bool operator==(const array& oth) const diff --git a/include/gp/function.hpp b/include/gp/function.hpp index 059f068..1a38cc9 100644 --- a/include/gp/function.hpp +++ b/include/gp/function.hpp @@ -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) <= sizeof(self)) { new((void*)&self) callable(t); - state = ACTIVE | SOO; + state = (state_t)(ACTIVE | SOO); } else { self = new callable(t); - state = ACTIVE | NO_SOO; + state = (state_t)(ACTIVE | NO_SOO); } } + function() + { + state = INACTIVE; + } + template function(T t) { if constexpr (sizeof(callable) <= sizeof(self)) { - new((void*)&self) callable(t); - state = ACTIVE | SOO; + new((void*)&self) callable(t); + state = (state_t)(ACTIVE | SOO); } else { - self = new callable(t); - state = ACTIVE | NO_SOO; + self = new callable(t); + state = (state_t)(ACTIVE | NO_SOO); } } @@ -90,13 +95,13 @@ namespace gp{ { if constexpr (sizeof(callable) <= sizeof(self)) { - new((void*)&self) callable(t); - state = ACTIVE | SOO; + new((void*)&self) callable(t); + state = (state_t)(ACTIVE | SOO); } else { - self = new callable(t); - state = ACTIVE | NO_SOO; + self = new callable(t); + state = (state_t)(ACTIVE | NO_SOO); } } diff --git a/include/gp/indexed_array.hpp b/include/gp/indexed_array.hpp new file mode 100644 index 0000000..8d8874a --- /dev/null +++ b/include/gp/indexed_array.hpp @@ -0,0 +1,130 @@ +#pragma once +#include +#include "gp_config.hpp" +#include "gp/algorithm/move.hpp" +#include "gp/iterator.hpp" +namespace gp{ + template + 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 begin() + { + return data_table; + } + + pointer_iterator end() + { + return data_table+data_top; + } + + const_pointer_iterator cbegin() + { + return data_table; + } + + const_pointer_iterator 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]]; + } + }; +} \ No newline at end of file diff --git a/include/gp/iterator.hpp b/include/gp/iterator.hpp index 9e2dc49..1f66b69 100644 --- a/include/gp/iterator.hpp +++ b/include/gp/iterator.hpp @@ -8,7 +8,7 @@ enum class iterator_type_t{ lazy_iterator }; -template +template struct pointer_iterator final { T* data; @@ -24,76 +24,171 @@ struct pointer_iterator final : data{ptr} {} - constexpr operator T&() + constexpr 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(data) <= reinterpret_cast(oth.data); + } + + constexpr bool operator<=(const pointer_iterator oth) + { + return before_or_equal(oth); + } +}; + +template +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(data) <= reinterpret_cast(oth.data); } - constexpr bool operator<=(const pointer_iterator& oth) + constexpr bool operator<=(const const_pointer_iterator oth) { return before_or_equal(oth); } diff --git a/include/gp/math.hpp b/include/gp/math.hpp new file mode 100644 index 0000000..6aa2bef --- /dev/null +++ b/include/gp/math.hpp @@ -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 + 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 + 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 left, T right) + : x{left.x} + , y{left.y} + , z{right} + {} + + vec3_g(T left, vec2_g 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 + 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 + vec2_g operator*(vec2_g p, T v) { + return {p.x*v, p.y*v}; + } + + template + vec3_g operator*(vec3_g p, T v) { + return {p.x*v, p.y*v, p.z*v}; + } + + template + vec4_g operator*(vec4_g p, T v) { + return {p.x*v, p.y*v, p.z*v, p.w*v}; + } + + template + vec2_g operator*(T v, vec2_g p) { + return p*v; + } + + template + vec3_g operator*(T v, vec3_g p) { + return p*v; + } + + template + vec4_g operator*(T v, vec4_g p) { + return p*v; + } +} \ No newline at end of file diff --git a/include/gp/math/fp_math.hpp b/include/gp/math/fp_math.hpp new file mode 100644 index 0000000..a021b93 --- /dev/null +++ b/include/gp/math/fp_math.hpp @@ -0,0 +1,196 @@ +#pragma once +#include +#include +#include +#include "gp/algorithm/repeat.hpp" + +namespace gp{ + + template + constexpr T pi; + + template<> + constexpr float pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; + + template<> + constexpr double pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; + + template + T abs(T); + + template<> + float abs(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 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 + T floor(T); + + template<> + float floor(float value) { + static_assert(sizeof(float) == 4, "bad float size"); + if( + value >= std::numeric_limits::max() + || value <= std::numeric_limits::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 value) { + static_assert(sizeof(double) == 8, "bad double size"); + if( + value >= std::numeric_limits::max() + || value <= std::numeric_limits::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 + T sign(T); + + template<> + float sign(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 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 + 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; + v = v - 2*pi*floor(v/(2*pi)); + v -= pi; + float s = sign(v); + v *= s; + return sin_taylor<10>(v)*s; + } + + double sin(double v) { + v += pi; + v = v - 2*pi*floor(v/(2*pi)); + v -= pi; + 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/2); + } + + // TODO: replace with an actual implementation + double cos(double v) { + return sin(v+pi/2); + } + + template + 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 + 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);} +} diff --git a/include/gp/integer_math.hpp b/include/gp/math/integer_math.hpp similarity index 100% rename from include/gp/integer_math.hpp rename to include/gp/math/integer_math.hpp diff --git a/include/gp/math/q_math.hpp b/include/gp/math/q_math.hpp new file mode 100644 index 0000000..e69de29 diff --git a/include/gp/optional.hpp b/include/gp/optional.hpp index 8864d29..c8eb4cc 100644 --- a/include/gp/optional.hpp +++ b/include/gp/optional.hpp @@ -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::value || std::is_fundamental::value> + template< + typename T, + typename allocator = gp_config::memory_module::default_allocator, + bool copy_allocator = false, + bool B = std::is_final::value || std::is_fundamental::value + > class optional; - template - class optional{ + template + class optional{ bool ready = false; char buffer[sizeof(T)]; + typename gp::either< + copy_allocator, + allocator, + gp::reference_wrapper + >::type alloc; public: - constexpr optional() + constexpr optional(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 - class optional{ + template + class optional{ bool ready = false; T* ptr; + typename gp::either< + copy_allocator, + allocator, + gp::reference_wrapper + >::type alloc; public: - constexpr optional() + constexpr optional(allocator p = allocator{}) : ready{false} + , alloc(p) {} - constexpr optional(nullopt_t) + constexpr optional(nullopt_t, allocator p = allocator{}) : ready{false} + , alloc(p) {} template - constexpr optional(U& value) + constexpr optional(U& value, allocator p = allocator{}) : ready{true} + , alloc(p) { ptr = new U(value); // TODO: Use allocators } template - constexpr optional(U&& value) + constexpr optional(U&& value, allocator p = allocator{}) : ready{true} + , alloc(p) { ptr = new U(gp::move(value)); // TODO: Use allocators } diff --git a/include/gp/rendering/renderer.hpp b/include/gp/rendering/renderer.hpp new file mode 100644 index 0000000..5c22cca --- /dev/null +++ b/include/gp/rendering/renderer.hpp @@ -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; +using material_t = gp::function; + +class renderer { + using g_t = gp_config::rendering::default_type; + constexpr static auto epsilon = gp_config::rendering::epsilon; +public: + gp::indexed_array scene_elements; + gp::indexed_array 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); + } +}; \ No newline at end of file diff --git a/include/gp/variant.hpp b/include/gp/variant.hpp index e8ab05e..05a30f3 100644 --- a/include/gp/variant.hpp +++ b/include/gp/variant.hpp @@ -10,17 +10,15 @@ namespace gp{ - template< typename Enable, typename ...T> - class variant; - template - class variant::value,int>::type, T...>{ + class fixed_variant{ std::size_t index = std::numeric_limits::max(); - char buffer[max_size]; + char buffer[max_size()]; gp::function dtor = [](void*){}; + static_assert(all_of_fixed_size::value, "not fixed"); public: template::value,int>::type> - constexpr variant(U& value) + constexpr fixed_variant(U& value) : index{r_index_of::value} { new(buffer) U(value); @@ -28,7 +26,7 @@ namespace gp{ } template::value,int>::type> - constexpr variant(U&& value) + constexpr fixed_variant(U&& value) : index{r_index_of::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::max()) { @@ -96,26 +94,27 @@ namespace gp{ } }; - template - class variant>::type, T...>{ + template + class variant{ std::size_t index = std::numeric_limits::max(); void* ptr; gp::function dtor = [](void*){}; + allocator_t allocator; public: template::value,int>::type> constexpr variant(U& value) : index{r_index_of::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::value,int>::type> constexpr variant(U&& value) : index{r_index_of::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::value,int>::type> @@ -124,11 +123,11 @@ namespace gp{ if(index != std::numeric_limits::max()) { dtor(ptr); - default_memory_allocator<>{}.deallocate(ptr); + allocator.deallocate(ptr); } index = r_index_of::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::value,int>::type> @@ -137,11 +136,11 @@ namespace gp{ if(index != std::numeric_limits::max()) { dtor(ptr); - default_memory_allocator<>{}.deallocate(ptr); + allocator.deallocate(ptr); } index = r_index_of::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::max()) { dtor(ptr); - default_memory_allocator<>{}.deallocate(ptr); + allocator.deallocate(ptr); } } diff --git a/include/gp/vfs/vfs.hpp b/include/gp/vfs/vfs.hpp new file mode 100644 index 0000000..7088a2f --- /dev/null +++ b/include/gp/vfs/vfs.hpp @@ -0,0 +1,385 @@ +#pragma once + +#include +#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::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::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, file_flags, file_permissions) = 0; + virtual read_return read(gp_config::file_descriptor_t, buffer) = 0; + virtual write_return write(gp_config::file_descriptor_t, buffer, size_t) = 0; + virtual close_return close(gp_config::file_descriptor_t) = 0; + }; + + template + 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 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 buff) override { + return internal_representation.read(fd, buff); + } + + virtual write_return write(gp_config::file_descriptor_t fd, buffer 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 allocator; + virtual_fs* file_system; + + public: + template + vfs(T&& v, reference_wrapper _ref) + : allocator{_ref} + , file_system{new(allocator.get().allocate(sizeof(T))) T(gp::move(v))} + {} + + open_return open(buffer path, file_flags flags, file_permissions perms) { + return file_system->open(path, flags, perms); + } + + + read_return read(gp_config::file_descriptor_t fd, buffer buff) { + return file_system->read(fd, buff); + } + + write_return write(gp_config::file_descriptor_t fd, buffer 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); + } + }; +} \ No newline at end of file diff --git a/include/gp_config.hpp b/include/gp_config.hpp index f5b7c0b..54cb9fb 100644 --- a/include/gp_config.hpp +++ b/include/gp_config.hpp @@ -4,46 +4,33 @@ #include #include -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 - constexpr void*(*memory_allocator)(std::size_t)=nullptr; - template - constexpr void(*memory_deallocator)(void*)=nullptr; - - // C Standard library memory usage - template<> - constexpr void*(*memory_allocator)(std::size_t) = malloc; - template<> - constexpr void(*memory_deallocator)(void*) = free; +#ifdef GP_TESTS + class static_mapper; +#else +namespace gp { + class c_allocator; +} +#endif - // Buffer memory usage only - template<> - constexpr void*(*memory_allocator)(std::size_t) = nullptr; - template<> - constexpr void(*memory_deallocator)(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)(std::size_t) = nullptr; - template<> - constexpr void(*memory_deallocator)(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 != nullptr ) - && ( memory_deallocator != nullptr ); + constexpr bool is_ok = true; } + typedef uint32_t file_descriptor_t; + constexpr bool has_exceptions = true; constexpr bool has_buffer_bounds = true; diff --git a/include/indexed_array.hpp b/include/indexed_array.hpp deleted file mode 100644 index b394313..0000000 --- a/include/indexed_array.hpp +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -// UNIMPLEMENTED: see filename \ No newline at end of file diff --git a/include/rc6_generic.hpp b/include/rc6_generic.hpp index b265b7b..2d6e4fd 100644 --- a/include/rc6_generic.hpp +++ b/include/rc6_generic.hpp @@ -1,13 +1,14 @@ #pragma once #include +#include #include -#include -#include -#include +#include +#include +#include // BUG: A proper investigation is required to fix this file so that it gives the correct output. -template +template 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; + using sched_t = gp::array; 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 L) + constexpr RC6_KeySched(gp::array L) { - assert(r_l(r_r(13,13),13) == 13); + 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 key_type; - typedef std::array block_type; + typedef gp::array key_type; + typedef gp::array 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); } }; \ No newline at end of file diff --git a/include/stored_indexed_array.hpp b/include/stored_indexed_array.hpp index b394313..d92606f 100644 --- a/include/stored_indexed_array.hpp +++ b/include/stored_indexed_array.hpp @@ -1,2 +1,2 @@ #pragma once -// UNIMPLEMENTED: see filename \ No newline at end of file +// UNIMPLEMENTED: see filename diff --git a/tests.cpp b/tests.cpp index e039d15..57d0db5 100644 --- a/tests.cpp +++ b/tests.cpp @@ -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 +alignas(2048) gp::array 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; - //try{ + try{ value = test->run(); if(value) { std::cout << std::dec << test->name << " failed with "<< value << std::endl; } - /*} catch (gp::runtime_error err) { + } 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 "< store; + static gp::buddy<> impl; + + void* allocate(size_t sz) { + return impl.allocate(sz); + } + + bool deallocate(void* ptr) { + return impl.deallocate(ptr); + } +}; \ No newline at end of file diff --git a/tests/gp_test.cpp b/tests/gp_test.cpp index 12ea7f4..7df025c 100644 --- a/tests/gp_test.cpp +++ b/tests/gp_test.cpp @@ -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 #include @@ -16,6 +19,7 @@ #include #include #include +#include "gp/vfs/vfs.hpp" @@ -28,20 +32,6 @@ constexpr bool time_fuzzes = true; -struct static_mapper { - static gp::array 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 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 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 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 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 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{}); \ No newline at end of file diff --git a/tests/math.cpp b/tests/math.cpp new file mode 100644 index 0000000..56098ed --- /dev/null +++ b/tests/math.cpp @@ -0,0 +1,47 @@ +#include "test_scaffold.h" +#include "gp/math.hpp" +#include "gp/rendering/renderer.hpp" +#include + + +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(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(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{}); \ No newline at end of file diff --git a/tests/rc6_generic.cpp b/tests/rc6_generic.cpp index f25b53e..9113f86 100644 --- a/tests/rc6_generic.cpp +++ b/tests/rc6_generic.cpp @@ -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; } };