diff options
author | samantharitter <samantha.ritter@10gen.com> | 2016-11-07 17:44:02 -0500 |
---|---|---|
committer | samantharitter <samantha.ritter@10gen.com> | 2016-11-08 16:30:37 -0500 |
commit | 158db044bb21a2ff39c2984a35850a28c9572c8d (patch) | |
tree | fb79dfc17888c9fb456e2fd8c34bd8aef289a3c7 /src/mongo/base | |
parent | 17c37d0e626a61aeae8f4f149da98df2496740fa (diff) | |
download | mongo-158db044bb21a2ff39c2984a35850a28c9572c8d.tar.gz |
SERVER-26674 Add checked_pointer_cast
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 |