diff --git a/include/bitcoin/network/async/enable_shared_from_base.hpp b/include/bitcoin/network/async/enable_shared_from_base.hpp index d091a03d0..53b6ec120 100644 --- a/include/bitcoin/network/async/enable_shared_from_base.hpp +++ b/include/bitcoin/network/async/enable_shared_from_base.hpp @@ -25,18 +25,8 @@ namespace libbitcoin { namespace network { -// "The constructors of std::shared_ptr detect the presence of an unambiguous -// and accessible (i.e. public inheritance is mandatory) -// enable_shared_from_this base and assign the newly created std::shared_ptr -// to weak-this if not already owned by a live std::shared_ptr. -// Constructing a std::shared_ptr for an object that is already managed by -// another std::shared_ptr will not consult weak-this and is undefined behavior. -// It is permitted to call shared_from_this only on a previously shared object, -// i.e. on an object managed by std::shared_ptr. Otherwise, -// std::bad_weak_ptr is thrown(by the shared_ptr constructor).." -// en.cppreference.com/w/cpp/memory/enable_shared_from_this - -/// Base instance must be downcastable to Derived. +/// Thread safe, base class. +/// Empty base optimization using CRTP. /// Because enable_shared_from_this does not support inheritance. template class enable_shared_from_base @@ -52,53 +42,6 @@ class enable_shared_from_base std::shared_ptr shared_from_base() NOEXCEPT; }; -/// Sibling instance must be castable to Derived:Base. -/// Because enable_shared_from_this/base do not support multiple inheritance. -/// Avoids diamond inheritance ambiguity by requiring a primary inheritance -/// linear path (sibling) from which classes in an independent path (Base) -/// may obtain a shared pointer within their own path (Derived). -template -class enable_shared_from_sibling -{ -public: - DELETE_COPY_MOVE(enable_shared_from_sibling); - - enable_shared_from_sibling() NOEXCEPT; - - /// Must be a polymorphic type (to use dynamic_cast). - virtual ~enable_shared_from_sibling() NOEXCEPT; - - /// Simplifies capture of the shared pointer for a nop handler. - void nop() volatile NOEXCEPT; - -protected: - /// Sibling (not Derived:Base) implements enable_shared_from... - /// Use in Derived to create shared instance of Derived from its Sibling. - /// Undefined behavior if cast from Sibling* to Derived* not well formed. - template = true> - std::shared_ptr shared_from_sibling() NOEXCEPT; -}; - -// class foo__ : enabled_shared_from_base -// class foo_ : foo__ -// class foo: foo_ -// auto fooptr = foo.shared_from_this() -// auto foo_ptr = foo.shared_from_base() -// auto foo__ptr = foo.shared_from_base() -// -// class bar__ : enabled_shared_from_sibling -// class bar_ : bar__ -// class bar : bar_ -// bar__/bar_/bar must be joined with foo. -// -// class foobar : public foo, public bar -// auto barptr = foobar.shared_from_sibling() -// auto bar_ptr = foobar.shared_from_sibling() -// auto bar__ptr = foobar.shared_from_sibling() -// auto fooptr = foobar.shared_from_base() -// auto foo_ptr = foobar.shared_from_base() -// auto foo__ptr = foobar.shared_from_base() - } // namespace network } // namespace libbitcoin diff --git a/include/bitcoin/network/impl/async/enable_shared_from_base.ipp b/include/bitcoin/network/impl/async/enable_shared_from_base.ipp index cae5dfc17..8ab481136 100644 --- a/include/bitcoin/network/impl/async/enable_shared_from_base.ipp +++ b/include/bitcoin/network/impl/async/enable_shared_from_base.ipp @@ -24,13 +24,9 @@ namespace libbitcoin { namespace network { - -// enable_shared_from_base : enable_shared_from_this -// ---------------------------------------------------------------------------- template -void enable_shared_from_base:: -nop() volatile NOEXCEPT +void enable_shared_from_base::nop() volatile NOEXCEPT { } @@ -39,44 +35,8 @@ template > std::shared_ptr enable_shared_from_base:: shared_from_base() NOEXCEPT { - BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) + // Instance must be downcastable to Derived. return std::static_pointer_cast(this->shared_from_this()); - BC_POP_WARNING() -} - -// enable_shared_from_sibling -// ---------------------------------------------------------------------------- - -template -enable_shared_from_sibling:: -enable_shared_from_sibling() NOEXCEPT -{ -} - -template -enable_shared_from_sibling:: -~enable_shared_from_sibling() NOEXCEPT -{ -} - -template -void enable_shared_from_sibling:: -nop() volatile NOEXCEPT -{ -} - -template -template > -std::shared_ptr enable_shared_from_sibling:: -shared_from_sibling() NOEXCEPT -{ - BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) - // Obtain shared pointer to object from Sibling class inheritance path. - const auto sibling = dynamic_cast(this)->shared_from_this(); - BC_POP_WARNING() - - // Cast pointer back to Derived (from Base) class it was created from. - return std::dynamic_pointer_cast(sibling); } } // namespace network