Skip to content

Commit 2d216a9

Browse files
[ADT] Simplify CastInfo<To, PointerUnion<PTs...>> (NFC) (#156274)
This patch simplifies CastInfo<To, PointerUnion<PTs...>> by "inlining" CastInfoPointerUnionImpl into the CastInfo specialization. Here is a brief background: https://reviews.llvm.org/D125609 added support for CastInfo<To, PointerUnion<PTs...>> along with helper struct CastInfoPointerUnionImpl. During the review, we did discuss the idea of implementing the CastInfo specialization without the helper struct, but the suggested solution did not work. This patch attempts to simplify the CastInfo specialization again by making CastInfo a friend of PointerUnion: template <typename To, typename From, typename Enable> friend struct CastInfo; This gives CastInfo more access to PointerUnion than strictly necessary, but the ability to simplify the CastInfo specialization outweighs the risk.
1 parent f502bab commit 2d216a9

File tree

1 file changed

+11
-30
lines changed

1 file changed

+11
-30
lines changed

llvm/include/llvm/ADT/PointerUnion.h

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,12 @@ class PointerUnion
126126
using First = TypeAtIndex<0, PTs...>;
127127
using Base = typename PointerUnion::PointerUnionMembers;
128128

129-
/// This is needed to give the CastInfo implementation below access
130-
/// to protected members.
131-
/// Refer to its definition for further details.
132-
friend struct CastInfoPointerUnionImpl<PTs...>;
129+
// Give the CastInfo specialization below access to protected members.
130+
//
131+
// This makes all of CastInfo a friend, which is more than strictly
132+
// necessary. It's a workaround for C++'s inability to friend a
133+
// partial template specialization.
134+
template <typename To, typename From, typename Enable> friend struct CastInfo;
133135

134136
public:
135137
PointerUnion() = default;
@@ -219,42 +221,21 @@ bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
219221
return lhs.getOpaqueValue() < rhs.getOpaqueValue();
220222
}
221223

222-
/// We can't (at least, at this moment with C++14) declare CastInfo
223-
/// as a friend of PointerUnion like this:
224-
/// ```
225-
/// template<typename To>
226-
/// friend struct CastInfo<To, PointerUnion<PTs...>>;
227-
/// ```
228-
/// The compiler complains 'Partial specialization cannot be declared as a
229-
/// friend'.
230-
/// So we define this struct to be a bridge between CastInfo and
231-
/// PointerUnion.
232-
template <typename... PTs> struct CastInfoPointerUnionImpl {
233-
using From = PointerUnion<PTs...>;
234-
235-
template <typename To> static inline bool isPossible(From &F) {
236-
return F.Val.getInt() == FirstIndexOfType<To, PTs...>::value;
237-
}
238-
239-
template <typename To> static To doCast(From &F) {
240-
assert(isPossible<To>(F) && "cast to an incompatible type!");
241-
return PointerLikeTypeTraits<To>::getFromVoidPointer(F.Val.getPointer());
242-
}
243-
};
244-
245224
// Specialization of CastInfo for PointerUnion
246225
template <typename To, typename... PTs>
247226
struct CastInfo<To, PointerUnion<PTs...>>
248227
: public DefaultDoCastIfPossible<To, PointerUnion<PTs...>,
249228
CastInfo<To, PointerUnion<PTs...>>> {
250229
using From = PointerUnion<PTs...>;
251-
using Impl = CastInfoPointerUnionImpl<PTs...>;
252230

253231
static inline bool isPossible(From &f) {
254-
return Impl::template isPossible<To>(f);
232+
return f.Val.getInt() == FirstIndexOfType<To, PTs...>::value;
255233
}
256234

257-
static To doCast(From &f) { return Impl::template doCast<To>(f); }
235+
static To doCast(From &f) {
236+
assert(isPossible(f) && "cast to an incompatible type!");
237+
return PointerLikeTypeTraits<To>::getFromVoidPointer(f.Val.getPointer());
238+
}
258239

259240
static inline To castFailed() { return To(); }
260241
};

0 commit comments

Comments
 (0)