// Only intended to be used by std::optional specialisations explicit cow_wrapper( std::nullopt_t ) noexcept :
m_pimpl( nullptr )
{
}
// Only intended to be used by std::optional specialisations explicit cow_wrapper( const cow_wrapper& rSrc, std::nullopt_t ) : // nothrow
m_pimpl( rSrc.m_pimpl )
{ if (m_pimpl)
MTPolicy::incrementCount( m_pimpl->m_ref_count );
}
~cow_wrapper() // nothrow, if ~T does not throw
{
release();
}
/// now sharing rSrc cow_wrapper instance with us
cow_wrapper& operator=( const cow_wrapper& rSrc ) // nothrow
{ // this already guards against self-assignment
MTPolicy::incrementCount( rSrc.m_pimpl->m_ref_count );
release();
m_pimpl = rSrc.m_pimpl;
return *this;
}
/// stealing rSrc's resource
cow_wrapper& operator=(cow_wrapper&& rSrc) noexcept
{ // self-movement guts ourself, see also 17.6.4.9
release();
m_pimpl = rSrc.m_pimpl;
rSrc.m_pimpl = nullptr;
return *this;
}
/// unshare with any other cow_wrapper instance
value_type& make_unique()
{ if( m_pimpl->m_ref_count > 1 )
{
impl_t* pimpl = new impl_t(m_pimpl->m_value);
release();
m_pimpl = pimpl;
}
return m_pimpl->m_value;
}
/// true, if not shared with any other cow_wrapper instance bool is_unique() const// nothrow
{ return !m_pimpl || m_pimpl->m_ref_count == 1;
}
/// return number of shared instances (1 for unique object)
size_t use_count() const// nothrow
{ return m_pimpl ? MTPolicy::getCount(m_pimpl->m_ref_count) : 0;
}
void swap(cow_wrapper& r) // never throws
{
std::swap(m_pimpl, r.m_pimpl);
}
/// true, if both cow_wrapper internally share the same object bool same_object( const cow_wrapper& rOther ) const
{ return rOther.m_pimpl == m_pimpl;
}
// Only intended to be used by std::optional specialisations bool empty() const { return m_pimpl == nullptr; } // Only intended to be used by std::optional specialisations void set_empty()
{ if (m_pimpl)
{
release();
m_pimpl = nullptr;
}
}
private:
impl_t* m_pimpl;
};
template<class T, class P> inlinebooloperator==( const cow_wrapper<T,P>& a, const cow_wrapper<T,P>& b )
{ return a.same_object(b) || *a == *b;
}
template<class T, class P> inlinebooloperator!=( const cow_wrapper<T,P>& a, const cow_wrapper<T,P>& b )
{ return !a.same_object(b) && *a != *b;
}
template<class A, class B, class P> inlinebooloperator<( const cow_wrapper<A,P>& a, const cow_wrapper<B,P>& b )
{ return *a < *b;
}
template<class T, class P> inlinevoid swap( cow_wrapper<T,P>& a,
cow_wrapper<T,P>& b )
{
a.swap(b);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.