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 * Constructs an optional instance with an initial value. 43 * 44 * @param object The initial value of the object. 45 */ 46 Optional(const ObjectType& object); 47 48 /** 49 * Constructs an optional instance with an initial value by moving it. 50 * 51 * @param object The instance of the initial object to take ownership of. 52 */ 53 Optional(ObjectType&& object); 54 55 /** 56 * @return Returns true if this container holds an object 57 */ 58 bool has_value() const; 59 60 /** 61 * Destroys any contained object, and marks this Optional as empty (i.e. 62 * has_value() will return false after this function returns) 63 */ 64 void reset(); 65 66 /** 67 * Gets a reference to the contained object. Does not check that this optional 68 * contains a value, so this object will be uninitialized if has_value() is 69 * false. 70 */ 71 ObjectType& value(); 72 const ObjectType& value() const; 73 74 /** 75 * Performs a move assignment operation to the underlying object managed by 76 * this container. 77 * 78 * @param other The other object to move from. 79 * @return Returns a reference to this object. 80 */ 81 Optional<ObjectType>& operator=(ObjectType&& other); 82 83 /** 84 * Performs a move assignment from one optional to another. Note that the 85 * other object still holds a value, but it is left in the moved-from state 86 * (as is the case in std::optional). 87 * 88 * @param other The other object to move. 89 * @return Returns a reference to this object. 90 */ 91 Optional<ObjectType>& operator=(Optional<ObjectType>&& other); 92 93 /** 94 * Performs a copy assignment operation to the underlying object managed by 95 * this container. 96 * 97 * @param other The other object to copy from. 98 * @return Returns a reference to this object. 99 */ 100 Optional<ObjectType>& operator=(const ObjectType& other); 101 102 /** 103 * Performs a copy assignment from one optional to another. 104 * 105 * @param other The other object to copy. 106 * @return Returns a reference to this object. 107 */ 108 Optional<ObjectType>& operator=(const Optional<ObjectType>& other); 109 110 /** 111 * Obtains a reference to the underlying object managed by this container. 112 * The behavior of this is undefined if has_value() returns false. 113 * 114 * @return Returns a reference to the underlying object tracked by this 115 * container. 116 */ 117 ObjectType& operator*(); 118 119 /** 120 * Obtains a const reference to the underlying object managed by this 121 * container. The behavior of this is undefined if has_value() returns false. 122 * 123 * @return Returns a const reference to the underlying object tracked by this 124 * container. 125 */ 126 const ObjectType& operator*() const; 127 128 /** 129 * Obtains a pointer to the underlying object managed by this container. The 130 * object may not be well-formed if has_value() returns false. 131 * 132 * @return Returns a pointer to the underlying object tracked by this 133 * container. 134 */ 135 ObjectType *operator->(); 136 137 /** 138 * Obtains a const pointer to the underlying object managed by this container. 139 * The object may not be well-formed if has_value() returns false. 140 * 141 * @return Returns a const pointer to the underlying object tracked by this 142 * container. 143 */ 144 const ObjectType *operator->() const; 145 146 private: 147 //! The optional object being tracked by this container. 148 typename std::aligned_storage<sizeof(ObjectType), alignof(ObjectType)>::type 149 mObject; 150 151 //! Whether or not the object is set. 152 bool mHasValue = false; 153 154 ObjectType& object(); 155 const ObjectType& object() const; 156 157 ObjectType *objectAddr(); 158 const ObjectType *objectAddr() const; 159 }; 160 161 } // namespace chre 162 163 #include "chre/util/optional_impl.h" 164 165 #endif // UTIL_CHRE_OPTIONAL_H_ 166