L4Re - L4 Runtime Environment
types
Go to the documentation of this file.
1 // vi:set ft=cpp: -*- Mode: C++ -*-
2 /*
3  * (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com>
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  *
9  * As a special exception, you may use this file as part of a free software
10  * library without restriction. Specifically, if other files instantiate
11  * templates or use macros or inline functions from this file, or you compile
12  * this file and link it with other files to produce an executable, this
13  * file does not by itself cause the resulting executable to be covered by
14  * the GNU General Public License. This exception does not however
15  * invalidate any other reasons why the executable file might be covered by
16  * the GNU General Public License.
17  */
18 
19 /// \file
20 
21 #pragma once
22 
23 // very simple type traits for basic L4 functions, for a more complete set
24 // use <l4/cxx/type_traits> or the standard <type_traits>.
25 
26 namespace L4 {
27 
28 /**
29  * L4 basic type helpers for C++
30  */
31 namespace Types {
32 
33  /**
34  * Template for defining typical Flags bitmaps.
35  * \tparam BITS_ENUM enum type that defines a name for each bit in
36  * the bitmap. The values of the enum members
37  * must be the number of the bit (_not_ a mask).
38  * \tparam UNDERLYING The underlying data type used to represent the bitmap.
39  *
40  *
41  * The resulting data type provides a type-safe version that allows
42  * bitwise `and` and `or` operations with the BITS_ENUM members.
43  * As well as, test for `0`or !`0`.
44  *
45  * Example:
46  * ~~~~
47  * enum Test_flag
48  * {
49  * Do_weak_tests,
50  * Do_strong_tests
51  * };
52  *
53  * typedef L4::Types::Flags<Test_flag> Test_flags;
54  *
55  * Test_flags x = Do_weak_tests;
56  *
57  * if (x & Do_strong_tests) { ... }
58  * x |= Do_strong_tests;
59  * if (x & Do_strong_tests) { ... }
60  * ~~~~
61  */
62  template<typename BITS_ENUM, typename UNDERLYING = unsigned long>
63  class Flags
64  {
65  public:
66  /// type of the underlying value
67  typedef UNDERLYING value_type;
68  /// enum type defining a name for each bit
69  typedef BITS_ENUM bits_enum_type;
70  /// the Flags<> type itself
71  typedef Flags<BITS_ENUM, UNDERLYING> type;
72 
73  private:
74  struct Private_bool;
75  value_type _v;
76  explicit Flags(value_type v) : _v(v) {}
77 
78  public:
79  /// The none type to get an empty bitmap
80  enum None_type { None /**< Use this to get an empty bitmap */ };
81 
82  /**
83  * Make an empty bitmap.
84  *
85  * Usually used for implicit conversion from `Flags::None`.
86  * ~~~
87  * Flags x = Flags::None;
88  * ~~~
89  */
90  Flags(None_type) : _v(0) {}
91 
92  /// Make default Flags
93  Flags() : _v(0) {}
94 
95  /**
96  * Make flags from bit name.
97  *
98  * Usually used for implicit conversion for a bit name.
99  * ~~~
100  * Test_flags f = Do_strong_tests;
101  * ~~~
102  */
103  Flags(BITS_ENUM e) : _v(((value_type)1) << e) {}
104 
105  /**
106  * Make flags from a raw value of \a value_type.
107  *
108  * This function may be used for example in C wrapper code.
109  */
110  static type from_raw(value_type v) { return type(v); }
111 
112  /// Support for `if (flags)` syntax (test for non-empty flags).
113  operator Private_bool * () const
114  { return _v != 0 ? (Private_bool *)1 : 0; }
115 
116  /// Support for `if (!flags)` syntax (test for empty flags).
117  bool operator ! () const { return _v == 0; }
118 
119  /// Support `|` of two compatible Flags types.
120  friend type operator | (type lhs, type rhs)
121  { return type(lhs._v | rhs._v); }
122 
123  /// Support `|` of Flags type and bit name.
124  friend type operator | (type lhs, bits_enum_type rhs)
125  { return lhs | type(rhs); }
126 
127  /// Support `&` of two compatible Flags types.
128  friend type operator & (type lhs, type rhs)
129  { return type(lhs._v & rhs._v); }
130 
131  /// Support `&` of Flags type and bit name.
132  friend type operator & (type lhs, bits_enum_type rhs)
133  { return lhs & type(rhs); }
134 
135  /// Support `|=` of two compatible Flags types.
136  type &operator |= (type rhs) { _v |= rhs._v; return *this; }
137  /// Support `|=` of Flags type and bit name.
138  type &operator |= (bits_enum_type rhs) { return operator |= (type(rhs)); }
139 
140  /// Support `&=` of two compatible Flags types.
141  type &operator &= (type rhs) { _v &= rhs._v; return *this; }
142  /// Support `&=` of Flags type and bit name.
143  type &operator &= (bits_enum_type rhs) { return operator &= (type(rhs)); }
144 
145  /// Support `~` for Flags types.
146  type operator ~ () const { return type(~_v); }
147 
148  /**
149  * Clear the given flag.
150  * \param flag The flag that shall be cleared.
151  *
152  * `flags.clear(The_flag)` is a shortcut for `flags &= ~Flags(The_flag)`.
153  */
154  type &clear(bits_enum_type flag) { return operator &= (~type(flag)); }
155 
156  /// Get the underlying value.
157  value_type as_value() const { return _v; }
158  };
159 
160  /**
161  * Boolean meta type
162  * \tparam V The boolean value
163  * \ingroup l4_cxx_ipc_internal
164  */
165  template< bool V > struct Bool
166  {
167  typedef Bool<V> type; ///< The meta type itself
168  enum { value = V }; ///< The boolean value
169  };
170 
171  /// False meta value
172  /// \ingroup l4_cxx_ipc_internal
173  struct False : Bool<false> {};
174 
175  /// True meta value
176  /// \ingroup l4_cxx_ipc_internal
177  struct True : Bool<true> {};
178 
179  /*********************/
180  /**
181  * Compare two data types for equality
182  * \tparam A The first data type
183  * \tparam B The second data type
184  * \ingroup l4_cxx_ipc_internal
185  *
186  * The result is the boolean True if A and B are the same types.
187  */
188  template<typename A, typename B>
189  struct Same : False {};
190 
191  template<typename A>
192  struct Same<A, A> : True {};
193 
194  template<bool EXP, typename T = void> struct Enable_if {};
195  template<typename T> struct Enable_if<true, T> { typedef T type; };
196 
197  template<typename T1, typename T2, typename T = void>
198  struct Enable_if_same : Enable_if<Same<T1, T2>::value, T> {};
199 
200  template<typename T> struct Remove_const { typedef T type; };
201  template<typename T> struct Remove_const<T const> { typedef T type; };
202  template<typename T> struct Remove_volatile { typedef T type; };
203  template<typename T> struct Remove_volatile<T volatile> { typedef T type; };
204  template<typename T> struct Remove_cv
205  { typedef typename Remove_const<typename Remove_volatile<T>::type>::type type; };
206 
207  template<typename T> struct Remove_pointer { typedef T type; };
208  template<typename T> struct Remove_pointer<T*> { typedef T type; };
209  template<typename T> struct Remove_reference { typedef T type; };
210  template<typename T> struct Remove_reference<T&> { typedef T type; };
211  template<typename T> struct Remove_pr { typedef T type; };
212  template<typename T> struct Remove_pr<T&> { typedef T type; };
213  template<typename T> struct Remove_pr<T*> { typedef T type; };
214 } // Types
215 } // L4