Separate out the tests for whether the compiler suports R-value
[oota-llvm.git] / include / llvm / ADT / Optional.h
1 //===-- Optional.h - Simple variant for passing optional values ---*- 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 provides Optional, a template class modeled in the spirit of
11 //  OCaml's 'opt' variant.  The idea is to strongly type whether or not
12 //  a value can be optional.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_ADT_OPTIONAL
17 #define LLVM_ADT_OPTIONAL
18
19 #include "llvm/Support/Compiler.h"
20 #include <cassert>
21
22 #if LLVM_USE_RVALUE_REFERENCES
23 #include <utility>
24 #endif
25
26 namespace llvm {
27
28 template<typename T>
29 class Optional {
30   T x;
31   unsigned hasVal : 1;
32 public:
33   explicit Optional() : x(), hasVal(false) {}
34   Optional(const T &y) : x(y), hasVal(true) {}
35
36 #if LLVM_USE_RVALUE_REFERENCES
37   Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
38 #endif
39
40   static inline Optional create(const T* y) {
41     return y ? Optional(*y) : Optional();
42   }
43
44   Optional &operator=(const T &y) {
45     x = y;
46     hasVal = true;
47     return *this;
48   }
49   
50   const T* getPointer() const { assert(hasVal); return &x; }
51   const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; }
52
53   operator bool() const { return hasVal; }
54   bool hasValue() const { return hasVal; }
55   const T* operator->() const { return getPointer(); }
56   const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; }
57
58 #if LLVM_HAS_RVALUE_REFERENCE_THIS
59   T&& getValue() && { assert(hasVal); return std::move(x); }
60   T&& operator*() && { assert(hasVal); return std::move(x); } 
61 #endif
62 };
63
64 template<typename T> struct simplify_type;
65
66 template <typename T>
67 struct simplify_type<const Optional<T> > {
68   typedef const T* SimpleType;
69   static SimpleType getSimplifiedValue(const Optional<T> &Val) {
70     return Val.getPointer();
71   }
72 };
73
74 template <typename T>
75 struct simplify_type<Optional<T> >
76   : public simplify_type<const Optional<T> > {};
77
78 /// \brief Poison comparison between two \c Optional objects. Clients needs to
79 /// explicitly compare the underlying values and account for empty \c Optional
80 /// objects.
81 ///
82 /// This routine will never be defined. It returns \c void to help diagnose 
83 /// errors at compile time.
84 template<typename T, typename U>
85 void operator==(const Optional<T> &X, const Optional<U> &Y);
86
87 /// \brief Poison comparison between two \c Optional objects. Clients needs to
88 /// explicitly compare the underlying values and account for empty \c Optional
89 /// objects.
90 ///
91 /// This routine will never be defined. It returns \c void to help diagnose 
92 /// errors at compile time.
93 template<typename T, typename U>
94 void operator!=(const Optional<T> &X, const Optional<U> &Y);
95
96 /// \brief Poison comparison between two \c Optional objects. Clients needs to
97 /// explicitly compare the underlying values and account for empty \c Optional
98 /// objects.
99 ///
100 /// This routine will never be defined. It returns \c void to help diagnose 
101 /// errors at compile time.
102 template<typename T, typename U>
103 void operator<(const Optional<T> &X, const Optional<U> &Y);
104
105 /// \brief Poison comparison between two \c Optional objects. Clients needs to
106 /// explicitly compare the underlying values and account for empty \c Optional
107 /// objects.
108 ///
109 /// This routine will never be defined. It returns \c void to help diagnose 
110 /// errors at compile time.
111 template<typename T, typename U>
112 void operator<=(const Optional<T> &X, const Optional<U> &Y);
113
114 /// \brief Poison comparison between two \c Optional objects. Clients needs to
115 /// explicitly compare the underlying values and account for empty \c Optional
116 /// objects.
117 ///
118 /// This routine will never be defined. It returns \c void to help diagnose 
119 /// errors at compile time.
120 template<typename T, typename U>
121 void operator>=(const Optional<T> &X, const Optional<U> &Y);
122
123 /// \brief Poison comparison between two \c Optional objects. Clients needs to
124 /// explicitly compare the underlying values and account for empty \c Optional
125 /// objects.
126 ///
127 /// This routine will never be defined. It returns \c void to help diagnose 
128 /// errors at compile time.
129 template<typename T, typename U>
130 void operator>(const Optional<T> &X, const Optional<U> &Y);
131
132 } // end llvm namespace
133
134 #endif