// vim:set ft=cpp: -*- Mode: C++ -*- /** * \file * */ /* * (c) 2017 Alexander Warg * * This file is part of TUD:OS and distributed under the terms of the * GNU General Public License 2. * Please see the COPYING-GPL-2 file for details. * * As a special exception, you may use this file as part of a free software * library without restriction. Specifically, if other files instantiate * templates or use macros or inline functions from this file, or you compile * this file and link it with other files to produce an executable, this * file does not by itself cause the resulting executable to be covered by * the GNU General Public License. This exception does not however * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. */ #pragma once #include namespace L4 { namespace Detail { template< typename T, typename IMPL > class Smart_cap_base : public Cap_base, protected IMPL { protected: template static IMPL &impl(Smart_cap_base &o) { return o; } template static IMPL const &impl(Smart_cap_base const &o) { return o; } public: template friend class ::L4::Detail::Smart_cap_base; Smart_cap_base(Smart_cap_base const &) = delete; Smart_cap_base &operator = (Smart_cap_base const &) = delete; Smart_cap_base() noexcept : Cap_base(Invalid) {} explicit Smart_cap_base(Cap_base::Cap_type t) noexcept : Cap_base(t) {} template explicit constexpr Smart_cap_base(Cap c) noexcept : Cap_base(c.cap()) {} template explicit constexpr Smart_cap_base(Cap c, IMPL const &impl) noexcept : Cap_base(c.cap()), IMPL(impl) {} Cap release() noexcept { l4_cap_idx_t c = this->cap(); IMPL::invalidate(*this); return Cap(c); } void reset() { IMPL::free(*this); } Cap operator -> () const noexcept { return Cap(this->cap()); } Cap get() const noexcept { return Cap(this->cap()); } ~Smart_cap_base() noexcept { IMPL::free(*this); } }; template< typename T, typename IMPL > class Unique_cap_impl final : public Smart_cap_base { private: typedef Smart_cap_base Base; public: using Base::Base; Unique_cap_impl() noexcept = default; Unique_cap_impl(Unique_cap_impl &&o) noexcept : Base(o.release(), Base::impl(o)) {} template Unique_cap_impl(Unique_cap_impl &&o) noexcept : Base(o.release(), Base::impl(o)) { T* __t = ((O*)100); (void)__t; } Unique_cap_impl &operator = (Unique_cap_impl &&o) noexcept { if (&o == this) return *this; IMPL::free(*this); this->_c = o.release().cap(); this->IMPL::operator = (Base::impl(o)); return *this; } template Unique_cap_impl &operator = (Unique_cap_impl &&o) noexcept { T* __t = ((O*)100); (void)__t; IMPL::free(*this); this->_c = o.release().cap(); this->IMPL::operator = (Base::impl(o)); return *this; } }; template class Shared_cap_impl final : public Smart_cap_base { private: typedef Smart_cap_base Base; public: using Base::Base; Shared_cap_impl() noexcept = default; Shared_cap_impl(Shared_cap_impl &&o) noexcept : Base(o.release()) {} template Shared_cap_impl(Shared_cap_impl &&o) noexcept : Base(o.release()) { T* __t = ((O*)100); (void)__t; } Shared_cap_impl &operator = (Shared_cap_impl &&o) noexcept { if (&o == this) return *this; IMPL::free(*this); this->_c = o.release().cap(); this->IMPL::operator = (Base::impl(o)); return *this; } template Shared_cap_impl &operator = (Shared_cap_impl &&o) noexcept { T* __t = ((O*)100); (void)__t; IMPL::free(*this); this->_c = o.release().cap(); this->IMPL::operator = (Base::impl(o)); return *this; } Shared_cap_impl(Shared_cap_impl const &o) noexcept : Base(L4::Cap(IMPL::copy(o).cap())) {} template Shared_cap_impl(Shared_cap_impl const &o) noexcept : Base(IMPL::copy(o)) { T* __t = ((O*)100); (void)__t; } Shared_cap_impl &operator = (Shared_cap_impl const &o) noexcept { if (&o == this) return *this; IMPL::free(*this); this->IMPL::operator = (static_cast(o)); this->_c = this->IMPL::copy(o).cap(); return *this; } template Shared_cap_impl &operator = (Shared_cap_impl const &o) noexcept { T* __t = ((O*)100); (void)__t; IMPL::free(*this); this->IMPL::operator = (static_cast(o)); this->_c = this->IMPL::copy(o).cap(); return *this; } }; }} // L4::Detail