2016-08-26 21:25:05 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
namespace ext
|
|
|
|
{
|
|
|
|
|
2017-11-04 03:20:18 +00:00
|
|
|
/** Allows to make std::shared_ptr from T with protected constructor.
|
|
|
|
*
|
|
|
|
* Derive your T class from shared_ptr_helper<T>
|
|
|
|
* and you will have static 'create' method in your class.
|
|
|
|
*
|
|
|
|
* Downsides:
|
|
|
|
* - your class cannot be final;
|
|
|
|
* - bad compilation error messages;
|
|
|
|
* - bad code navigation.
|
2017-11-04 20:57:10 +00:00
|
|
|
* - different dynamic type of created object, you cannot use typeid.
|
2016-10-23 07:41:26 +00:00
|
|
|
*/
|
|
|
|
template <typename T>
|
2017-11-03 21:50:22 +00:00
|
|
|
struct shared_ptr_helper
|
2016-08-26 21:25:05 +00:00
|
|
|
{
|
2017-06-06 18:36:13 +00:00
|
|
|
template <typename... TArgs>
|
2017-11-03 21:50:22 +00:00
|
|
|
static auto create(TArgs &&... args)
|
2017-06-06 18:36:13 +00:00
|
|
|
{
|
2017-11-04 03:20:18 +00:00
|
|
|
/** Local struct makes protected constructor to be accessible by std::make_shared function.
|
|
|
|
* This trick is suggested by Yurii Diachenko,
|
|
|
|
* inspired by https://habrahabr.ru/company/mailru/blog/341584/
|
|
|
|
* that is translation of http://videocortex.io/2017/Bestiary/#-voldemort-types
|
|
|
|
*/
|
|
|
|
struct Local : T
|
|
|
|
{
|
|
|
|
Local(TArgs &&... args) : T(std::forward<TArgs>(args)...) {};
|
|
|
|
};
|
|
|
|
|
2017-11-03 21:50:22 +00:00
|
|
|
return std::make_shared<Local>(std::forward<TArgs>(args)...);
|
2017-06-06 18:36:13 +00:00
|
|
|
}
|
2016-08-26 21:25:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|