浏览代码

Allow me to save the weirdest ass bug I ever had

devel
Ludovic 'Archivist' Lagouardette 4 年前
父节点
当前提交
314c1458d8
共有 2 个文件被更改,包括 69 次插入44 次删除
  1. +64
    -39
      include/gp/function.hpp
  2. +5
    -5
      tests/math.cpp

+ 64
- 39
include/gp/function.hpp 查看文件

@ -1,6 +1,7 @@
#pragma once
#include "gp/exception.hpp"
#include "gp/algorithm/tmp_manip.hpp"
#include "gp/algorithm/move.hpp"
namespace gp{
template <typename>
@ -10,21 +11,24 @@ namespace gp{
class function<ret(args...)>{
struct virtual_callable
{
virtual void inplace_copy(char*) = 0;
virtual void inplace_move(char*) = 0;
virtual virtual_callable* all_copy() = 0;
virtual void inplace_copy(char*) = 0;
virtual virtual_callable* all_move() = 0;
virtual ~virtual_callable() = default;
virtual ret operator() (args...) = 0;
};
template<typename fn>
class callable : public virtual_callable{
fn internal_representation;
class callable k">final : public virtual_callable{
k">typename gp::remove_reference<fn>::type internal_representation;
public:
callable(const fn& func)
: internal_representation{func}
callable(const fn func)
: internal_representation{gp::move(func)}
{}
callable(callable&) = default;
callable(callable&&) = default;
virtual ~callable() override = default;
@ -36,6 +40,14 @@ namespace gp{
return new callable(*this);
}
virtual void inplace_move(char* ptr) override {
new(ptr) callable(gp::move(*this));
}
virtual virtual_callable* all_move() override {
return new callable(gp::move(*this));
}
ret operator() (args... arg_list) override
{
return internal_representation(arg_list...);
@ -94,46 +106,59 @@ namespace gp{
}
template <typename T>
function(T t)
functiono"><>(T& t)
{
if constexpr (sizeof(callable<T>) <= sizeof(self))
{
new((void*)self.inplace) callable<T>(t);
state = (state_t)(ACTIVE | SOO);
}
else
{
self.functor = new callable<T>(t);
state = (state_t)(ACTIVE | NO_SOO);
}
}
template<>
function<function>(function& t) {
if(t.state & SOO)
{
t.self.functor->inplace_copy(self.inplace);
state = (state_t)(ACTIVE | SOO);
}
else
{
self.functor = t.self.functor->all_copy();
state = (state_t)(ACTIVE | NO_SOO);
if constexpr (!std::is_same_v<T, function>) {
if constexpr (sizeof(callable<T>) <= sizeof(self))
{
new((void*)self.inplace) callable<T>(t);
state = (state_t)(ACTIVE | SOO);
}
else
{
self.functor = new callable<T>(t);
state = (state_t)(ACTIVE | NO_SOO);
}
} else {
if(t.state & SOO)
{
t.self.functor->inplace_copy(self.inplace);
state = (state_t)(ACTIVE | SOO);
}
else
{
self.functor = t.self.functor->all_copy();
state = (state_t)(ACTIVE | NO_SOO);
}
}
}
template <typename T>
function(T& t)
function(T&& t)
{
if constexpr (sizeof(callable<T>) <= sizeof(self))
{
new((void*)&self) callable<T>(t);
state = (state_t)(ACTIVE | SOO);
}
else
{
self.functor = new callable<T>(t);
state = (state_t)(ACTIVE | NO_SOO);
if constexpr (!std::is_same_v<T, function>) {
if constexpr (sizeof(callable<T>) <= sizeof(self))
{
new((void*)self.inplace) callable<T>(gp::move(t));
state = (state_t)(ACTIVE | SOO);
}
else
{
self.functor = new callable<T>(gp::move(t));
state = (state_t)(ACTIVE | NO_SOO);
}
} else {
if(t.state & SOO)
{
auto& ref = t.self.functor;
ref->inplace_move((char*)&self);
state = (state_t)(ACTIVE | SOO);
}
else
{
self.functor = t.self.functor->all_move();
state = (state_t)(ACTIVE | NO_SOO);
}
}
}

+ 5
- 5
tests/math.cpp 查看文件

@ -156,12 +156,12 @@ struct function_test : public test_scaffold {
virtual int run() {
int res = 0;
gp::function<float(vec3)> l_sdf_b = gp::sphere_sdf<float>({0.0,0.0,0.0}, 1.0);
gp::function<float(vec3)> sdf = l_sdf_b;
gp_config::assertion(sdf(vec3(0,0,0)) == -1, "Bad sdf");
gp::function<float(vec3)> l_sdf_b{gp::sphere_sdf<float>({0.0,0.0,0.0}, 1.0)};
{
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");
}
return res;
}
};

正在加载...
取消
保存