1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef UTIL_CHRE_OPTIONAL_H_ 18 #define UTIL_CHRE_OPTIONAL_H_ 19 20 #include <type_traits> 21 22 namespace chre { 23 24 /** 25 * This container keeps track of an optional object. The container is similar to 26 * std::optional introduced in C++17. 27 */ 28 template<typename ObjectType> 29 class Optional { 30 public: 31 // Per the standard, a program that instantiates template optional for a 32 // reference type is ill-formed 33 static_assert(!std::is_reference<ObjectType>::value, 34 "Optional references are not allowed"); 35 36 /** 37 * Default constructs the optional object with no initial value. 38 */ 39 Optional() = default; 40 41 /** 42 * Default copy constructor. 43 * 44 * @param object The object to copy construct from. 45 */ 46 Optional(const Optional<ObjectType>& object) = default; 47 48 /** 49 * Default copy constructor. 50 * 51 * @param object The object to copy construct from. 52 */ 53 Optional(Optional<ObjectType>& object) = default; 54 55 /** 56 * Constructs an optional instance with an initial value. 57 * 58 * @param object The initial value of the object. 59 */ 60 Optional(const ObjectType& object); 61 62 /** 63 * Constructs an optional instance with an initial value by moving it. 64 * 65 * @param object The instance of the initial object to take ownership of. 66 */ 67 Optional(ObjectType&& object); 68 69 /** 70 * Destructs the object. Calls through reset() to destroy the contained 71 * object before destructing this container. 72 */ 73 ~Optional(); 74 75 /** 76 * @return Returns true if this container holds an object 77 */ 78 bool has_value() const; 79 80 /** 81 * Destroys any contained object, and marks this Optional as empty (i.e. 82 * has_value() will return false after this function returns) 83 */ 84 void reset(); 85 86 /** 87 * Gets a reference to the contained object. Does not check that this optional 88 * contains a value, so this object will be uninitialized if has_value() is 89 * false. 90 */ 91 ObjectType& value(); 92 const ObjectType& value() const; 93 94 /** 95 * Performs a move assignment operation to the underlying object managed by 96 * this container. 97 * 98 * @param other The other object to move from. 99 * @return Returns a reference to this object. 100 */ 101 Optional<ObjectType>& operator=(ObjectType&& other); 102 103 /** 104 * Performs a move assignment from one optional to another. Note that the 105 * other object still holds a value, but it is left in the moved-from state 106 * (as is the case in std::optional). 107 * 108 * @param other The other object to move. 109 * @return Returns a reference to this object. 110 */ 111 Optional<ObjectType>& operator=(Optional<ObjectType>&& other); 112 113 /** 114 * Performs a copy assignment operation to the underlying object managed by 115 * this container. 116 * 117 * @param other The other object to copy from. 118 * @return Returns a reference to this object. 119 */ 120 Optional<ObjectType>& operator=(const ObjectType& other); 121 122 /** 123 * Performs a copy assignment from one optional to another. 124 * 125 * @param other The other object to copy. 126 * @return Returns a reference to this object. 127 */ 128 Optional<ObjectType>& operator=(const Optional<ObjectType>& other); 129 130 /** 131 * Obtains a reference to the underlying object managed by this container. 132 * The behavior of this is undefined if has_value() returns false. 133 * 134 * @return Returns a reference to the underlying object tracked by this 135 * container. 136 */ 137 ObjectType& operator*(); 138 139 /** 140 * Obtains a const reference to the underlying object managed by this 141 * container. The behavior of this is undefined if has_value() returns false. 142 * 143 * @return Returns a const reference to the underlying object tracked by this 144 * container. 145 */ 146 const ObjectType& operator*() const; 147 148 /** 149 * Obtains a pointer to the underlying object managed by this container. The 150 * object may not be well-formed if has_value() returns false. 151 * 152 * @return Returns a pointer to the underlying object tracked by this 153 * container. 154 */ 155 ObjectType *operator->(); 156 157 /** 158 * Obtains a const pointer to the underlying object managed by this container. 159 * The object may not be well-formed if has_value() returns false. 160 * 161 * @return Returns a const pointer to the underlying object tracked by this 162 * container. 163 */ 164 const ObjectType *operator->() const; 165 166 private: 167 //! The optional object being tracked by this container. 168 typename std::aligned_storage<sizeof(ObjectType), alignof(ObjectType)>::type 169 mObject; 170 171 //! Whether or not the object is set. 172 bool mHasValue = false; 173 174 ObjectType& object(); 175 const ObjectType& object() const; 176 177 ObjectType *objectAddr(); 178 const ObjectType *objectAddr() const; 179 }; 180 181 } // namespace chre 182 183 #include "chre/util/optional_impl.h" 184 185 #endif // UTIL_CHRE_OPTIONAL_H_ 186