16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License. 66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at 76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software 116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and 146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License. 156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#ifndef AAPT_MAYBE_H 186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#define AAPT_MAYBE_H 196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <cassert> 216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <type_traits> 226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <utility> 236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt { 256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Either holds a valid value of type T, or holds Nothing. 286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * The value is stored inline in this structure, so no 296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * heap memory is used when creating a Maybe<T> object. 306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass Maybe { 336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskipublic: 346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski /** 356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Construct Nothing. 366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 3724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe(); 386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 3924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski ~Maybe(); 4024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 4124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe(const Maybe& rhs); 426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski template <typename U> 4424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe(const Maybe<U>& rhs); 4524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 4624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe(Maybe&& rhs); 476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski template <typename U> 4924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe(Maybe<U>&& rhs); 5024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 5124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe& operator=(const Maybe& rhs); 526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski template <typename U> 5424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe& operator=(const Maybe<U>& rhs); 5524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 5624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe& operator=(Maybe&& rhs); 576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski template <typename U> 5924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe& operator=(Maybe<U>&& rhs); 606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski /** 626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Construct a Maybe holding a value. 636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 6424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe(const T& value); 656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski /** 676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Construct a Maybe holding a value. 686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 6924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe(T&& value); 706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski /** 726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * True if this holds a value, false if 736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * it holds Nothing. 746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 7524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski operator bool() const; 766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski /** 786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Gets the value if one exists, or else 796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * panics. 806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 8124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski T& value(); 826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski /** 846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Gets the value if one exists, or else 856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * panics. 866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 8724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski const T& value() const; 886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprivate: 906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski template <typename U> 916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski friend class Maybe; 926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 9324aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski template <typename U> 9424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe& copy(const Maybe<U>& rhs); 9524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 9624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski template <typename U> 9724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski Maybe& move(Maybe<U>&& rhs); 9824aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski void destroy(); 1006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski bool mNothing; 1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski typename std::aligned_storage<sizeof(T), alignof(T)>::type mStorage; 1046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}; 1056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 1076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiMaybe<T>::Maybe() 1086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski: mNothing(true) { 1096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiMaybe<T>::~Maybe() { 1136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (!mNothing) { 1146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski destroy(); 1156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 11924aad163bc88cb10d2275385e9afc3de7f342d65Adam LesinskiMaybe<T>::Maybe(const Maybe& rhs) 12024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski: mNothing(rhs.mNothing) { 12124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski if (!rhs.mNothing) { 12224aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski new (&mStorage) T(reinterpret_cast<const T&>(rhs.mStorage)); 12324aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski } 12424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski} 12524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 12624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename T> 1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename U> 1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiMaybe<T>::Maybe(const Maybe<U>& rhs) 1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski: mNothing(rhs.mNothing) { 1306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (!rhs.mNothing) { 1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage)); 1326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 13624aad163bc88cb10d2275385e9afc3de7f342d65Adam LesinskiMaybe<T>::Maybe(Maybe&& rhs) 13724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski: mNothing(rhs.mNothing) { 13824aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski if (!rhs.mNothing) { 13924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski rhs.mNothing = true; 14024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 14124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski // Move the value from rhs. 14224aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski new (&mStorage) T(std::move(reinterpret_cast<T&>(rhs.mStorage))); 14324aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski rhs.destroy(); 14424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski } 14524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski} 14624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 14724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename T> 1486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename U> 1496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiMaybe<T>::Maybe(Maybe<U>&& rhs) 1506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski: mNothing(rhs.mNothing) { 1516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (!rhs.mNothing) { 1526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski rhs.mNothing = true; 1536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // Move the value from rhs. 1556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage))); 1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski rhs.destroy(); 1576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 16124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskiinline Maybe<T>& Maybe<T>::operator=(const Maybe& rhs) { 16224aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski // Delegate to the actual assignment. 16324aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski return copy(rhs); 16424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski} 16524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 16624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename T> 16724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename U> 16824aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskiinline Maybe<T>& Maybe<T>::operator=(const Maybe<U>& rhs) { 16924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski return copy(rhs); 17024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski} 17124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 17224aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename T> 1736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename U> 17424aad163bc88cb10d2275385e9afc3de7f342d65Adam LesinskiMaybe<T>& Maybe<T>::copy(const Maybe<U>& rhs) { 1756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (mNothing && rhs.mNothing) { 1766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // Both are nothing, nothing to do. 1776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return *this; 1786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else if (!mNothing && !rhs.mNothing) { 1796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We both are something, so assign rhs to us. 1806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski reinterpret_cast<T&>(mStorage) = reinterpret_cast<const U&>(rhs.mStorage); 1816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else if (mNothing) { 1826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We are nothing but rhs is something. 1836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mNothing = rhs.mNothing; 1846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // Copy the value from rhs. 1866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage)); 1876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else { 1886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We are something but rhs is nothing, so destroy our value. 1896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mNothing = rhs.mNothing; 1906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski destroy(); 1916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return *this; 1936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 19624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskiinline Maybe<T>& Maybe<T>::operator=(Maybe&& rhs) { 19724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski // Delegate to the actual assignment. 19824aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski return move(std::forward<Maybe<T>>(rhs)); 19924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski} 20024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 20124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename T> 20224aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename U> 20324aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskiinline Maybe<T>& Maybe<T>::operator=(Maybe<U>&& rhs) { 20424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski return move(std::forward<Maybe<U>>(rhs)); 20524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski} 20624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 20724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinskitemplate <typename T> 2086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename U> 20924aad163bc88cb10d2275385e9afc3de7f342d65Adam LesinskiMaybe<T>& Maybe<T>::move(Maybe<U>&& rhs) { 2106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (mNothing && rhs.mNothing) { 2116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // Both are nothing, nothing to do. 2126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return *this; 2136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else if (!mNothing && !rhs.mNothing) { 2146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We both are something, so move assign rhs to us. 2156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski rhs.mNothing = true; 2166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski reinterpret_cast<T&>(mStorage) = std::move(reinterpret_cast<U&>(rhs.mStorage)); 2176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski rhs.destroy(); 2186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else if (mNothing) { 2196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We are nothing but rhs is something. 22024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski mNothing = false; 22124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski rhs.mNothing = true; 2226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // Move the value from rhs. 2246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage))); 2256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski rhs.destroy(); 2266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else { 2276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We are something but rhs is nothing, so destroy our value. 22824aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski mNothing = true; 2296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski destroy(); 2306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 2316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return *this; 2326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiMaybe<T>::Maybe(const T& value) 2366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski: mNothing(false) { 2376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski new (&mStorage) T(value); 2386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiMaybe<T>::Maybe(T&& value) 2426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski: mNothing(false) { 2436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski new (&mStorage) T(std::forward<T>(value)); 2446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiMaybe<T>::operator bool() const { 2486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return !mNothing; 2496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiT& Maybe<T>::value() { 2536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski assert(!mNothing && "Maybe<T>::value() called on Nothing"); 2546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return reinterpret_cast<T&>(mStorage); 2556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiconst T& Maybe<T>::value() const { 2596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski assert(!mNothing && "Maybe<T>::value() called on Nothing"); 2606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return reinterpret_cast<const T&>(mStorage); 2616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskivoid Maybe<T>::destroy() { 2656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski reinterpret_cast<T&>(mStorage).~T(); 2666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline Maybe<typename std::remove_reference<T>::type> make_value(T&& value) { 2706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return Maybe<typename std::remove_reference<T>::type>(std::forward<T>(value)); 2716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T> 2746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline Maybe<T> make_nothing() { 2756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return Maybe<T>(); 2766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} // namespace aapt 2796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#endif // AAPT_MAYBE_H 281