ADTF
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
object.h
Go to the documentation of this file.
1
7#pragma once
8
9namespace adtf
10{
11namespace ucom
12{
13namespace catwo
14{
15namespace detail
16{
17
19template<typename T>
20class has_interface_type : private T
21{
22 typedef char one;
23 typedef long two;
24
25 template<typename C> static one test(typename C::interface_type*);
26 template<typename C> static two test(...);
27
28public:
29 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) };
30};
31
32template <typename T>
33using is_interface_helper = std::is_same<T, typename T::interface_type>; // see get_iid
34
36template<typename T, typename Enable = void>
38
39template<typename T>
40struct is_interface<T, typename std::enable_if<!has_interface_type<T>::value>::type> : std::false_type
41{
42};
43
44template<typename T>
45struct is_interface<T, typename std::enable_if<has_interface_type<T>::value && !is_interface_helper<T>::value>::type> : std::false_type
46{
47};
48
49template<typename T>
50struct is_interface<T, typename std::enable_if<has_interface_type<T>::value && is_interface_helper<T>::value>::type> : std::true_type
51{
52};
53
55template <typename T>
56class has_get_interface: private T
57{
58 typedef char one;
59 typedef long two;
60
61 template <typename C> static one test(decltype(static_cast<tResult(T::*)(const char*, void*&)>(&has_get_interface<C>::GetInterface)));
62 template <typename C> static two test(...);
63
64public:
65 enum { value = sizeof(test<T>(static_cast<tResult(T::*)(const char*, void*&)>(nullptr))) == sizeof(char) };
66};
67
68// template that dispatches type resolution to static error, dynamic GetInterface or inline type comparison
69template<typename BaseClass, typename Enable = void>
71
72template<>
73struct base_dispatcher<void, void>
74{
75protected:
76 virtual ~base_dispatcher() = default;
77
78 inline tResult GetInterfaceStatic(const char* /* i_strIID */, void*& /* o_pInterface */)
79 {
80 RETURN_ERROR(ERR_NO_INTERFACE);
81 }
82
83 inline tResult GetInterfaceStatic(const char* /* i_strIID */, const void*& /* o_pInterface */) const
84 {
85 RETURN_ERROR(ERR_NO_INTERFACE);
86 }
87
88public:
89 enum { dispatch = false };
90};
91
92
94template<typename BaseClass>
95struct base_dispatcher<BaseClass, typename std::enable_if<!is_interface<BaseClass>::value && !has_get_interface<BaseClass>::value>::type> :
96 public BaseClass
97{
98 protected:
99 using BaseClass::BaseClass;
100
101 virtual ~base_dispatcher() = default;
102
103 inline tResult GetInterfaceStatic(const char* /* i_strIID */, void*& /* o_pInterface */)
104 {
105 RETURN_ERROR(ERR_NO_INTERFACE);
106 }
107
108 inline tResult GetInterfaceStatic(const char* /* i_strIID */, const void*& /* o_pInterface */) const
109 {
110 RETURN_ERROR(ERR_NO_INTERFACE);
111 }
112};
113
114
116template <typename BaseClass>
117struct base_dispatcher<BaseClass, typename std::enable_if<!is_interface<BaseClass>::value && has_get_interface<BaseClass>::value>::type> :
118 public BaseClass
119{
120 protected:
121 using BaseClass::BaseClass;
122
123 virtual ~base_dispatcher() = default;
124
125 inline tResult GetInterfaceStatic(const char* i_strIID, void*& o_pInterface)
126 {
127 return BaseClass::GetInterface(i_strIID, o_pInterface);
128 }
129
130 inline tResult GetInterfaceStatic(const char* i_strIID, const void*& o_pInterface) const
131 {
132 return BaseClass::GetInterface(i_strIID, o_pInterface);
133 }
134};
135
137template <typename Interface>
138struct base_dispatcher<Interface, typename std::enable_if<is_interface<Interface>::value>::type>:
139 Interface
140{
141 protected:
142 using Interface::Interface;
143
144 virtual ~base_dispatcher() = default;
145
146 inline tResult GetInterfaceStatic(const char* i_strIID, void*& o_pInterface)
147 {
148 if (util::cStringUtil::IsEqual(ucom::get_iid<Interface>(), i_strIID))
149 {
150 o_pInterface = static_cast<Interface*>(this);
152 }
153
154 RETURN_ERROR(ERR_NO_INTERFACE);
155 }
156
157 inline tResult GetInterfaceStatic(const char* i_strIID, const void*& o_pInterface) const
158 {
159 if (util::cStringUtil::IsEqual(ucom::get_iid<Interface>(), i_strIID))
160 {
161 o_pInterface = static_cast<const Interface*>(this);
163 }
164
165 RETURN_ERROR(ERR_NO_INTERFACE);
166 }
167};
168
171template <typename Base, typename NextBase>
173 public base_dispatcher<Base>,
174 public base_dispatcher<NextBase>
175{
176 protected:
178
179 tResult GetInterface(const char* i_strIID, void*& o_pInterface)
180 {
181 if (IS_OK(base_dispatcher<Base>::GetInterfaceStatic(i_strIID, o_pInterface)))
182 {
184 }
185
186 return base_dispatcher<NextBase>::GetInterfaceStatic(i_strIID, o_pInterface);
187 }
188
189 tResult GetInterface(const char* i_strIID, const void*& o_pInterface) const
190 {
191 if (IS_OK(base_dispatcher<Base>::GetInterfaceStatic(i_strIID, o_pInterface)))
192 {
194 }
195
196 return base_dispatcher<NextBase>::GetInterfaceStatic(i_strIID, o_pInterface);
197 }
198
199 // Base interface is deprecated, but still needs to be overloaded to be able to correctly call the destructor.
200#if defined(__GNUC__)
201 #pragma GCC diagnostic push
202 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
203#endif
205 void Destroy() const
206 {
207 delete this;
208 }
209#if defined(__GNUC__)
210 #pragma GCC diagnostic pop
211#endif
212};
213
216template <typename Base, typename NextBase>
218 public derive_from_without_hierarchy<Base, NextBase>
219{
220 public:
222
223 protected:
225};
226
227template<typename Base, typename ...Interfaces>
229{
230 protected:
232
233 tResult GetInterface(const char* i_strIID, void*& o_pInterface)
234 {
235 if (IS_OK(detail::base_dispatcher<Base>::GetInterfaceStatic(i_strIID, o_pInterface)))
236 {
238 }
239 return ucom::ant::interface_expose<Interfaces...>::Get(this, i_strIID, o_pInterface);
240 }
241
242 tResult GetInterface(const char* i_strIID, const void*& o_pInterface) const
243 {
244 if (IS_OK(detail::base_dispatcher<Base>::GetInterfaceStatic(i_strIID, o_pInterface)))
245 {
247 }
248 return ucom::ant::interface_expose<Interfaces...>::Get(this, i_strIID, o_pInterface);
249 }
250
251 // Base interface is deprecated, but still needs to be overloaded to be able to correctly call the destructor.
252#if defined(__GNUC__)
253 #pragma GCC diagnostic push
254 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
255#endif
257 void Destroy() const
258 {
259 delete this;
260 }
261#if defined(__GNUC__)
262 #pragma GCC diagnostic pop
263#endif
264};
265
267template <typename ...Bases>
269{
270};
271
273template <typename Base, typename NextBase>
274using derive_from_type = typename std::conditional<std::is_same<NextBase, object_without_iobject<>>::value,
276 typename std::conditional<std::is_base_of<Base, NextBase>::value,
278 typename std::conditional<std::is_base_of<ucom::ant::IObject, Base>::value,
281
285template <typename Base, typename NextBase>
286class derive_from: public derive_from_type<Base, NextBase>
287{
288 public:
289 using derive_from_type<Base, NextBase>::derive_from_type;
290};
291
293template <typename ...Bases>
294struct parent_follows_child: std::false_type
295{
296};
297
299template <typename Base, typename NextBase, typename ...Bases>
300struct parent_follows_child<Base, NextBase, Bases...>:
301 std::conditional<!std::is_same<NextBase, Base>::value &&
302 std::is_base_of<NextBase, Base>::value,
303 std::true_type,
304 parent_follows_child<Base, Bases...>>::type
305{
306};
307
309template <typename Base, typename ...Bases>
310class object_without_iobject<Base, Bases...>:
311 public derive_from<Base, object_without_iobject<Bases...>>
312{
313 public:
314 object_without_iobject()
315 {
316 static_assert(!detail::parent_follows_child<Base, Bases...>::value,
317 "One or more of the template parameters are in the wrong order. "
318 "Make sure that derived classes are specified after their parents.");
319 }
320
321 protected:
322 using derive_from<Base, object_without_iobject<Bases...>>::derive_from;
323};
324
325}//detail
326
394template <typename ...Bases>
395class object:
396 public ucom::ant::IObject
397{
398 public:
399 virtual ~object() = default;
400
401 tResult GetInterface(const char* i_strIID, void*& o_pInterface) override
402 {
403 return ucom::ant::interface_expose<ucom::ant::IObject>::Get(this, i_strIID, o_pInterface);
404 }
405
406 tResult GetInterface(const char* i_strIID, const void*& o_pInterface) const override
407 {
408 return ucom::ant::interface_expose<ucom::ant::IObject>::Get(this, i_strIID, o_pInterface);
409 }
410
411 // Base interface is deprecated, but still needs to be overloaded to be able to correctly call the destructor.
412#if defined(__GNUC__)
413 #pragma GCC diagnostic push
414 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
415#endif
417 void Destroy() const override
418 {
419 delete this;
420 }
421#if defined(__GNUC__)
422 #pragma GCC diagnostic pop
423#endif
424};
425
426// Workaround for MSVC bug where writing this template inline twice would not be recognized as being the same base class
427template<typename Base, typename... Bases>
428using object_base_type_helper =
429 typename std::conditional<std::is_base_of<object<>, Base>::value,
430 detail::derive_from<Base, detail::object_without_iobject<Bases...>>,
431 detail::derive_from<Base, object<Bases...>>>::type;
432
434template<typename Base, typename... Bases>
435class object<Base, Bases...> : public object_base_type_helper<Base, Bases...>
436{
437public:
438 using object_base_type_helper<Base, Bases...>::object_base_type_helper;
439
440 object()
441 {
442 static_assert(!detail::parent_follows_child<Base, Bases...>::value,
443 "One or more of the template parameters are in the wrong order. "
444 "Make sure that derived classes are specified after their parents.");
445 }
446};
447
448}//namespace catwo
449
450using catwo::object;
451
452}//namespace ucom
453}//namespace adtf
#define UCOM_RESOLVE(...)
Resolve a path to a base class which is inherited multiple times.
Definition adtf_iid.h:45
A_UTILS_NS::cResult tResult
For backwards compatibility and to bring latest version into scope.
#define RETURN_NOERROR
Return status ERR_NOERROR, which requires the calling function's return type to be tResult.
#define RETURN_ERROR(code)
Return specific error code, which requires the calling function's return type to be tResult.
Base class for every interface type within the uCOM.
Definition object_intf.h:33
static tResult Get(Provider *i_pObj, const char *i_strIID, VoidType *&o_pInterface)
Definition adtf_iid.h:594
This template checks if the first base implements the requested interface, otherwise checks the next ...
Definition object.h:219
This template checks if the first base implements the requested interface, otherwise checks the next ...
Definition object.h:175
void Destroy() const
Possibly required override of IObject::Destroy() while destructor is still non-virtual.
Definition object.h:205
This template checks if the first base implements the requested interface, otherwise checks the next ...
Definition object.h:287
void Destroy() const
Possibly required override of IObject::Destroy() while destructor is still non-virtual.
Definition object.h:257
template that checks whether a type has an accessible (protected or public) GetInterface method.
Definition object.h:57
template that checks whether a type has an accessible interface_type property.
Definition object.h:21
This template is used to prevent an ambiguous base of ucom::ant::IObject.
Definition object.h:269
Use this template if you want to implement an ucom::ant::IObject based Interface and/or subclass an e...
Definition object.h:397
void Destroy() const override
Switch from non-virtual destructor to virtual destructor.
Definition object.h:417
tResult GetInterface(const char *i_strIID, const void *&o_pInterface) const override
Provides const correct interface querying.
Definition object.h:406
tResult GetInterface(const char *i_strIID, void *&o_pInterface) override
Query interfaces on an object.
Definition object.h:401
Namespace for all internally used uCOM functionality implemented.
typename std::conditional< std::is_same< NextBase, object_without_iobject<> >::value, expose_additional_interfaces< Base >, typename std::conditional< std::is_base_of< Base, NextBase >::value, expose_additional_interfaces< NextBase, Base >, typename std::conditional< std::is_base_of< ucom::ant::IObject, Base >::value, derive_from_with_hierarchy< Base, NextBase >, derive_from_without_hierarchy< Base, NextBase > >::type >::type >::type derive_from_type
this intermediate type is used to keep binary compatibility
Definition object.h:274
Namespace for all functionality provided since v3.2.
Namespace for the ADTF uCOM3 SDK.
const char * get_iid()
Alias bringing the latest version of get_iid() into scope.
Definition adtf_iid.h:434
Namespace for entire ADTF SDK.
template that checks whether a type is an interface with an IID.
Definition object.h:37
this template checks if parent interfaces are not specified before their children
Definition object.h:295