[PATCH] D15910: Make isa, cast, dyn_cast, etc. work with std::unique_ptr and std::shared_ptr.
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 13 22:47:17 PST 2016
Justin Lebar via llvm-commits <llvm-commits at lists.llvm.org> writes:
> jlebar created this revision.
> jlebar added a reviewer: echristo.
> jlebar added a subscriber: llvm-commits.
>
> This lets us use these functions without calling 'get()' everywhere.
Making this work for isa<> is really nice, but I'm kind of uncomfortable
witht the subtlety it adds to cast/dyn_cast/dyn_cast_or_null wrt
unique_ptr. I worry about accidentally escaping (and then capturing) the
raw pointer via a type cast.
> http://reviews.llvm.org/D15910
>
> Files:
> include/llvm/Support/Casting.h
> unittests/Support/Casting.cpp
>
> Index: unittests/Support/Casting.cpp
> ===================================================================
> --- unittests/Support/Casting.cpp
> +++ unittests/Support/Casting.cpp
> @@ -165,6 +165,26 @@
> EXPECT_NE(F5, null_foo);
> }
>
> +// We should be able to treat unique_ptr<T> just like T* for the purposes of
> +// isa, dyn_cast, cast, etc.
> +TEST(CastingTest, unique_ptr) {
> + std::unique_ptr<foo> a(new foo());
> + EXPECT_TRUE(isa<foo>(a));
> +
> + std::unique_ptr<bar> b(new bar());
> + EXPECT_NE(dyn_cast_or_null<foo>(b), null_foo);
> +}
> +
> +// We should be able to treat shared_ptr<T> just like T* for the purposes of
> +// isa, dyn_cast, cast, etc.
> +TEST(CastingTest, shared_ptr) {
> + auto a = std::make_shared<foo>();
> + EXPECT_TRUE(isa<foo>(a));
> +
> + auto b = std::make_shared<bar>();
> + EXPECT_NE(dyn_cast_or_null<foo>(b), null_foo);
> +}
> +
> // These lines are errors...
> //foo *F20 = cast<foo>(B2); // Yields const foo*
> //foo &F21 = cast<foo>(B3); // Yields const foo&
> Index: include/llvm/Support/Casting.h
> ===================================================================
> --- include/llvm/Support/Casting.h
> +++ include/llvm/Support/Casting.h
> @@ -18,6 +18,7 @@
> #include "llvm/Support/Compiler.h"
> #include "llvm/Support/type_traits.h"
> #include <cassert>
> +#include <memory>
>
> namespace llvm {
>
> @@ -47,6 +48,30 @@
> }
> };
>
> +template<class T> struct simplify_type<std::unique_ptr<T>> {
> + typedef T* SimpleType;
> + static SimpleType getSimplifiedValue(std::unique_ptr<T> &Val) { return Val.get(); }
> +};
> +
> +template<class T> struct simplify_type<const std::unique_ptr<T>> {
> + typedef /*const*/ T* SimpleType;
> + static SimpleType getSimplifiedValue(const std::unique_ptr<T> &Val) {
> + return Val.get();
> + }
> +};
> +
> +template<class T> struct simplify_type<std::shared_ptr<T>> {
> + typedef T* SimpleType;
> + static SimpleType getSimplifiedValue(std::shared_ptr<T> &Val) { return Val.get(); }
> +};
> +
> +template<class T> struct simplify_type<const std::shared_ptr<T>> {
> + typedef /*const*/ T* SimpleType;
> + static SimpleType getSimplifiedValue(const std::shared_ptr<T> &Val) {
> + return Val.get();
> + }
> +};
> +
> // The core of the implementation of isa<X> is here; To and From should be
> // the names of classes. This template can be specialized to customize the
> // implementation of isa<> without rewriting it from scratch.
>
More information about the llvm-commits
mailing list