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 namespace chre {
21 
22 /**
23  * This container keeps track of an optional object. The container is similar to
24  * std::optional introduced in C++17.
25  */
26 template<typename ObjectType>
27 class Optional {
28  public:
29   /**
30    * Default constructs the optional object with no initial value.
31    */
32   Optional();
33 
34   /**
35    * Constructs an optional instance with an initial value.
36    *
37    * @param object The initial value of the object.
38    */
39   Optional(const ObjectType& object);
40 
41   /**
42    * Constructs an optional instance with an initial value by moving it.
43    *
44    * @param object The instance of the initial object to take ownership of.
45    */
46   Optional(ObjectType&& object);
47 
48   /**
49    * @return Returns true if the object tracked by this container has been
50    * assigned.
51    */
52   bool has_value() const;
53 
54   /**
55    * Resets the optional container by invoking the destructor on the underlying
56    * object.
57    */
58   void reset();
59 
60   /**
61    * Performs a move assignment operation to the underlying object managed by
62    * this container.
63    *
64    * @param other The other object to move from.
65    * @return Returns a reference to this object.
66    */
67   Optional<ObjectType>& operator=(ObjectType&& other);
68 
69   /**
70    * Performs a move assignment from one optional to another. The other is left
71    * in a state with no value.
72    *
73    * @param other The other object to move.
74    * @return Returns a reference to this object.
75    */
76   Optional<ObjectType>& operator=(Optional<ObjectType>&& other);
77 
78   /**
79    * Performs a copy assignment operation to the underlying object managed by
80    * this container.
81    *
82    * @param other The other object to copy from.
83    * @return Returns a reference to this object.
84    */
85   Optional<ObjectType>& operator=(const ObjectType& other);
86 
87   /**
88    * Performs a copy assignment from one optional to another.
89    *
90    * @param other The other object to copy.
91    * @return Returns a reference to this object.
92    */
93   Optional<ObjectType>& operator=(const Optional<ObjectType>& other);
94 
95   /**
96    * Obtains a reference to the underlying object managed by this container.
97    * The behavior of this is undefined if has_value() returns false.
98    *
99    * @return Returns a reference to the underlying object tracked by this
100    *         container.
101    */
102   ObjectType& operator*();
103 
104   /**
105    * Obtains a const reference to the underlying object managed by this
106    * container. The behavior of this is undefined if has_value() returns false.
107    *
108    * @return Returns a const reference to the underlying object tracked by this
109    *         container.
110    */
111   const ObjectType& operator*() const;
112 
113   /**
114    * Obtains a pointer to the underlying object managed by this container. The
115    * object may not be well-formed if has_value() returns false.
116    *
117    * @return Returns a pointer to the underlying object tracked by this
118    *         container.
119    */
120   ObjectType *operator->();
121 
122   /**
123    * Obtains a const pointer to the underlying object managed by this container.
124    * The object may not be well-formed if has_value() returns false.
125    *
126    * @return Returns a const pointer to the underlying object tracked by this
127    *         container.
128    */
129   const ObjectType *operator->() const;
130 
131  private:
132   //! The optional object being tracked by this container.
133   ObjectType mObject;
134 
135   //! Whether or not the object is set.
136   bool mHasValue = false;
137 };
138 
139 }  // namespace chre
140 
141 #include "chre/util/optional_impl.h"
142 
143 #endif  // UTIL_CHRE_OPTIONAL_H_
144