diff options
Diffstat (limited to 'src/mongo/base')
-rw-r--r-- | src/mongo/base/checked_cast.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/mongo/base/checked_cast.h b/src/mongo/base/checked_cast.h index 94cf5ea9c1f..e434a4c6e12 100644 --- a/src/mongo/base/checked_cast.h +++ b/src/mongo/base/checked_cast.h @@ -30,6 +30,8 @@ #pragma once +#include <memory> + #include "mongo/util/assert_util.h" #include "mongo/util/debug_util.h" @@ -73,4 +75,39 @@ T checked_cast(const U& u) { return checked_cast_impl<kDebugBuild>::cast<T>(u); }; +/** + * Similar to static_pointer_cast, but in debug builds uses RTTI to confirm that the cast + * is legal at runtime. + */ +template <bool> +struct checked_pointer_cast_impl; + +template <> +struct checked_pointer_cast_impl<false> { + template <typename T, typename U> + static std::shared_ptr<T> cast(const std::shared_ptr<U>& u) { + return std::static_pointer_cast<T>(u); + } +}; + +template <> +struct checked_pointer_cast_impl<true> { + template <typename T, typename U> + static std::shared_ptr<T> cast(const std::shared_ptr<U>& u) { + if (!u) { + return nullptr; + } + + std::shared_ptr<T> t = std::dynamic_pointer_cast<T>(u); + invariant(t); + + return t; + } +}; + +template <typename T, typename U> +std::shared_ptr<T> checked_pointer_cast(const std::shared_ptr<U>& u) { + return checked_pointer_cast_impl<kDebugBuild>::cast<T>(u); +}; + } // namespace mongo |