summaryrefslogtreecommitdiffstats
path: root/util/generic/ptr.h
diff options
context:
space:
mode:
authorionagamed <[email protected]>2022-10-01 11:18:40 +0300
committerionagamed <[email protected]>2022-10-01 11:18:40 +0300
commitfecbe41234ec99b7709d8d9ec617219655ac51a7 (patch)
tree04de3a8f2f402fd94185c2a5d7d9dca80a21d67c /util/generic/ptr.h
parentd479316c284f478d8bd44dd5eb57d5899b1ded4e (diff)
util: add .As<T> to TSharedPtr
Diffstat (limited to 'util/generic/ptr.h')
-rw-r--r--util/generic/ptr.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/util/generic/ptr.h b/util/generic/ptr.h
index 3addc85753e..b35d54d780a 100644
--- a/util/generic/ptr.h
+++ b/util/generic/ptr.h
@@ -7,6 +7,7 @@
#include "typetraits.h"
#include "singleton.h"
+#include <type_traits>
#include <utility>
#include <util/system/compiler.h>
@@ -895,6 +896,24 @@ public:
return C_ ? C_->Val() : 0;
}
+ template <class TT>
+ [[nodiscard]] inline TSharedPtr<TT, C, D> As() & noexcept {
+ static_assert(std::has_virtual_destructor<TT>(), "Type should have a virtual dtor");
+ static_assert(std::is_base_of<T, TT>(), "When downcasting from T to TT, T should be a parent of TT");
+ Ref();
+ return TSharedPtr<TT, C, D>(dynamic_cast<TT*>(T_), C_);
+ }
+
+ template <class TT>
+ [[nodiscard]] inline TSharedPtr<TT, C, D> As() && noexcept {
+ static_assert(std::has_virtual_destructor<TT>(), "Type should have a virtual dtor");
+ static_assert(std::is_base_of<T, TT>(), "When downcasting from T to TT, T should be a parent of TT");
+ auto resultPtr = TSharedPtr<TT, C, D>(dynamic_cast<TT*>(T_), C_);
+ T_ = nullptr;
+ C_ = nullptr;
+ return resultPtr;
+ }
+
#ifdef __cpp_impl_three_way_comparison
template <class Other>
inline bool operator==(const Other& p) const noexcept {