iceoryx_doc  1.0.1
variant_internal.hpp
1 // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // SPDX-License-Identifier: Apache-2.0
16 #ifndef IOX_UTILS_CXX_VARIANT_INTERNAL_HPP
17 #define IOX_UTILS_CXX_VARIANT_INTERNAL_HPP
18 
19 #include <assert.h>
20 #include <cstdint>
21 #include <type_traits>
22 #include <utility>
23 
24 namespace iox
25 {
26 namespace cxx
27 {
28 namespace internal
29 {
30 using byte_t = uint8_t;
31 template <typename TypeToCheck, typename T, typename... Targs>
33 {
34  static constexpr bool value =
35  std::is_same<TypeToCheck, T>::value || does_contain_type<TypeToCheck, Targs...>::value;
36 };
37 
38 template <typename TypeToCheck, typename T>
39 struct does_contain_type<TypeToCheck, T>
40 {
41  static constexpr bool value = std::is_same<TypeToCheck, T>::value;
42 };
43 
44 template <uint64_t N, typename Type, typename T, typename... Targs>
46 {
47  static constexpr uint64_t index = get_index_of_type<N + 1, Type, Targs...>::index;
48 };
49 
50 template <uint64_t N, typename Type, typename... Targs>
51 struct get_index_of_type<N, Type, Type, Targs...>
52 {
53  static constexpr uint64_t index = N;
54 };
55 
56 template <uint64_t N, uint64_t Index, typename T, typename... Targs>
58 {
59  using type = typename get_type_at_index<N + 1, Index, Targs...>::type;
60 };
61 
62 template <uint64_t N, typename T, typename... Targs>
63 struct get_type_at_index<N, N, T, Targs...>
64 {
65  using type = T;
66 };
67 
68 template <uint64_t N, typename T, typename... Targs>
70 {
71  static void destructor(const uint64_t index, byte_t* ptr)
72  {
73  if (N == index)
74  {
75  reinterpret_cast<T*>(ptr)->~T();
76  }
77  else
78  {
80  }
81  }
82 
83  static void move(const uint64_t index, byte_t* source, byte_t* destination)
84  {
85  if (N == index)
86  {
87  *reinterpret_cast<T*>(destination) = std::move(*reinterpret_cast<T*>(source));
88  }
89  else
90  {
91  call_at_index<N + 1, Targs...>::move(index, source, destination);
92  }
93  }
94 
95  static void moveConstructor(const uint64_t index, byte_t* source, byte_t* destination)
96  {
97  if (N == index)
98  {
99  new (destination) T(std::move(*reinterpret_cast<T*>(source)));
100  }
101  else
102  {
103  call_at_index<N + 1, Targs...>::moveConstructor(index, source, destination);
104  }
105  }
106 
107  static void copy(const uint64_t index, byte_t* source, byte_t* destination)
108  {
109  if (N == index)
110  {
111  *reinterpret_cast<T*>(destination) = *reinterpret_cast<T*>(source);
112  }
113  else
114  {
115  call_at_index<N + 1, Targs...>::copy(index, source, destination);
116  }
117  }
118 
119  static void copyConstructor(const uint64_t index, byte_t* source, byte_t* destination)
120  {
121  if (N == index)
122  {
123  new (destination) T(*reinterpret_cast<T*>(source));
124  }
125  else
126  {
127  call_at_index<N + 1, Targs...>::copyConstructor(index, source, destination);
128  }
129  }
130 };
131 
132 template <uint64_t N, typename T>
133 struct call_at_index<N, T>
134 {
135  static void destructor(const uint64_t index, byte_t* ptr)
136  {
137  if (N == index)
138  {
139  reinterpret_cast<T*>(ptr)->~T();
140  }
141  else
142  {
143  assert(false && "Could not call destructor for variant element");
144  }
145  }
146 
147  static void move(const uint64_t index, byte_t* source, byte_t* destination)
148  {
149  if (N == index)
150  {
151  *reinterpret_cast<T*>(destination) = std::move(*reinterpret_cast<T*>(source));
152  }
153  else
154  {
155  assert(false && "Could not call move assignment for variant element");
156  }
157  }
158 
159  static void moveConstructor(const uint64_t index, byte_t* source, byte_t* destination)
160  {
161  if (N == index)
162  {
163  new (destination) T(std::move(*reinterpret_cast<T*>(source)));
164  }
165  else
166  {
167  assert(false && "Could not call move constructor for variant element");
168  }
169  }
170 
171  static void copy(const uint64_t index, byte_t* source, byte_t* destination)
172  {
173  if (N == index)
174  {
175  *reinterpret_cast<T*>(destination) = *reinterpret_cast<T*>(source);
176  }
177  else
178  {
179  assert(false && "Could not call copy assignment for variant element");
180  }
181  }
182 
183  static void copyConstructor(const uint64_t index, byte_t* source, byte_t* destination)
184  {
185  if (N == index)
186  {
187  new (destination) T(*reinterpret_cast<T*>(source));
188  }
189  else
190  {
191  assert(false && "Could not call copy constructor for variant element");
192  }
193  }
194 };
195 
196 } // namespace internal
197 } // namespace cxx
198 } // namespace iox
199 
200 #endif // IOX_UTILS_CXX_VARIANT_INTERNAL_HPP
building block to easily create free function for logging in a library context
Definition: lockfree_queue.hpp:28
Definition: variant_internal.hpp:70
Definition: variant_internal.hpp:33
Definition: variant_internal.hpp:46
Definition: variant_internal.hpp:58