For the implementation strategy, I'm not sure if there's some robust and standardized way to check fancy pointers.
We need to check the standard on the terminology "fancy pointer". I'm at least aware that we can't simply delegate to std::pointer_traits<T> because there's some legit fallback that mistakenly enables its specialization, e.g. some classes like std::span define ::element_type even though they are not fancy pointers.
The ad-hoc way (or maybe the only way if there exists no robust way) is to enable partial specialization for all variants below:
std::unique_ptr<T>
std::shared_ptr<T>
We are not confident how these should be treated:
std::weak_ptr<T> -- even though we can define this is a fancy pointer, the typical use case of iris::is_fancy_pointer<T> is a pre-check for when you want to obtain the raw pointer of the given type unconditionally. That means, if we return true for std::weak_ptr<T>, we are inevitably going to invoke return ptr.lock().get();. I'm 100% sure that's misleading and semantically broken, because the reference can get destroyed in subtle timings.
If we are going to reject std::weak_ptr<T>, we might need to change our traits' name to like iris::is_owning_fancy_ptr<T>. It really depends on how the C++ standard defines the term "fancy pointer" though.
For the implementation strategy, I'm not sure if there's some robust and standardized way to check fancy pointers.
We need to check the standard on the terminology "fancy pointer". I'm at least aware that we can't simply delegate to
std::pointer_traits<T>because there's some legit fallback that mistakenly enables its specialization, e.g. some classes likestd::spandefine::element_typeeven though they are not fancy pointers.The ad-hoc way (or maybe the only way if there exists no robust way) is to enable partial specialization for all variants below:
std::unique_ptr<T>std::shared_ptr<T>We are not confident how these should be treated:
std::weak_ptr<T>-- even though we can define this is a fancy pointer, the typical use case ofiris::is_fancy_pointer<T>is a pre-check for when you want to obtain the raw pointer of the given type unconditionally. That means, if we returntrueforstd::weak_ptr<T>, we are inevitably going to invokereturn ptr.lock().get();. I'm 100% sure that's misleading and semantically broken, because the reference can get destroyed in subtle timings.If we are going to reject
std::weak_ptr<T>, we might need to change our traits' name to likeiris::is_owning_fancy_ptr<T>. It really depends on how the C++ standard defines the term "fancy pointer" though.