File: PluginPtr.hh

package info (click to toggle)
ignition-plugin 1.2.1%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 728 kB
  • sloc: cpp: 4,712; ansic: 277; ruby: 128; sh: 38; makefile: 12
file content (223 lines) | stat: -rw-r--r-- 10,290 bytes parent folder | download
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
/*
 * 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_PLUGIN_PLUGINPTR_HH_
#define IGNITION_PLUGIN_PLUGINPTR_HH_

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

#include <ignition/plugin/Plugin.hh>

namespace ignition
{
  namespace plugin
  {
    // Forward declarations
    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::plugin::Loader 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 which is being moved.
      /// \param[in] _other 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 Pointer to plugin being casted, which is of a
      /// different type.
      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 Pointer to plugin being casted, which is of a
      /// different type.
      /// \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 Plugin being moved.
      /// \return A reference to this object.
      public: TemplatePluginPtr &operator=(TemplatePluginPtr &&_other);

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

      /// \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.
      /// \param[in] _other Plugin to compare to.
      /// \returns True if this Plugin is holding the same plugin
      /// instance as _other, otherwise returns false.
      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.
      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.
      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.
      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.
      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.
      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 whether this is pointing at a valid plugin.
      /// \returns False if this PluginPtr is pointing at a valid plugin
      /// instance. If it is instead pointing at 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 Pointer to the plugin wrapper that this PluginPtr is managing.
      private: std::unique_ptr<PluginType> dataPtr;

      // Declare friendship
      friend class Loader;
      template <class> friend class TemplatePluginPtr;

      /// \brief Private constructor. Creates a plugin instance based on the
      /// Info provided. This should only be called by Loader to ensure that
      /// the Info is well-formed, so we keep it private.
      /// \param[in] _info An Info instance that was generated by
      /// Loader. Alternatively, this can take a nullptr to create an
      /// empty PluginPtr.
      /// \param[in] _dlHandlePtr A reference count for the DL handle.
      private: explicit TemplatePluginPtr(
          const ConstInfoPtr &_info,
          const std::shared_ptr<void> &_dlHandlePtr);
    };

    /// \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/plugin/detail/PluginPtr.hh"

#endif