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