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
|