]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/__typeinfo.h
update
[l4.git] / l4 / pkg / l4sys / include / __typeinfo.h
1 /**
2  * \file
3  * \brief Type information handling.
4  */
5 /*
6  * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
7  *     economic rights: Technische Universität Dresden (Germany)
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 #pragma once
23
24 #if defined(__GXX_RTTI) || !defined(L4_NO_RTTI)
25 #  include <typeinfo>
26    typedef std::type_info const *L4_std_type_info_ptr;
27 #  define L4_KOBJECT_META_RTTI(type) (&typeid(type))
28    inline char const *L4_kobject_type_name(L4_std_type_info_ptr n)
29    { return n ? n->name() : 0; }
30 #else
31    typedef void const *L4_std_type_info_ptr;
32 #  define L4_KOBJECT_META_RTTI(type) (0)
33    inline char const *L4_kobject_type_name(L4_std_type_info_ptr)
34    { return 0; }
35 #endif
36
37 namespace L4 {
38
39 /**
40  * \brief Dynamic Type Information for L4Re Interfaces.
41  *
42  * This class represents the runtime-dynamic type information for
43  * L4Re interfaces, and is not intended to be used directly by applications.
44  * \note The interface of is subject to changes.
45  *
46  * The main use for this info is to be used by the implementation of the
47  * L4::cap_dynamic_cast() function.
48  *
49  */
50 struct Type_info
51 {
52   L4_std_type_info_ptr _type;
53   Type_info const *const *_bases;
54   unsigned _num_bases;
55   long _proto;
56
57   L4_std_type_info_ptr type() const { return _type; }
58   Type_info const *base(unsigned idx) const { return _bases[idx]; }
59   unsigned num_bases() const { return _num_bases; }
60   long proto() const { return _proto; }
61   char const *name() const { return L4_kobject_type_name(type()); }
62   bool has_proto(long proto) const
63   {
64     if (_proto && _proto == proto)
65       return true;
66
67     if (!proto)
68       return false;
69
70     for (unsigned i = 0; i < _num_bases; ++i)
71       if (base(i)->has_proto(proto))
72         return true;
73
74     return false;
75   }
76 };
77
78
79 /**
80  * \brief Get the L4::Type_info for the L4Re interface given in \a T.
81  * \param T The type (L4Re interface) for which the information shall be
82  *          returned.
83  * \return A pointer to the L4::Type_info structure for \a T.
84  */
85 template<typename T>
86 inline
87 Type_info const *kobject_typeid()
88 { return &T::__Kobject_typeid::_m; }
89
90
91 /**
92  * \internal
93  */
94 #define L4____GEN_TI(t...)                             \
95 Type_info const t::__Kobject_typeid::_m =                                \
96 {                                                      \
97   L4_KOBJECT_META_RTTI(Derived),                       \
98   &t::__Kobject_typeid::_b[0], sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), PROTO   \
99 }
100
101 /**
102  * \internal
103  */
104 #define L4____GEN_TI_MEMBERS()                                     \
105 private:                                                           \
106   template< typename T > friend Type_info const *kobject_typeid(); \
107 protected: \
108   struct __Kobject_typeid { \
109   static Type_info const *const _b[];                              \
110   static Type_info const _m;    };                                 \
111 public:                                                            \
112   static long const Protocol = PROTO;
113
114
115 /**
116  * \brief Helper class to create an L4Re interface class that is derived
117  *        from a single base class.
118  *
119  * \param Derived is the name of the new interface.
120  * \param Base is the name of the interfaces single base class.
121  * \param PROTO may be set to the statically assigned protocol number
122  *              used to communicate with this interface.
123  *
124  * The typical usage pattern is shown in the following code snippet. The
125  * semantics of this example is an interface My_iface that is derived from
126  * L4::Kobject.
127  *
128  * \code
129  * class My_iface : public L4::Kobject_t<My_iface, L4::Kobject>
130  * {
131  *   ...
132  * };
133  * \endcode
134  *
135  */
136 template< typename Derived, typename Base, long PROTO = 0 >
137 class Kobject_t : public Base
138 { L4____GEN_TI_MEMBERS() };
139
140
141 template< typename Derived, typename Base, long PROTO >
142 Type_info const *const Kobject_t<Derived, Base, PROTO>::__Kobject_typeid::_b[] =
143 { &Base::__Kobject_typeid::_m };
144
145 /**
146  * \internal
147  */
148 template< typename Derived, typename Base, long PROTO >
149 L4____GEN_TI(Kobject_t<Derived, Base, PROTO>);
150
151
152 /**
153  * \brief Helper class to create an L4Re interface class that is derived
154  *        from two base classes.
155  *
156  * \param Derived is the name of the new interface.
157  * \param Base1 is the name of the interfaces first base class.
158  * \param Base2 is the name of the interfaces second base class.
159  * \param PROTO may be set to the statically assigned protocol number
160  *              used to communicate with this interface.
161  *
162  * The typical usage pattern is shown in the following code snippet. The
163  * semantics of this example is an interface My_iface that is derived from
164  * L4::Icu and L4Re::Dataspace.
165  *
166  * \code
167  * class My_iface : public L4::Kobject_2t<My_iface, L4::Icu, L4Re::Dataspace>
168  * {
169  *   ...
170  * };
171  * \endcode
172  *
173  */
174 template< typename Derived, typename Base1, typename Base2, long PROTO = 0 >
175 class Kobject_2t : public Base1, public Base2
176 { L4____GEN_TI_MEMBERS() };
177
178
179 template< typename Derived, typename Base1, typename Base2, long PROTO >
180 Type_info const *const  Kobject_2t<Derived, Base1, Base2, PROTO>::__Kobject_typeid::_b[] =
181 {
182   &Base1::__Kobject_typeid::_m,
183   &Base2::__Kobject_typeid::_m
184 };
185
186 /**
187  * \internal
188  */
189 template< typename Derived, typename Base1, typename Base2, long PROTO >
190 L4____GEN_TI(Kobject_2t<Derived, Base1, Base2, PROTO>);
191
192 #undef L4____GEN_TI
193 #undef L4____GEN_TI_MEMBERS
194
195 }