Home | History | Annotate | Download | only in util
      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