From 810999fadf41576204752113f33336a69603de4a Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Thu, 7 Feb 2019 12:13:19 +0200 Subject: [core] Simplify util::peer Remove custom vtable, base implementation on `std::unique_ptr`. --- include/mbgl/util/peer.hpp | 97 +++++----------------------------------------- 1 file changed, 9 insertions(+), 88 deletions(-) (limited to 'include/mbgl') diff --git a/include/mbgl/util/peer.hpp b/include/mbgl/util/peer.hpp index a4abea0e88..d56526b80d 100644 --- a/include/mbgl/util/peer.hpp +++ b/include/mbgl/util/peer.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -8,102 +9,22 @@ namespace util { class peer { public: - peer() = default; - peer(const peer&) = delete; - - peer(peer&& other) - : vtable(other.vtable) - { - if (vtable) { - vtable->move(other.storage, storage); - } - other.vtable = nullptr; - } + peer() noexcept : storage(nullptr, noop_deleter) {} template - peer(T&& value) { - using _Vt = std::decay_t; - vtable = get_vtable<_Vt>(); - new (&storage) _Vt(std::forward(value)); - } - - ~peer() { - reset(); - } - - peer& operator=(peer&& rhs) { - peer(std::move(rhs)).swap(*this); - return *this; - } - - void reset() { - if (vtable) { - vtable->destroy(storage); - vtable = nullptr; - } - } + peer(T&& value) noexcept : storage(new std::decay_t(std::forward(value)), cast_deleter>) {} - void swap(peer& rhs) { - if (this == &rhs) { - return; - } else { - peer tmp(std::move(rhs)); - rhs.vtable = vtable; - if (rhs.vtable) { - rhs.vtable->move(storage, rhs.storage); - } - vtable = tmp.vtable; - if (vtable) { - vtable->move(tmp.storage, storage); - } - } - } - - bool has_value() const { - return vtable != nullptr; - } - - template - T& get() { - return reinterpret_cast(storage); - } + bool has_value() const noexcept { return static_cast(storage); } template - T&& take() { - reset(); - return std::move(get()); - } + T& get() noexcept { return *reinterpret_cast(storage.get()); } private: - using storage_t = std::aligned_storage_t<2*sizeof(void*), alignof(void*)>; - - struct vtable { - virtual ~vtable() = default; - virtual void move(storage_t&, storage_t&) = 0; - virtual void destroy(storage_t&) = 0; - }; - - template - struct vtable_impl : public vtable { - static_assert(sizeof(T) <= sizeof(storage_t), "peer object is too big"); - - void move(storage_t& src, storage_t& dst) override { - new (&dst) T(std::move(reinterpret_cast(src))); - destroy(src); - } - - void destroy(storage_t& s) override { - reinterpret_cast(s).~T(); - } - }; - - template - static vtable* get_vtable() { - static vtable_impl vtable; - return &vtable; - } + template + static void cast_deleter(void* ptr) noexcept { delete reinterpret_cast(ptr); } + static void noop_deleter(void*) noexcept {} - vtable* vtable = nullptr; + using storage_t = std::unique_ptr; storage_t storage; }; -- cgit v1.2.1