1fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol/*
2fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * Copyright (C) 2016 The Android Open Source Project
3fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol *
4fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * Licensed under the Apache License, Version 2.0 (the "License");
5fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * you may not use this file except in compliance with the License.
6fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * You may obtain a copy of the License at
7fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol *
8fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol *      http://www.apache.org/licenses/LICENSE-2.0
9fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol *
10fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * Unless required by applicable law or agreed to in writing, software
11fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * distributed under the License is distributed on an "AS IS" BASIS,
12fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * See the License for the specific language governing permissions and
14fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol * limitations under the License.
15fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol */
16fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
17fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol#ifndef UTIL_CHRE_OPTIONAL_IMPL_H_
18fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol#define UTIL_CHRE_OPTIONAL_IMPL_H_
19fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
202d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie#include <new>
215104fb101aaea4793daa061b160fbc3feb051b0dAndrew Rossignol#include <utility>
225104fb101aaea4793daa061b160fbc3feb051b0dAndrew Rossignol
23fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol#include "chre/util/optional.h"
24fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
25fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignolnamespace chre {
26fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
27fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignoltemplate<typename ObjectType>
282d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian DuddieOptional<ObjectType>::Optional(const ObjectType& object) {
292d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  new (objectAddr()) ObjectType(object);
302d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  mHasValue = true;
312d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
3235577195df7ab14e9f58443c2e59293499fe7a8fAndrew Rossignol
3335577195df7ab14e9f58443c2e59293499fe7a8fAndrew Rossignoltemplate<typename ObjectType>
342d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian DuddieOptional<ObjectType>::Optional(ObjectType&& object) {
352d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  new (objectAddr()) ObjectType(std::move(object));
362d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  mHasValue = true;
372d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
3839993a0032116a71eb51cbf14186eec6bab328f2Andrew Rossignol
3939993a0032116a71eb51cbf14186eec6bab328f2Andrew Rossignoltemplate<typename ObjectType>
40fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignolbool Optional<ObjectType>::has_value() const {
41fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol  return mHasValue;
42fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol}
43fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
44fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignoltemplate<typename ObjectType>
45fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignolvoid Optional<ObjectType>::reset() {
462d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  if (mHasValue) {
472d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    object().~ObjectType();
482d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    mHasValue = false;
492d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  }
502d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
512d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
522d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddietemplate<typename ObjectType>
532d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian DuddieObjectType& Optional<ObjectType>::value() {
542d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return object();
552d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
562d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
572d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddietemplate<typename ObjectType>
582d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddieconst ObjectType& Optional<ObjectType>::value() const {
592d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return object();
60fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol}
61fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
62fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignoltemplate<typename ObjectType>
63fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew RossignolOptional<ObjectType>& Optional<ObjectType>::operator=(ObjectType&& other) {
642d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  if (mHasValue) {
652d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    object() = std::move(other);
662d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  } else {
672d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    new (objectAddr()) ObjectType(std::move(other));
682d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  }
692d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
70fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol  mHasValue = true;
71fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol  return *this;
72fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol}
73fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
74fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignoltemplate<typename ObjectType>
75a168da9318a8d996ffd82beacb69a248b11d8569Andrew RossignolOptional<ObjectType>& Optional<ObjectType>::operator=(
76a168da9318a8d996ffd82beacb69a248b11d8569Andrew Rossignol    Optional<ObjectType>&& other) {
772d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  if (mHasValue) {
782d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    if (other.mHasValue) {
792d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie      object() = std::move(other.object());
802d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    } else {
812d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie      reset();
822d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    }
832d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  } else if (other.mHasValue) {
842d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    new (objectAddr()) ObjectType(std::move(other.object()));
852d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  }
862d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
87a168da9318a8d996ffd82beacb69a248b11d8569Andrew Rossignol  mHasValue = other.mHasValue;
88a168da9318a8d996ffd82beacb69a248b11d8569Andrew Rossignol  return *this;
89a168da9318a8d996ffd82beacb69a248b11d8569Andrew Rossignol}
90a168da9318a8d996ffd82beacb69a248b11d8569Andrew Rossignol
91a168da9318a8d996ffd82beacb69a248b11d8569Andrew Rossignoltemplate<typename ObjectType>
92fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew RossignolOptional<ObjectType>& Optional<ObjectType>::operator=(const ObjectType& other) {
932d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  if (mHasValue) {
942d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    object() = std::move(other);
952d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  } else {
962d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    new (objectAddr()) ObjectType(other);
972d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  }
982d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
99fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol  mHasValue = true;
100fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol  return *this;
101fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol}
102fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
103fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignoltemplate<typename ObjectType>
1041bbcacadd7331e0db5cf17f01e8ba7f451ff6740Andrew RossignolOptional<ObjectType>& Optional<ObjectType>::operator=(
1051bbcacadd7331e0db5cf17f01e8ba7f451ff6740Andrew Rossignol    const Optional<ObjectType>& other) {
1062d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  if (mHasValue) {
1072d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    if (other.mHasValue) {
1082d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie      object() = other.object();
1092d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    } else {
1102d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie      reset();
1112d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    }
1122d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  } else if (other.mHasValue) {
1132d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie    new (objectAddr()) ObjectType(other.object());
1142d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  }
1152d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
1161bbcacadd7331e0db5cf17f01e8ba7f451ff6740Andrew Rossignol  mHasValue = other.mHasValue;
1171bbcacadd7331e0db5cf17f01e8ba7f451ff6740Andrew Rossignol  return *this;
1181bbcacadd7331e0db5cf17f01e8ba7f451ff6740Andrew Rossignol}
1191bbcacadd7331e0db5cf17f01e8ba7f451ff6740Andrew Rossignol
1201bbcacadd7331e0db5cf17f01e8ba7f451ff6740Andrew Rossignoltemplate<typename ObjectType>
121fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew RossignolObjectType& Optional<ObjectType>::operator*() {
1222d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return object();
123fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol}
124fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
125fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignoltemplate<typename ObjectType>
126e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chungconst ObjectType& Optional<ObjectType>::operator*() const {
1272d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return object();
128e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung}
129e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung
130e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chungtemplate<typename ObjectType>
131fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew RossignolObjectType *Optional<ObjectType>::operator->() {
1322d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return objectAddr();
133fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol}
134fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
135e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chungtemplate<typename ObjectType>
136e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chungconst ObjectType *Optional<ObjectType>::operator->() const {
1372d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return objectAddr();
1382d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
1392d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
1402d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddietemplate<typename ObjectType>
1412d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian DuddieObjectType& Optional<ObjectType>::object() {
1422d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return *objectAddr();
1432d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
1442d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
1452d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddietemplate<typename ObjectType>
1462d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddieconst ObjectType& Optional<ObjectType>::object() const {
1472d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return *objectAddr();
1482d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
1492d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
1502d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddietemplate<typename ObjectType>
1512d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian DuddieObjectType *Optional<ObjectType>::objectAddr() {
1522d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return reinterpret_cast<ObjectType *>(&mObject);
1532d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie}
1542d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie
1552d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddietemplate<typename ObjectType>
1562d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddieconst ObjectType *Optional<ObjectType>::objectAddr() const {
1572d7d24a7bb72c9c3b4ff1af5f7fef8b303fd8c0eBrian Duddie  return reinterpret_cast<const ObjectType *>(&mObject);
158e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung}
159e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung
160fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol}  // namespace chre
161fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol
162fe38dd8c9780b599cf2eff09ff6fbf60fbe9ab76Andrew Rossignol#endif  // UTIL_CHRE_OPTIONAL_IMPL_H_
163