diff options
author | Alec Thomas <alec@swapoff.org> | 2018-06-15 17:41:17 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-15 17:41:17 +1000 |
commit | 1b0a2fba5902056e17543d527e3e6891472d1770 (patch) | |
tree | 0b228af1128646f1c1554ed7ede07a17c65fc1cd | |
parent | 97a47c4f8f13f6be791991b4f3e3e83e5a3c797a (diff) |
Revert "Fix minor memory leak from simplesignal.h and inside pool_test.cc"
-rw-r--r-- | entityx/3rdparty/simplesignal.h | 675 | ||||
-rw-r--r-- | entityx/help/Pool_test.cc | 2 |
2 files changed, 480 insertions, 197 deletions
diff --git a/entityx/3rdparty/simplesignal.h b/entityx/3rdparty/simplesignal.h index d9c8e72..3c60273 100644 --- a/entityx/3rdparty/simplesignal.h +++ b/entityx/3rdparty/simplesignal.h @@ -1,295 +1,580 @@ // CC0 Public Domain: http://creativecommons.org/publicdomain/zero/1.0/ -#pragma once +#ifndef SIMPLE_SIGNAL_H__ +#define SIMPLE_SIGNAL_H__ -#include <unistd.h> #include <assert.h> #include <stdint.h> -#include <functional> #include <vector> +#include <functional> namespace Simple { namespace Lib { /// ProtoSignal is the template implementation for callback list. -template<typename,typename> class ProtoSignal; // undefined +template <typename, typename> +class ProtoSignal; // undefined -/// CollectorInvocation invokes signal handlers differently depending on return type. -template<typename,typename> struct CollectorInvocation; +/// CollectorInvocation invokes signal handlers differently depending on return +/// type. +template <typename, typename> +struct CollectorInvocation; -/// CollectorLast returns the result of the last signal handler from a signal emission. -template<typename Result> +/// CollectorLast returns the result of the last signal handler from a signal +/// emission. +template <typename Result> struct CollectorLast { - using CollectorResult = Result; - explicit CollectorLast () : last_() {} - inline bool operator() (Result r) { last_ = r; return true; } - CollectorResult result () { return last_; } -private: + typedef Result CollectorResult; + explicit CollectorLast() : last_() {} + inline bool operator()(Result r) { + last_ = r; + return true; + } + CollectorResult result() { return last_; } + + private: Result last_; }; /// CollectorDefault implements the default signal handler collection behaviour. -template<typename Result> -struct CollectorDefault : CollectorLast<Result> -{}; +template <typename Result> +struct CollectorDefault : CollectorLast<Result> {}; /// CollectorDefault specialisation for signals with void return type. -template<> +template <> struct CollectorDefault<void> { - using CollectorResult = void; - void result () {} - inline bool operator() (void) { return true; } + typedef void CollectorResult; + void result() {} + inline bool operator()(void) { return true; } }; /// CollectorInvocation specialisation for regular signals. -template<class Collector, class R, class... Args> -struct CollectorInvocation<Collector, R (Args...)> { - inline bool - invoke (Collector &collector, const std::function<R (Args...)> &cbf, Args... args) - { - return collector (cbf (args...)); +template <class Collector, class R, class... Args> +struct CollectorInvocation<Collector, R(Args...)> { + inline bool invoke(Collector &collector, const std::function<R(Args...)> &cbf, + Args... args) { + return collector(cbf(args...)); } }; /// CollectorInvocation specialisation for signals with void return type. -template<class Collector, class... Args> -struct CollectorInvocation<Collector, void (Args...)> { - inline bool - invoke (Collector &collector, const std::function<void (Args...)> &cbf, Args... args) - { - cbf (args...); return collector(); +template <class Collector, class... Args> +struct CollectorInvocation<Collector, void(Args...)> { + inline bool invoke(Collector &collector, + const std::function<void(Args...)> &cbf, Args... args) { + cbf(args...); + return collector(); } }; /// ProtoSignal template specialised for the callback signature and collector. -template<class Collector, class R, class... Args> -class ProtoSignal<R (Args...), Collector> : private CollectorInvocation<Collector, R (Args...)> { -protected: - using CbFunction = std::function<R (Args...)>; - using Result = typename CbFunction::result_type; - using CollectorResult = typename Collector::CollectorResult; -private: - /// SignalLink implements a doubly-linked ring with ref-counted nodes containing the signal handlers. +template <class Collector, class R, class... Args> +class ProtoSignal<R(Args...), Collector> : private CollectorInvocation< + Collector, R(Args...)> { + protected: + typedef std::function<R(Args...)> CbFunction; + typedef typename CbFunction::result_type Result; + typedef typename Collector::CollectorResult CollectorResult; + + private: + /// SignalLink implements a doubly-linked ring with ref-counted nodes + /// containing the signal handlers. struct SignalLink { SignalLink *next, *prev; - CbFunction function; - int ref_count; - explicit SignalLink (const CbFunction &cbf) : next (nullptr), prev (nullptr), function (cbf), ref_count (1) {} - /*dtor*/ ~SignalLink () { assert (ref_count == 0); } - void incref () { ref_count += 1; assert (ref_count > 0); } - void decref () { ref_count -= 1; if (!ref_count) delete this; else assert (ref_count > 0); } - void - unlink () - { + CbFunction function; + int ref_count; + explicit SignalLink(const CbFunction &cbf) + : next(0), prev(0), function(cbf), ref_count(1) {} + /*dtor*/ ~SignalLink() { assert(ref_count == 0); } + void incref() { + ref_count += 1; + assert(ref_count > 0); + } + void decref() { + ref_count -= 1; + if (!ref_count) + delete this; + else + assert(ref_count > 0); + } + void unlink() { function = nullptr; - if (next) - next->prev = prev; - if (prev) - prev->next = next; + if (next) next->prev = prev; + if (prev) prev->next = next; decref(); // leave intact ->next, ->prev for stale iterators } - size_t - add_before (const CbFunction &cb) - { - SignalLink *link = new SignalLink (cb); - link->prev = prev; // link to last + size_t add_before(const CbFunction &cb) { + SignalLink *link = new SignalLink(cb); + link->prev = prev; // link to last link->next = this; - prev->next = link; // link from last + prev->next = link; // link from last prev = link; - static_assert (sizeof (link) == sizeof (size_t), "sizeof size_t"); - return size_t (link); + static_assert(sizeof(link) == sizeof(size_t), "sizeof size_t"); + return size_t(link); + } + bool deactivate(const CbFunction &cbf) { + if (cbf == function) { + function = 0; // deactivate static head + return true; + } + for (SignalLink *link = this->next ? this->next : this; link != this; + link = link->next) + if (cbf == link->function) { + link->unlink(); // deactivate and unlink sibling + return true; + } + return false; } - bool - remove_sibling (size_t id) - { - for (SignalLink *link = this->next ? this->next : this; link != this; link = link->next) - if (id == size_t (link)) - { - link->unlink(); // deactivate and unlink sibling - return true; - } + bool remove_sibling(size_t id) { + for (SignalLink *link = this->next ? this->next : this; link != this; + link = link->next) + if (id == size_t(link)) { + link->unlink(); // deactivate and unlink sibling + return true; + } return false; } }; - SignalLink *callback_ring_; // linked ring of callback nodes - /*copy-ctor*/ ProtoSignal (const ProtoSignal&) = delete; - ProtoSignal& operator= (const ProtoSignal&) = delete; - void - ensure_ring () - { - if (!callback_ring_) - { - callback_ring_ = new SignalLink (CbFunction()); // ref_count = 1 - callback_ring_->incref(); // ref_count = 2, head of ring, can be deactivated but not removed - callback_ring_->next = callback_ring_; // ring head initialization - callback_ring_->prev = callback_ring_; // ring tail initialization - } + SignalLink *callback_ring_; // linked ring of callback nodes + /*copy-ctor*/ ProtoSignal(const ProtoSignal &) = delete; + ProtoSignal &operator=(const ProtoSignal &) = delete; + void ensure_ring() { + if (!callback_ring_) { + callback_ring_ = new SignalLink(CbFunction()); // ref_count = 1 + callback_ring_->incref(); // ref_count = 2, head of ring, can be + // deactivated but not removed + callback_ring_->next = callback_ring_; // ring head initialization + callback_ring_->prev = callback_ring_; // ring tail initialization + } } -public: - /// ProtoSignal constructor, connects default callback if non-nullptr. - ProtoSignal (const CbFunction &method) : - callback_ring_ (nullptr) - { - if (method != nullptr) - { - ensure_ring(); - callback_ring_->function = method; - } + + public: + /// ProtoSignal constructor, connects default callback if non-0. + ProtoSignal(const CbFunction &method) : callback_ring_(0) { + if (method != 0) { + ensure_ring(); + callback_ring_->function = method; + } } /// ProtoSignal destructor releases all resources associated with this signal. - ~ProtoSignal () - { - if (callback_ring_) - { - while (callback_ring_->next != callback_ring_) - callback_ring_->next->unlink(); - assert (callback_ring_->ref_count >= 2); - callback_ring_->decref(); - callback_ring_->decref(); - } + ~ProtoSignal() { + if (callback_ring_) { + while (callback_ring_->next != callback_ring_) + callback_ring_->next->unlink(); + assert(callback_ring_->ref_count >= 2); + callback_ring_->decref(); + callback_ring_->decref(); + } + } + /// Operator to add a new function or lambda as signal handler, returns a + /// handler connection ID. + size_t connect(const CbFunction &cb) { + ensure_ring(); + return callback_ring_->add_before(cb); } - /// Operator to add a new function or lambda as signal handler, returns a handler connection ID. - size_t connect (const CbFunction &cb) { ensure_ring(); return callback_ring_->add_before (cb); } - /// Operator to remove a signal handler through it connection ID, returns if a handler was removed. - bool disconnect (size_t connection) { return callback_ring_ ? callback_ring_->remove_sibling (connection) : false; } - /// Emit a signal, i.e. invoke all its callbacks and collect return types with the Collector. - CollectorResult - emit (Args... args) - { + /// Operator to remove a signal handler through it connection ID, returns if a + /// handler was removed. + bool disconnect(size_t connection) { + return callback_ring_ ? callback_ring_->remove_sibling(connection) : false; + } + /// Emit a signal, i.e. invoke all its callbacks and collect return types with + /// the Collector. + CollectorResult emit(Args... args) { Collector collector; - if (!callback_ring_) - return collector.result(); + if (!callback_ring_) return collector.result(); SignalLink *link = callback_ring_; link->incref(); - do - { - if (link->function != nullptr) - { - const bool continue_emission = this->invoke (collector, link->function, args...); - if (!continue_emission) - break; - } - SignalLink *old = link; - link = old->next; - link->incref(); - old->decref(); + do { + if (link->function != 0) { + const bool continue_emission = + this->invoke(collector, link->function, args...); + if (!continue_emission) break; } - while (link != callback_ring_); + SignalLink *old = link; + link = old->next; + link->incref(); + old->decref(); + } while (link != callback_ring_); link->decref(); return collector.result(); } // Number of connected slots. - int - size () - { - int size = 0; + std::size_t size() { + std::size_t size = 0; SignalLink *link = callback_ring_; link->incref(); - do - { - if (link->function != 0) - { - size++; - } - SignalLink *old = link; - link = old->next; - link->incref(); - old->decref(); + do { + if (link->function != 0) { + size++; } - while (link != callback_ring_); - link->decref(); + SignalLink *old = link; + link = old->next; + link->incref(); + old->decref(); + } while (link != callback_ring_); return size; } }; -} // Lib -// namespace Simple +} // Lib + // namespace Simple /** - * Signal is a template type providing an interface for arbitrary callback lists. - * A signal type needs to be declared with the function signature of its callbacks, + * Signal is a template type providing an interface for arbitrary callback + * lists. + * A signal type needs to be declared with the function signature of its + * callbacks, * and optionally a return result collector class type. - * Signal callbacks can be added with operator+= to a signal and removed with operator-=, using + * Signal callbacks can be added with operator+= to a signal and removed with + * operator-=, using * a callback connection ID return by operator+= as argument. - * The callbacks of a signal are invoked with the emit() method and arguments according to the signature. - * The result returned by emit() depends on the signal collector class. By default, the result of - * the last callback is returned from emit(). Collectors can be implemented to accumulate callback + * The callbacks of a signal are invoked with the emit() method and arguments + * according to the signature. + * The result returned by emit() depends on the signal collector class. By + * default, the result of + * the last callback is returned from emit(). Collectors can be implemented to + * accumulate callback * results or to halt a running emissions in correspondance to callback results. - * The signal implementation is safe against recursion, so callbacks may be removed and + * The signal implementation is safe against recursion, so callbacks may be + * removed and * added during a signal emission and recursive emit() calls are also safe. - * The overhead of an unused signal is intentionally kept very low, around the size of a single pointer. + * The overhead of an unused signal is intentionally kept very low, around the + * size of a single pointer. * Note that the Signal template types is non-copyable. */ -template <typename SignalSignature, class Collector = Lib::CollectorDefault<typename std::function<SignalSignature>::result_type> > -struct Signal /*final*/ : - Lib::ProtoSignal<SignalSignature, Collector> -{ - using ProtoSignal = Lib::ProtoSignal<SignalSignature, Collector>; - using CbFunction = typename ProtoSignal::CbFunction; +template <typename SignalSignature, + class Collector = Lib::CollectorDefault< + typename std::function<SignalSignature>::result_type>> +struct Signal /*final*/ : Lib::ProtoSignal<SignalSignature, Collector> { + typedef Lib::ProtoSignal<SignalSignature, Collector> ProtoSignal; + typedef typename ProtoSignal::CbFunction CbFunction; /// Signal constructor, supports a default callback as argument. - Signal (const CbFunction &method = CbFunction()) : ProtoSignal (method) {} + Signal(const CbFunction &method = CbFunction()) : ProtoSignal(method) {} }; -/// This function creates a std::function by binding @a object to the member function pointer @a method. -template<class Instance, class Class, class R, class... Args> std::function<R (Args...)> -slot (Instance &object, R (Class::*method) (Args...)) -{ - return [&object, method] (Args... args) { return (object .* method) (args...); }; +/// This function creates a std::function by binding @a object to the member +/// function pointer @a method. +template <class Instance, class Class, class R, class... Args> +std::function<R(Args...)> slot(Instance &object, R (Class::*method)(Args...)) { + return [&object, method](Args... args) { return (object.*method)(args...); }; } -/// This function creates a std::function by binding @a object to the member function pointer @a method. -template<class Class, class R, class... Args> std::function<R (Args...)> -slot (Class *object, R (Class::*method) (Args...)) -{ - return [object, method] (Args... args) { return (object ->* method) (args...); }; +/// This function creates a std::function by binding @a object to the member +/// function pointer @a method. +template <class Class, class R, class... Args> +std::function<R(Args...)> slot(Class *object, R (Class::*method)(Args...)) { + return [object, method](Args... args) { return (object->*method)(args...); }; } /// Keep signal emissions going while all handlers return !0 (true). -template<typename Result> +template <typename Result> struct CollectorUntil0 { - using CollectorResult = Result; - explicit CollectorUntil0 () : result_() {} - const CollectorResult& result () { return result_; } - inline bool - operator() (Result r) - { + typedef Result CollectorResult; + explicit CollectorUntil0() : result_() {} + const CollectorResult &result() { return result_; } + inline bool operator()(Result r) { result_ = r; return result_ ? true : false; } -private: + + private: CollectorResult result_; }; /// Keep signal emissions going while all handlers return 0 (false). -template<typename Result> +template <typename Result> struct CollectorWhile0 { - using CollectorResult = Result; - explicit CollectorWhile0 () : result_() {} - const CollectorResult& result () { return result_; } - inline bool - operator() (Result r) - { + typedef Result CollectorResult; + explicit CollectorWhile0() : result_() {} + const CollectorResult &result() { return result_; } + inline bool operator()(Result r) { result_ = r; return result_ ? false : true; } -private: + + private: CollectorResult result_; }; -/// CollectorVector returns the result of the all signal handlers from a signal emission in a std::vector. -template<typename Result> +/// CollectorVector returns the result of the all signal handlers from a signal +/// emission in a std::vector. +template <typename Result> struct CollectorVector { - using CollectorResult = std::vector<Result>; - const CollectorResult& result () { return result_; } - inline bool - operator() (Result r) - { - result_.push_back (r); + typedef std::vector<Result> CollectorResult; + const CollectorResult &result() { return result_; } + inline bool operator()(Result r) { + result_.push_back(r); return true; } -private: + + private: CollectorResult result_; }; -} // Simple +} // Simple + +#endif // SIMPLE_SIGNAL_H__ + +#ifdef ENABLE_SIMPLE_SIGNAL_TESTS + +#include <string> +#include <stdarg.h> +#include <time.h> +#include <sys/time.h> + +#ifdef __MACH__ +#include <mach/clock.h> +#include <mach/mach.h> +#endif + +static std::string string_printf(const char *format, ...) + __attribute__((__format__(__printf__, 1, 2))); +static std::string string_printf(const char *format, ...) { + std::string result; + char *str = 0; + va_list args; + va_start(args, format); + if (vasprintf(&str, format, args) >= 0) result = str; + va_end(args); + if (str) free(str); + return result; +} + +static uint64_t timestamp_benchmark() { + struct timespec tp = {0, 0}; + +#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + tp.tv_sec = mts.tv_sec; + tp.tv_nsec = mts.tv_nsec; +#else + clock_gettime(CLOCK_REALTIME, &tp); +#endif + uint64_t stamp = tp.tv_sec * 1000000000ULL + tp.tv_nsec; + return stamp; +} + +struct TestCounter { + static uint64_t get(); + static void set(uint64_t); + static void add2(void *, uint64_t); +}; + +namespace { // Anon +void (*test_counter_add2)(void *, uint64_t) = + TestCounter::add2; // external symbol to prevent easy inlining +static uint64_t test_counter_var = 0; +} // Anon + +class BasicSignalTests { + static std::string accu; + struct Foo { + char foo_bool(float f, int i, std::string s) { + accu += string_printf("Foo: %.2f\n", f + i + s.size()); + return true; + } + }; + static char float_callback(float f, int, std::string) { + accu += string_printf("float: %.2f\n", f); + return 0; + } + + public: + static void run() { + accu = ""; + Simple::Signal<char(float, int, std::string)> sig1; + size_t id1 = sig1.connect(float_callback); + size_t id2 = sig1.connect([](float, int i, std::string) { + accu += string_printf("int: %d\n", i); + return 0; + }); + size_t id3 = sig1.connect([](float, int, const std::string &s) { + accu += string_printf("string: %s\n", s.c_str()); + return 0; + }); + sig1.emit(.3, 4, "huhu"); + bool success; + success = sig1.disconnect(id1); + assert(success == true); + success = sig1.disconnect(id1); + assert(success == false); + success = sig1.disconnect(id2); + assert(success == true); + success = sig1.disconnect(id3); + assert(success == true); + success = sig1.disconnect(id3); + assert(success == false); + success = sig1.disconnect(id2); + assert(success == false); + Foo foo; + sig1.connect(Simple::slot(foo, &Foo::foo_bool)); + sig1.connect(Simple::slot(&foo, &Foo::foo_bool)); + sig1.emit(.5, 1, "12"); + + Simple::Signal<void(std::string, int)> sig2; + sig2.connect([](std::string msg, + int) { accu += string_printf("msg: %s", msg.c_str()); }); + sig2.connect([](std::string, + int d) { accu += string_printf(" *%d*\n", d); }); + sig2.emit("in sig2", 17); + + accu += "DONE"; + + const char *expected = + "float: 0.30\n" + "int: 4\n" + "string: huhu\n" + "Foo: 3.50\n" + "Foo: 3.50\n" + "msg: in sig2 *17*\n" + "DONE"; + assert(accu == expected); + } +}; +std::string BasicSignalTests::accu; + +class TestCollectorVector { + static int handler1() { return 1; } + static int handler42() { return 42; } + static int handler777() { return 777; } + + public: + static void run() { + Simple::Signal<int(), Simple::CollectorVector<int>> sig_vector; + sig_vector.connect(handler777); + sig_vector.connect(handler42); + sig_vector.connect(handler1); + sig_vector.connect(handler42); + sig_vector.connect(handler777); + std::vector<int> results = sig_vector.emit(); + const std::vector<int> reference = {777, 42, 1, 42, 777, }; + assert(results == reference); + } +}; + +class TestCollectorUntil0 { + bool check1, check2; + TestCollectorUntil0() : check1(0), check2(0) {} + bool handler_true() { + check1 = true; + return true; + } + bool handler_false() { + check2 = true; + return false; + } + bool handler_abort() { abort(); } + + public: + static void run() { + TestCollectorUntil0 self; + Simple::Signal<bool(), Simple::CollectorUntil0<bool>> sig_until0; + sig_until0.connect(Simple::slot(self, &TestCollectorUntil0::handler_true)); + sig_until0.connect(Simple::slot(self, &TestCollectorUntil0::handler_false)); + sig_until0.connect(Simple::slot(self, &TestCollectorUntil0::handler_abort)); + assert(!self.check1 && !self.check2); + const bool result = sig_until0.emit(); + assert(!result && self.check1 && self.check2); + } +}; + +class TestCollectorWhile0 { + bool check1, check2; + TestCollectorWhile0() : check1(0), check2(0) {} + bool handler_0() { + check1 = true; + return false; + } + bool handler_1() { + check2 = true; + return true; + } + bool handler_abort() { abort(); } + + public: + static void run() { + TestCollectorWhile0 self; + Simple::Signal<bool(), Simple::CollectorWhile0<bool>> sig_while0; + sig_while0.connect(Simple::slot(self, &TestCollectorWhile0::handler_0)); + sig_while0.connect(Simple::slot(self, &TestCollectorWhile0::handler_1)); + sig_while0.connect(Simple::slot(self, &TestCollectorWhile0::handler_abort)); + assert(!self.check1 && !self.check2); + const bool result = sig_while0.emit(); + assert(result == true && self.check1 && self.check2); + } +}; + +static void bench_simple_signal() { + Simple::Signal<void(void *, uint64_t)> sig_increment; + sig_increment.connect(test_counter_add2); + const uint64_t start_counter = TestCounter::get(); + const uint64_t benchstart = timestamp_benchmark(); + uint64_t i; + for (i = 0; i < 999999; i++) { + sig_increment.emit(0, 1); + } + const uint64_t benchdone = timestamp_benchmark(); + const uint64_t end_counter = TestCounter::get(); + assert(end_counter - start_counter == i); + printf("OK\n Benchmark: Simple::Signal: %fns per emission (size=%zu): ", + size_t(benchdone - benchstart) * 1.0 / size_t(i), + sizeof(sig_increment)); +} + +static void bench_callback_loop() { + void (*counter_increment)(void *, uint64_t) = test_counter_add2; + const uint64_t start_counter = TestCounter::get(); + const uint64_t benchstart = timestamp_benchmark(); + uint64_t i; + for (i = 0; i < 999999; i++) { + counter_increment(0, 1); + } + const uint64_t benchdone = timestamp_benchmark(); + const uint64_t end_counter = TestCounter::get(); + assert(end_counter - start_counter == i); + printf("OK\n Benchmark: callback loop: %fns per round: ", + size_t(benchdone - benchstart) * 1.0 / size_t(i)); +} + +uint64_t TestCounter::get() { return test_counter_var; } + +void TestCounter::set(uint64_t v) { test_counter_var = v; } + +void TestCounter::add2(void *, uint64_t v) { test_counter_var += v; } + +int main(int argc, char *argv[]) { + printf("Signal/Basic Tests: "); + BasicSignalTests::run(); + printf("OK\n"); + + printf("Signal/CollectorVector: "); + TestCollectorVector::run(); + printf("OK\n"); + + printf("Signal/CollectorUntil0: "); + TestCollectorUntil0::run(); + printf("OK\n"); + + printf("Signal/CollectorWhile0: "); + TestCollectorWhile0::run(); + printf("OK\n"); + + printf("Signal/Benchmark: Simple::Signal: "); + bench_simple_signal(); + printf("OK\n"); + + printf("Signal/Benchmark: callback loop: "); + bench_callback_loop(); + printf("OK\n"); + + return 0; +} + +#endif // DISABLE_TESTS + +// g++ -Wall -O2 -std=gnu++0x -pthread simplesignal.cc -lrt && ./a.out diff --git a/entityx/help/Pool_test.cc b/entityx/help/Pool_test.cc index 631ccec..56ca85a 100644 --- a/entityx/help/Pool_test.cc +++ b/entityx/help/Pool_test.cc @@ -64,8 +64,6 @@ TEST_CASE("TestPoolPointers") { REQUIRE(extrapolated_p16 != static_cast<void*>(p16)); void *extrapolated_p24 = p16 + 8 * sizeof(Position); REQUIRE(extrapolated_p24 != static_cast<void*>(p24)); - - for (auto ptr : ptrs) delete[] ptr; } TEST_CASE("TestDeconstruct") { |