diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c1a6b0..321860a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,9 @@ find_package(ignition-cmake3 REQUIRED) # Configure the project #============================================================================ set(c++standard 17) -ign_configure_project(VERSION_SUFFIX pre1) +ign_configure_project( + REPLACE_IGNITION_INCLUDE_PATH gz/utils + VERSION_SUFFIX pre1) #============================================================================ # Set project-specific options diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 25ec897..4b2bdd7 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1 +1,2 @@ -add_subdirectory(ignition) +add_subdirectory(gz) +install(DIRECTORY ignition DESTINATION ${IGN_INCLUDE_INSTALL_DIR_FULL}) diff --git a/include/ignition/CMakeLists.txt b/include/gz/CMakeLists.txt similarity index 100% rename from include/ignition/CMakeLists.txt rename to include/gz/CMakeLists.txt diff --git a/include/ignition/utils/CMakeLists.txt b/include/gz/utils/CMakeLists.txt similarity index 100% rename from include/ignition/utils/CMakeLists.txt rename to include/gz/utils/CMakeLists.txt diff --git a/include/gz/utils/Environment.hh b/include/gz/utils/Environment.hh new file mode 100644 index 0000000..36cad0b --- /dev/null +++ b/include/gz/utils/Environment.hh @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2021 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 GZ_UTILS_ENVIRONMENT_HH_ +#define GZ_UTILS_ENVIRONMENT_HH_ + +#include +#include + +#include + +namespace ignition +{ +namespace utils +{ +inline namespace IGNITION_UTILS_VERSION_NAMESPACE { + +/// \brief Find the environment variable '_name' and return its value. +/// +/// Note: This function is not thread-safe and should not be called +/// concurrently with `setenv` or `unsetenv` +/// +/// \param[in] _name Name of the environment variable. +/// \param[out] _value Value if the variable was found. +/// \param[in] _allowEmpty Allow set-but-empty variables. +/// (Unsupported on Windows) +/// \return True if the variable was found or false otherwise. +bool IGNITION_UTILS_VISIBLE env( + const std::string &_name, std::string &_value, + bool _allowEmpty = false); + +/// \brief Set the environment variable '_name'. +/// +/// Note: On Windows setting an empty string (_value=="") +/// is the equivalent of unsetting the variable. +// +/// Note: This function is not thread-safe and should not be called +/// concurrently with `env` or `unsetenv` +/// +/// \param[in] _name Name of the environment variable. +/// \param[in] _value Value of the variable to be set. +/// \return True if the variable was set or false otherwise. +bool IGNITION_UTILS_VISIBLE setenv( + const std::string &_name, const std::string &_value); + +/// \brief Unset the environment variable '_name'. +/// +/// Note: This function is not thread-safe and should not be called +/// concurrently with `env` or `setenv` +/// +/// \param[in] _name Name of the environment variable. +/// \return True if the variable was unset or false otherwise. +bool IGNITION_UTILS_VISIBLE unsetenv(const std::string &_name); + +} +} // namespace utils +} // namespace ignition + +#endif // GZ_UTILS_ENVIRONMENT_HH_ + diff --git a/include/gz/utils/ExtraTestMacros.hh b/include/gz/utils/ExtraTestMacros.hh new file mode 100644 index 0000000..625d21b --- /dev/null +++ b/include/gz/utils/ExtraTestMacros.hh @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 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 GZ_UTILS_EXTRATESTMACROS_HH +#define GZ_UTILS_EXTRATESTMACROS_HH + +#include + +/// \brief Restrict the execution of the test for the Windows platform. +/// The test will be compiled on Windows too but will never be run as +/// part of the test suite. The macro uses the Disabled_ prefix provided +/// by googletest. See +/// https://chromium.googlesource.com/external/github.com/google/googletest/+/HEAD/googletest/docs/advanced.md +#define IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) \ + DETAIL_IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) + +/// \brief Restrict the execution of the test for the Mac platform. +/// The test will be compiled on Windows too but will never be run as +/// part of the test suite. The macro uses the Disabled_ prefix provided +/// by googletest. See +/// https://chromium.googlesource.com/external/github.com/google/googletest/+/HEAD/googletest/docs/advanced.md +#define IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) \ + DETAIL_IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) + +/// \brief Restrict the execution of the test to just the Linux platform +/// Other platforms will get the test compiled but it won't be run +/// as part of the test suite execution. +/// The macro uses the Disabled_ prefix provided by googletest. See +/// https://chromium.googlesource.com/external/github.com/google/googletest/+/HEAD/googletest/docs/advanced.md +#define IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) \ + DETAIL_IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) + +#endif // GZ_UTILS_EXTRATESTMACROS_HH diff --git a/include/gz/utils/ImplPtr.hh b/include/gz/utils/ImplPtr.hh new file mode 100644 index 0000000..dfc8881 --- /dev/null +++ b/include/gz/utils/ImplPtr.hh @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2018 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 GZ_UTILS__IMPLPTR_HH_ +#define GZ_UTILS__IMPLPTR_HH_ + +#include +#include + +#include +#include +#include + +namespace ignition +{ + namespace utils + { + ////////////////////////////////////////////////// + /// \brief The ImplPtr class provides a convenient away to achieve the + /// + /// Rule of Zero while keeping all the benefits of PIMPL. This saves us + /// from writing an enormous amount of boilerplate code for each class. + /// + /// To follow PIMPL design principles, create an object of this type as the + /// one and only member variable of your class, e.g.: + /// + /// \code + /// class MyClass + /// { + /// public: /* ... public member functions ... */ + /// + /// private: class Implementation; + /// private: ImplPtr dataPtr; + /// }; + /// \endcode + /// + /// When constructing the `dataPtr` object, pass it + /// `MakeImpl(/* ... args ... */)` in the + /// initialization list of your class. \sa MakeImpl() + /// + /// This class was inspired by the following blog post: + /// http://oliora.github.io/2015/12/29/pimpl-and-rule-of-zero.html + /// + /// For interface classes that should not be copiable, see the UniqueImplPtr + /// class further down in this header. + /// + /// \note Switching between ImplPtr and UniqueImplPtr is \em NOT ABI-safe. + /// This is essentially the same as changing whether or not the class + /// provides a copy-constructor and a copy-assignment operator, which is + /// bound to result in runtime linking issues at a minimum (but more + /// importantly, it changes the binary footprint of the class). If it is not + /// obvious whether a class should be copiable, then the safest choice is to + /// use a UniqueImplPtr and then manually add the copy constructor/operator + /// later if it is deemed acceptable. The next time an ABI update is + /// permitted, those manually written functions can be removed and the + /// UniqueImplPtr can be replaced with an ImplPtr. + template > + class ImplPtr + { + /// \brief Constructor + /// \tparam U A type that is compatible with T, i.e. either T or a class + /// that is derived from T. + /// \tparam D The deleter type + /// \tparam Ops The copy operation container type + /// \param[in] _ptr The raw pointer to the implementation + /// \param[in] _deleter The deleter object + /// \param[in] _ops The copy operation object + public: template + ImplPtr(U *_ptr, D &&_deleter, Ops &&_ops); + + /// \brief Copy constructor + /// \param[in] _other Another ImplPtr of the same type + public: ImplPtr(const ImplPtr &_other); + + /// \brief Copy assignment operator + /// \param[in] _other Another ImplPtr of the same type + /// \return A reference to this ImplPtr + public: ImplPtr &operator=(const ImplPtr &_other); + + // We explicitly declare the move constructor to make it clear that it is + // available. + public: ImplPtr(ImplPtr &&) = default; + + // We explicitly declare the move assignment operator to make it clear + // that it is available. + public: ImplPtr &operator=(ImplPtr &&) = default; + + /// \brief Destructor + public: ~ImplPtr() = default; + + /// \brief Non-const dereference operator. This const-unqualified operator + /// ensures that logical const-correctness is followed by the consumer + /// class. + /// \return A mutable reference to the contained object. + public: T &operator*(); + + /// \brief Const dereference operator. This const-qualified operator + /// ensures that logical const-correctness is followed by the consumer + /// class. + /// \return A const-reference to the contained object. + public: const T &operator*() const; + + /// \brief Non-const member access operator. This const-unqualified + /// operator ensures that logical const-correctness is followed by the + /// consumer class. + /// \return Mutable access to the contained object's members. + public: T *operator->(); + + /// \brief Const member access operator. This const-qualified operator + /// ensures that logical const-correctness is followed by the consumer + /// class. + /// \return Immutable access to the contained object's members. + public: const T *operator->() const; + + /// \brief Non-const member access function. This const-unqualified + /// operator ensures that logical const-correctness is followed by the + /// consumer class. + /// \return Mutable access to the contained object's members. + public: T *Get(); + + /// \brief Const member access function. This const-qualified operator + /// ensures that logical const-correctness is followed by the consumer + /// class. + /// \return Immutable access to the contained object's members. + public: const T *Get() const; + + /// \internal \brief Create a clone of this ImplPtr's contents. This is + /// for internal use only. The copy constructor and copy assignment + /// operators should suffice for consumers. + /// + /// This function is needed internally for consumers' default copy + /// constructors to compile. + /// + /// \return An ImplPtr that has been copied from the current one. + private: ImplPtr Clone() const; + + /// \brief Pointer to the contained object + private: std::unique_ptr ptr; + + /// \brief Structure to hold the copy operators + private: Operations ops; + }; + + ////////////////////////////////////////////////// + /// \brief Pass this to the constructor of an ImplPtr object to easily + /// initialize it. All the arguments passed into this function will be + /// perfectly forwarded to the implementation class that gets created. + /// + /// E.g.: + /// + /// \code + /// MyClass::MyClass(Arg1 arg1, Arg2 arg2, Arg3 arg3) + /// : dataPtr(utils::MakeImpl(arg1, arg2, arg3)) + /// { + /// // Do nothing + /// } + /// \endcode + /// + /// \tparam T The typename of the implementation class. This must be set + /// explicitly. + /// \tparam Args The argument types. These will be inferred automatically. + /// \param[in] _args The arguments to be forwarded to the implementation + /// class. + /// \return A new ImplPtr. Passing this along to a class's ImplPtr + /// object's constructor will efficiently move this newly created object + /// into it. + template + ImplPtr MakeImpl(Args &&..._args); + + ////////////////////////////////////////////////// + /// \brief This is an alternative to ImplPtr which serves the same + /// purpose, except it only provide move semantics (i.e. it does not allow + /// copying). This should be used in cases where it is not safe (or not + /// possible) to copy the underlying state of an implementation class. + /// + /// Note that when creating an implementation class that is unsafe to copy, + /// you should explicitly delete its copy constructor (unless one of its + /// members has an explicitly deleted copy constructor). Doing so will force + /// you to use UniqueImplPtr instead of ImplPtr, and it will signal to + /// future developers or maintainers that the implementation class is not + /// meant to be copiable. + /// + /// Use MakeUniqueImpl() to construct UniqueImplPtr objects. + template + using UniqueImplPtr = std::unique_ptr; + + ////////////////////////////////////////////////// + /// \brief Pass this to the constructor of a UniqueImplPtr object to easily + /// initialize it. All the arguments passed into this function will be + /// perfectly forwarded to the implementation class that gets created. + /// + /// E.g.: + /// + /// \code + /// MyClass::MyClass(Arg1 arg1, Arg2 arg2, Arg3 arg3) + /// : dataPtr(utils::MakeUniqueImpl(arg1, arg2, arg3)) + /// { + /// // Do nothing + /// } + /// \endcode + /// + /// \tparam T The typename of the implementation class. This must be set + /// explicitly. + /// \tparam Args The argument types. These will be inferred automatically. + /// \param[in] _args The arguments to be forwarded to the implementation + /// class. + /// \return A new UniqueImplPtr. Passing this along to a class's + /// UniqueImplPtr object's constructor will efficiently move this newly + /// created object into it. + template + UniqueImplPtr MakeUniqueImpl(Args &&..._args); + } // namespace utils +} // namespace ignition + +/// \brief Add a private ImplPtr to a class as dataPtr. +/// This variant takes a forward-declared ImplementationClass as the impl. +#define IGN_UTILS_IMPL_PTR_FWD(ImplementationClass, memberName) \ + IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ + private: ::ignition::utils::ImplPtr memberName; \ + IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + +/// \brief Add a private UniqueImplPtr to a class as dataPtr. +/// This variant takes a forward-declared ImplementationClass as the impl. +#define IGN_UTILS_UNIQUE_IMPL_PTR_FWD(ImplementationClass, memberName) \ + IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ + private: ::ignition::utils::UniqueImplPtr memberName; \ + IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + +/// \brief Add a private ImplPtr to a class as dataPtr. +/// This variant forward-declares Class::Implementation as the impl. +#define IGN_UTILS_IMPL_PTR(memberName) \ + public: class Implementation; \ + IGN_UTILS_IMPL_PTR_FWD(Implementation, memberName) + +/// \brief Add a private UniqueImplPtr to a class as dataPtr. +/// This variant forward-declares Class::Implementation as the impl. +#define IGN_UTILS_UNIQUE_IMPL_PTR(memberName) \ + public: class Implementation; \ + IGN_UTILS_UNIQUE_IMPL_PTR_FWD(Implementation, memberName) + + +#include + +#endif // GZ_UTILS__IMPLPTR_HH_ diff --git a/include/gz/utils/NeverDestroyed.hh b/include/gz/utils/NeverDestroyed.hh new file mode 100644 index 0000000..8537a79 --- /dev/null +++ b/include/gz/utils/NeverDestroyed.hh @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2021 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 GZ_UTILS_NEVERDESTROYED_HH_ +#define GZ_UTILS_NEVERDESTROYED_HH_ + +#include +#include +#include + +namespace ignition +{ +namespace utils +{ + +/// Originally copied from https://github.com/RobotLocomotion/drake/blob/v0.36.0/common/never_destroyed.h +/// Originally licensed BSD 3-Clause (https://github.com/RobotLocomotion/drake/blob/v0.36.0/LICENSE.TXT) +/// Re-licensed Apache-2.0 with permission from: +/// jwnimmer-tri (https://github.com/ignitionrobotics/ign-utils/pull/31#issuecomment-989173512) +/// +/// Wraps an underlying type T such that its storage is a direct member field +/// of this object (i.e., without any indirection into the heap), but *unlike* +/// most member fields T's destructor is never invoked. +/// +/// This is especially useful for function-local static variables that are not +/// trivially destructable. We shouldn't call their destructor at program exit +/// because of the "indeterminate order of ... destruction" as mentioned in +/// cppguide's +/// Static +/// and Global Variables section, but other solutions to this problem place +/// the objects on the heap through an indirection. +/// +/// Compared with other approaches, this mechanism more clearly describes the +/// intent to readers, avoids "possible leak" warnings from memory-checking +/// tools, and is probably slightly faster. +/// +/// Example uses: +/// +/// The singleton pattern: +/// @code +/// class Singleton +/// { +/// public: +/// Singleton(const Singleton&) = delete; +/// void operator=(const Singleton&) = delete; +/// Singleton(Singleton&&) = delete; +/// void operator=(Singleton&&) = delete; +/// +/// static Singleton& getInstance() +/// { +/// static ignition::utils::NeverDestroyed instance; +/// return instance.access(); +/// } +/// private: +/// friend ignition::utils::NeverDestroyed; +/// Singleton() = default; +/// }; +/// @endcode +/// +/// A lookup table, created on demand the first time its needed, and then +/// reused thereafter: +/// @code +/// enum class Foo { kBar, kBaz }; +/// Foo ParseFoo(const std::string& foo_string) +/// { +/// using Dict = std::unordered_map; +/// static const ignition::utils::NeverDestroyed string_to_enum +/// { +/// std::initializer_list +/// { +/// {"bar", Foo::kBar}, +/// {"baz", Foo::kBaz}, +/// } +/// }; +/// return string_to_enum.access().at(foo_string); +/// } +/// @endcode +/// +/// In cases where computing the static data is more complicated than an +/// initializer_list, you can use a temporary lambda to populate the value: +/// @code +/// const std::vector& GetConstantMagicNumbers() +/// { +/// static const ignition::utils::NeverDestroyed> result +/// { +/// []() +/// { +/// std::vector prototype; +/// std::mt19937 random_generator; +/// for (int i = 0; i < 10; ++i) +/// { +/// double new_value = random_generator(); +/// prototype.push_back(new_value); +/// } +/// return prototype; +/// }() +/// }; +/// return result.access(); +/// } +/// @endcode +/// +/// Note in particular the `()` after the lambda. That causes it to be invoked. +// +// The above examples are repeated in the unit test; keep them in sync. +template +class NeverDestroyed +{ + /// Passes the constructor arguments along to T using perfect forwarding. + public: template + explicit NeverDestroyed(Args &&... args) + { + // Uses "placement new" to construct a `T` in `storage_`. + new (&this->storage) T(std::forward(args)...); + } + + /// Does nothing. Guaranteed! + public: ~NeverDestroyed() = default; + + /// \brief Deleted copy constructor + public: NeverDestroyed(const NeverDestroyed &) = delete; + + /// \brief Deleted move constructor + public: NeverDestroyed(NeverDestroyed &&) = delete; + + /// \brief Deleted copy assignment constructor + public: NeverDestroyed &operator=(const NeverDestroyed &) = delete; + + /// \brief Deleted move assignment constructor + public: NeverDestroyed &operator=(NeverDestroyed &&) noexcept = delete; + + /// Returns the underlying T reference. + public: T &Access() + { + return *reinterpret_cast(&this->storage); + } + + public: const T &Access() const + { + return *reinterpret_cast(&this->storage); + } + + private: typename std::aligned_storage::type storage; +}; + +} // namespace utils +} // namespace ignition + +#endif // GZ_UTILS_NEVERDESTROYED_HH_ diff --git a/include/gz/utils/SuppressWarning.hh b/include/gz/utils/SuppressWarning.hh new file mode 100644 index 0000000..af9d72d --- /dev/null +++ b/include/gz/utils/SuppressWarning.hh @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018 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 GZ_UTILS__SUPPRESSWARNING_HH_ +#define GZ_UTILS__SUPPRESSWARNING_HH_ + +#include + +// This header contains cross-platform macros for suppressing warnings. Please +// only use these macros responsibly when you are certain that the compiler is +// producing a warning that is not applicable to the specific instance. Do not +// use these macros to ignore legitimate warnings, even if you may find them +// irritating. + +/* + * Usage example: + * + * SomeClass *ptr = CreatePtr(); + * IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR + * delete ptr; + * IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR + * + */ + +// Be sure to call the IGN_UTILS_WARN_RESUME__XXXXX macro at the end of the +// block of code where the warning suppression is needed. Otherwise, you might +// inadvertently suppress legitimate warnings. + +// ---- List of available suppressions ---- + +/// \brief Compilers might warn about deleting a pointer to a class that has +/// virtual functions without a virtual destructor or a `final` declaration, +/// because the pointer might secretly be pointing to a more derived class type. +/// We want to suppress this warning when we know for certain (via the design +/// of our implementation) that the pointer is definitely not pointing to a more +/// derived type. +#ifndef IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR + #define IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR \ + DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR +#endif + +#ifndef IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR + #define IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR \ + DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR +#endif + +/// \brief Microsoft Visual Studio does not automatically export the interface +/// information for member variables that belong to interface classes of a DLL. +/// Instead it issues this warning. When the member variable is private, we +/// choose to suppress the warning instead of needlessly adding the class +/// information to the DLL interface. +#ifndef IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING + #define IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ + DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING +#endif + +#ifndef IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + #define IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING \ + DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING +#endif + +/// \brief Use this to suppress deprecation warnings. This may be useful when +/// retaining tests for deprecated methods to preserve code coverage. +#ifndef IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION + #define IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION \ + DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION +#endif + +#ifndef IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION + #define IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION \ + DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION +#endif + +// TODO(anyone): Add more warning types as they become relevant. +// Do not add warning types to suppress unless they are genuinely necessary. + +#endif // GZ_UTILS__SUPPRESSWARNING_HH_ diff --git a/include/ignition/utils/config.hh.in b/include/gz/utils/config.hh.in similarity index 100% rename from include/ignition/utils/config.hh.in rename to include/gz/utils/config.hh.in diff --git a/include/gz/utils/detail/DefaultOps.hh b/include/gz/utils/detail/DefaultOps.hh new file mode 100644 index 0000000..16b09e7 --- /dev/null +++ b/include/gz/utils/detail/DefaultOps.hh @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 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 GZ_UTILS__DETAIL__DEFAULTOPS_HH_ +#define GZ_UTILS__DETAIL__DEFAULTOPS_HH_ + +#include + +namespace ignition +{ + namespace utils + { + namespace detail + { + ////////////////////////////////////////////////// + template + void VerifyComplete() + { + // If you are brought here by a compilation error while using the + // ImplPtr class or the UniqueImplPtr class, be sure to use the + // MakeImpl() or MakeUniqueImpl() function when constructing your + // [Unique]ImplPtr instance. + static_assert(sizeof(T) > 0, + "DefaultDelete cannot delete an incomplete type"); + static_assert(!std::is_void::value, + "DefaultDelete cannot delete an incomplete type"); + } + + ////////////////////////////////////////////////// + template + void DefaultDelete(T *_ptr) noexcept + { + VerifyComplete(); + delete _ptr; + } + + ////////////////////////////////////////////////// + template + T *DefaultCopyConstruct(const T &_source) + { + VerifyComplete(); + return new T(_source); + } + + ////////////////////////////////////////////////// + template + void DefaultCopyAssign(T &_dest, const T &_source) + { + VerifyComplete(); + _dest = _source; + } + + ////////////////////////////////////////////////// + template + struct CopyMoveDeleteOperations + { + public: template + CopyMoveDeleteOperations(C &&_construct, A &&_assign); + + public: CopyConstruct construct; + public: CopyAssign assign; + }; + } // namespace detail + } // namespace utils +} // namespace ignition + +#endif // GZ_UTILS__DETAIL__DEFAULTOPS_HH_ + diff --git a/include/gz/utils/detail/ExtraTestMacros.hh b/include/gz/utils/detail/ExtraTestMacros.hh new file mode 100644 index 0000000..c24c408 --- /dev/null +++ b/include/gz/utils/detail/ExtraTestMacros.hh @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 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 GZ_UTILS_DETAIL_EXTRATESTMACROS_HH +#define GZ_UTILS_DETAIL_EXTRATESTMACROS_HH + +#include + +#define DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(x) DISABLED_##x + +#if defined _WIN32 + + #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) \ + DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(TestName) + +#else + + #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) \ + TestName + +#endif // defined _WIN32 + +#if defined __APPLE__ + + #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) \ + DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(TestName) + +#else + + #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) \ + TestName + +#endif // defined __APPLE__ + +#if defined __linux__ + + #define DETAIL_IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) \ + TestName + +#else + + #define DETAIL_IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) \ + DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(TestName) + +#endif // defined __linux__ + + +#endif // GZ_UTILS_DETAIL_EXTRATESTMACROS_HH diff --git a/include/gz/utils/detail/ImplPtr.hh b/include/gz/utils/detail/ImplPtr.hh new file mode 100644 index 0000000..65dcf71 --- /dev/null +++ b/include/gz/utils/detail/ImplPtr.hh @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2018 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 GZ_UTILS__DETAIL__IMPLPTR_HH_ +#define GZ_UTILS__DETAIL__IMPLPTR_HH_ + +#include + +#include + +namespace ignition +{ + namespace utils + { + namespace detail + { + ////////////////////////////////////////////////// + template + // cppcheck-suppress syntaxError + template + CopyMoveDeleteOperations:: + CopyMoveDeleteOperations(C &&_construct, A &&_assign) + : construct(_construct), + assign(_assign) + { + // Do nothing + } + } // namespace detail + + ////////////////////////////////////////////////// + template + template + ImplPtr::ImplPtr( + Ptr *_ptr, D &&_deleter, Ops &&_ops) + : ptr(_ptr, std::forward(_deleter)), + ops(std::forward(_ops)) + { + // Do nothing + } + + ////////////////////////////////////////////////// + template + ImplPtr::ImplPtr(const ImplPtr &_other) + // Delegate to the move constructor after cloning + : ImplPtr(_other.Clone()) + { + // Do nothing + } + + ////////////////////////////////////////////////// + template + auto ImplPtr::operator=( + const ImplPtr &_other) -> ImplPtr& + { + if (this->ptr) + this->ops.assign(*this->ptr, *_other.ptr); + else + this->ptr.reset(this->ops.construct(*_other.ptr)); + + return *this; + } + + ////////////////////////////////////////////////// + template + auto ImplPtr::Clone() const -> ImplPtr + { + return ImplPtr(this->ptr ? this->ops.construct(*this->ptr) : nullptr, + this->ptr.get_deleter(), + this->ops); + } + + ////////////////////////////////////////////////// + template + T &ImplPtr::operator*() + { + return *ptr; + } + + ////////////////////////////////////////////////// + template + const T &ImplPtr::operator*() const + { + return *ptr; + } + + ////////////////////////////////////////////////// + template + T *ImplPtr::operator->() + { + return ptr.get(); + } + + ////////////////////////////////////////////////// + template + const T *ImplPtr::operator->() const + { + return ptr.get(); + } + + ////////////////////////////////////////////////// + template + T *ImplPtr::Get() + { + return ptr.get(); + } + + ////////////////////////////////////////////////// + template + const T *ImplPtr::Get() const + { + return ptr.get(); + } + + ////////////////////////////////////////////////// + template + ImplPtr MakeImpl(Args &&..._args) + { + return ImplPtr( + new T{std::forward(_args)...}, + &detail::DefaultDelete, + detail::CopyMoveDeleteOperations( + &detail::DefaultCopyConstruct, + &detail::DefaultCopyAssign)); + } + + ////////////////////////////////////////////////// + template + UniqueImplPtr MakeUniqueImpl(Args &&...args) + { + return UniqueImplPtr( + new T{std::forward(args)...}, + &detail::DefaultDelete); + } + } // namespace utils +} // namespace ignition + +#endif // GZ_UTILS__DETAIL__IMPLPTR_HH_ diff --git a/include/gz/utils/detail/SuppressWarning.hh b/include/gz/utils/detail/SuppressWarning.hh new file mode 100644 index 0000000..bcfcb22 --- /dev/null +++ b/include/gz/utils/detail/SuppressWarning.hh @@ -0,0 +1,241 @@ +/* + * 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 GZ_UTILS__DETAIL__SUPPRESSWARNING_HH_ +#define GZ_UTILS__DETAIL__SUPPRESSWARNING_HH_ + +#include + +#ifndef DETAIL_IGN_UTILS_STRINGIFY + #define DETAIL_IGN_UTILS_STRINGIFY(x) #x +#endif + +/* cppcheck-suppress */ + +// BEGIN / FINISH Macros + +#if defined __clang__ + + #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH + #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ + _Pragma("clang diagnostic push") + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER_2 + #define DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w) \ + DETAIL_IGN_UTILS_STRINGIFY(clang diagnostic ignored w) + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER + #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) \ + _Pragma(DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w)) + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME + #define DETAIL_IGN_UTILS_WARN_RESUME \ + _Pragma("clang diagnostic pop") + #endif + + +#elif defined __GNUC__ + + // NOTE: clang will define both __clang__ and __GNUC__, and it seems that + // clang will gladly accept GCC pragmas. Even so, if we want the pragmas to + // target the "correct" compiler, we should check if __clang__ is defined + // before checking whether __GNUC__ is defined. + + #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH + #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ + _Pragma("GCC diagnostic push") + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER_2 + #define DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w) \ + DETAIL_IGN_UTILS_STRINGIFY(GCC diagnostic ignored w) + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER + #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) \ + _Pragma(DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w)) + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME + #define DETAIL_IGN_UTILS_WARN_RESUME \ + _Pragma("GCC diagnostic pop") + #endif + + +#elif defined _MSC_VER + + + #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH + #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ + __pragma(warning(push)) + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER + #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) \ + __pragma(warning(disable: w)) + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME + #define DETAIL_IGN_UTILS_WARN_RESUME \ + __pragma(warning(pop)) + #endif + + +#else + + // Make these into no-ops if we don't know the type of compiler + + #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH + #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER + #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME + #define DETAIL_IGN_UTILS_WARN_RESUME + #endif + + +#endif + + +#ifndef DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION + #define DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(warning_token) \ + DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ + DETAIL_IGN_UTILS_WARN_SUP_HELPER(warning_token) +#endif + + + +// Warning Tokens +#if defined __GNUC__ || defined __clang__ + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR + #define DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR \ + DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION("-Wdelete-non-virtual-dtor") + #endif + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR + #define DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR \ + DETAIL_IGN_UTILS_WARN_RESUME + #endif + + + // There is no analogous warning for this in GCC or Clang so we just make + // blank macros for this warning type. + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING + #define DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING + #endif + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + #define DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION + #define DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION \ + DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION("-Wdeprecated-declarations") + #endif + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION + #define DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION \ + DETAIL_IGN_UTILS_WARN_RESUME + #endif + + +#elif defined _MSC_VER + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR + #define DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR \ + DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(4265) \ + DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(5205) + #endif + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR + #define DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR \ + DETAIL_IGN_UTILS_WARN_RESUME + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING + #define DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ + DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(4251) + #endif + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + #define DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING \ + DETAIL_IGN_UTILS_WARN_RESUME + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION + #define DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION \ + DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(4996) + #endif + + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION + #define DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION \ + DETAIL_IGN_UTILS_WARN_RESUME + #endif + + +#else + + // If the compiler is unknown, we simply leave these macros blank to avoid + // compilation errors. + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR + #define DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR + #endif + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR + #define DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING + #define DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING + #endif + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + #define DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING + #endif + + + #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION + #define DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION + #endif + #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION + #define DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION + #endif + + +#endif + +#endif // GZ_UTILS__DETAIL__SUPPRESSWARNING_HH_ diff --git a/include/ignition/utils/utils.hh.in b/include/gz/utils/utils.hh.in similarity index 53% rename from include/ignition/utils/utils.hh.in rename to include/gz/utils/utils.hh.in index 8071d70..5964169 100644 --- a/include/ignition/utils/utils.hh.in +++ b/include/gz/utils/utils.hh.in @@ -1,3 +1,3 @@ // Automatically generated -#include +#include ${ign_headers} diff --git a/include/ignition/utils.hh b/include/ignition/utils.hh new file mode 100644 index 0000000..2c876fa --- /dev/null +++ b/include/ignition/utils.hh @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2022 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. + * + */ + +#include diff --git a/include/ignition/utils/Environment.hh b/include/ignition/utils/Environment.hh index 658a13f..d58de5d 100644 --- a/include/ignition/utils/Environment.hh +++ b/include/ignition/utils/Environment.hh @@ -15,60 +15,4 @@ * */ -#ifndef IGNITION_UTILS_ENVIRONMENT_HH_ -#define IGNITION_UTILS_ENVIRONMENT_HH_ - -#include -#include - -#include - -namespace ignition -{ -namespace utils -{ -inline namespace IGNITION_UTILS_VERSION_NAMESPACE { - -/// \brief Find the environment variable '_name' and return its value. -/// -/// Note: This function is not thread-safe and should not be called -/// concurrently with `setenv` or `unsetenv` -/// -/// \param[in] _name Name of the environment variable. -/// \param[out] _value Value if the variable was found. -/// \param[in] _allowEmpty Allow set-but-empty variables. -/// (Unsupported on Windows) -/// \return True if the variable was found or false otherwise. -bool IGNITION_UTILS_VISIBLE env( - const std::string &_name, std::string &_value, - bool _allowEmpty = false); - -/// \brief Set the environment variable '_name'. -/// -/// Note: On Windows setting an empty string (_value=="") -/// is the equivalent of unsetting the variable. -// -/// Note: This function is not thread-safe and should not be called -/// concurrently with `env` or `unsetenv` -/// -/// \param[in] _name Name of the environment variable. -/// \param[in] _value Value of the variable to be set. -/// \return True if the variable was set or false otherwise. -bool IGNITION_UTILS_VISIBLE setenv( - const std::string &_name, const std::string &_value); - -/// \brief Unset the environment variable '_name'. -/// -/// Note: This function is not thread-safe and should not be called -/// concurrently with `env` or `setenv` -/// -/// \param[in] _name Name of the environment variable. -/// \return True if the variable was unset or false otherwise. -bool IGNITION_UTILS_VISIBLE unsetenv(const std::string &_name); - -} -} // namespace utils -} // namespace ignition - -#endif // IGNITION_UTILS_ENVIRONMENT_HH_ - +#include diff --git a/include/ignition/utils/Export.hh b/include/ignition/utils/Export.hh new file mode 100644 index 0000000..1632fb2 --- /dev/null +++ b/include/ignition/utils/Export.hh @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2022 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. + * + */ + +#include diff --git a/include/ignition/utils/ExtraTestMacros.hh b/include/ignition/utils/ExtraTestMacros.hh index bad461e..875855e 100644 --- a/include/ignition/utils/ExtraTestMacros.hh +++ b/include/ignition/utils/ExtraTestMacros.hh @@ -15,33 +15,4 @@ * */ -#ifndef IGNITION_UTILS_EXTRATESTMACROS_HH -#define IGNITION_UTILS_EXTRATESTMACROS_HH - -#include - -/// \brief Restrict the execution of the test for the Windows platform. -/// The test will be compiled on Windows too but will never be run as -/// part of the test suite. The macro uses the Disabled_ prefix provided -/// by googletest. See -/// https://chromium.googlesource.com/external/github.com/google/googletest/+/HEAD/googletest/docs/advanced.md -#define IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) \ - DETAIL_IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) - -/// \brief Restrict the execution of the test for the Mac platform. -/// The test will be compiled on Windows too but will never be run as -/// part of the test suite. The macro uses the Disabled_ prefix provided -/// by googletest. See -/// https://chromium.googlesource.com/external/github.com/google/googletest/+/HEAD/googletest/docs/advanced.md -#define IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) \ - DETAIL_IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) - -/// \brief Restrict the execution of the test to just the Linux platform -/// Other platforms will get the test compiled but it won't be run -/// as part of the test suite execution. -/// The macro uses the Disabled_ prefix provided by googletest. See -/// https://chromium.googlesource.com/external/github.com/google/googletest/+/HEAD/googletest/docs/advanced.md -#define IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) \ - DETAIL_IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) - -#endif // IGNITION_UTILS_EXTRATESTMACROS_HH +#include diff --git a/include/ignition/utils/ImplPtr.hh b/include/ignition/utils/ImplPtr.hh index 8eba453..17f0df5 100644 --- a/include/ignition/utils/ImplPtr.hh +++ b/include/ignition/utils/ImplPtr.hh @@ -15,246 +15,4 @@ * */ -#ifndef IGNITION_UTILS__IMPLPTR_HH_ -#define IGNITION_UTILS__IMPLPTR_HH_ - -#include -#include - -#include -#include -#include - -namespace ignition -{ - namespace utils - { - ////////////////////////////////////////////////// - /// \brief The ImplPtr class provides a convenient away to achieve the - /// - /// Rule of Zero while keeping all the benefits of PIMPL. This saves us - /// from writing an enormous amount of boilerplate code for each class. - /// - /// To follow PIMPL design principles, create an object of this type as the - /// one and only member variable of your class, e.g.: - /// - /// \code - /// class MyClass - /// { - /// public: /* ... public member functions ... */ - /// - /// private: class Implementation; - /// private: ImplPtr dataPtr; - /// }; - /// \endcode - /// - /// When constructing the `dataPtr` object, pass it - /// `MakeImpl(/* ... args ... */)` in the - /// initialization list of your class. \sa MakeImpl() - /// - /// This class was inspired by the following blog post: - /// http://oliora.github.io/2015/12/29/pimpl-and-rule-of-zero.html - /// - /// For interface classes that should not be copiable, see the UniqueImplPtr - /// class further down in this header. - /// - /// \note Switching between ImplPtr and UniqueImplPtr is \em NOT ABI-safe. - /// This is essentially the same as changing whether or not the class - /// provides a copy-constructor and a copy-assignment operator, which is - /// bound to result in runtime linking issues at a minimum (but more - /// importantly, it changes the binary footprint of the class). If it is not - /// obvious whether a class should be copiable, then the safest choice is to - /// use a UniqueImplPtr and then manually add the copy constructor/operator - /// later if it is deemed acceptable. The next time an ABI update is - /// permitted, those manually written functions can be removed and the - /// UniqueImplPtr can be replaced with an ImplPtr. - template > - class ImplPtr - { - /// \brief Constructor - /// \tparam U A type that is compatible with T, i.e. either T or a class - /// that is derived from T. - /// \tparam D The deleter type - /// \tparam Ops The copy operation container type - /// \param[in] _ptr The raw pointer to the implementation - /// \param[in] _deleter The deleter object - /// \param[in] _ops The copy operation object - public: template - ImplPtr(U *_ptr, D &&_deleter, Ops &&_ops); - - /// \brief Copy constructor - /// \param[in] _other Another ImplPtr of the same type - public: ImplPtr(const ImplPtr &_other); - - /// \brief Copy assignment operator - /// \param[in] _other Another ImplPtr of the same type - /// \return A reference to this ImplPtr - public: ImplPtr &operator=(const ImplPtr &_other); - - // We explicitly declare the move constructor to make it clear that it is - // available. - public: ImplPtr(ImplPtr &&) = default; - - // We explicitly declare the move assignment operator to make it clear - // that it is available. - public: ImplPtr &operator=(ImplPtr &&) = default; - - /// \brief Destructor - public: ~ImplPtr() = default; - - /// \brief Non-const dereference operator. This const-unqualified operator - /// ensures that logical const-correctness is followed by the consumer - /// class. - /// \return A mutable reference to the contained object. - public: T &operator*(); - - /// \brief Const dereference operator. This const-qualified operator - /// ensures that logical const-correctness is followed by the consumer - /// class. - /// \return A const-reference to the contained object. - public: const T &operator*() const; - - /// \brief Non-const member access operator. This const-unqualified - /// operator ensures that logical const-correctness is followed by the - /// consumer class. - /// \return Mutable access to the contained object's members. - public: T *operator->(); - - /// \brief Const member access operator. This const-qualified operator - /// ensures that logical const-correctness is followed by the consumer - /// class. - /// \return Immutable access to the contained object's members. - public: const T *operator->() const; - - /// \brief Non-const member access function. This const-unqualified - /// operator ensures that logical const-correctness is followed by the - /// consumer class. - /// \return Mutable access to the contained object's members. - public: T *Get(); - - /// \brief Const member access function. This const-qualified operator - /// ensures that logical const-correctness is followed by the consumer - /// class. - /// \return Immutable access to the contained object's members. - public: const T *Get() const; - - /// \internal \brief Create a clone of this ImplPtr's contents. This is - /// for internal use only. The copy constructor and copy assignment - /// operators should suffice for consumers. - /// - /// This function is needed internally for consumers' default copy - /// constructors to compile. - /// - /// \return An ImplPtr that has been copied from the current one. - private: ImplPtr Clone() const; - - /// \brief Pointer to the contained object - private: std::unique_ptr ptr; - - /// \brief Structure to hold the copy operators - private: Operations ops; - }; - - ////////////////////////////////////////////////// - /// \brief Pass this to the constructor of an ImplPtr object to easily - /// initialize it. All the arguments passed into this function will be - /// perfectly forwarded to the implementation class that gets created. - /// - /// E.g.: - /// - /// \code - /// MyClass::MyClass(Arg1 arg1, Arg2 arg2, Arg3 arg3) - /// : dataPtr(utils::MakeImpl(arg1, arg2, arg3)) - /// { - /// // Do nothing - /// } - /// \endcode - /// - /// \tparam T The typename of the implementation class. This must be set - /// explicitly. - /// \tparam Args The argument types. These will be inferred automatically. - /// \param[in] _args The arguments to be forwarded to the implementation - /// class. - /// \return A new ImplPtr. Passing this along to a class's ImplPtr - /// object's constructor will efficiently move this newly created object - /// into it. - template - ImplPtr MakeImpl(Args &&..._args); - - ////////////////////////////////////////////////// - /// \brief This is an alternative to ImplPtr which serves the same - /// purpose, except it only provide move semantics (i.e. it does not allow - /// copying). This should be used in cases where it is not safe (or not - /// possible) to copy the underlying state of an implementation class. - /// - /// Note that when creating an implementation class that is unsafe to copy, - /// you should explicitly delete its copy constructor (unless one of its - /// members has an explicitly deleted copy constructor). Doing so will force - /// you to use UniqueImplPtr instead of ImplPtr, and it will signal to - /// future developers or maintainers that the implementation class is not - /// meant to be copiable. - /// - /// Use MakeUniqueImpl() to construct UniqueImplPtr objects. - template - using UniqueImplPtr = std::unique_ptr; - - ////////////////////////////////////////////////// - /// \brief Pass this to the constructor of a UniqueImplPtr object to easily - /// initialize it. All the arguments passed into this function will be - /// perfectly forwarded to the implementation class that gets created. - /// - /// E.g.: - /// - /// \code - /// MyClass::MyClass(Arg1 arg1, Arg2 arg2, Arg3 arg3) - /// : dataPtr(utils::MakeUniqueImpl(arg1, arg2, arg3)) - /// { - /// // Do nothing - /// } - /// \endcode - /// - /// \tparam T The typename of the implementation class. This must be set - /// explicitly. - /// \tparam Args The argument types. These will be inferred automatically. - /// \param[in] _args The arguments to be forwarded to the implementation - /// class. - /// \return A new UniqueImplPtr. Passing this along to a class's - /// UniqueImplPtr object's constructor will efficiently move this newly - /// created object into it. - template - UniqueImplPtr MakeUniqueImpl(Args &&..._args); - } // namespace utils -} // namespace ignition - -/// \brief Add a private ImplPtr to a class as dataPtr. -/// This variant takes a forward-declared ImplementationClass as the impl. -#define IGN_UTILS_IMPL_PTR_FWD(ImplementationClass, memberName) \ - IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ - private: ::ignition::utils::ImplPtr memberName; \ - IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - -/// \brief Add a private UniqueImplPtr to a class as dataPtr. -/// This variant takes a forward-declared ImplementationClass as the impl. -#define IGN_UTILS_UNIQUE_IMPL_PTR_FWD(ImplementationClass, memberName) \ - IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ - private: ::ignition::utils::UniqueImplPtr memberName; \ - IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - -/// \brief Add a private ImplPtr to a class as dataPtr. -/// This variant forward-declares Class::Implementation as the impl. -#define IGN_UTILS_IMPL_PTR(memberName) \ - public: class Implementation; \ - IGN_UTILS_IMPL_PTR_FWD(Implementation, memberName) - -/// \brief Add a private UniqueImplPtr to a class as dataPtr. -/// This variant forward-declares Class::Implementation as the impl. -#define IGN_UTILS_UNIQUE_IMPL_PTR(memberName) \ - public: class Implementation; \ - IGN_UTILS_UNIQUE_IMPL_PTR_FWD(Implementation, memberName) - - -#include - -#endif // IGNITION_UTILS__IMPLPTR_HH_ +#include diff --git a/include/ignition/utils/NeverDestroyed.hh b/include/ignition/utils/NeverDestroyed.hh index 2ad9351..aeaeb3a 100644 --- a/include/ignition/utils/NeverDestroyed.hh +++ b/include/ignition/utils/NeverDestroyed.hh @@ -15,148 +15,4 @@ * */ -#ifndef IGNITION_UTILS_NEVERDESTROYED_HH_ -#define IGNITION_UTILS_NEVERDESTROYED_HH_ - -#include -#include -#include - -namespace ignition -{ -namespace utils -{ - -/// Originally copied from https://github.com/RobotLocomotion/drake/blob/v0.36.0/common/never_destroyed.h -/// Originally licensed BSD 3-Clause (https://github.com/RobotLocomotion/drake/blob/v0.36.0/LICENSE.TXT) -/// Re-licensed Apache-2.0 with permission from: -/// jwnimmer-tri (https://github.com/ignitionrobotics/ign-utils/pull/31#issuecomment-989173512) -/// -/// Wraps an underlying type T such that its storage is a direct member field -/// of this object (i.e., without any indirection into the heap), but *unlike* -/// most member fields T's destructor is never invoked. -/// -/// This is especially useful for function-local static variables that are not -/// trivially destructable. We shouldn't call their destructor at program exit -/// because of the "indeterminate order of ... destruction" as mentioned in -/// cppguide's -/// Static -/// and Global Variables section, but other solutions to this problem place -/// the objects on the heap through an indirection. -/// -/// Compared with other approaches, this mechanism more clearly describes the -/// intent to readers, avoids "possible leak" warnings from memory-checking -/// tools, and is probably slightly faster. -/// -/// Example uses: -/// -/// The singleton pattern: -/// @code -/// class Singleton -/// { -/// public: -/// Singleton(const Singleton&) = delete; -/// void operator=(const Singleton&) = delete; -/// Singleton(Singleton&&) = delete; -/// void operator=(Singleton&&) = delete; -/// -/// static Singleton& getInstance() -/// { -/// static ignition::utils::NeverDestroyed instance; -/// return instance.access(); -/// } -/// private: -/// friend ignition::utils::NeverDestroyed; -/// Singleton() = default; -/// }; -/// @endcode -/// -/// A lookup table, created on demand the first time its needed, and then -/// reused thereafter: -/// @code -/// enum class Foo { kBar, kBaz }; -/// Foo ParseFoo(const std::string& foo_string) -/// { -/// using Dict = std::unordered_map; -/// static const ignition::utils::NeverDestroyed string_to_enum -/// { -/// std::initializer_list -/// { -/// {"bar", Foo::kBar}, -/// {"baz", Foo::kBaz}, -/// } -/// }; -/// return string_to_enum.access().at(foo_string); -/// } -/// @endcode -/// -/// In cases where computing the static data is more complicated than an -/// initializer_list, you can use a temporary lambda to populate the value: -/// @code -/// const std::vector& GetConstantMagicNumbers() -/// { -/// static const ignition::utils::NeverDestroyed> result -/// { -/// []() -/// { -/// std::vector prototype; -/// std::mt19937 random_generator; -/// for (int i = 0; i < 10; ++i) -/// { -/// double new_value = random_generator(); -/// prototype.push_back(new_value); -/// } -/// return prototype; -/// }() -/// }; -/// return result.access(); -/// } -/// @endcode -/// -/// Note in particular the `()` after the lambda. That causes it to be invoked. -// -// The above examples are repeated in the unit test; keep them in sync. -template -class NeverDestroyed -{ - /// Passes the constructor arguments along to T using perfect forwarding. - public: template - explicit NeverDestroyed(Args &&... args) - { - // Uses "placement new" to construct a `T` in `storage_`. - new (&this->storage) T(std::forward(args)...); - } - - /// Does nothing. Guaranteed! - public: ~NeverDestroyed() = default; - - /// \brief Deleted copy constructor - public: NeverDestroyed(const NeverDestroyed &) = delete; - - /// \brief Deleted move constructor - public: NeverDestroyed(NeverDestroyed &&) = delete; - - /// \brief Deleted copy assignment constructor - public: NeverDestroyed &operator=(const NeverDestroyed &) = delete; - - /// \brief Deleted move assignment constructor - public: NeverDestroyed &operator=(NeverDestroyed &&) noexcept = delete; - - /// Returns the underlying T reference. - public: T &Access() - { - return *reinterpret_cast(&this->storage); - } - - public: const T &Access() const - { - return *reinterpret_cast(&this->storage); - } - - private: typename std::aligned_storage::type storage; -}; - -} // namespace utils -} // namespace ignition - -#endif // IGNITION_UTILS_NEVERDESTROYED_HH_ +#include diff --git a/include/ignition/utils/SuppressWarning.hh b/include/ignition/utils/SuppressWarning.hh index d8bb134..8b7d4c3 100644 --- a/include/ignition/utils/SuppressWarning.hh +++ b/include/ignition/utils/SuppressWarning.hh @@ -15,77 +15,4 @@ * */ -#ifndef IGNITION_UTILS__SUPPRESSWARNING_HH_ -#define IGNITION_UTILS__SUPPRESSWARNING_HH_ - -#include - -// This header contains cross-platform macros for suppressing warnings. Please -// only use these macros responsibly when you are certain that the compiler is -// producing a warning that is not applicable to the specific instance. Do not -// use these macros to ignore legitimate warnings, even if you may find them -// irritating. - -/* - * Usage example: - * - * SomeClass *ptr = CreatePtr(); - * IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR - * delete ptr; - * IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR - * - */ - -// Be sure to call the IGN_UTILS_WARN_RESUME__XXXXX macro at the end of the -// block of code where the warning suppression is needed. Otherwise, you might -// inadvertently suppress legitimate warnings. - -// ---- List of available suppressions ---- - -/// \brief Compilers might warn about deleting a pointer to a class that has -/// virtual functions without a virtual destructor or a `final` declaration, -/// because the pointer might secretly be pointing to a more derived class type. -/// We want to suppress this warning when we know for certain (via the design -/// of our implementation) that the pointer is definitely not pointing to a more -/// derived type. -#ifndef IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR - #define IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR \ - DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR -#endif - -#ifndef IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR - #define IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR \ - DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR -#endif - -/// \brief Microsoft Visual Studio does not automatically export the interface -/// information for member variables that belong to interface classes of a DLL. -/// Instead it issues this warning. When the member variable is private, we -/// choose to suppress the warning instead of needlessly adding the class -/// information to the DLL interface. -#ifndef IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING - #define IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ - DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING -#endif - -#ifndef IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - #define IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING \ - DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING -#endif - -/// \brief Use this to suppress deprecation warnings. This may be useful when -/// retaining tests for deprecated methods to preserve code coverage. -#ifndef IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION - #define IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION \ - DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION -#endif - -#ifndef IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION - #define IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION \ - DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION -#endif - -// TODO(anyone): Add more warning types as they become relevant. -// Do not add warning types to suppress unless they are genuinely necessary. - -#endif // IGNITION_UTILS__SUPPRESSWARNING_HH_ +#include diff --git a/include/ignition/utils/config.hh b/include/ignition/utils/config.hh new file mode 100644 index 0000000..fea1896 --- /dev/null +++ b/include/ignition/utils/config.hh @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2022 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. + * + */ + +#include diff --git a/include/ignition/utils/detail/DefaultOps.hh b/include/ignition/utils/detail/DefaultOps.hh index 0c966cc..d9f4fc6 100644 --- a/include/ignition/utils/detail/DefaultOps.hh +++ b/include/ignition/utils/detail/DefaultOps.hh @@ -15,70 +15,4 @@ * */ -#ifndef IGNITION_UTILS__DETAIL__DEFAULTOPS_HH_ -#define IGNITION_UTILS__DETAIL__DEFAULTOPS_HH_ - -#include - -namespace ignition -{ - namespace utils - { - namespace detail - { - ////////////////////////////////////////////////// - template - void VerifyComplete() - { - // If you are brought here by a compilation error while using the - // ImplPtr class or the UniqueImplPtr class, be sure to use the - // MakeImpl() or MakeUniqueImpl() function when constructing your - // [Unique]ImplPtr instance. - static_assert(sizeof(T) > 0, - "DefaultDelete cannot delete an incomplete type"); - static_assert(!std::is_void::value, - "DefaultDelete cannot delete an incomplete type"); - } - - ////////////////////////////////////////////////// - template - void DefaultDelete(T *_ptr) noexcept - { - VerifyComplete(); - delete _ptr; - } - - ////////////////////////////////////////////////// - template - T *DefaultCopyConstruct(const T &_source) - { - VerifyComplete(); - return new T(_source); - } - - ////////////////////////////////////////////////// - template - void DefaultCopyAssign(T &_dest, const T &_source) - { - VerifyComplete(); - _dest = _source; - } - - ////////////////////////////////////////////////// - template - struct CopyMoveDeleteOperations - { - public: template - CopyMoveDeleteOperations(C &&_construct, A &&_assign); - - public: CopyConstruct construct; - public: CopyAssign assign; - }; - } // namespace detail - } // namespace utils -} // namespace ignition - -#endif // IGNITION_UTILS__DETAIL__DEFAULTOPS_HH_ - +#include diff --git a/include/ignition/utils/detail/ExtraTestMacros.hh b/include/ignition/utils/detail/ExtraTestMacros.hh index 02f2a49..b048f54 100644 --- a/include/ignition/utils/detail/ExtraTestMacros.hh +++ b/include/ignition/utils/detail/ExtraTestMacros.hh @@ -15,48 +15,4 @@ * */ -#ifndef IGNITION_UTILS_DETAIL_EXTRATESTMACROS_HH -#define IGNITION_UTILS_DETAIL_EXTRATESTMACROS_HH - -#include - -#define DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(x) DISABLED_##x - -#if defined _WIN32 - - #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) \ - DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(TestName) - -#else - - #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_WIN32(TestName) \ - TestName - -#endif // defined _WIN32 - -#if defined __APPLE__ - - #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) \ - DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(TestName) - -#else - - #define DETAIL_IGN_UTILS_TEST_DISABLED_ON_MAC(TestName) \ - TestName - -#endif // defined __APPLE__ - -#if defined __linux__ - - #define DETAIL_IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) \ - TestName - -#else - - #define DETAIL_IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(TestName) \ - DETAIL_IGN_UTILS_ADD_DISABLED_PREFIX(TestName) - -#endif // defined __linux__ - - -#endif // IGNITION_UTILS_DETAIL_EXTRATESTMACROS_HH +#include diff --git a/include/ignition/utils/detail/ImplPtr.hh b/include/ignition/utils/detail/ImplPtr.hh index 0926f29..2041ed9 100644 --- a/include/ignition/utils/detail/ImplPtr.hh +++ b/include/ignition/utils/detail/ImplPtr.hh @@ -15,137 +15,4 @@ * */ -#ifndef IGNITION_UTILS__DETAIL__IMPLPTR_HH_ -#define IGNITION_UTILS__DETAIL__IMPLPTR_HH_ - -#include - -#include - -namespace ignition -{ - namespace utils - { - namespace detail - { - ////////////////////////////////////////////////// - template - // cppcheck-suppress syntaxError - template - CopyMoveDeleteOperations:: - CopyMoveDeleteOperations(C &&_construct, A &&_assign) - : construct(_construct), - assign(_assign) - { - // Do nothing - } - } // namespace detail - - ////////////////////////////////////////////////// - template - template - ImplPtr::ImplPtr( - Ptr *_ptr, D &&_deleter, Ops &&_ops) - : ptr(_ptr, std::forward(_deleter)), - ops(std::forward(_ops)) - { - // Do nothing - } - - ////////////////////////////////////////////////// - template - ImplPtr::ImplPtr(const ImplPtr &_other) - // Delegate to the move constructor after cloning - : ImplPtr(_other.Clone()) - { - // Do nothing - } - - ////////////////////////////////////////////////// - template - auto ImplPtr::operator=( - const ImplPtr &_other) -> ImplPtr& - { - if (this->ptr) - this->ops.assign(*this->ptr, *_other.ptr); - else - this->ptr.reset(this->ops.construct(*_other.ptr)); - - return *this; - } - - ////////////////////////////////////////////////// - template - auto ImplPtr::Clone() const -> ImplPtr - { - return ImplPtr(this->ptr ? this->ops.construct(*this->ptr) : nullptr, - this->ptr.get_deleter(), - this->ops); - } - - ////////////////////////////////////////////////// - template - T &ImplPtr::operator*() - { - return *ptr; - } - - ////////////////////////////////////////////////// - template - const T &ImplPtr::operator*() const - { - return *ptr; - } - - ////////////////////////////////////////////////// - template - T *ImplPtr::operator->() - { - return ptr.get(); - } - - ////////////////////////////////////////////////// - template - const T *ImplPtr::operator->() const - { - return ptr.get(); - } - - ////////////////////////////////////////////////// - template - T *ImplPtr::Get() - { - return ptr.get(); - } - - ////////////////////////////////////////////////// - template - const T *ImplPtr::Get() const - { - return ptr.get(); - } - - ////////////////////////////////////////////////// - template - ImplPtr MakeImpl(Args &&..._args) - { - return ImplPtr( - new T{std::forward(_args)...}, - &detail::DefaultDelete, - detail::CopyMoveDeleteOperations( - &detail::DefaultCopyConstruct, - &detail::DefaultCopyAssign)); - } - - ////////////////////////////////////////////////// - template - UniqueImplPtr MakeUniqueImpl(Args &&...args) - { - return UniqueImplPtr( - new T{std::forward(args)...}, - &detail::DefaultDelete); - } - } // namespace utils -} // namespace ignition - -#endif // IGNITION_UTILS__DETAIL__IMPLPTR_HH_ +#include diff --git a/include/ignition/utils/detail/SuppressWarning.hh b/include/ignition/utils/detail/SuppressWarning.hh index da1f736..27059c3 100644 --- a/include/ignition/utils/detail/SuppressWarning.hh +++ b/include/ignition/utils/detail/SuppressWarning.hh @@ -15,227 +15,4 @@ * */ -#ifndef IGNITION_UTILS__DETAIL__SUPPRESSWARNING_HH_ -#define IGNITION_UTILS__DETAIL__SUPPRESSWARNING_HH_ - -#include - -#ifndef DETAIL_IGN_UTILS_STRINGIFY - #define DETAIL_IGN_UTILS_STRINGIFY(x) #x -#endif - -/* cppcheck-suppress */ - -// BEGIN / FINISH Macros - -#if defined __clang__ - - #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH - #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ - _Pragma("clang diagnostic push") - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER_2 - #define DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w) \ - DETAIL_IGN_UTILS_STRINGIFY(clang diagnostic ignored w) - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER - #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) \ - _Pragma(DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w)) - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME - #define DETAIL_IGN_UTILS_WARN_RESUME \ - _Pragma("clang diagnostic pop") - #endif - - -#elif defined __GNUC__ - - // NOTE: clang will define both __clang__ and __GNUC__, and it seems that - // clang will gladly accept GCC pragmas. Even so, if we want the pragmas to - // target the "correct" compiler, we should check if __clang__ is defined - // before checking whether __GNUC__ is defined. - - #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH - #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ - _Pragma("GCC diagnostic push") - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER_2 - #define DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w) \ - DETAIL_IGN_UTILS_STRINGIFY(GCC diagnostic ignored w) - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER - #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) \ - _Pragma(DETAIL_IGN_UTILS_WARN_SUP_HELPER_2(w)) - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME - #define DETAIL_IGN_UTILS_WARN_RESUME \ - _Pragma("GCC diagnostic pop") - #endif - - -#elif defined _MSC_VER - - - #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH - #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ - __pragma(warning(push)) - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER - #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) \ - __pragma(warning(disable: w)) - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME - #define DETAIL_IGN_UTILS_WARN_RESUME \ - __pragma(warning(pop)) - #endif - - -#else - - // Make these into no-ops if we don't know the type of compiler - - #ifndef DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH - #define DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_SUP_HELPER - #define DETAIL_IGN_UTILS_WARN_SUP_HELPER(w) - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME - #define DETAIL_IGN_UTILS_WARN_RESUME - #endif - - -#endif - - -#ifndef DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION - #define DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(warning_token) \ - DETAIL_IGN_UTILS_BEGIN_WARN_SUP_PUSH \ - DETAIL_IGN_UTILS_WARN_SUP_HELPER(warning_token) -#endif - - - -// Warning Tokens -#if defined __GNUC__ || defined __clang__ - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR - #define DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR \ - DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION("-Wdelete-non-virtual-dtor") - #endif - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR - #define DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR \ - DETAIL_IGN_UTILS_WARN_RESUME - #endif - - - // There is no analogous warning for this in GCC or Clang so we just make - // blank macros for this warning type. - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING - #define DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING - #endif - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - #define DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION - #define DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION \ - DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION("-Wdeprecated-declarations") - #endif - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION - #define DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION \ - DETAIL_IGN_UTILS_WARN_RESUME - #endif - - -#elif defined _MSC_VER - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR - #define DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR \ - DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(4265) \ - DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(5205) - #endif - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR - #define DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR \ - DETAIL_IGN_UTILS_WARN_RESUME - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING - #define DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING \ - DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(4251) - #endif - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - #define DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING \ - DETAIL_IGN_UTILS_WARN_RESUME - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION - #define DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION \ - DETAIL_IGN_UTILS_BEGIN_WARNING_SUPPRESSION(4996) - #endif - - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION - #define DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION \ - DETAIL_IGN_UTILS_WARN_RESUME - #endif - - -#else - - // If the compiler is unknown, we simply leave these macros blank to avoid - // compilation errors. - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR - #define DETAIL_IGN_UTILS_WARN_IGNORE__NON_VIRTUAL_DESTRUCTOR - #endif - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR - #define DETAIL_IGN_UTILS_WARN_RESUME__NON_VIRTUAL_DESTRUCTOR - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING - #define DETAIL_IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING - #endif - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - #define DETAIL_IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING - #endif - - - #ifndef DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION - #define DETAIL_IGN_UTILS_WARN_IGNORE__DEPRECATED_DECLARATION - #endif - #ifndef DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION - #define DETAIL_IGN_UTILS_WARN_RESUME__DEPRECATED_DECLARATION - #endif - - -#endif - -#endif // IGNITION_UTILS__DETAIL__SUPPRESSWARNING_HH_ +#include