ADTF
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
adtf_iid.h
Go to the documentation of this file.
1
7#pragma once
8
10
11#include <tuple>
12#include <type_traits>
13
19#define ADTF_IID(_interface, _striid) \
20 typedef _interface interface_type; \
21 template<_interface*> \
22 struct interface_info \
23 { \
24 static const char* IID() \
25 { \
26 return _striid; \
27 } \
28 }
29
44#ifndef UCOM_RESOLVE
45 #define UCOM_RESOLVE(...) typedef std::tuple < __VA_ARGS__ > hierarchy_type;
46#endif //UCOM_RESOLVE
47
48namespace adtf
49{
50namespace ucom
51{
52namespace ant
53{
54
55//forward declare for usage in "has_interface_expose_type<>"
56template<typename...> class interface_expose;
57
59namespace detail
60{
61
65template<typename...> struct peel_off_first { typedef void type; };
66
71template<typename T, typename... TRemaining>
72struct peel_off_first<T, TRemaining...>
73{
74 typedef T type;
75};//template<typename T, typename...> struct peel_off
76
81template<typename T>
82struct is_template : std::false_type {};
83
89template<template<typename...> class C, typename ...T>
90struct is_template<C<T...>> : std::true_type {};
91
96template<typename T>
97class has_interface_expose_type
98{
100 struct yes { char x[1]; };
102 struct no { char x[2]; };
103
109 template<typename C> static yes exists(typename C::interface_expose_type*);
115 template<typename C> static no exists(...);
116
117public:
119 static const bool value = sizeof(exists<T>(nullptr)) == sizeof(yes);
120};//template<typename T> class has_interface_expose_type
121
126template<typename T>
127class has_hierarchy_type
128{
130 struct yes { char x[1]; };
132 struct no { char x[2]; };
133
139 template<typename C> static yes exists(typename C::hierarchy_type*);
145 template<typename C> static no exists(...);
146
147public:
149 static const bool value = sizeof(exists<T>(nullptr)) == sizeof(yes);
150};//template<typename T> class has_hierarchy_type
151
152
158template<typename T,
159 typename U = T*>
160class has_interface_info_type
161{
163 struct yes { char x[1]; };
165 struct no { char x[2]; };
166
172 template<typename C>
173 static yes exists(typename C::template interface_info<static_cast<C*>(nullptr)>* = nullptr);
179 template<typename C> static no exists(...);
180
181public:
183 static const bool value = sizeof(exists<T>(nullptr)) == sizeof(yes);
184};//template<typename T> class has_interface_info_type
185
190template<typename QueriedInterface, typename ...>
191class find_intermediate : std::false_type
192{
193public:
195 typedef void* first_type;
197 typedef void* second_type;
199 typedef QueriedInterface query_type;
201 typedef typename std::remove_pointer<second_type>::type value_type;
202};
203
212template<typename QueriedInterface, typename ...HierarchyTypes>
213class find_intermediate<QueriedInterface, std::tuple<HierarchyTypes...>>
214{
216 template<typename...>
217 struct extract_pair
218 {
219 typedef void key_type;
220 typedef void value_type;
221 typedef void tuple_type;
222 };
223
230 template<typename KeyType, typename ValueType, typename... TRemaining>
231 struct extract_pair<KeyType, ValueType, TRemaining...>
232 {
233 typedef KeyType key_type;
234 typedef ValueType value_type;
235 typedef std::tuple<TRemaining...> tuple_type;
236 };
237
239 template<typename...>
240 struct extract_wrapped_pair;
241
249 template<template<typename, typename> class C,
250 typename KeyType,
251 typename ValueType,
252 typename ...TRemaining>
253 struct extract_wrapped_pair<C<KeyType, ValueType>, TRemaining...> :
254 extract_pair<KeyType, ValueType, TRemaining...> {};
255
256 //check whether the first type in the tuple is a template or an ordinary type or empty
257 typedef typename peel_off_first<HierarchyTypes...>::type current_type;
258
259 //check which extract_type pair we need to use (wrapped or unwrapped one)
260 typedef typename
261 std::conditional
262 <
263 is_template<current_type>::value, //check whether wrapped or ordinary key-value-pair
264 extract_wrapped_pair<HierarchyTypes...>,
265 extract_pair<HierarchyTypes...>
266 >::type extract_pair_type;
267
268 //If we found the QueriedInterface as key type of the current extracted key-value-pair,
269 //we can stop here. Otherwise call this for the remaining parameters in the parameter pack
270 typedef typename
271 std::conditional
272 <
273 std::is_same
274 <
275 typename std::remove_cv<QueriedInterface>::type,
276 typename extract_pair_type::key_type
277 >::value,
278 //using pointers as workaround for problems with typedefing the interfaces later...
279 std::pair<typename extract_pair_type::key_type*,
280 typename extract_pair_type::value_type*>,
281 find_intermediate<QueriedInterface, typename extract_pair_type::tuple_type>
282 >::type pair_type;
283
284public:
285 //necessary typedefs for recursive calls
286 typedef typename pair_type::first_type first_type;
287 typedef typename pair_type::second_type second_type;
288
289 //necessary typedefs for the user
290 typedef typename std::remove_pointer<first_type>::type query_type;
291 typedef typename std::remove_pointer<second_type>::type value_type;
292
293 //indicate whether the interface is part of any hierarchy
294 static const bool value = !std::is_void<query_type>::value;
295};//class find_intermediate<QueriedInterface, std::tuple<HierarchyTypes...>>
296
297//forward declaration for @ref ucom_resolve()
298template<typename InterfaceType, bool Cond>
299struct ucom_resolve_helper;
300
309template<typename InterfaceType, typename ObjectType>
310static typename
311 std::enable_if
312 <
313 find_intermediate< InterfaceType, typename ObjectType::hierarchy_type >::value, //condition
314 typename std::conditional //const correct return type
315 <
316 std::is_const<ObjectType>::value,
317 const InterfaceType*,
318 InterfaceType*
319 >::type
320 >::type
321ucom_resolve(ObjectType* i_pObject)
322{ //cast to the intermediate type and pass this intermediate type further down
323 typedef typename
324 find_intermediate
325 <
326 InterfaceType,
327 typename ObjectType::hierarchy_type
328 >::value_type intermediate_type;
329
330 typedef typename
331 std::conditional
332 <
333 std::is_const<ObjectType>::value,
334 const intermediate_type*,
335 intermediate_type*
336 >::type intermediate_pointer;
337
338 intermediate_pointer pIntermediate = i_pObject;
339 return ucom_resolve_helper<InterfaceType,
340 has_hierarchy_type<intermediate_type>::value>::get(pIntermediate);
341}
342
351template<typename InterfaceType, typename ObjectType>
352static typename
353 std::enable_if
354 <
355 !find_intermediate< InterfaceType, typename ObjectType::hierarchy_type >::value,//condition
356 typename std::conditional //const correct return type
357 <
358 std::is_const<ObjectType>::value,
359 const InterfaceType*,
360 InterfaceType*
361 >::type
362 >::type
363ucom_resolve(ObjectType* i_pObject)
364{ //we cannot cast further down, so just return the pointer
365 return i_pObject;
366}
367
372template<typename InterfaceType>
373struct ucom_resolve_helper<InterfaceType, true>
374{
382 template<typename IntermediateType>
383 static typename std::conditional
384 <
385 std::is_const<IntermediateType>::value,
386 const InterfaceType*,
387 InterfaceType*
388 >::type
389 get(IntermediateType* i_pObject)
390 {
391 return ucom_resolve<InterfaceType, IntermediateType>(i_pObject);
392 }
393};
394
399template<typename InterfaceType>
400struct ucom_resolve_helper<InterfaceType, false>
401{
409 template<typename IntermediateType>
410 static typename std::conditional
411 <
412 std::is_const<IntermediateType>::value,
413 const InterfaceType*,
414 InterfaceType*
415 >::type
416 get(IntermediateType* i_pObject)
417 {
418 return i_pObject;
419 }
420};
421
422}//ns detail
424
433template<typename Interface>
434const char* get_iid()
435{
436 using namespace std; //remove_const, remove_pointer, is_same
437 typedef typename remove_const<typename remove_pointer<Interface>::type>::type value_type;
438 static_assert(is_same<value_type, typename value_type::interface_type>::value,
439 "get_iid<> failed. Check whether your interface correctly defined ADTF_IID()");
440
441 constexpr typename value_type::interface_type* pNullInstance = nullptr;
442 (void)(pNullInstance);
443 return value_type::template interface_info<pNullInstance>::IID();
444}
445
450template<typename Interface> const char* get_iid(const Interface&)
451{
452 return get_iid<Interface>();
453}
454
459template<typename Interface> const char* get_iid(const Interface*)
460{
461 return get_iid<Interface>();
462}
463
470template<typename ...Interfaces>
472{
473private:
475
479 template<typename ...InterfacesInner>
480 struct iid_dispatch
481 {
490 template<typename Provider, typename VoidType>
491 static tResult dispatch(Provider*, const char*, VoidType*& o_pInterface)
492 {
493 o_pInterface = nullptr;
494 return ERR_NO_INTERFACE;
495 }
496 };//struct iid_dispatch<InterfacesInner...>
497
503 template<typename Interface, typename ...InterfacesInner>
504 struct iid_dispatch<Interface, InterfacesInner...>
505 {
514 template<typename ObjectType, typename VoidType>
515 static typename std::enable_if<detail::has_hierarchy_type<ObjectType>::value, void>::type
516 resolve(ObjectType* i_pObject, VoidType*& o_pInterface)
517 {
518 o_pInterface = detail::ucom_resolve<Interface>(i_pObject);
519 }
520
529 template<typename ObjectType, typename VoidType>
530 static typename std::enable_if<!detail::has_hierarchy_type<ObjectType>::value, void>::type
531 resolve(ObjectType* i_pObject, VoidType*& o_pInterface)
532 {
533 typedef typename std::conditional
534 <
535 std::is_const<ObjectType>::value,
536 const Interface*,
537 Interface*
538 >::type interface_pointer;
539 o_pInterface = static_cast<interface_pointer>(i_pObject);
540 }
541
557 template<typename Provider, typename VoidType>
558 static tResult dispatch(Provider* i_pObj, const char* i_strIID, VoidType*& o_pInterface)
559 { //if Provider is const, we need a const Interface*
560 using namespace std; //std::conditional, std::is_const
561 if (adtf_util::cStringUtil::IsEqual(get_iid<Interface>(), i_strIID))
562 { //check whether we need to resolve things
563 resolve(i_pObj, o_pInterface);
564 }
565 else
566 {
567 return iid_dispatch<InterfacesInner...>::dispatch(i_pObj, i_strIID, o_pInterface);
568 }
569 return ERR_NOERROR;
570 }
571 };//struct iid_dispatch<Interface, InterfacesInner...>
572
573public:
575 interface_expose() = delete;
576
593 template<typename Provider, typename VoidType>
594 static tResult Get(Provider* i_pObj, const char* i_strIID, VoidType*& o_pInterface)
595 { //check whether VoidType is either of type void or const void
596 static_assert(std::is_void<VoidType>::value, "\"VoidType\" must be of type void");
597 return iid_dispatch<Interfaces...>::dispatch(i_pObj, i_strIID, o_pInterface);
598 }
599};//template<typename ...Interfaces> interface_expose
600
607template<typename...>
608struct inherit_from {};
609
616template<typename ...>
618
623template<typename...>
625
642template<typename Child, typename ...Interfaces, typename ...Parents>
643class default_object<inherit_from<Parents...>,expose_interfaces<Interfaces...>, Child>
644 : public Parents...
645{
646public:
648 typedef interface_expose < Interfaces... > interface_expose_type;
649
650protected:
653 {
654 }
655
671 virtual tResult GetInterface(const char* i_strIID, void*& o_pInterface)
672 { //if there are any UCOM_RESOLVE() information, these are inside the Child type
673 //Use CRTP to perform the cast from this base class to the Child class!
674 static_assert(std::is_base_of<default_object, Child>::value,
675 "The given Child type must be a child type of this default_object type!");
676 return interface_expose_type::Get(static_cast<Child*>(this), i_strIID, o_pInterface);
677 }
678
694 virtual tResult GetInterface(const char* i_strIID, const void*& o_pInterface) const
695 { //if there are any UCOM_RESOLVE() information, these are inside the Child type
696 //Use CRTP to perform the cast from this base class to the Child class!
697 static_assert(std::is_base_of<default_object, Child>::value,
698 "The given Child type must be a child type of this default_object type!");
699 return interface_expose_type::Get(static_cast<const Child*>(this), i_strIID, o_pInterface);
700 }
701
705 [[deprecated("Use of Destroy results in a mismatched deallocation. Use adtf::ucom::allocate_object_ptr "
706 "instead.")]] virtual void
707 Destroy() const
708 {
709 delete this;
710 }
711};//class default_object<inherit_from<Parents...>,expose_interfaces<Interfaces...>>
712
731template<typename BASE_OBJECT, typename EXTEND_INTERFACE, typename Child>
732class extend_object : public BASE_OBJECT, public EXTEND_INTERFACE
733{
734public:
735 typedef BASE_OBJECT base_type;
736
737protected:
739 virtual ~extend_object() {}
740
756 virtual tResult GetInterface(const char* i_strIID, void*& o_pInterface)
757 { //cast this to its child class using CRPT to get possible UCOM_RESOLVE() information
758 static_assert(std::is_base_of<extend_object, Child>::value,
759 "The given Child type must be a child type of this extend_object type!");
760 if (IS_FAILED(interface_expose<EXTEND_INTERFACE>::Get(static_cast<Child*>(this),
761 i_strIID,
762 o_pInterface)))
763 {
764 return BASE_OBJECT::GetInterface(i_strIID, o_pInterface);
765 }
767 }
768
784 virtual tResult GetInterface(const char* i_strIID, const void*& o_pInterface) const
785 { //cast this to its child class using CRPT to get possible UCOM_RESOLVE() information
786 static_assert(std::is_base_of<extend_object, Child>::value,
787 "The given Child type must be a child type of this extend_object type!");
788 if (IS_FAILED(interface_expose<EXTEND_INTERFACE>::Get(static_cast<const Child*>(this),
789 i_strIID,
790 o_pInterface)))
791 {
792 return BASE_OBJECT::GetInterface(i_strIID, o_pInterface);
793 }
795 }
796
800 [[deprecated("Use of Destroy results in a mismatched deallocation. Use adtf::ucom::allocate_object_ptr "
801 "instead.")]] virtual void
802 Destroy() const
803 {
804 delete this;
805 }
806};//template<typename BASE_OBJECT, typename EXTEND_INTERFACE> class extend_object
807
808//template<typename BASE_OBJECT, typename EXTEND_INTERFACE>
809//class extend_object<BASE_OBJECT, EXTEND_INTERFACE, void> :
810// public extend_object
811// <
812// BASE_OBJECT,
813// EXTEND_INTERFACE,
814// extend_object<BASE_OBJECT, EXTEND_INTERFACE>
815// >
816//{};
817
818}//ns ant
819
821using ant::get_iid;
822
824template<typename ...Interfaces>
826
828template<typename ...ParentTypes>
829using inherit_from = ant::inherit_from<ParentTypes...>;
830
832template<typename ...InterfaceTypes>
833using expose_interfaces = ant::expose_interfaces<InterfaceTypes...>;
834
836template<typename ...Types>
838
840template<typename BASE_CLASS, typename EXTEND_INTERFACE, typename Child>
842
843}//ns ucom
844}//ns adtf
Copyright © Audi Electronics Venture GmbH.
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.
interface_expose< Interfaces... > interface_expose_type
Enables accessing the exposed interfaces via typedef (e.g. for ucom_cast<> access)
Definition adtf_iid.h:648
virtual void Destroy() const
Default implementation to destroy an object of this type.
Definition adtf_iid.h:707
virtual tResult GetInterface(const char *i_strIID, const void *&o_pInterface) const
Default implementation of IObject::GetInterface() provided for const correctness.
Definition adtf_iid.h:694
virtual tResult GetInterface(const char *i_strIID, void *&o_pInterface)
Default implementation of IObject::GetInterface()
Definition adtf_iid.h:671
virtual ~default_object()
Protected destructor --> Only the final implementation can be destroyed!
Definition adtf_iid.h:652
Used to implement IObject::GetInterface() methods with given interfaces to expose.
Definition adtf_iid.h:733
virtual ~extend_object()
Protected destructor --> Only the final implementation can be destroyed!
Definition adtf_iid.h:739
virtual void Destroy() const
Default implementation to destroy an object of this type.
Definition adtf_iid.h:802
virtual tResult GetInterface(const char *i_strIID, const void *&o_pInterface) const
Default implementation of IObject::GetInterface() provided for const correctness.
Definition adtf_iid.h:784
virtual tResult GetInterface(const char *i_strIID, void *&o_pInterface)
Default implementation of IObject::GetInterface()
Definition adtf_iid.h:756
BASE_OBJECT base_type
base object type
Definition adtf_iid.h:735
Meta template struct used to expose all interfaces.
Definition adtf_iid.h:472
static tResult Get(Provider *i_pObj, const char *i_strIID, VoidType *&o_pInterface)
Get the interface with IID i_strIID exposed from i_pObj.
Definition adtf_iid.h:594
const char * get_iid()
Get the interface id (IID) of the Interface type.
Definition adtf_iid.h:434
ant::interface_expose< Interfaces... > interface_expose
Alias bringing the latest version of meta struct template interface_expose into scope.
Definition adtf_iid.h:825
ant::extend_object< BASE_CLASS, EXTEND_INTERFACE, Child > extend_object
Alias bringing the latest version of meta struct template extend_object into scope.
Definition adtf_iid.h:841
ant::inherit_from< ParentTypes... > inherit_from
Alias bringing the latest version of meta struct template inherit_from into scope.
Definition adtf_iid.h:829
ant::default_object< Types... > default_object
Alias bringing the latest version of meta struct template default_object into scope.
Definition adtf_iid.h:837
ant::expose_interfaces< InterfaceTypes... > expose_interfaces
Alias bringing the latest version of meta struct template expose_interfaces into scope.
Definition adtf_iid.h:833
Namespace for entire ADTF SDK.
Declares the class to use when implementing GetInterface using inheritance.
Definition adtf_iid.h:624
Meta struct template evaluated at compile time when compiling default_object.
Definition adtf_iid.h:617
Meta struct template evaluated at compile time when compiling default_object.
Definition adtf_iid.h:608