1 /*++ 2 Copyright (c) 2006 Microsoft Corporation 3 4 Module Name: 5 6 optional.h 7 8 Abstract: 9 10 Discriminated union of a type T. 11 It defines the notion of initialized/uninitialized objects. 12 13 Author: 14 15 Leonardo de Moura (leonardo) 2006-09-29. 16 17 Revision History: 18 19 --*/ 20 21 #pragma once 22 23 template<class T> 24 class optional { 25 T* m_obj = nullptr; 26 destroy()27 void destroy() { 28 dealloc(m_obj); 29 m_obj = nullptr; 30 } 31 32 public: optional()33 optional() {} 34 optional(const T & val)35 explicit optional(const T & val) { 36 m_obj = alloc(T, val); 37 } 38 optional(T && val)39 explicit optional(T && val) { 40 m_obj = alloc(T, std::move(val)); 41 } 42 optional(optional<T> && val)43 optional(optional<T> && val) noexcept { 44 std::swap(m_obj, val.m_obj); 45 } 46 optional(const optional<T> & val)47 optional(const optional<T> & val) { 48 if (val.m_obj) { 49 m_obj = alloc(T, *val); 50 } 51 } 52 ~optional()53 ~optional() { 54 destroy(); 55 } 56 undef()57 static optional const & undef() { static optional u; return u; } 58 initialized()59 bool initialized() const { return m_obj; } 60 operator bool() const { return m_obj; } 61 bool operator!() const { return !m_obj; } 62 get()63 T * get() const { 64 return m_obj; 65 } 66 set_invalid()67 void set_invalid() { 68 destroy(); 69 } 70 71 T * operator->() { 72 SASSERT(m_obj); 73 return m_obj; 74 } 75 76 T const * operator->() const { 77 SASSERT(m_obj); 78 return m_obj; 79 } 80 81 const T & operator*() const { 82 SASSERT(m_obj); 83 return *m_obj; 84 } 85 86 T & operator*() { 87 SASSERT(m_obj); 88 return *m_obj; 89 } 90 91 optional & operator=(const T & val) { 92 destroy(); 93 m_obj = alloc(T, val); 94 return * this; 95 } 96 97 optional & operator=(optional && val) { 98 std::swap(m_obj, val.m_obj); 99 return *this; 100 } 101 102 optional & operator=(const optional & val) { 103 if (&val != this) { 104 destroy(); 105 if (val.m_obj) { 106 m_obj = alloc(T, *val); 107 } 108 } 109 return *this; 110 } 111 }; 112 113 114 /** 115 \brief Template specialization for pointers. NULL represents uninitialized pointers. 116 */ 117 template<typename T> 118 class optional<T*> { 119 T * m_ptr; 120 121 static optional m_undef; 122 123 public: 124 optional()125 optional():m_ptr(nullptr) {} 126 optional(T * val)127 explicit optional(T * val):m_ptr(val) {} 128 undef()129 static optional const & undef() { return m_undef; } 130 initialized()131 bool initialized() const { return m_ptr != 0 ; } 132 133 operator bool() const { return m_ptr != 0; } 134 135 bool operator!() const { return m_ptr == nullptr; } 136 reset()137 void reset() { m_ptr = 0; } 138 139 optional & operator=(T * val) { 140 m_ptr = val; 141 return *this; 142 } 143 144 optional & operator=(const optional & val) { 145 m_ptr = val.m_ptr; 146 return *this; 147 } 148 149 T ** operator->() { return &m_ptr; } 150 151 T * operator*() const { return m_ptr; } 152 153 T * & operator*() { return m_ptr; } 154 }; 155