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