Avoid O(n*m) complexity in StringRef::find_first(_not)_of(StringRef).
[oota-llvm.git] / include / llvm / ADT / PointerUnion.h
1 //===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the PointerUnion class, which is a discriminated union of
11 // pointer types.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_ADT_POINTERUNION_H
16 #define LLVM_ADT_POINTERUNION_H
17
18 #include "llvm/ADT/PointerIntPair.h"
19
20 namespace llvm {
21
22   /// getPointerUnionTypeNum - If the argument has type PT1* or PT2* return
23   /// false or true respectively.
24   template <typename PT1, typename PT2>
25   static inline int getPointerUnionTypeNum(PT1 *P) { return 0; }
26   template <typename PT1, typename PT2>
27   static inline int getPointerUnionTypeNum(PT2 *P) { return 1; }
28   template <typename PT1, typename PT2>
29   static inline int getPointerUnionTypeNum(...) { return -1; }
30   
31   
32   /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
33   /// for the two template arguments.
34   template <typename PT1, typename PT2>
35   class PointerUnionUIntTraits {
36   public:
37     static inline void *getAsVoidPointer(void *P) { return P; }
38     static inline void *getFromVoidPointer(void *P) { return P; }
39     enum {
40       PT1BitsAv = PointerLikeTypeTraits<PT1>::NumLowBitsAvailable,
41       PT2BitsAv = PointerLikeTypeTraits<PT2>::NumLowBitsAvailable,
42       NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
43     };
44   };
45   
46   /// PointerUnion - This implements a discriminated union of two pointer types,
47   /// and keeps the discriminator bit-mangled into the low bits of the pointer.
48   /// This allows the implementation to be extremely efficient in space, but
49   /// permits a very natural and type-safe API.
50   ///
51   /// Common use patterns would be something like this:
52   ///    PointerUnion<int*, float*> P;
53   ///    P = (int*)0;
54   ///    printf("%d %d", P.is<int*>(), P.is<float*>());  // prints "1 0"
55   ///    X = P.get<int*>();     // ok.
56   ///    Y = P.get<float*>();   // runtime assertion failure.
57   ///    Z = P.get<double*>();  // runtime assertion failure (regardless of tag)
58   ///    P = (float*)0;
59   ///    Y = P.get<float*>();   // ok.
60   ///    X = P.get<int*>();     // runtime assertion failure.
61   template <typename PT1, typename PT2>
62   class PointerUnion {
63   public:
64     typedef PointerIntPair<void*, 1, bool, 
65                            PointerUnionUIntTraits<PT1,PT2> > ValTy;
66   private:
67     ValTy Val;
68   public:
69     PointerUnion() {}
70     
71     PointerUnion(PT1 V) {
72       Val.setPointer(
73          const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
74       Val.setInt(0);
75     }
76     PointerUnion(PT2 V) {
77       Val.setPointer(
78          const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
79       Val.setInt(1);
80     }
81     
82     /// isNull - Return true if the pointer held in the union is null,
83     /// regardless of which type it is.
84     bool isNull() const { return Val.getPointer() == 0; }
85     operator bool() const { return !isNull(); }
86
87     /// is<T>() return true if the Union currently holds the type matching T.
88     template<typename T>
89     int is() const {
90       int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0);
91       assert(TyNo != -1 && "Type query could never succeed on PointerUnion!");
92       return static_cast<int>(Val.getInt()) == TyNo;
93     }
94     
95     /// get<T>() - Return the value of the specified pointer type. If the
96     /// specified pointer type is incorrect, assert.
97     template<typename T>
98     T get() const {
99       assert(is<T>() && "Invalid accessor called");
100       return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
101     }
102     
103     /// dyn_cast<T>() - If the current value is of the specified pointer type,
104     /// return it, otherwise return null.
105     template<typename T>
106     T dyn_cast() const {
107       if (is<T>()) return get<T>();
108       return T();
109     }
110     
111     /// Assignment operators - Allow assigning into this union from either
112     /// pointer type, setting the discriminator to remember what it came from.
113     const PointerUnion &operator=(const PT1 &RHS) {
114       Val.setPointer(
115          const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
116       Val.setInt(0);
117       return *this;
118     }
119     const PointerUnion &operator=(const PT2 &RHS) {
120       Val.setPointer(
121         const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)));
122       Val.setInt(1);
123       return *this;
124     }
125     
126     void *getOpaqueValue() const { return Val.getOpaqueValue(); }
127     static inline PointerUnion getFromOpaqueValue(void *VP) {
128       PointerUnion V;
129       V.Val = ValTy::getFromOpaqueValue(VP);
130       return V;
131     }
132   };
133   
134   // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
135   // # low bits available = min(PT1bits,PT2bits)-1.
136   template<typename PT1, typename PT2>
137   class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > {
138   public:
139     static inline void *
140     getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
141       return P.getOpaqueValue();
142     }
143     static inline PointerUnion<PT1, PT2>
144     getFromVoidPointer(void *P) {
145       return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
146     }
147     
148     // The number of bits available are the min of the two pointer types.
149     enum {
150       NumLowBitsAvailable = 
151         PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy>
152           ::NumLowBitsAvailable
153     };
154   };
155   
156   
157   /// PointerUnion3 - This is a pointer union of three pointer types.  See
158   /// documentation for PointerUnion for usage.
159   template <typename PT1, typename PT2, typename PT3>
160   class PointerUnion3 {
161   public:
162     typedef PointerUnion<PT1, PT2> InnerUnion;
163     typedef PointerUnion<InnerUnion, PT3> ValTy;
164   private:
165     ValTy Val;
166   public:
167     PointerUnion3() {}
168     
169     PointerUnion3(PT1 V) {
170       Val = InnerUnion(V);
171     }
172     PointerUnion3(PT2 V) {
173       Val = InnerUnion(V);
174     }
175     PointerUnion3(PT3 V) {
176       Val = V;
177     }
178     
179     /// isNull - Return true if the pointer held in the union is null,
180     /// regardless of which type it is.
181     bool isNull() const { return Val.isNull(); }
182     operator bool() const { return !isNull(); }
183     
184     /// is<T>() return true if the Union currently holds the type matching T.
185     template<typename T>
186     int is() const {
187       // Is it PT1/PT2?
188       if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1)
189         return Val.template is<InnerUnion>() && 
190                Val.template get<InnerUnion>().template is<T>();
191       return Val.template is<T>();
192     }
193     
194     /// get<T>() - Return the value of the specified pointer type. If the
195     /// specified pointer type is incorrect, assert.
196     template<typename T>
197     T get() const {
198       assert(is<T>() && "Invalid accessor called");
199       // Is it PT1/PT2?
200       if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1)
201         return Val.template get<InnerUnion>().template get<T>();
202       
203       return Val.template get<T>();
204     }
205     
206     /// dyn_cast<T>() - If the current value is of the specified pointer type,
207     /// return it, otherwise return null.
208     template<typename T>
209     T dyn_cast() const {
210       if (is<T>()) return get<T>();
211       return T();
212     }
213     
214     /// Assignment operators - Allow assigning into this union from either
215     /// pointer type, setting the discriminator to remember what it came from.
216     const PointerUnion3 &operator=(const PT1 &RHS) {
217       Val = InnerUnion(RHS);
218       return *this;
219     }
220     const PointerUnion3 &operator=(const PT2 &RHS) {
221       Val = InnerUnion(RHS);
222       return *this;
223     }
224     const PointerUnion3 &operator=(const PT3 &RHS) {
225       Val = RHS;
226       return *this;
227     }
228     
229     void *getOpaqueValue() const { return Val.getOpaqueValue(); }
230     static inline PointerUnion3 getFromOpaqueValue(void *VP) {
231       PointerUnion3 V;
232       V.Val = ValTy::getFromOpaqueValue(VP);
233       return V;
234     }
235   };
236  
237   // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
238   // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
239   template<typename PT1, typename PT2, typename PT3>
240   class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > {
241   public:
242     static inline void *
243     getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
244       return P.getOpaqueValue();
245     }
246     static inline PointerUnion3<PT1, PT2, PT3>
247     getFromVoidPointer(void *P) {
248       return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
249     }
250     
251     // The number of bits available are the min of the two pointer types.
252     enum {
253       NumLowBitsAvailable = 
254         PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy>
255           ::NumLowBitsAvailable
256     };
257   };
258
259   /// PointerUnion4 - This is a pointer union of four pointer types.  See
260   /// documentation for PointerUnion for usage.
261   template <typename PT1, typename PT2, typename PT3, typename PT4>
262   class PointerUnion4 {
263   public:
264     typedef PointerUnion<PT1, PT2> InnerUnion1;
265     typedef PointerUnion<PT3, PT4> InnerUnion2;
266     typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy;
267   private:
268     ValTy Val;
269   public:
270     PointerUnion4() {}
271     
272     PointerUnion4(PT1 V) {
273       Val = InnerUnion1(V);
274     }
275     PointerUnion4(PT2 V) {
276       Val = InnerUnion1(V);
277     }
278     PointerUnion4(PT3 V) {
279       Val = InnerUnion2(V);
280     }
281     PointerUnion4(PT4 V) {
282       Val = InnerUnion2(V);
283     }
284     
285     /// isNull - Return true if the pointer held in the union is null,
286     /// regardless of which type it is.
287     bool isNull() const { return Val.isNull(); }
288     operator bool() const { return !isNull(); }
289     
290     /// is<T>() return true if the Union currently holds the type matching T.
291     template<typename T>
292     int is() const {
293       // Is it PT1/PT2?
294       if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1)
295         return Val.template is<InnerUnion1>() && 
296                Val.template get<InnerUnion1>().template is<T>();
297       return Val.template is<InnerUnion2>() && 
298              Val.template get<InnerUnion2>().template is<T>();
299     }
300     
301     /// get<T>() - Return the value of the specified pointer type. If the
302     /// specified pointer type is incorrect, assert.
303     template<typename T>
304     T get() const {
305       assert(is<T>() && "Invalid accessor called");
306       // Is it PT1/PT2?
307       if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1)
308         return Val.template get<InnerUnion1>().template get<T>();
309       
310       return Val.template get<InnerUnion2>().template get<T>();
311     }
312     
313     /// dyn_cast<T>() - If the current value is of the specified pointer type,
314     /// return it, otherwise return null.
315     template<typename T>
316     T dyn_cast() const {
317       if (is<T>()) return get<T>();
318       return T();
319     }
320     
321     /// Assignment operators - Allow assigning into this union from either
322     /// pointer type, setting the discriminator to remember what it came from.
323     const PointerUnion4 &operator=(const PT1 &RHS) {
324       Val = InnerUnion1(RHS);
325       return *this;
326     }
327     const PointerUnion4 &operator=(const PT2 &RHS) {
328       Val = InnerUnion1(RHS);
329       return *this;
330     }
331     const PointerUnion4 &operator=(const PT3 &RHS) {
332       Val = InnerUnion2(RHS);
333       return *this;
334     }
335     const PointerUnion4 &operator=(const PT4 &RHS) {
336       Val = InnerUnion2(RHS);
337       return *this;
338     }
339     
340     void *getOpaqueValue() const { return Val.getOpaqueValue(); }
341     static inline PointerUnion4 getFromOpaqueValue(void *VP) {
342       PointerUnion4 V;
343       V.Val = ValTy::getFromOpaqueValue(VP);
344       return V;
345     }
346   };
347   
348   // Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
349   // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
350   template<typename PT1, typename PT2, typename PT3, typename PT4>
351   class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4> > {
352   public:
353     static inline void *
354     getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
355       return P.getOpaqueValue();
356     }
357     static inline PointerUnion4<PT1, PT2, PT3, PT4>
358     getFromVoidPointer(void *P) {
359       return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
360     }
361     
362     // The number of bits available are the min of the two pointer types.
363     enum {
364       NumLowBitsAvailable = 
365         PointerLikeTypeTraits<typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>
366           ::NumLowBitsAvailable
367     };
368   };
369 }
370
371 #endif