Casting.h revision 589df88ba03a81b2b3dc9d084c191a3a74724ecd
1//===-- Support/Casting.h - Allow flexible, checked, casts -------*- C++ -*--=//
2//
3// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
4// and dyn_cast_or_null<X>() templates.
5//
6//===----------------------------------------------------------------------===//
7
8#ifndef SUPPORT_CASTING_H
9#define SUPPORT_CASTING_H
10
11// real_type - Provide a macro to get the real type of a value that might be
12// a use.  This provides a typedef 'Type' that is the argument type for all
13// non UseTy types, and is the contained pointer type of the use if it is a
14// UseTy.
15//
16template <class X> class real_type { typedef X Type; };
17
18//===----------------------------------------------------------------------===//
19//                          Type Checking Templates
20//===----------------------------------------------------------------------===//
21
22// isa<X> - Return true if the parameter to the template is an instance of the
23// template type argument.  Used like this:
24//
25//  if (isa<Type>(myVal)) { ... }
26//
27template <class X, class Y>
28inline bool isa(Y Val) {
29  assert(Val && "isa<Ty>(NULL) invoked!");
30  return X::classof(Val);
31}
32
33
34// cast<X> - Return the argument parameter cast to the specified type.  This
35// casting operator asserts that the type is correct, so it does not return null
36// on failure.  But it will correctly return NULL when the input is NULL.
37// Used Like this:
38//
39//  cast<      Instruction>(myVal)->getParent()
40//  cast<const Instruction>(myVal)->getParent()
41//
42template <class X, class Y>
43inline X *cast(Y Val) {
44  assert(isa<X>(Val) && "cast<Ty>() argument of uncompatible type!");
45  return (X*)(real_type<Y>::Type)Val;
46}
47
48// cast_or_null<X> - Functionally identical to cast, except that a null value is
49// accepted.
50//
51template <class X, class Y>
52inline X *cast_or_null(Y Val) {
53  assert((Val == 0 || isa<X>(Val)) &&
54         "cast_or_null<Ty>() argument of uncompatible type!");
55  return (X*)(real_type<Y>::Type)Val;
56}
57
58
59// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
60// casting operator returns null if the argument is of the wrong type, so it can
61// be used to test for a type as well as cast if successful.  This should be
62// used in the context of an if statement like this:
63//
64//  if (const Instruction *I = dyn_cast<const Instruction>(myVal)) { ... }
65//
66
67template <class X, class Y>
68inline X *dyn_cast(Y Val) {
69  return isa<X>(Val) ? cast<X>(Val) : 0;
70}
71
72// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
73// value is accepted.
74//
75template <class X, class Y>
76inline X *dyn_cast_or_null(Y Val) {
77  return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
78}
79
80#endif
81