1// vim:set ft=cpp: -*- Mode: C++ -*- 2/** 3 * \file 4 * 5 */ 6/* 7 * (c) 2017 Alexander Warg <alexander.warg@kernkonzept.com> 8 * 9 * This file is part of TUD:OS and distributed under the terms of the 10 * GNU General Public License 2. 11 * Please see the COPYING-GPL-2 file for details. 12 * 13 * As a special exception, you may use this file as part of a free software 14 * library without restriction. Specifically, if other files instantiate 15 * templates or use macros or inline functions from this file, or you compile 16 * this file and link it with other files to produce an executable, this 17 * file does not by itself cause the resulting executable to be covered by 18 * the GNU General Public License. This exception does not however 19 * invalidate any other reasons why the executable file might be covered by 20 * the GNU General Public License. 21 */ 22 23#pragma once 24 25#include <l4/sys/capability> 26 27namespace L4 { namespace Detail { 28 29template< typename T, typename IMPL > 30class Smart_cap_base : public Cap_base, protected IMPL 31{ 32protected: 33 template<typename X> 34 static IMPL &impl(Smart_cap_base<X, IMPL> &o) { return o; } 35 36 template<typename X> 37 static IMPL const &impl(Smart_cap_base<X, IMPL> const &o) { return o; } 38 39public: 40 template<typename X, typename I> 41 friend class ::L4::Detail::Smart_cap_base; 42 43 Smart_cap_base(Smart_cap_base const &) = delete; 44 Smart_cap_base &operator = (Smart_cap_base const &) = delete; 45 46 Smart_cap_base() noexcept : Cap_base(Invalid) {} 47 48 explicit Smart_cap_base(Cap_base::Cap_type t) noexcept 49 : Cap_base(t) 50 {} 51 52 template<typename O> 53 explicit constexpr Smart_cap_base(Cap<O> c) noexcept 54 : Cap_base(c.cap()) 55 {} 56 57 template<typename O> 58 explicit constexpr Smart_cap_base(Cap<O> c, IMPL const &impl) noexcept 59 : Cap_base(c.cap()), IMPL(impl) 60 {} 61 62 Cap<T> release() noexcept 63 { 64 l4_cap_idx_t c = this->cap(); 65 IMPL::invalidate(*this); 66 return Cap<T>(c); 67 } 68 69 void reset() 70 { IMPL::free(*this); } 71 72 Cap<T> operator -> () const noexcept { return Cap<T>(this->cap()); } 73 Cap<T> get() const noexcept { return Cap<T>(this->cap()); } 74 ~Smart_cap_base() noexcept { IMPL::free(*this); } 75}; 76 77 78template< typename T, typename IMPL > 79class Unique_cap_impl final : public Smart_cap_base<T, IMPL> 80{ 81private: 82 typedef Smart_cap_base<T, IMPL> Base; 83 84public: 85 using Base::Base; 86 Unique_cap_impl() noexcept = default; 87 88 Unique_cap_impl(Unique_cap_impl &&o) noexcept 89 : Base(o.release(), Base::impl(o)) 90 {} 91 92 template<typename O> 93 Unique_cap_impl(Unique_cap_impl<O, IMPL> &&o) noexcept 94 : Base(o.release(), Base::impl(o)) 95 { T* __t = ((O*)100); (void)__t; } 96 97 Unique_cap_impl &operator = (Unique_cap_impl &&o) noexcept 98 { 99 if (&o == this) 100 return *this; 101 102 IMPL::free(*this); 103 this->_c = o.release().cap(); 104 this->IMPL::operator = (Base::impl(o)); 105 return *this; 106 } 107 108 template<typename O> 109 Unique_cap_impl &operator = (Unique_cap_impl<O, IMPL> &&o) noexcept 110 { 111 T* __t = ((O*)100); (void)__t; 112 113 IMPL::free(*this); 114 this->_c = o.release().cap(); 115 this->IMPL::operator = (Base::impl(o)); 116 return *this; 117 } 118}; 119 120template<typename T, typename IMPL> 121class Shared_cap_impl final : public Smart_cap_base<T, IMPL> 122{ 123private: 124 typedef Smart_cap_base<T, IMPL> Base; 125 126public: 127 using Base::Base; 128 Shared_cap_impl() noexcept = default; 129 130 Shared_cap_impl(Shared_cap_impl &&o) noexcept 131 : Base(o.release()) 132 {} 133 134 template<typename O> 135 Shared_cap_impl(Shared_cap_impl<O, IMPL> &&o) noexcept 136 : Base(o.release()) 137 { T* __t = ((O*)100); (void)__t; } 138 139 Shared_cap_impl &operator = (Shared_cap_impl &&o) noexcept 140 { 141 if (&o == this) 142 return *this; 143 144 IMPL::free(*this); 145 this->_c = o.release().cap(); 146 this->IMPL::operator = (Base::impl(o)); 147 return *this; 148 } 149 150 template<typename O> 151 Shared_cap_impl &operator = (Shared_cap_impl<O, IMPL> &&o) noexcept 152 { 153 T* __t = ((O*)100); (void)__t; 154 155 IMPL::free(*this); 156 this->_c = o.release().cap(); 157 this->IMPL::operator = (Base::impl(o)); 158 return *this; 159 } 160 161 Shared_cap_impl(Shared_cap_impl const &o) noexcept 162 : Base(L4::Cap<T>(IMPL::copy(o).cap())) 163 {} 164 165 template<typename O> 166 Shared_cap_impl(Shared_cap_impl<O, IMPL> const &o) noexcept 167 : Base(IMPL::copy(o)) 168 { T* __t = ((O*)100); (void)__t; } 169 170 Shared_cap_impl &operator = (Shared_cap_impl const &o) noexcept 171 { 172 if (&o == this) 173 return *this; 174 175 IMPL::free(*this); 176 this->IMPL::operator = (static_cast<IMPL const &>(o)); 177 this->_c = this->IMPL::copy(o).cap(); 178 return *this; 179 } 180 181 template<typename O> 182 Shared_cap_impl &operator = (Shared_cap_impl<O, IMPL> const &o) noexcept 183 { 184 T* __t = ((O*)100); (void)__t; 185 IMPL::free(*this); 186 this->IMPL::operator = (static_cast<IMPL const &>(o)); 187 this->_c = this->IMPL::copy(o).cap(); 188 return *this; 189 } 190}; 191 192}} // L4::Detail 193