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 <cassert>
20
21namespace llvm {
22
23template<typename T>
24class Optional {
25  T x;
26  unsigned hasVal : 1;
27public:
28  explicit Optional() : x(), hasVal(false) {}
29  Optional(const T &y) : x(y), hasVal(true) {}
30
31  static inline Optional create(const T* y) {
32    return y ? Optional(*y) : Optional();
33  }
34
35  Optional &operator=(const T &y) {
36    x = y;
37    hasVal = true;
38    return *this;
39  }
40
41  const T* getPointer() const { assert(hasVal); return &x; }
42  const T& getValue() const { assert(hasVal); return x; }
43
44  operator bool() const { return hasVal; }
45  bool hasValue() const { return hasVal; }
46  const T* operator->() const { return getPointer(); }
47  const T& operator*() const { assert(hasVal); return x; }
48};
49
50template<typename T> struct simplify_type;
51
52template <typename T>
53struct simplify_type<const Optional<T> > {
54  typedef const T* SimpleType;
55  static SimpleType getSimplifiedValue(const Optional<T> &Val) {
56    return Val.getPointer();
57  }
58};
59
60template <typename T>
61struct simplify_type<Optional<T> >
62  : public simplify_type<const Optional<T> > {};
63
64/// \brief Poison comparison between two \c Optional objects. Clients needs to
65/// explicitly compare the underlying values and account for empty \c Optional
66/// objects.
67///
68/// This routine will never be defined. It returns \c void to help diagnose
69/// errors at compile time.
70template<typename T, typename U>
71void operator==(const Optional<T> &X, const Optional<U> &Y);
72
73/// \brief Poison comparison between two \c Optional objects. Clients needs to
74/// explicitly compare the underlying values and account for empty \c Optional
75/// objects.
76///
77/// This routine will never be defined. It returns \c void to help diagnose
78/// errors at compile time.
79template<typename T, typename U>
80void operator!=(const Optional<T> &X, const Optional<U> &Y);
81
82/// \brief Poison comparison between two \c Optional objects. Clients needs to
83/// explicitly compare the underlying values and account for empty \c Optional
84/// objects.
85///
86/// This routine will never be defined. It returns \c void to help diagnose
87/// errors at compile time.
88template<typename T, typename U>
89void operator<(const Optional<T> &X, const Optional<U> &Y);
90
91/// \brief Poison comparison between two \c Optional objects. Clients needs to
92/// explicitly compare the underlying values and account for empty \c Optional
93/// objects.
94///
95/// This routine will never be defined. It returns \c void to help diagnose
96/// errors at compile time.
97template<typename T, typename U>
98void operator<=(const Optional<T> &X, const Optional<U> &Y);
99
100/// \brief Poison comparison between two \c Optional objects. Clients needs to
101/// explicitly compare the underlying values and account for empty \c Optional
102/// objects.
103///
104/// This routine will never be defined. It returns \c void to help diagnose
105/// errors at compile time.
106template<typename T, typename U>
107void operator>=(const Optional<T> &X, const Optional<U> &Y);
108
109/// \brief Poison comparison between two \c Optional objects. Clients needs to
110/// explicitly compare the underlying values and account for empty \c Optional
111/// objects.
112///
113/// This routine will never be defined. It returns \c void to help diagnose
114/// errors at compile time.
115template<typename T, typename U>
116void operator>(const Optional<T> &X, const Optional<U> &Y);
117
118} // end llvm namespace
119
120#endif
121