diff --git a/Makefile b/Makefile index 8efacb6..ff986fc 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ CXX= clang++-8 CXXFLAGS= --std=c++17 -O0 -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -pedantic -Werror \ -Wno-unknown-attributes -frtti \ - -g -fprofile-instr-generate -fcoverage-mapping -# -fsanitize=address -fno-omit-frame-pointer + -g -fprofile-instr-generate -fcoverage-mapping \ + -fsanitize=address -fno-omit-frame-pointer all: tests tests: bin/tests diff --git a/include/gp/function.hpp b/include/gp/function.hpp index 5ca6172..08efa3e 100644 --- a/include/gp/function.hpp +++ b/include/gp/function.hpp @@ -1,6 +1,6 @@ #pragma once #include "gp/exception.hpp" - +#include "gp/algorithm/tmp_manip.hpp" namespace gp{ template @@ -10,6 +10,8 @@ namespace gp{ class function{ struct virtual_callable { + virtual void inplace_copy(char*) = 0; + virtual virtual_callable* all_copy() = 0; virtual ~virtual_callable() = default; virtual ret operator() (args...) = 0; }; @@ -22,8 +24,18 @@ namespace gp{ : internal_representation{func} {} + callable(callable&) = default; + virtual ~callable() override = default; + virtual void inplace_copy(char* ptr) override { + new(ptr) callable(*this); + } + + virtual virtual_callable* all_copy() override { + return new callable(*this); + } + ret operator() (args... arg_list) override { return internal_representation(arg_list...); @@ -59,16 +71,21 @@ namespace gp{ delete self.functor; } } - if constexpr (sizeof(callable) <= sizeof(self)) - { - new((void*)self.inplace) callable(t); - state = (state_t)(ACTIVE | SOO); - } - else + if(t.state | ACTIVE) { - self.functor = new callable(t); - state = (state_t)(ACTIVE | NO_SOO); + if constexpr (sizeof(callable) <= sizeof(self)) + { + 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); + } + return; } + state = INACTIVE; } function() @@ -91,6 +108,20 @@ namespace gp{ } } + template<> + 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); + } + } + template function(T& t) {