1// vim:set ft=cpp: -*- Mode: C++ -*-
2/**
3 * \file
4 * L4::Capability class.
5 *
6 * \author Alexander Warg <alexander.warg@os.inf.tu-dresden.de>
7 *
8 */
9/*
10 * (c) 2008-2009 Author(s)
11 *     economic rights: Technische Universität Dresden (Germany)
12 *
13 * This file is part of TUD:OS and distributed under the terms of the
14 * GNU General Public License 2.
15 * Please see the COPYING-GPL-2 file for details.
16 *
17 * As a special exception, you may use this file as part of a free software
18 * library without restriction.  Specifically, if other files instantiate
19 * templates or use macros or inline functions from this file, or you compile
20 * this file and link it with other files to produce an executable, this
21 * file does not by itself cause the resulting executable to be covered by
22 * the GNU General Public License.  This exception does not however
23 * invalidate any other reasons why the executable file might be covered by
24 * the GNU General Public License.
25 */
26#pragma once
27
28#include <l4/sys/capability>
29
30namespace L4 {
31
32/**
33 * Smart capability class.
34 */
35template< typename T, typename SMART >
36class Smart_cap : public Cap_base, private SMART
37{
38public:
39
40  SMART const &smart() const noexcept { return *this; }
41
42  void _delete() noexcept
43  {
44    SMART::free(const_cast<Smart_cap<T,SMART>&>(*this));
45  }
46
47  Cap<T> release() const noexcept
48  {
49    l4_cap_idx_t r = cap();
50    SMART::invalidate(const_cast<Smart_cap<T,SMART>&>(*this));
51
52    return Cap<T>(r);
53  }
54
55  void reset() noexcept
56  {
57    _c = L4_INVALID_CAP;
58  }
59
60  Smart_cap() noexcept : Cap_base(Invalid) {}
61
62  Smart_cap(Cap_base::Cap_type t) noexcept : Cap_base(t) {}
63
64  /**
65   * Internal constructor, use to generate a capability from a `this` pointer.
66   *
67   * \attention This constructor is only useful to generate a capability
68   *            from the `this` pointer of an objected that is an L4::Kobject.
69   *            Do `never` use this constructor for something else!
70   * \param p  The `this` pointer of the Kobject or derived object
71   */
72  template< typename O >
73  Smart_cap(Cap<O> const &p) noexcept : Cap_base(p.cap())
74  { T* __t = ((O*)100); (void)__t; }
75
76  template< typename O >
77  Smart_cap(Cap<O> const &p, SMART const &smart) noexcept
78  : Cap_base(p.cap()), SMART(smart)
79  { T* __t = ((O*)100); (void)__t; }
80
81  template< typename O >
82  Smart_cap(Smart_cap<O, SMART> const &o) noexcept
83  : Cap_base(SMART::copy(o)), SMART(o.smart())
84  { T* __t = ((O*)100); (void)__t; }
85
86  Smart_cap(Smart_cap const &o) noexcept
87  : Cap_base(SMART::copy(o)), SMART(o.smart())
88  { }
89
90  template< typename O >
91  Smart_cap(typename Cap<O>::Cap_type cap) noexcept : Cap_base(cap)
92  { T* __t = ((O*)100); (void)__t; }
93
94  void operator = (typename Cap<T>::Cap_type cap) noexcept
95  {
96    _delete();
97    _c = cap;
98  }
99
100  template< typename O >
101  void operator = (Smart_cap<O, SMART> const &o) noexcept
102  {
103    _delete();
104    _c = this->SMART::copy(o).cap();
105    this->SMART::operator = (o.smart());
106    // return *this;
107  }
108
109  Smart_cap const &operator = (Smart_cap const &o) noexcept
110  {
111    if (&o == this)
112      return *this;
113
114    _delete();
115    _c = this->SMART::copy(o).cap();
116    this->SMART::operator = (o.smart());
117    return *this;
118  }
119
120#if __cplusplus >= 201103L
121  template< typename O >
122  Smart_cap(Smart_cap<O, SMART> &&o) noexcept
123  : Cap_base(o.release()), SMART(o.smart())
124  { T* __t = ((O*)100); (void)__t; }
125
126  Smart_cap(Smart_cap &&o) noexcept
127  : Cap_base(o.release()), SMART(o.smart())
128  { }
129
130  template< typename O >
131  void operator = (Smart_cap<O, SMART> &&o) noexcept
132  {
133    _delete();
134    _c = o.release().cap();
135    this->SMART::operator = (o.smart());
136    // return *this;
137  }
138
139  Smart_cap const &operator = (Smart_cap &&o) noexcept
140  {
141    if (&o == this)
142      return *this;
143
144    _delete();
145    _c = o.release().cap();
146    this->SMART::operator = (o.smart());
147    return *this;
148  }
149#endif
150
151  /**
152   * Member access of a `T`.
153   */
154  Cap<T> operator -> () const noexcept { return Cap<T>(_c); }
155
156  Cap<T> get() const noexcept { return Cap<T>(_c); }
157
158  ~Smart_cap() noexcept { _delete(); }
159};
160
161template< typename T >
162class Weak_cap : public Cap_base
163{
164public:
165  Weak_cap() noexcept : Cap_base(Invalid) {}
166
167  template< typename O >
168  Weak_cap(typename Cap<O>::Cap_type t) noexcept : Cap_base(t)
169  { T* __t = ((O*)100); (void)__t; }
170
171  template< typename O, typename S >
172  Weak_cap(Smart_cap<O, S> const &c) noexcept : Cap_base(c.cap())
173  { T* __t = ((O*)100); (void)__t; }
174
175  Weak_cap(Weak_cap const &o) noexcept : Cap_base(o) {}
176
177  template< typename O >
178  Weak_cap(Weak_cap<O> const &o) noexcept : Cap_base(o)
179  { T* __t = ((O*)100); (void)__t; }
180
181};
182
183namespace Cap_traits {
184  template< typename T1, typename T2 >
185  struct Type { enum { Equal = false }; };
186
187  template< typename T1 >
188  struct Type<T1,T1> { enum { Equal = true }; };
189};
190
191/**
192 * `static_cast` for (smart) capabilities.
193 *
194 * \tparam T      Type to cast the capability to.
195 * \tparam F      (implicit) Type of the passed capability.
196 * \tparam SMART  (implicit) Class implementing the Smart_cap interface.
197 * \param  c      Capability to be casted.
198 *
199 * \return A smart capability with new type `T`.
200 */
201template< typename T, typename F, typename SMART >
202inline
203Smart_cap<T, SMART> cap_cast(Smart_cap<F, SMART> const &c) noexcept
204{
205  (void)static_cast<T const *>(reinterpret_cast<F const *>(100));
206  return Smart_cap<T, SMART>(Cap<T>(SMART::copy(c).cap()));
207}
208
209
210/**
211 * `reinterpret_cast` for (smart) capabilities.
212 *
213 * \tparam T      Type to cast the capability to.
214 * \tparam F      (implicit) Type of the passed capability.
215 * \tparam SMART  (implicit) Class implementing the Smart_cap interface.
216 * \param  c      Capability to be casted.
217 *
218 * \return A smart capability with new type `T`.
219 */
220template< typename T, typename F, typename SMART >
221inline
222Smart_cap<T, SMART> cap_reinterpret_cast(Smart_cap<F, SMART> const &c) noexcept
223{
224  return Smart_cap<T, SMART>(Cap<T>(SMART::copy(c).cap()));
225}
226
227
228}
229
230