| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | #include <memory> | ||
| 3 | #include <type_traits> | ||
| 4 | |||
| 5 | // Derived publicly from [std::enable_shared_from_this](https://en.cppreference.com/w/cpp/memory/enable_shared_from_this#Example) | ||
| 6 | class SharedObject : public std::enable_shared_from_this<SharedObject> { | ||
| 7 | public: | ||
| 8 | // Non-member factory function. Any number of arguments. | ||
| 9 | template <typename Derived, typename... Args> | ||
| 10 | friend std::shared_ptr<Derived> create(Args&&... args); | ||
| 11 | |||
| 12 | 44 | virtual ~SharedObject() noexcept = default; | |
| 13 | |||
| 14 | protected: | ||
| 15 | struct Protected; // Tag type available to derived classes. | ||
| 16 | |||
| 17 | 16 | SharedObject() noexcept = default; | |
| 18 | 4 | SharedObject(const SharedObject& other) = default; | |
| 19 | 2 | SharedObject(SharedObject&& other) noexcept = default; | |
| 20 | 2 | SharedObject& operator=(const SharedObject& other) = default; | |
| 21 | 2 | SharedObject& operator=(SharedObject&& other) noexcept = default; | |
| 22 | }; | ||
| 23 | |||
| 24 | // [Making sure that people use make_unique and make_shared to make your object](https://devblogs.microsoft.com/oldnewthing/20220721-00/?p=106879) | ||
| 25 | struct SharedObject::Protected { | ||
| 26 | explicit Protected() noexcept = default; | ||
| 27 | }; | ||
| 28 | |||
| 29 | template <typename Derived, typename... Args> | ||
| 30 | 44 | std::shared_ptr<Derived> create(Args&&... args) { | |
| 31 | static_assert( | ||
| 32 | std::is_convertible<Derived*, SharedObject*>::value, | ||
| 33 | "SharedObject must be a public base class of Derived!"); | ||
| 34 | static_assert( | ||
| 35 | not(std::is_default_constructible<Derived>::value | ||
| 36 | || std::is_copy_constructible<Derived>::value | ||
| 37 | || std::is_move_constructible<Derived>::value), | ||
| 38 | "Constructors should not be publicly accessible!"); | ||
| 39 | return std::make_shared<Derived>( | ||
| 40 |
2/3✓ Branch 3 taken 10 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
112 | SharedObject::Protected{}, std::forward<Args>(args)...); |
| 41 | } | ||
| 42 |