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_IMPL_H_
     18 #define UTIL_CHRE_OPTIONAL_IMPL_H_
     19 
     20 #include <new>
     21 #include <utility>
     22 
     23 #include "chre/util/optional.h"
     24 
     25 namespace chre {
     26 
     27 template<typename ObjectType>
     28 Optional<ObjectType>::Optional(const ObjectType& object) {
     29   new (objectAddr()) ObjectType(object);
     30   mHasValue = true;
     31 }
     32 
     33 template<typename ObjectType>
     34 Optional<ObjectType>::Optional(ObjectType&& object) {
     35   new (objectAddr()) ObjectType(std::move(object));
     36   mHasValue = true;
     37 }
     38 
     39 template<typename ObjectType>
     40 bool Optional<ObjectType>::has_value() const {
     41   return mHasValue;
     42 }
     43 
     44 template<typename ObjectType>
     45 void Optional<ObjectType>::reset() {
     46   if (mHasValue) {
     47     object().~ObjectType();
     48     mHasValue = false;
     49   }
     50 }
     51 
     52 template<typename ObjectType>
     53 ObjectType& Optional<ObjectType>::value() {
     54   return object();
     55 }
     56 
     57 template<typename ObjectType>
     58 const ObjectType& Optional<ObjectType>::value() const {
     59   return object();
     60 }
     61 
     62 template<typename ObjectType>
     63 Optional<ObjectType>& Optional<ObjectType>::operator=(ObjectType&& other) {
     64   if (mHasValue) {
     65     object() = std::move(other);
     66   } else {
     67     new (objectAddr()) ObjectType(std::move(other));
     68   }
     69 
     70   mHasValue = true;
     71   return *this;
     72 }
     73 
     74 template<typename ObjectType>
     75 Optional<ObjectType>& Optional<ObjectType>::operator=(
     76     Optional<ObjectType>&& other) {
     77   if (mHasValue) {
     78     if (other.mHasValue) {
     79       object() = std::move(other.object());
     80     } else {
     81       reset();
     82     }
     83   } else if (other.mHasValue) {
     84     new (objectAddr()) ObjectType(std::move(other.object()));
     85   }
     86 
     87   mHasValue = other.mHasValue;
     88   return *this;
     89 }
     90 
     91 template<typename ObjectType>
     92 Optional<ObjectType>& Optional<ObjectType>::operator=(const ObjectType& other) {
     93   if (mHasValue) {
     94     object() = std::move(other);
     95   } else {
     96     new (objectAddr()) ObjectType(other);
     97   }
     98 
     99   mHasValue = true;
    100   return *this;
    101 }
    102 
    103 template<typename ObjectType>
    104 Optional<ObjectType>& Optional<ObjectType>::operator=(
    105     const Optional<ObjectType>& other) {
    106   if (mHasValue) {
    107     if (other.mHasValue) {
    108       object() = other.object();
    109     } else {
    110       reset();
    111     }
    112   } else if (other.mHasValue) {
    113     new (objectAddr()) ObjectType(other.object());
    114   }
    115 
    116   mHasValue = other.mHasValue;
    117   return *this;
    118 }
    119 
    120 template<typename ObjectType>
    121 ObjectType& Optional<ObjectType>::operator*() {
    122   return object();
    123 }
    124 
    125 template<typename ObjectType>
    126 const ObjectType& Optional<ObjectType>::operator*() const {
    127   return object();
    128 }
    129 
    130 template<typename ObjectType>
    131 ObjectType *Optional<ObjectType>::operator->() {
    132   return objectAddr();
    133 }
    134 
    135 template<typename ObjectType>
    136 const ObjectType *Optional<ObjectType>::operator->() const {
    137   return objectAddr();
    138 }
    139 
    140 template<typename ObjectType>
    141 ObjectType& Optional<ObjectType>::object() {
    142   return *objectAddr();
    143 }
    144 
    145 template<typename ObjectType>
    146 const ObjectType& Optional<ObjectType>::object() const {
    147   return *objectAddr();
    148 }
    149 
    150 template<typename ObjectType>
    151 ObjectType *Optional<ObjectType>::objectAddr() {
    152   return reinterpret_cast<ObjectType *>(&mObject);
    153 }
    154 
    155 template<typename ObjectType>
    156 const ObjectType *Optional<ObjectType>::objectAddr() const {
    157   return reinterpret_cast<const ObjectType *>(&mObject);
    158 }
    159 
    160 }  // namespace chre
    161 
    162 #endif  // UTIL_CHRE_OPTIONAL_IMPL_H_
    163