Ignition Common

API Reference

3.0.0
detail/SpecializedPlugin.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 
19 #ifndef IGNITION_COMMON_DETAIL_SPECIALIZEDPLUGIN_HH_
20 #define IGNITION_COMMON_DETAIL_SPECIALIZEDPLUGIN_HH_
21 
23 #include <memory>
24 
25 // This preprocessor token should only be used by the unittest that is
26 // responsible for checking that the specialized routines are being used to
27 // access specialized plugin interfaces.
28 #ifdef IGNITION_UNITTEST_SPECIALIZED_PLUGIN_ACCESS
29 bool usedSpecializedInterfaceAccess;
30 #endif
31 
32 
33 namespace ignition
34 {
35  namespace common
36  {
38  template <class SpecInterface>
39  // the following is a false positive with cppcheck 1.82 fixed in 1.83
40  // cppcheck-suppress syntaxError
41  template <class Interface>
43  {
44  return this->PrivateQueryInterface(type<Interface>());
45  }
46 
48  template <class SpecInterface>
49  template <class Interface>
51  {
52  return this->PrivateQueryInterface(type<Interface>());
53  }
54 
56  template <class SpecInterface>
57  template <class Interface>
60  {
61  Interface *ptr = this->QueryInterface<Interface>();
62  if (ptr)
63  return std::shared_ptr<Interface>(this->PrivateGetInstancePtr(), ptr);
64 
65  return nullptr;
66  }
67 
69  template <class SpecInterface>
70  template <class Interface>
73  {
74  const Interface *ptr = this->QueryInterface<Interface>();
75  if (ptr)
76  return std::shared_ptr<Interface>(this->PrivateGetInstancePtr(), ptr);
77 
78  return nullptr;
79  }
80 
82  template <class SpecInterface>
83  template <class Interface>
85  {
86  return this->PrivateHasInterface(type<Interface>());
87  }
88 
90  template <class SpecInterface>
91  template <class Interface>
93  type<Interface>)
94  {
95  return this->Plugin::QueryInterface<Interface>();
96  }
97 
99  template <class SpecInterface>
101  type<SpecInterface>)
102  {
103  #ifdef IGNITION_UNITTEST_SPECIALIZED_PLUGIN_ACCESS
104  usedSpecializedInterfaceAccess = true;
105  #endif
106  return static_cast<SpecInterface*>(
107  this->privateSpecializedInterfaceIterator->second);
108  }
109 
111  template <class SpecInterface>
112  template <class Interface>
113  const Interface *SpecializedPlugin<SpecInterface>::
114  PrivateQueryInterface(type<Interface>) const
115  {
116  return this->Plugin::QueryInterface<Interface>();
117  }
118 
120  template <class SpecInterface>
121  const SpecInterface *SpecializedPlugin<SpecInterface>::
122  PrivateQueryInterface(type<SpecInterface>) const
123  {
124  #ifdef IGNITION_UNITTEST_SPECIALIZED_PLUGIN_ACCESS
125  usedSpecializedInterfaceAccess = true;
126  #endif
127  return static_cast<SpecInterface*>(
128  this->privateSpecializedInterfaceIterator->second);
129  }
130 
132  template <class SpecInterface>
133  template <class Interface>
135  type<Interface>) const
136  {
137  return this->Plugin::HasInterface<Interface>();
138  }
139 
141  template <class SpecInterface>
143  type<SpecInterface>) const
144  {
145  #ifdef IGNITION_UNITTEST_SPECIALIZED_PLUGIN_ACCESS
146  usedSpecializedInterfaceAccess = true;
147  #endif
148  return (nullptr != this->privateSpecializedInterfaceIterator->second);
149  }
150 
152  template <class SpecInterface>
154  : privateSpecializedInterfaceIterator(
155  this->PrivateGetOrCreateIterator(
156  SpecInterface::IGNCOMMONInterfaceName))
157  {
158  // Do nothing
159  }
160 
161  namespace detail
162  {
169  template <typename Interface, bool specialized>
170  struct SelectSpecalizerIfAvailableImpl
171  {
172  using Specializer = SpecializedPlugin<Interface>;
173  };
174 
178  template <typename Interface>
179  struct SelectSpecalizerIfAvailableImpl<Interface, false>
180  {
181  using Specializer = Plugin;
182  };
183 
188  template <typename Interface, typename Specialization>
189  struct SelectSpecalizerIfAvailable
190  {
191  using Specializer = typename SelectSpecalizerIfAvailableImpl<Interface,
192  std::is_base_of<SpecializedPlugin<Interface>, Specialization>::value
193  >::Specializer;
194  };
195 
203  template <class Base1, class Base2>
204  class ComposePlugin : public virtual Base1, public virtual Base2
205  {
207  public: virtual ~ComposePlugin() = default;
208 
209  // Inherit function overloads
212  using Plugin::HasInterface;
213 
214  // Used for template metaprogramming
215  using Specialization = ComposePlugin<Base1, Base2>;
216 
226  #define DETAIL_IGN_COMMON_COMPOSEPLUGIN_DISPATCH( \
227  ReturnType, Function, Suffix, CastTo, Args) \
228  public: /* NOLINT(*) */ \
229  template <class T> \
230  ReturnType Function Suffix \
231  { \
232  using Specializer = typename detail::SelectSpecalizerIfAvailable< \
233  T, Specialization>::Specializer; \
234  return static_cast<CastTo*>(this)->template Function <T> Args; \
235  }
236 
237 
239  T*, QueryInterface, (), Specializer, ())
240 
242  const T*, QueryInterface, () const, const Specializer, ())
243 
245  std::shared_ptr<T>, QueryInterfaceSharedPtr, (), Specializer, ())
246 
248  std::shared_ptr<const T>, QueryInterfaceSharedPtr,
249  () const, const Specializer, ())
250 
252  bool, HasInterface, () const, const Specializer, ())
253 
254 
255  // Declare friendship
256  template <class...> friend class ignition::common::SpecializedPlugin;
257  template <class, class> friend class ComposePlugin;
258 
259  private: ComposePlugin() = default;
260  };
261  }
262 
265  template <class SpecInterface1, class... OtherSpecInterfaces>
266  class SpecializedPlugin<SpecInterface1, OtherSpecInterfaces...> :
267  public virtual detail::ComposePlugin<
268  SpecializedPlugin<SpecInterface1>,
269  SpecializedPlugin<OtherSpecInterfaces...> >
270  {
271  // Declare friendship
272  template <class...> friend class SpecializedPlugin;
273  template <class, class> friend class detail::ComposePlugin;
274  template <class> friend class TemplatePluginPtr;
275 
277  public: virtual ~SpecializedPlugin() = default;
278 
280  private: SpecializedPlugin() = default;
281  };
282  }
283 }
284 
285 #endif
Definition: Plugin.hh:38
friend class SpecializedPlugin
Definition: detail/SpecializedPlugin.hh:272
friend class TemplatePluginPtr
Definition: detail/SpecializedPlugin.hh:274
STL namespace.
bool HasInterface() const
Returns true if this Plugin has the specified type of interface. Note that this function only works w...
Definition: detail/Plugin.hh:105
Interface * QueryInterface()
Get an interface of the specified type. Note that this function only works when the Interface type is...
Definition: detail/Plugin.hh:32
Definition: SpecializedPlugin.hh:34
#define DETAIL_IGN_COMMON_COMPOSEPLUGIN_DISPATCH(ReturnType, Function, Suffix, CastTo, Args)
Implement functions whose only roles are to dispatch their functionalities between two base classes...
Definition: detail/SpecializedPlugin.hh:226
Forward declarations for the common classes.
std::shared_ptr< Interface > QueryInterfaceSharedPtr()
Get the requested interface as a std::shared_ptr. Note that this function only works when the Interfa...
Definition: detail/Plugin.hh:65