ADTF
adtf_iid.h
Go to the documentation of this file.
1 
8 #ifndef _ADTF_UCOM_ANT_ADTF_IID_HEADER_
9 #define _ADTF_UCOM_ANT_ADTF_IID_HEADER_
10 
11 #ifndef ADTF_IID
17  #define ADTF_IID(_interface, _striid) \
18  typedef _interface interface_type; \
19  template<_interface*> struct interface_info \
20  { \
21  static const char* IID() { return _striid; } \
22  }
23 #endif //ADTF_IID
24 
39 #ifndef UCOM_RESOLVE
40  #define UCOM_RESOLVE(...) typedef std::tuple < __VA_ARGS__ > hierarchy_type;
41 #endif //UCOM_RESOLVE
42 
43 namespace adtf
44 {
45 namespace ucom
46 {
47 namespace ant
48 {
49 
50 //forward declare for usage in "has_interface_expose_type<>"
51 template<typename...> class interface_expose;
52 
54 namespace detail
55 {
56 
60 template<typename...> struct peel_off_first { typedef void type; };
61 
66 template<typename T, typename... TRemaining>
67 struct peel_off_first<T, TRemaining...>
68 {
69  typedef T type;
70 };//template<typename T, typename...> struct peel_off
71 
76 template<typename T>
77 struct is_template : std::false_type {};
78 
84 template<template<typename...> class C, typename ...T>
85 struct is_template<C<T...>> : std::true_type {};
86 
91 template<typename T>
92 class has_interface_expose_type
93 {
95  struct yes { char x[1]; };
97  struct no { char x[2]; };
98 
104  template<typename C> static yes exists(typename C::interface_expose_type*);
110  template<typename C> static no exists(...);
111 
112 public:
114  static const bool value = sizeof(exists<T>(nullptr)) == sizeof(yes);
115 };//template<typename T> class has_interface_expose_type
116 
121 template<typename T>
122 class has_hierarchy_type
123 {
125  struct yes { char x[1]; };
127  struct no { char x[2]; };
128 
134  template<typename C> static yes exists(typename C::hierarchy_type*);
140  template<typename C> static no exists(...);
141 
142 public:
144  static const bool value = sizeof(exists<T>(nullptr)) == sizeof(yes);
145 };//template<typename T> class has_hierarchy_type
146 
147 
153 template<typename T,
154  typename U = T*>
155 class has_interface_info_type
156 {
158  struct yes { char x[1]; };
160  struct no { char x[2]; };
161 
167  template<typename C>
168  static yes exists(typename C::template interface_info<static_cast<C*>(nullptr)>* = nullptr);
174  template<typename C> static no exists(...);
175 
176 public:
178  static const bool value = sizeof(exists<T>(nullptr)) == sizeof(yes);
179 };//template<typename T> class has_interface_info_type
180 
185 template<typename QueriedInterface, typename ...>
186 class find_intermediate : std::false_type
187 {
188 public:
190  typedef void* first_type;
192  typedef void* second_type;
194  typedef QueriedInterface query_type;
196  typedef typename std::remove_pointer<second_type>::type value_type;
197 };
198 
207 template<typename QueriedInterface, typename ...HierarchyTypes>
208 class find_intermediate<QueriedInterface, std::tuple<HierarchyTypes...>>
209 {
211  template<typename...>
212  struct extract_pair
213  {
214  typedef void key_type;
215  typedef void value_type;
216  typedef void tuple_type;
217  };
218 
225  template<typename KeyType, typename ValueType, typename... TRemaining>
226  struct extract_pair<KeyType, ValueType, TRemaining...>
227  {
228  typedef KeyType key_type;
229  typedef ValueType value_type;
230  typedef std::tuple<TRemaining...> tuple_type;
231  };
232 
234  template<typename...>
235  struct extract_wrapped_pair;
236 
244  template<template<typename, typename> class C,
245  typename KeyType,
246  typename ValueType,
247  typename ...TRemaining>
248  struct extract_wrapped_pair<C<KeyType, ValueType>, TRemaining...> :
249  extract_pair<KeyType, ValueType, TRemaining...> {};
250 
251  //check whether the first type in the tuple is a template or an ordinary type or empty
252  typedef typename peel_off_first<HierarchyTypes...>::type current_type;
253 
254  //check which extract_type pair we need to use (wrapped or unwrapped one)
255  typedef typename
256  std::conditional
257  <
258  is_template<current_type>::value, //check whether wrapped or ordinary key-value-pair
259  extract_wrapped_pair<HierarchyTypes...>,
260  extract_pair<HierarchyTypes...>
261  >::type extract_pair_type;
262 
263  //If we found the QueriedInterface as key type of the current extracted key-value-pair,
264  //we can stop here. Otherwise call this for the remaining parameters in the parameter pack
265  typedef typename
266  std::conditional
267  <
268  std::is_same
269  <
270  typename std::remove_cv<QueriedInterface>::type,
271  typename extract_pair_type::key_type
272  >::value,
273  //using pointers as workaround for problems with typedefing the interfaces later...
274  std::pair<typename extract_pair_type::key_type*,
275  typename extract_pair_type::value_type*>,
276  find_intermediate<QueriedInterface, typename extract_pair_type::tuple_type>
277  >::type pair_type;
278 
279 public:
280  //necessary typedefs for recursive calls
281  typedef typename pair_type::first_type first_type;
282  typedef typename pair_type::second_type second_type;
283 
284  //necessary typedefs for the user
285  typedef typename std::remove_pointer<first_type>::type query_type;
286  typedef typename std::remove_pointer<second_type>::type value_type;
287 
288  //indicate whether the interface is part of any hierarchy
289  static const bool value = !std::is_void<query_type>::value;
290 };//class find_intermediate<QueriedInterface, std::tuple<HierarchyTypes...>>
291 
292 //forward declaration for @ref ucom_resolve()
293 template<typename InterfaceType, bool Cond>
294 struct ucom_resolve_helper;
295 
304 template<typename InterfaceType, typename ObjectType>
305 static typename
306  std::enable_if
307  <
308  find_intermediate< InterfaceType, typename ObjectType::hierarchy_type >::value, //condition
309  typename std::conditional //const correct return type
310  <
311  std::is_const<ObjectType>::value,
312  const InterfaceType*,
313  InterfaceType*
314  >::type
315  >::type
316 ucom_resolve(ObjectType* i_pObject)
317 { //cast to the intermediate type and pass this intermediate type further down
318  typedef typename
319  find_intermediate
320  <
321  InterfaceType,
322  typename ObjectType::hierarchy_type
323  >::value_type intermediate_type;
324 
325  typedef typename
326  std::conditional
327  <
328  std::is_const<ObjectType>::value,
329  const intermediate_type*,
330  intermediate_type*
331  >::type intermediate_pointer;
332 
333  intermediate_pointer pIntermediate = i_pObject;
334  return ucom_resolve_helper<InterfaceType,
335  has_hierarchy_type<intermediate_type>::value>::get(pIntermediate);
336 }
337 
346 template<typename InterfaceType, typename ObjectType>
347 static typename
348  std::enable_if
349  <
350  !find_intermediate< InterfaceType, typename ObjectType::hierarchy_type >::value,//condition
351  typename std::conditional //const correct return type
352  <
353  std::is_const<ObjectType>::value,
354  const InterfaceType*,
355  InterfaceType*
356  >::type
357  >::type
358 ucom_resolve(ObjectType* i_pObject)
359 { //we cannot cast further down, so just return the pointer
360  return i_pObject;
361 }
362 
367 template<typename InterfaceType>
368 struct ucom_resolve_helper<InterfaceType, true>
369 {
377  template<typename IntermediateType>
378  static typename std::conditional
379  <
380  std::is_const<IntermediateType>::value,
381  const InterfaceType*,
382  InterfaceType*
383  >::type
384  get(IntermediateType* i_pObject)
385  {
386  return ucom_resolve<InterfaceType, IntermediateType>(i_pObject);
387  }
388 };
389 
394 template<typename InterfaceType>
395 struct ucom_resolve_helper<InterfaceType, false>
396 {
404  template<typename IntermediateType>
405  static typename std::conditional
406  <
407  std::is_const<IntermediateType>::value,
408  const InterfaceType*,
409  InterfaceType*
410  >::type
411  get(IntermediateType* i_pObject)
412  {
413  return i_pObject;
414  }
415 };
416 
417 }//ns detail
419 
428 template<typename Interface>
429 const char* get_iid()
430 {
431  using namespace std; //remove_const, remove_pointer, is_same
432  typedef typename remove_const<typename remove_pointer<Interface>::type>::type value_type;
433  static_assert(is_same<value_type, typename value_type::interface_type>::value,
434  "get_iid<> failed. Check whether your interface correctly defined ADTF_IID()");
435 
436  constexpr typename value_type::interface_type* pNullInstance = nullptr;
437  (void)(pNullInstance);
438  return value_type::template interface_info<pNullInstance>::IID();
439 }
440 
445 template<typename Interface> const char* get_iid(const Interface&)
446 {
447  return get_iid<Interface>();
448 }
449 
454 template<typename Interface> const char* get_iid(const Interface*)
455 {
456  return get_iid<Interface>();
457 }
458 
465 template<typename ...Interfaces>
467 {
468 private:
470 
474  template<typename ...InterfacesInner>
475  struct iid_dispatch
476  {
485  template<typename Provider, typename VoidType>
486  static tResult dispatch(Provider*, const char*, VoidType*& o_pInterface)
487  {
488  o_pInterface = nullptr;
489  return ERR_NO_INTERFACE;
490  }
491  };//struct iid_dispatch<InterfacesInner...>
492 
498  template<typename Interface, typename ...InterfacesInner>
499  struct iid_dispatch<Interface, InterfacesInner...>
500  {
509  template<typename ObjectType, typename VoidType>
510  static typename std::enable_if<detail::has_hierarchy_type<ObjectType>::value, void>::type
511  resolve(ObjectType* i_pObject, VoidType*& o_pInterface)
512  {
513  o_pInterface = detail::ucom_resolve<Interface>(i_pObject);
514  }
515 
524  template<typename ObjectType, typename VoidType>
525  static typename std::enable_if<!detail::has_hierarchy_type<ObjectType>::value, void>::type
526  resolve(ObjectType* i_pObject, VoidType*& o_pInterface)
527  {
528  typedef typename std::conditional
529  <
530  std::is_const<ObjectType>::value,
531  const Interface*,
532  Interface*
533  >::type interface_pointer;
534  o_pInterface = static_cast<interface_pointer>(i_pObject);
535  }
536 
552  template<typename Provider, typename VoidType>
553  static tResult dispatch(Provider* i_pObj, const char* i_strIID, VoidType*& o_pInterface)
554  { //if Provider is const, we need a const Interface*
555  using namespace std; //std::conditional, std::is_const
556  if (adtf_util::cStringUtil::IsEqual(get_iid<Interface>(), i_strIID))
557  { //check whether we need to resolve things
558  resolve(i_pObj, o_pInterface);
559  }
560  else
561  {
562  return iid_dispatch<InterfacesInner...>::dispatch(i_pObj, i_strIID, o_pInterface);
563  }
564  return ERR_NOERROR;
565  }
566  };//struct iid_dispatch<Interface, InterfacesInner...>
567 
568 public:
570  interface_expose() = delete;
571 
588  template<typename Provider, typename VoidType>
589  static tResult Get(Provider* i_pObj, const char* i_strIID, VoidType*& o_pInterface)
590  { //check whether VoidType is either of type void or const void
591  static_assert(std::is_void<VoidType>::value, "\"VoidType\" must be of type void");
592  return iid_dispatch<Interfaces...>::dispatch(i_pObj, i_strIID, o_pInterface);
593  }
594 };//template<typename ...Interfaces> interface_expose
595 
602 template<typename...>
603 struct inherit_from {};
604 
611 template<typename ...>
613 
618 template<typename...>
620 
637 template<typename Child, typename ...Interfaces, typename ...Parents>
638 class default_object<inherit_from<Parents...>,expose_interfaces<Interfaces...>, Child>
639  : public Parents...
640 {
641 public:
643  typedef interface_expose < Interfaces... > interface_expose_type;
644 
645 protected:
649  virtual ~default_object()
650  {
651  }
652 
668  virtual tResult GetInterface(const char* i_strIID, void*& o_pInterface)
669  { //if there are any UCOM_RESOLVE() information, these are inside the Child type
670  //Use CRTP to perform the cast from this base class to the Child class!
671  static_assert(std::is_base_of<default_object, Child>::value,
672  "The given Child type must be a child type of this default_object type!");
673  return interface_expose_type::Get(static_cast<Child*>(this), i_strIID, o_pInterface);
674  }
675 
691  virtual tResult GetInterface(const char* i_strIID, const void*& o_pInterface) const
692  { //if there are any UCOM_RESOLVE() information, these are inside the Child type
693  //Use CRTP to perform the cast from this base class to the Child class!
694  static_assert(std::is_base_of<default_object, Child>::value,
695  "The given Child type must be a child type of this default_object type!");
696  return interface_expose_type::Get(static_cast<const Child*>(this), i_strIID, o_pInterface);
697  }
698 
702  virtual void Destroy() const
703  {
704  delete this;
705  }
706 };//class default_object<inherit_from<Parents...>,expose_interfaces<Interfaces...>>
707 
726 template<typename BASE_OBJECT, typename EXTEND_INTERFACE, typename Child>
727 class extend_object : public BASE_OBJECT, public EXTEND_INTERFACE
728 {
729 public:
730  typedef BASE_OBJECT base_type;
731 
732 protected:
736  virtual ~extend_object() {}
737 
753  virtual tResult GetInterface(const char* i_strIID, void*& o_pInterface)
754  { //cast this to its child class using CRPT to get possible UCOM_RESOLVE() information
755  static_assert(std::is_base_of<extend_object, Child>::value,
756  "The given Child type must be a child type of this extend_object type!");
757  if (IS_FAILED(interface_expose<EXTEND_INTERFACE>::Get(static_cast<Child*>(this),
758  i_strIID,
759  o_pInterface)))
760  {
761  return BASE_OBJECT::GetInterface(i_strIID, o_pInterface);
762  }
764  }
765 
781  virtual tResult GetInterface(const char* i_strIID, const void*& o_pInterface) const
782  { //cast this to its child class using CRPT to get possible UCOM_RESOLVE() information
783  static_assert(std::is_base_of<extend_object, Child>::value,
784  "The given Child type must be a child type of this extend_object type!");
785  if (IS_FAILED(interface_expose<EXTEND_INTERFACE>::Get(static_cast<const Child*>(this),
786  i_strIID,
787  o_pInterface)))
788  {
789  return BASE_OBJECT::GetInterface(i_strIID, o_pInterface);
790  }
792  }
793 
797  virtual void Destroy() const
798  {
799  delete this;
800  }
801 };//template<typename BASE_OBJECT, typename EXTEND_INTERFACE> class extend_object
802 
803 //template<typename BASE_OBJECT, typename EXTEND_INTERFACE>
804 //class extend_object<BASE_OBJECT, EXTEND_INTERFACE, void> :
805 // public extend_object
806 // <
807 // BASE_OBJECT,
808 // EXTEND_INTERFACE,
809 // extend_object<BASE_OBJECT, EXTEND_INTERFACE>
810 // >
811 //{};
812 
813 }//ns ant
814 
816 using ant::get_iid;
817 
819 template<typename ...Interfaces>
821 
823 template<typename ...ParentTypes>
824 using inherit_from = ant::inherit_from<ParentTypes...>;
825 
827 template<typename ...InterfaceTypes>
828 using expose_interfaces = ant::expose_interfaces<InterfaceTypes...>;
829 
831 template<typename ...Types>
833 
835 template<typename BASE_CLASS, typename EXTEND_INTERFACE, typename Child>
837 
838 }//ns ucom
839 }//ns adtf
840 
841 #endif //_ADTF_UCOM_ANT_ADTF_IID_HEADER_
#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:643
virtual void Destroy() const
Default implementation to destroy an object of this type.
Definition: adtf_iid.h:702
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:691
virtual tResult GetInterface(const char *i_strIID, void *&o_pInterface)
Default implementation of IObject::GetInterface()
Definition: adtf_iid.h:668
virtual ~default_object()
Virtual destructor needed for call to this->Destroy()
Definition: adtf_iid.h:649
Used to implement IObject::GetInterface() methods with given interfaces to expose.
Definition: adtf_iid.h:728
virtual ~extend_object()
Virtual destructor needed for call to this->Destroy()
Definition: adtf_iid.h:736
virtual void Destroy() const
Default implementation to destroy an object of this type.
Definition: adtf_iid.h:797
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:781
virtual tResult GetInterface(const char *i_strIID, void *&o_pInterface)
Default implementation of IObject::GetInterface()
Definition: adtf_iid.h:753
BASE_OBJECT base_type
base object type
Definition: adtf_iid.h:730
Meta template struct used to expose all interfaces.
Definition: adtf_iid.h:467
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:589
bool exists(const Path &path)
Check whether the file or directory exists on the filesystem.
const char * get_iid()
Get the interface id (IID) of the Interface type.
Definition: adtf_iid.h:429
ant::interface_expose< Interfaces... > interface_expose
Alias bringing the latest version of meta struct template ant::interface_expose into scope.
Definition: adtf_iid.h:820
ant::default_object< Types... > default_object
Alias bringing the latest version of meta struct template ant::default_object into scope.
Definition: adtf_iid.h:832
Namespace for entire ADTF SDK.
Declares the class to use when implementing IObject::GetInterface using inheritance.
Definition: adtf_iid.h:619
Meta struct template evaluated at compile time when compiling default_object.
Definition: adtf_iid.h:612
Meta struct template evaluated at compile time when compiling default_object.
Definition: adtf_iid.h:603