Created
April 23, 2019 06:13
-
-
Save eao197/d094659467996207c39e68b61f25ee23 to your computer and use it in GitHub Desktop.
Полный код для статьи о деталях реализации message_holder_t из SObjectizer-5.6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template< typename Payload, typename Envelope > | |
class basic_message_holder_impl_t | |
{ | |
protected : | |
intrusive_ptr_t< Envelope > m_msg; | |
public : | |
using payload_type = Payload; | |
using envelope_type = Envelope; | |
basic_message_holder_impl_t() noexcept = default; | |
basic_message_holder_impl_t( intrusive_ptr_t< Envelope > msg ) | |
: m_msg{ std::move(msg) } | |
{} | |
void reset() noexcept { m_msg.reset(); } | |
[[nodiscard]] | |
bool empty() const noexcept { return static_cast<bool>( m_msg ); } | |
[[nodiscard]] | |
operator bool() const noexcept { return !this->empty(); } | |
[[nodiscard]] | |
bool operator!() const noexcept { return this->empty(); } | |
}; | |
template< typename Payload, typename Envelope > | |
class shared_message_holder_impl_t | |
: public basic_message_holder_impl_t<Payload, Envelope> | |
{ | |
using direct_base_type = basic_message_holder_impl_t<Payload, Envelope>; | |
public : | |
using direct_base_type::direct_base_type; | |
[[nodiscard]] intrusive_ptr_t< Envelope > | |
make_reference() const noexcept | |
{ | |
return this->m_msg; | |
} | |
}; | |
template< typename Payload, typename Envelope > | |
class unique_message_holder_impl_t | |
: public basic_message_holder_impl_t<Payload, Envelope> | |
{ | |
using direct_base_type = basic_message_holder_impl_t<Payload, Envelope>; | |
public : | |
using direct_base_type::direct_base_type; | |
unique_message_holder_impl_t( | |
const unique_message_holder_impl_t & ) = delete; | |
unique_message_holder_impl_t( | |
unique_message_holder_impl_t && ) = default; | |
unique_message_holder_impl_t & | |
operator=( const unique_message_holder_impl_t & ) = delete; | |
unique_message_holder_impl_t & | |
operator=( unique_message_holder_impl_t && ) = default; | |
[[nodiscard]] intrusive_ptr_t< Envelope > | |
make_reference() noexcept | |
{ | |
return { std::move(this->m_msg) }; | |
} | |
}; | |
template< typename Msg, message_ownership_t Ownership > | |
struct impl_selector | |
{ | |
static_assert( !is_signal<Msg>::value, | |
"Signals can't be used with message_holder" ); | |
using P = typename message_payload_type< Msg >::payload_type; | |
using E = typename message_payload_type< Msg >::envelope_type; | |
using type = std::conditional_t< | |
message_ownership_t::autodetected == Ownership, | |
std::conditional_t< | |
message_mutability_t::immutable_message == | |
message_mutability_traits<Msg>::mutability, | |
shared_message_holder_impl_t<P, E>, | |
unique_message_holder_impl_t<P, E> >, | |
std::conditional_t< | |
message_ownership_t::shared == Ownership, | |
shared_message_holder_impl_t<P, E>, | |
unique_message_holder_impl_t<P, E> > | |
>; | |
}; | |
template< typename Msg, message_ownership_t Ownership > | |
using impl_selector_t = typename impl_selector<Msg, Ownership>::type; | |
template< typename M > | |
M * get_ptr( const intrusive_ptr_t<M> & msg ) noexcept | |
{ | |
return msg.get(); | |
} | |
template< typename M > | |
M * get_ptr( const intrusive_ptr_t< user_type_message_t<M> > & msg ) noexcept | |
{ | |
return std::addressof(msg->m_payload); | |
} | |
template< typename Base, typename Return_Type > | |
class msg_accessors_t : public Base | |
{ | |
public : | |
using Base::Base; | |
[[nodiscard]] Return_Type * | |
get() const noexcept | |
{ | |
return get_ptr( this->m_msg ); | |
} | |
[[nodiscard]] Return_Type & | |
operator * () const noexcept { return *get(); } | |
[[nodiscard]] Return_Type * | |
operator->() const noexcept { return get(); } | |
}; | |
template< message_mutability_t Mutability, typename Base > | |
struct accessor_selector | |
{ | |
using type = std::conditional_t< | |
message_mutability_t::immutable_message == Mutability, | |
msg_accessors_t<Base, typename Base::payload_type const>, | |
msg_accessors_t<Base, typename Base::payload_type> >; | |
}; | |
template< message_mutability_t Mutability, typename Base > | |
using accessor_selector_t = typename accessor_selector<Mutability, Base>::type; | |
template< | |
typename Msg, | |
message_ownership_t Ownership = message_ownership_t::autodetected > | |
class message_holder_t | |
: public details::message_holder_details::accessor_selector_t< | |
details::message_mutability_traits<Msg>::mutability, | |
details::message_holder_details::impl_selector_t<Msg, Ownership> > | |
{ | |
using base_type = details::message_holder_details::accessor_selector_t< | |
details::message_mutability_traits<Msg>::mutability, | |
details::message_holder_details::impl_selector_t<Msg, Ownership> >; | |
public : | |
using payload_type = typename base_type::payload_type; | |
using envelope_type = typename base_type::envelope_type; | |
using base_type::base_type; | |
friend void | |
swap( message_holder_t & a, message_holder_t & b ) noexcept | |
{ | |
using std::swap; | |
swap( a.m_msg, b.m_msg ); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment