ADTF
Loading...
Searching...
No Matches
ucom_cast.h
Go to the documentation of this file.
1
7
8#ifndef _ADTF_UCOM_ANT_UCOM_CAST_INCLUDES_HEADER_
9#define _ADTF_UCOM_ANT_UCOM_CAST_INCLUDES_HEADER_
10
11#include <cstddef>
12#include <typeinfo>
13#include <limits>
14
15namespace adtf
16{
17namespace ucom
18{
19namespace ant
20{
21
22class IObject; // forward declaration for ucom_cast_convert template
23
25namespace detail
26{
30struct ucom_cast_cache final
31{
32 static constexpr auto cache_miss = (::std::numeric_limits<::std::ptrdiff_t>::lowest)();
33 static constexpr auto interface_not_found = (::std::numeric_limits<::std::ptrdiff_t>::max)();
42 static ::std::ptrdiff_t& open_cache_line(const IObject* pBase, const ::std::type_info* pTargetType) noexcept;
43};
44
50template<typename QueriedInterfaceType, bool>
51struct ucom_cast_to_implicit_cast final
52{
60 template<typename ObjectType>
61 static QueriedInterfaceType* perform_cast(ObjectType* i_pObject) noexcept
62 {
63 // provided for const correctness
64 using interface_type =
65 typename ::std::conditional_t<::std::is_const_v<QueriedInterfaceType>, const IObject, IObject>;
66 using base_pointer =
67 typename ::std::conditional_t<::std::is_const_v<QueriedInterfaceType>, const IObject*, IObject*>;
68 using void_pointer = typename ::std::conditional_t<::std::is_const_v<QueriedInterfaceType>, const void*, void*>;
69 using memory_type = typename ::std::conditional_t<::std::is_const_v<QueriedInterfaceType>, const char*, char*>;
70
71 // perform the actual cast
72 if (nullptr != i_pObject)
73 {
74 base_pointer const pBase = ucom_cast_to_implicit_cast<interface_type, true>::perform_cast(i_pObject);
75 auto& nCachedOffset = ucom_cast_cache::open_cache_line(pBase, &typeid(::std::remove_cv_t<QueriedInterfaceType>));
76 if (ucom_cast_cache::cache_miss == nCachedOffset)
77 {
78 // the cast from the interface to void must be performed inside the GetInterface()
79 // method, because only there we have all necessary cast information!
80 QueriedInterfaceType* nRet = nullptr;
81 const char* const strIID = get_iid<QueriedInterfaceType*>();
82 if (pBase->GetInterface(strIID, reinterpret_cast<void_pointer&>(nRet)).IsOk())
83 {
84 nCachedOffset = reinterpret_cast<memory_type>(nRet) - reinterpret_cast<memory_type>(pBase);
85 return nRet;
86 }
87 else
88 {
89 nCachedOffset = ucom_cast_cache::interface_not_found;
90 }
91 }
92 else if (ucom_cast_cache::interface_not_found != nCachedOffset)
93 {
94 return reinterpret_cast<QueriedInterfaceType*>(reinterpret_cast<memory_type>(pBase) + nCachedOffset);
95 }
96 }
97
98 return nullptr;
99 }
100}; // template<> struct<false> ucom_cast_to_implicit_cast
101
106template<typename QueriedInterfaceType>
107struct ucom_cast_to_implicit_cast<QueriedInterfaceType, true> final
108{
109public: // private methods
118 template<typename ObjectType>
119 static constexpr typename ::std::enable_if_t<detail::has_hierarchy_type<ObjectType>::value, QueriedInterfaceType>*
120 perform_cast(ObjectType* i_pObject) noexcept
121 {
122 // resolve possible ambiguous calls (multiple inheritance)
123 return ucom_resolve<QueriedInterfaceType>(i_pObject);
124 }
125
134 template<typename ObjectType>
135 static constexpr typename ::std::enable_if_t<!detail::has_hierarchy_type<ObjectType>::value, QueriedInterfaceType>*
136 perform_cast(ObjectType* i_pObject) noexcept
137 {
138 return i_pObject;
139 }
140}; // template<> struct<true> ucom_cast_to_implicit_cast
141
142} // namespace detail
144
156template<typename InterfacePointerType, typename ObjectPointerType>
157InterfacePointerType ucom_cast(ObjectPointerType i_pObject) noexcept
158{
159 using object_type = typename ::std::remove_pointer_t<ObjectPointerType>;
160 using interface_type = typename ::std::remove_pointer_t<InterfacePointerType>;
161 // make sure the cast is performed const correct
162
163 static_assert(::std::is_pointer_v<ObjectPointerType>, "ucom_cast<> failed. \"i_pObject\" is not a pointer");
164 static_assert(::std::is_base_of_v<IObject, typename ::std::remove_const_t<object_type>>,
165 "ucom_cast<> failed. \"i_pObject\" does not point to a type derived from IObject");
166
167 // if the interface_type is base of the object type, we can use an implicit cast
168 return detail::ucom_cast_to_implicit_cast<
169 typename ::std::conditional_t<::std::is_const_v<object_type>, const interface_type, interface_type>,
170 ::std::is_base_of_v<interface_type, object_type>>::perform_cast(i_pObject);
171} // fn ucom_cast<>
172
173} // namespace ant
174
176using ant::ucom_cast;
177
178} // namespace ucom
179} // namespace adtf
180
181#endif //_ADTF_UCOM_ANT_UCOM_CAST_INCLUDES_HEADER_
Definition object_intf.h:33
Namespace for all internally used functionality implemented.
Definition class_info.h:17
Namespace for all functionality of the ADTF UCOM SDK provided since v3.0.
Definition test_runtime.h:14
InterfacePointerType ucom_cast(ObjectPointerType i_pObject) noexcept
Definition ucom_cast.h:157
Namespace for the ADTF uCOM SDK.
Definition adtf_system.h:324
ant::IObject IObject
Alias always bringing the latest version of ant::IObject into scope.
Definition object_intf.h:109
Namespace for all functionality provided by ADTF and its SDKs.
Definition adtf_client_connector.h:14