Просмотр исходного кода

Allocators are now polymorphic

cbor
Ludovic 'Archivist' Lagouardette 4 лет назад
Родитель
Сommit
5e9a41293d
13 измененных файлов: 146 добавлений и 298 удалений
  1. +14
    -46
      include/gp/allocator/aggregator.hpp
  2. +15
    -0
      include/gp/allocator/allocator.hpp
  3. +22
    -20
      include/gp/allocator/arena.hpp
  4. +17
    -12
      include/gp/allocator/buddy.hpp
  5. +6
    -4
      include/gp/allocator/dummy.hpp
  6. +12
    -16
      include/gp/function.hpp
  7. +7
    -145
      include/gp/optional.hpp
  8. +2
    -2
      include/gp/rendering/bmp_viewport.hpp
  9. +2
    -2
      include/gp/rendering/renderer.hpp
  10. +7
    -15
      include/gp/ring_list.hpp
  11. +3
    -3
      tests.cpp
  12. +36
    -30
      tests/gp_test.cpp
  13. +3
    -3
      tests/math.cpp

+ 14
- 46
include/gp/allocator/aggregator.hpp Просмотреть файл

@ -1,73 +1,41 @@
#pragma once
#include "gp/ring_list.hpp"
#include "gp/allocator/allocator.hpp"
#include <stddef.h>
namespace gp {
class aggregator {
struct virtual_allocator
{
virtual ~virtual_allocator() = default;
virtual void* allocate(size_t) = 0;
virtual bool deallocate(void*) = 0;
virtual bool try_reallocate(void*, size_t) = 0;
};
template<typename alloc>
class abstract_allocator final : public virtual_allocator{
alloc internal_representation;
public:
abstract_allocator(abstract_allocator& v)
: internal_representation{v.internal_representation}
{}
abstract_allocator(alloc& v)
: internal_representation{v}
{}
virtual ~abstract_allocator() override = default;
virtual void* allocate(size_t sz) override {
return internal_representation.allocate(sz);
}
virtual bool deallocate(void* ptr) override {
return internal_representation.deallocate(ptr);
}
virtual bool try_reallocate(void* ptr, size_t sz) override {
return internal_representation.try_reallocate(ptr, sz);
}
};
using local_container = ring_list<virtual_allocator, aggregator, false, true>;
class aggregator : public allocator {
using local_container = ring_list<allocator, true>;
local_container contents;
local_container::explorer mark;
public:
template<typename bootstrapper>
aggregator(bootstrapper&& allocator)
aggregator(bootstrapper&& allocator_v)
: contents{
new(allocator.allocate(sizeof(local_container::node)))
new(allocator_v.allocate(sizeof(local_container::node)))
local_container::node(
new(allocator.allocate(sizeof(bootstrapper))) abstract_allocator(allocator)
new(allocator_v.allocate(sizeof(bootstrapper))) std::remove_reference_t<bootstrapper>(gp::forward<bootstrapper&&>(allocator_v))
),
*this
}
, mark{contents.explore()}
{}
template<typename allocator>
bool insert(allocator&& value) {
template<typename s_allocator>
bool insert(s_allocator&& value) {
return contents.insert<
abstract_allocator<
std::remove_reference_t<
allocator
>
std::remove_reference_t<
s_allocator
>
>(abstract_allocator(value));
>(gp::forward<s_allocator>(value));
}
void* allocate(size_t sz) {
virtual void* allocate(size_t sz) {
auto cpy = mark;
do{
if(auto allocated = (*mark).allocate(sz))
@ -78,7 +46,7 @@ namespace gp {
}while(cpy != mark);
return nullptr;
}
bool deallocate(void* ptr) {
">virtual bool deallocate(void* ptr) {
auto cpy = mark;
do{
if((*cpy).deallocate(ptr))
@ -89,7 +57,7 @@ namespace gp {
}while(cpy != mark);
return false;
}
bool try_reallocate(void* ptr, size_t sz) {
">virtual bool try_reallocate(void* ptr, size_t sz) {
auto cpy = mark;
do{
if((*cpy).try_reallocate(ptr, sz))

+ 15
- 0
include/gp/allocator/allocator.hpp Просмотреть файл

@ -0,0 +1,15 @@
#pragma once
#include <stddef.h>
namespace gp {
struct allocator{
virtual void* allocate(size_t) = 0;
virtual bool deallocate(void*) = 0;
virtual bool try_reallocate(void*, size_t) = 0;
virtual ~allocator() = default;
};
}

+ 22
- 20
include/gp/allocator/arena.hpp Просмотреть файл

@ -6,16 +6,16 @@
#include "gp/algorithm/tmp_manip.hpp"
#include "gp/buffer.hpp"
#include "gp/math/integer_math.hpp"
#include "gp/allocator/allocator.hpp"
#include <type_traits>
namespace gp {
template<typename page_allocator = int>
class arena {
page_allocator allocator;
gp::buffer<char> data;
class arena : public allocator {
gp::optional<gp::reference_wrapper<allocator>> allocator_v;
size_t next;
size_t count;
gp::buffer<char> data;
public:
arena()
: next(0)
@ -23,31 +23,33 @@ namespace gp {
, data(gp::buffer<char>(nullptr,nullptr))
{}
arena(size_t sz)
: next(0)
arena(allocator& allocator_p, size_t sz)
: allocator_v(allocator_p)
, next(0)
, count(0)
, data(nullptr,nullptr)
{
if constexpr (gp::has_allocator_interface<page_allocator>::value)
if(sz != 0)
{
if(sz!=0)
auto v = allocator_v.value().get().allocate(sz);
if(v != nullptr)
{
auto v=allocator.allocate(sz);
if(v!=nullptr)
{
data=gp::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz);
}
data=gp::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz);
}
}
}
arena(char* pos,size_t sz)
arena(char* pos, size_t sz)
: next(0)
, count(0)
, data(pos,pos+sz)
{}
void* allocate(size_t sz)
void reset() {
next = count = 0;
}
virtual void* allocate(size_t sz)
{
size_t align = gp::min((1 << gp::math::log2(sz)), 16);
size_t padding = align - (reinterpret_cast<uintptr_t>(data.begin().data + next)) % align;
@ -65,11 +67,11 @@ namespace gp {
}
}
constexpr bool try_reallocate(void*, size_t) {
virtual bool try_reallocate(void*, size_t) {
return false;
}
bool deallocate(void* ptr)
">virtual bool deallocate(void* ptr)
{
if(data.contains((char*)ptr))
{
@ -87,11 +89,11 @@ namespace gp {
return false;
}
~arena()
k">virtual ~arena()
{
if constexpr(gp::has_allocator_interface<page_allocator>::value)
if(allocator_v.has_value())
{
allocator.deallocate(&data[0]);
allocator_v.value().get().deallocate(&data[0]);
}
}
};

+ 17
- 12
include/gp/allocator/buddy.hpp Просмотреть файл

@ -8,13 +8,14 @@
#include "gp/array.hpp"
#include "gp/buffer.hpp"
#include "gp/math/integer_math.hpp"
#include "gp/allocator/allocator.hpp"
#include <type_traits>
namespace gp{
template<k">typename page_allocator = gp::dummy_allocator, size_t max_msb = 24, size_t align = 8>
class buddy{
template<size_t max_msb = 24, size_t align = 8>
class buddy : public allocator {
struct twig {
bool used : 1;
bool used_children : 1;
@ -37,7 +38,7 @@ namespace gp{
a = 0; b = 0; c = 0; d = 0;
}
};
page_allocator allocator;
gppan>::optional<gp::reference_wrapper<allocator>> allocator_v;
gp::buffer<char> data;
const size_t max_depth;
const size_t twig_explore_length;
@ -212,14 +213,15 @@ namespace gp{
, twig_explore_length(1 << max_depth)
{}
buddy(size_t sz)
: data(nullptr,nullptr)
buddy(size_t sz, allocator& allocator_p)
: allocator_v(allocator_p)
, data(nullptr,nullptr)
, max_depth(gp::math::msb(sz)-gp::math::msb(align))
, twig_explore_length(1 << max_depth)
{
if(sz!=0 && (sz & (sz - 1)) == 0)
{
auto v=allocator.allocate(sz);
auto v=allocator_v.value().get().allocate(sz);
if(v!=nullptr)
{
if((reinterpret_cast<intptr_t>(v) % align) ==0)
@ -228,7 +230,7 @@ namespace gp{
}
else
{
allocator.deallocate(v);
allocator_v.value().get().deallocate(v);
}
}
}
@ -241,7 +243,7 @@ namespace gp{
{
}
void* allocate(size_t sz)
">virtual void* allocate(size_t sz)
{
auto depth = size_to_depth(sz);
auto index = find_free_twig(depth);
@ -271,11 +273,11 @@ namespace gp{
return pot;
}
constexpr bool try_reallocate(void*, size_t) {
virtual bool try_reallocate(void*, size_t) {
return false;
}
bool deallocate(void* ptr)
">virtual bool deallocate(void* ptr)
{
if(data.contains((char*)ptr))
{
@ -308,9 +310,12 @@ namespace gp{
return empty_node(addr, 0) && !is_any_child(0, pred);
}
~buddy()
k">virtual ~buddy()
{
allocator.deallocate(data.begin().data);
if(allocator_v.has_value())
{
allocator_v.value().get().deallocate(data.begin().data);
}
}
};
}

+ 6
- 4
include/gp/allocator/dummy.hpp Просмотреть файл

@ -1,21 +1,23 @@
#pragma once
#include <stddef.h>
#include "gp/allocator/allocator.hpp"
namespace gp {
struct dummy_allocator{
void* allocate(size_t)
struct dummy_allocator : public allocator {
">virtual void* allocate(size_t)
{
return nullptr;
}
bool deallocate(void*)
">virtual bool deallocate(void*)
{
return false;
}
constexpr bool try_reallocate(void*, size_t) {
virtual bool try_reallocate(void*, size_t) {
return false;
}
virtual ~dummy_allocator() = default;
};
}

+ 12
- 16
include/gp/function.hpp Просмотреть файл

@ -4,24 +4,20 @@
#include "gp/algorithm/modifiers.hpp"
#include "gp/algorithm/move.hpp"
#include "gp/algorithm/tmp_manip.hpp"
#include "gp/allocator/allocator.hpp"
namespace gp{
template <typename fnp">, typename allocator, bool copy_allocator = false>
template <typename fn>
class function;
template <typename ret, typename n">allocator, bool copy_allocator, typename ...args>
class function<ret(args...)p">, allocator, copy_allocator>{
template <typename ret, typename ...args>
class function<ret(args...)>{
using fn_ptr = char*;
using invoke_fn_t = ret (*)(fn_ptr, args&&...);
using condestruct_fn_t = void (*) (fn_ptr, fn_ptr);
using allocator_t = typename gp::either<
copy_allocator,
allocator,
gp::reference_wrapper<allocator>
>::type;
allocator_t alloc;
gp::reference_wrapper<allocator> alloc;
invoke_fn_t invokator;
condestruct_fn_t condestructor;
fn_ptr data_ptr;
@ -51,9 +47,9 @@ namespace gp{
#pragma clang diagnostic ignored "-Wnull-dereference"
#pragma gcc diagnostic push
#pragma gcc diagnostic ignored "-Wnull-dereference"
function(allocator_t alloc_v = gp::reference_wrapper<allocator_t>{*reinterpret_cast<allocator_t*>(0)})
function(allocator& alloc_v)
#pragma gcc pop
#pragma clang pop
#pragma clang diagnostic pop
: alloc(alloc_v)
, invokator(nullptr)
, condestructor(nullptr)
@ -62,11 +58,11 @@ namespace gp{
{}
template<typename func>
function(func f, allocator_t alloc_v)
function(func f, allocator& alloc_v)
: alloc(alloc_v)
, invokator(reinterpret_cast<invoke_fn_t>(invoke<func>))
, condestructor(reinterpret_cast<condestruct_fn_t>(condestruct<func>))
, data_ptr((char*)(p">(allocator&)alloc).allocate(sizeof(func)))
, data_ptr((char*)(n">alloc.get().allocate(sizeof(func))))
, data_size(sizeof(func))
{
gp_config::assertion(data_ptr != nullptr, "allocator failed in function");
@ -77,7 +73,7 @@ namespace gp{
: alloc(rhs.alloc)
, invokator(rhs.invokator)
, condestructor(rhs.condestructor)
, data_ptr(rhs.data_size != 0 ? (char*)(p">(allocator&)alloc).allocate(rhs.data_size) : nullptr)
, data_ptr(rhs.data_size != 0 ? (char*)(n">alloc.get().allocate(rhs.data_size)) : nullptr)
, data_size(rhs.data_size)
{
gp_config::assertion(data_ptr != nullptr, "allocator failed in function");
@ -97,7 +93,7 @@ namespace gp{
rhs.data_ptr = nullptr;
}
constexpr f">function(ret(*fn)(args...), allocator_t alloc_v = allocator_t{})
constexpr function(ret(*fn)(args...), allocator alloc_v)
: alloc(alloc_v)
, invokator(reinterpret_cast<invoke_fn_t>(invoke<ret(args...)>))
, condestructor(nop_condestruct)
@ -111,7 +107,7 @@ namespace gp{
}
if(data_ptr != nullptr) {
condestructor(nullptr, data_ptr);
p">((allocator&)alloc).deallocate(data_ptr);
n">alloc.get().deallocate(data_ptr);
data_ptr = nullptr;
}
}

+ 7
- 145
include/gp/optional.hpp Просмотреть файл

@ -7,50 +7,34 @@
#include "gp/exception.hpp"
#include <type_traits>
#include <new>
namespace gp{
struct nullopt_t{};
constexpr nullopt_t nullopt;
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, typename allocator, bool copy_allocator>
class optional<T, allocator, copy_allocator, true>{
template<typename T>
class optional{
bool ready = false;
char buffer[sizeof(T)];
typename gp::either<
copy_allocator,
allocator,
gp::reference_wrapper<allocator>
>::type alloc;
public:
constexpr optional(n">allocator p = allocator{})
constexpr optional()
: ready{false}
, alloc(p)
{}
constexpr optional(nullopt_t, allocator p = allocator{})
constexpr optional(nullopt_t)
: ready{false}
, alloc(p)
{}
constexpr optional(T& value, allocator p = allocator{})
constexpr optional(T& value)
: ready{true}
, alloc(p)
{
new(buffer) T(value);
}
constexpr optional(T&& value, allocator p = allocator{})
constexpr optional(T&& value)
: ready{true}
, alloc(p)
{
new(buffer) T(gp::move(value));
}
@ -103,126 +87,4 @@ namespace gp{
return *reinterpret_cast<T*>(buffer);
}
};
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(allocator p = allocator{})
: ready{false}
, alloc(p)
{}
constexpr optional(nullopt_t, allocator p = allocator{})
: ready{false}
, alloc(p)
{}
template<typename U>
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, allocator p = allocator{})
: ready{true}
, alloc(p)
{
ptr = new U(gp::move(value)); // TODO: Use allocators
}
optional& operator=(nullopt_t) {
if(ready) {
delete ptr;
ready = false;
}
return *this;
}
template<typename U>
optional& operator=(U& value) {
if(ready) {
if constexpr (std::is_same_v<T, U>) {
*ptr = value;
} else {
delete ptr; // TODO: Use allocators
ptr = new U(value); // TODO: Use allocators
}
} else {
ready = true;
ptr = new U(value); // TODO: Use allocators
}
return *this;
}
optional& operator=(optional&& value){
if(ready) {
delete ptr; // TODO: Use allocators
}
if(value.ready) {
ptr = value.ptr;
value.ready = false;
ready = true;
return *this;
} else {
ready = false;
return *this;
}
}
template<typename U>
optional& operator=(U&& value) {
if(ready) {
if constexpr (std::is_same_v<T, U>) {
*ptr = gp::move(value);
} else {
delete ptr; // TODO: Use allocators
ptr = new U(gp::move(value)); // TODO: Use allocators
}
} else {
ready = true;
ptr = new U(gp::move(value)); // TODO: Use allocators
}
return *this;
}
operator T&() {
gp_config::assertion(ready, "bad optional access");
return *ptr;
}
constexpr bool has_value()
{
return ready;
}
constexpr T& value()
{
if constexpr (gp_config::has_exceptions)
{
if(!ready)
{
throw bad_optional{};
}
} else {
gp_config::assertion(ready, "bad optional access");
}
return *ptr;
}
~optional() {
if(ready) {
delete ptr; // TODO: Use allocators
}
}
};
}

+ 2
- 2
include/gp/rendering/bmp_viewport.hpp Просмотреть файл

@ -10,11 +10,11 @@
#include <iostream>
namespace gp{
template<bool lazy, typename color_typep">, typename allocator>
template<bool lazy, typename color_type>
class bmp_viewport {
public:
using src_t = typename gp::either<lazy,
gp::function<color_type(gp::vec2_g<int32_t>)p">, allocator>,
gp::function<color_type(gp::vec2_g<int32_t>)>,
gp::buffer<gp::buffer<color_type>>
>::type;
private:

+ 2
- 2
include/gp/rendering/renderer.hpp Просмотреть файл

@ -30,8 +30,8 @@ struct render_point{
}
};
using sdf_t = gp::function<render_point(vec3&)p">, gp::buddy<>>;
using material_t = gp::function<color_t(vec3&)p">, gp::buddy<>>;
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;

+ 7
- 15
include/gp/ring_list.hpp Просмотреть файл

@ -4,11 +4,13 @@
#include "gp/algorithm/modifiers.hpp"
#include "gp/algorithm/tmp_manip.hpp"
#include "gp/allocator/allocator.hpp"
#include "gp/allocator/dummy.hpp"
#include <stddef.h>
namespace gp {
template<typename T, ">typename allocator, bool copy_allocator = false, bool may_contain_self = false>
template<typename T, bool may_contain_self = false>
class ring_list{
public:
class explorer;
@ -23,8 +25,8 @@ namespace gp {
, next{this}
{}
friend class gp::ring_list<T, allocator, copy_allocator, may_contain_self>::explorer;
friend class gp::ring_list<T, allocator, copy_allocator, may_contain_self>;
friend class gp::ring_list<T, may_contain_self>::explorer;
friend class gp::ring_list<T, may_contain_self>;
};
class explorer {
@ -74,11 +76,7 @@ namespace gp {
private:
node* any_node;
size_t sz;
typename gp::either<
copy_allocator,
allocator,
gp::reference_wrapper<allocator>
>::type alloc;
gp::reference_wrapper<allocator> alloc;
void stitch_around(node* n) {
n->prev->next = n->next;
@ -86,12 +84,6 @@ namespace gp {
}
public:
ring_list()
: any_node{nullptr}
, sz{0}
, alloc{}
{}
ring_list(node* initial, allocator& _alloc)
: any_node{initial}
, sz{1}
@ -134,6 +126,7 @@ namespace gp {
}
void remove(explorer value) {
allocator& used_allocator = alloc;
auto v = value.pos;
if(v == any_node) {
if(v->next == v) {
@ -145,7 +138,6 @@ namespace gp {
} else {
stitch_around(v);
}
allocator& used_allocator = alloc;
v->value->~T();
gp_config::assertion(used_allocator.deallocate(v->value), "Bad free of value");
v->~node();

+ 3
- 3
tests.cpp Просмотреть файл

@ -22,13 +22,13 @@ int main()
{
++runned;
int value;
k">try{
cm">/*try{*/
value = test->run();
if(value)
{
std::cout << std::dec << test->name << " failed with "<< value << std::endl;
}
p">} catch (gp::runtime_error err) {
cm">/*} 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) {
@ -37,7 +37,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;

+ 36
- 30
tests/gp_test.cpp Просмотреть файл

@ -120,11 +120,14 @@ struct buddy_test : public test_scaffold {
gp::repeat(10, [&](){
gp::array<char, 4096> store;
{
gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> dum_bud{store.size()};
gp::buddy<static_mapper> inner_bud{2048};
gp::dummy_allocator dummyall;
static_assert(gp::math::msb<uint64_t>(8) == 3);
static_assert(gp::math::msb<uint64_t>(127) == 7);
static_assert(gp::math::msb<uint64_t>(4096) == 12);
gp::buddy<gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
gp::buddy<gp::math::msb<uint64_t>(4096)> dum_bud{store.size(), dummyall};
{
gp::buddy<> inner_bud{2048, bud};
gp_config::assertion(!dummyall.try_reallocate(nullptr, 0), "reallocation works wut?");
gp_config::assertion(!bud.try_reallocate(nullptr, 0), "reallocation works wut?");
gp_config::assertion(!inner_bud.try_reallocate(nullptr, 0), "reallocation works wut?");
@ -133,7 +136,10 @@ struct buddy_test : public test_scaffold {
{
void* v = inner_bud.allocate(16);
gp_config::assertion(!inner_bud.empty(), "allocator should have elements");
if(v == nullptr) throw gp::runtime_error("allocation failed");
if(v == nullptr)
{
throw gp::runtime_error("allocation failed");
}
ptr_set.insert(v);
}
bool wut = ptr_set.count(nullptr)!=0 || ptr_set.size()!=(2048/16);
@ -250,7 +256,7 @@ struct buddy_fuzz_test : public test_scaffold {
virtual int run() {
int res = 0;
alignas(8) gp::array<char, 4096> store;
gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
gp::buddy<gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
std::vector<void*> ptr_set;
auto get_random_mem_qt = [&]() -> size_t {
return 1+rng()%(store.size()-1);
@ -342,10 +348,10 @@ struct ring_list_test : public test_scaffold {
virtual int run() {
int res = 0;
alignas(8) gp::array<char, 4096> store;
using local_allocator = gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)>;
using local_allocator = gp::buddy<gp::math::msb<uint64_t>(4096)>;
local_allocator bud{&*store.begin(), store.size()};
{
using string_ring = gp::ring_list<std::stringp">, local_allocator, false>;
using string_ring = gp::ring_list<std::string>;
auto p = new(bud.allocate(sizeof(std::string))) std::string("Hello");
auto orig = new(bud.allocate(sizeof(string_ring::node))) string_ring::node(p);
string_ring ring{orig, bud};
@ -377,12 +383,12 @@ struct aggregator_test : public test_scaffold {
virtual int run() {
int res = 0;
alignas(8) gp::array<char, 4096> store;
using local_allocator = gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)>;
using local_allocator = gp::buddy<gp::math::msb<uint64_t>(4096)>;
local_allocator bud{&*store.begin(), store.size()};
alignas(8) gp::array<char, 4096> store2;
local_allocator bud2{&*store2.begin(), store2.size()};
gp::aggregator allocator{bud};
gp::aggregator allocator(bud);
allocator.insert(bud2);
{
std::vector<void*> ptr_set;
@ -423,28 +429,28 @@ struct aggregator_test : public test_scaffold {
gp_config::assertion(allocator.deallocate(nullptr) == false, "error, could free an invalid pointer");
allocator.deallocate(a);
{
gp::ring_list<intp">, gp::aggregator, false> list{allocator};
gp::ring_list<int> list{allocator};
list.insert(8);
list.insert(16);
list.insert(32);
}
{
gp::array<char, 256> work_array;
gp::arena<> alloc_work(work_array.begin().data, work_array.size());
gp::ring_list<intp">, gp::arena<>, false> list{alloc_work};
gp::arena alloc_work(work_array.begin().data, work_array.size());
gp::ring_list<int> list{alloc_work};
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
}
{
gp::array<char, sizeof(int)> once_array;
gp::arena<> alloc_once(once_array.begin().data, once_array.size());
gp::ring_list<intp">, gp::arena<>, false> list{alloc_once};
gp::arena alloc_once(once_array.begin().data, once_array.size());
gp::ring_list<int> list{alloc_once};
gp_config::assertion(list.insert(8) == false, "could allocate in list with insufficient allocator");
}
{
gp::arena<> alloc_none(nullptr, 0);
gp::ring_list<intp">, gp::arena<>, false> list{alloc_none};
gp::arena alloc_none(nullptr, 0);
gp::ring_list<int> list{alloc_none};
gp_config::assertion(list.insert(8) == false, "could allocate in list with fake allocator");
}
return res;
@ -699,7 +705,7 @@ struct alloc_bench_test : public test_scaffold {
if(do_bench) {
auto store = std::make_unique<std::array<char, 1 << 16>>();
using buddy_loc = gp::buddy<>;
using arena_loc = gp::arenao"><>;
using arena_loc = gp::arena;
buddy_loc bud{&*store->begin(), store->size()};
arena_loc are{&*store->begin(), store->size()};
@ -707,13 +713,13 @@ struct alloc_bench_test : public test_scaffold {
for(size_t divider = 2; divider < 32; ++divider)
{
gp::ring_list<intp">, buddy_loc> a{bud};
gp::ring_list<intp">, arena_loc> b{are};
gp::ring_list<int> a{bud};
gp::ring_list<int> b{are};
std::cout <<
"ARE | " << "INS | " << divider << " | " <<
time_operation([&](){
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<intp">, arena_loc>::node)/divider; i++) {
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
b.insert(i);
}
}).count() << std::endl;
@ -721,8 +727,8 @@ struct alloc_bench_test : public test_scaffold {
std::cout <<
"ARE | " << "DEL | " << divider << " | " <<
time_operation([&](){
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<intp">, arena_loc>::node)/divider; i++) {
gp::ring_list<intp">, arena_loc>::explorer e = b.explore();
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
gp::ring_list<int>::explorer e = b.explore();
b.remove(e);
}
}).count() << std::endl;
@ -730,7 +736,7 @@ struct alloc_bench_test : public test_scaffold {
std::cout <<
"BUD | " << "INS | " << divider << " | " <<
time_operation([&](){
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<intp">, buddy_loc>::node)/divider; i++) {
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
a.insert(i);
}
}).count() << std::endl;
@ -738,22 +744,22 @@ struct alloc_bench_test : public test_scaffold {
std::cout <<
"BUD | " << "DEL | " << divider << " | " <<
time_operation([&](){
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<intp">, buddy_loc>::node)/divider; i++) {
gp::ring_list<intp">, buddy_loc>::explorer e = a.explore();
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
gp::ring_list<int>::explorer e = a.explore();
a.remove(e);
}
}).count() << std::endl;
}
{
gp::ring_list<intp">, buddy_loc> a{bud};
gp::ring_list<intp">, arena_loc> b{are};
gp::ring_list<int> a{bud};
gp::ring_list<int> b{are};
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<intp">, buddy_loc>::node)/2; i++) {
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/2; i++) {
a.insert(i);
}
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<intp">, buddy_loc>::node)/2; i++) {
gp::ring_list<intp">, buddy_loc>::explorer e = a.explore();
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/2; i++) {
gp::ring_list<int>::explorer e = a.explore();
a.remove(++e);
}
}

+ 3
- 3
tests/math.cpp Просмотреть файл

@ -112,7 +112,7 @@ struct render_test : public test_scaffold {
a._camera.normal = vec3{0, 0, 1};
using pic_color = gp::vec4_g<uint8_t>;
using viewport = gp::bmp_viewport<true, pic_colorp">, gp::buddy<>>;
using viewport = gp::bmp_viewport<true, pic_color>;
viewport vp{
{128,64},
@ -168,9 +168,9 @@ struct function_test : public test_scaffold {
gp::array<char, 2048> allocation_buffer;
gp::buddy<> allocator{allocation_buffer.begin().data, allocation_buffer.size()};
gp::function<float(vec3)p">, gp::buddy<>> l_sdf_b{gp::sphere_sdf<float>({0.0,0.0,0.0}, 1.0), allocator};
gp::function<float(vec3)> l_sdf_b{gp::sphere_sdf<float>({0.0,0.0,0.0}, 1.0), allocator};
{
gp::function<float(vec3)p">, gp::buddy<>> sdf{l_sdf_b};
gp::function<float(vec3)> sdf{l_sdf_b};
gp_config::assertion(l_sdf_b(vec3(0,0,0)) == -1 && sdf(vec3(0,0,0)) == -1, "Bad sdf");
}

Загрузка…
Отмена
Сохранить