File: PluginPtr.hh

package info (click to toggle)
ignition-common 4.5.1%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,120 kB
  • sloc: cpp: 29,331; ansic: 5,583; javascript: 2,998; sh: 31; makefile: 23
file content (231 lines) | stat: -rw-r--r-- 10,876 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
 * Copyright (C) 2017 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */


#ifndef IGNITION_COMMON_PLUGINPTR_HH_
#define IGNITION_COMMON_PLUGINPTR_HH_

#include <map>
#include <string>
#include <memory>

#include "ignition/common/Plugin.hh"

namespace ignition
{
  namespace common
  {
    // Forward declarations
    struct PluginInfo;
    namespace detail { template<class, class> class ComposePlugin; }

    /// \brief This class manages the lifecycle of a plugin instance. It can
    /// receive a plugin instance from the ignition::common::PluginLoader class
    /// or by copy-construction or assignment from another PluginPtr instance.
    ///
    /// This class behaves similarly to a std::shared_ptr where multiple
    /// PluginPtr objects can share a single plugin instance, and the plugin
    /// instance will not be deleted until all PluginPtr objects that refer to
    /// it are either destroyed, cleared, or begin referring to a different
    /// plugin instance.
    ///
    /// A PluginPtr object can be "cast" to a SpecializedPluginPtr object by
    /// simply using the copy/move constructor or assignment operator of a
    /// SpecializedPluginPtr object. Note that this "cast" does have a small
    /// amount of overhead associated with it, but it may result in huge savings
    /// after initialization is finished if you frequently access the interfaces
    /// that the SpecializedPluginPtr is specialized for.
    template <typename PluginType>
    class TemplatePluginPtr final
    {
      /// \brief Destructor. Deletes this PluginPtr's reference to the plugin
      /// instance. Once all PluginPtrs that refer to a plugin instance are
      /// deleted, the plugin will also be deleted.
      public: ~TemplatePluginPtr() = default;

      /// \brief Default constructor. Creates a PluginPtr object that does not
      /// point to any plugin instance. IsEmpty() will return true until a
      /// plugin instance is provided.
      public: TemplatePluginPtr();

      /// \brief Copy constructor. This PluginPtr will now point at the same
      /// plugin instance as _other, and they will share ownership.
      /// \param[in] _other Pointer to plugin being copied.
      public: TemplatePluginPtr(const TemplatePluginPtr &_other);

      /// \brief Move constructor. This PluginPtr will take ownership of the
      /// plugin instance held by _other. If this PluginPtr was holding an
      /// instance to another plugin, that instance will be deleted if no other
      /// PluginPtr is referencing it.
      /// \param[in] _other Pointer to plugin being moved.
      public: TemplatePluginPtr(TemplatePluginPtr &&_other);

      /// \brief Casting constructor. This PluginPtr will now point at the same
      /// plugin instance as _other, and they will share ownership. This
      /// essentially allows casting between PluginPtrs that are holding
      /// different types of plugin wrappers (for example, you can cast a
      /// generic PluginPtr to any SpecializedPluginPtr type, or you can cast
      /// between different types of specializations).
      /// \param[in] _other Another PluginPtr object. It may have a different
      /// kind of specialization.
      public: template <typename OtherPluginType>
              TemplatePluginPtr(
                  const TemplatePluginPtr<OtherPluginType> &_other);

      /// \brief Copy assignment operator. This PluginPtr will now point at the
      /// same plugin instance as _other, and they will share ownership. If this
      /// PluginPtr was holding an instance to another plugin, that instance
      /// will be deleted if no other PluginPtr is referencing it.
      /// \param[in] _other Pointer to plugin being copied.
      public: TemplatePluginPtr &operator =(const TemplatePluginPtr &_other);

      /// \brief Casting operator. This PluginPtr will now point at the same
      /// plugin instance as _other, and they will share ownership. This
      /// essentially allows casting between PluginPtrs that are holding
      /// different types of plugin wrappers.
      /// \param[in] _other Another PluginPtr object. It may have a different
      /// kind of specialization.
      /// \return A reference to this object.
      public: template <typename OtherPluginType>
              TemplatePluginPtr &operator =(
                  const TemplatePluginPtr<OtherPluginType> &_other);

      /// \brief Move assignment operator. This PluginPtr will take ownership
      /// of the plugin instance held by _other. If this PluginPtr was holding
      /// an instance to another plugin, that instance will be deleted if no
      /// other PluginPtr is referencing it.
      /// \param[in] _other Another PluginPtr object.
      /// \return A reference to this object.
      public: TemplatePluginPtr &operator =(TemplatePluginPtr &&_other);

      /// \brief nullptr assignment operator. Same as calling Clear()
      /// \param[in] A nullptr object.
      /// \return A reference to this object.
      public: TemplatePluginPtr &operator =(std::nullptr_t);

      /// \brief Access the wrapper for the plugin instance and call one of its
      /// member functions.
      /// \return The ability to call a member function on the underlying Plugin
      /// object.
      public: PluginType *operator ->() const;

      /// \brief Get a reference to the wrapper for the plugin instance that is
      /// being managed by this PluginPtr.
      /// \return A reference to the underlying Plugin object.
      public: PluginType &operator *() const;

      /// \brief Comparison operator. Returns true if this Plugin is holding the
      /// same plugin instance as _other, otherwise returns false.
      /// \param[in] _other Another PluginPtr object.
      /// \return True if the value of this pointer is == _other.
      public: bool operator ==(const TemplatePluginPtr &_other) const;

      /// \brief Comparison operator.
      /// \param[in] _other Plugin to compare to.
      /// \returns True if the pointer value of the plugin instance held
      /// by this PluginPtr is less than the pointer value of the instance held
      /// by _other.
      /// \param[in] _other Another PluginPtr object.
      /// \return True if the value of this pointer is < _other.
      public: bool operator <(const TemplatePluginPtr &_other) const;

      /// \brief Comparison operator.
      /// \param[in] _other Plugin to compare to.
      /// \returns True if the pointer value of the plugin instance held
      /// by this PluginPtr is greater than the pointer value of the instance
      /// held by _other.
      /// \param[in] _other Another PluginPtr object.
      /// \return True if the value of this pointer is > _other.
      public: bool operator >(const TemplatePluginPtr &_other) const;

      /// \brief Comparison operator.
      /// \param[in] _other Plugin to compare to.
      /// \returns True if the pointer instance held by this PluginPtr is
      /// different from the pointer instance held by _other.
      /// \param[in] _other Another PluginPtr object.
      /// \return True if the value of this pointer is != _other.
      public: bool operator !=(const TemplatePluginPtr &_other) const;

      /// \brief Comparison operator.
      /// \param[in] _other Plugin to compare to.
      /// \returns True if the value of the pointer instance held by this
      /// PluginPtr is less than or equal to the value of the pointer instance
      /// held by _other.
      /// \param[in] _other Another PluginPtr object.
      /// \return True if the value of this pointer is <= _other.
      public: bool operator <=(const TemplatePluginPtr &_other) const;

      /// \brief Comparison operator.
      /// \param[in] _other Plugin to compare to.
      /// \returns True if the value of the pointer instance held by this
      /// PluginPtr is greater than or equal to the value of the pointer
      /// instance held by _other.
      /// \param[in] _other Another PluginPtr object.
      /// \return True if the value of this pointer is >= _other.
      public: bool operator >=(const TemplatePluginPtr &_other) const;

      /// \brief Produces a hash for the plugin instance that this PluginPtr is
      /// holding. This function allows PluginPtr instances to be used as values
      /// in a std::unordered_set<PluginPtr> or keys in a
      /// std::unordered_map<PluginPtr, T>. Using this function directly should
      /// not normally be necessary.
      /// \return A hash of the underlying pointer object.
      public: std::size_t Hash() const;

      /// \brief Check if this PluginPtr is holding a plugin instance.
      /// \return False if this PluginPtr contains a plugin instance. If it
      /// instead contains a nullptr, this returns true.
      public: bool IsEmpty() const;

      /// \brief Implicitly convert this PluginPtr to a boolean.
      /// \return The opposite value of IsEmpty().
      public: operator bool() const;

      /// \brief Clears the Plugin instance from this PluginPtr. IsEmpty() will
      /// return true after this is used, and none of the interfaces will be
      /// available any longer.
      public: void Clear();

      /// \brief Private constructor. Creates a plugin instance based on the
      /// PluginInfo provided. This should only be called by PluginLoader to
      /// ensure that the PluginInfo is well-formed, so we keep it private.
      /// \param[in] _info A PluginInfo instance that was generated by
      /// PluginLoader. Alternatively, this can take a nullptr to create an
      /// empty PluginPtr.
      private: explicit TemplatePluginPtr(const PluginInfo *_info);

      /// \brief Pointer to the plugin wrapper that this PluginPtr is managing.
      private: std::unique_ptr<PluginType> dataPtr;

      // Declare friendship
      friend class PluginLoader;
      template <class> friend class TemplatePluginPtr;
    };

    /// \brief Typical usage for TemplatePluginPtr is to just hold a generic
    /// Plugin type.
    using PluginPtr = TemplatePluginPtr<Plugin>;

    /// \brief This produces a PluginPtr whose Plugin wrapper only grants access
    /// to const-qualified interfaces of the plugin instance.
    using ConstPluginPtr = TemplatePluginPtr<const Plugin>;
  }
}

#include "ignition/common/detail/PluginPtr.hh"

#endif