/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AAPT_MAYBE_H
#define AAPT_MAYBE_H

#include <cassert>
#include <type_traits>
#include <utility>

namespace aapt {

/**
 * Either holds a valid value of type T, or holds Nothing.
 * The value is stored inline in this structure, so no
 * heap memory is used when creating a Maybe<T> object.
 */
template <typename T>
class Maybe {
public:
    /**
     * Construct Nothing.
     */
    inline Maybe();

    inline ~Maybe();

    template <typename U>
    inline Maybe(const Maybe<U>& rhs);

    template <typename U>
    inline Maybe(Maybe<U>&& rhs);

    template <typename U>
    inline Maybe& operator=(const Maybe<U>& rhs);

    template <typename U>
    inline Maybe& operator=(Maybe<U>&& rhs);

    /**
     * Construct a Maybe holding a value.
     */
    inline Maybe(const T& value);

    /**
     * Construct a Maybe holding a value.
     */
    inline Maybe(T&& value);

    /**
     * True if this holds a value, false if
     * it holds Nothing.
     */
    inline operator bool() const;

    /**
     * Gets the value if one exists, or else
     * panics.
     */
    inline T& value();

    /**
     * Gets the value if one exists, or else
     * panics.
     */
    inline const T& value() const;

private:
    template <typename U>
    friend class Maybe;

    void destroy();

    bool mNothing;

    typename std::aligned_storage<sizeof(T), alignof(T)>::type mStorage;
};

template <typename T>
Maybe<T>::Maybe()
: mNothing(true) {
}

template <typename T>
Maybe<T>::~Maybe() {
    if (!mNothing) {
        destroy();
    }
}

template <typename T>
template <typename U>
Maybe<T>::Maybe(const Maybe<U>& rhs)
: mNothing(rhs.mNothing) {
    if (!rhs.mNothing) {
        new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage));
    }
}

template <typename T>
template <typename U>
Maybe<T>::Maybe(Maybe<U>&& rhs)
: mNothing(rhs.mNothing) {
    if (!rhs.mNothing) {
        rhs.mNothing = true;

        // Move the value from rhs.
        new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage)));

        // Since the value in rhs is now Nothing,
        // run the destructor for the value.
        rhs.destroy();
    }
}

template <typename T>
template <typename U>
Maybe<T>& Maybe<T>::operator=(const Maybe<U>& rhs) {
    if (mNothing && rhs.mNothing) {
        // Both are nothing, nothing to do.
        return *this;
    } else if  (!mNothing && !rhs.mNothing) {
        // We both are something, so assign rhs to us.
        reinterpret_cast<T&>(mStorage) = reinterpret_cast<const U&>(rhs.mStorage);
    } else if (mNothing) {
        // We are nothing but rhs is something.
        mNothing = rhs.mNothing;

        // Copy the value from rhs.
        new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage));
    } else {
        // We are something but rhs is nothing, so destroy our value.
        mNothing = rhs.mNothing;
        destroy();
    }
    return *this;
}

template <typename T>
template <typename U>
Maybe<T>& Maybe<T>::operator=(Maybe<U>&& rhs) {
    if (mNothing && rhs.mNothing) {
        // Both are nothing, nothing to do.
        return *this;
    } else if  (!mNothing && !rhs.mNothing) {
        // We both are something, so move assign rhs to us.
        rhs.mNothing = true;
        reinterpret_cast<T&>(mStorage) = std::move(reinterpret_cast<U&>(rhs.mStorage));
        rhs.destroy();
    } else if (mNothing) {
        // We are nothing but rhs is something.
        mNothing = rhs.mNothing;

        // Move the value from rhs.
        new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage)));
        rhs.destroy();
    } else {
        // We are something but rhs is nothing, so destroy our value.
        mNothing = rhs.mNothing;
        destroy();
    }
    return *this;
}

template <typename T>
Maybe<T>::Maybe(const T& value)
: mNothing(false) {
    new (&mStorage) T(value);
}

template <typename T>
Maybe<T>::Maybe(T&& value)
: mNothing(false) {
    new (&mStorage) T(std::forward<T>(value));
}

template <typename T>
Maybe<T>::operator bool() const {
    return !mNothing;
}

template <typename T>
T& Maybe<T>::value() {
    assert(!mNothing && "Maybe<T>::value() called on Nothing");
    return reinterpret_cast<T&>(mStorage);
}

template <typename T>
const T& Maybe<T>::value() const {
    assert(!mNothing && "Maybe<T>::value() called on Nothing");
    return reinterpret_cast<const T&>(mStorage);
}

template <typename T>
void Maybe<T>::destroy() {
    reinterpret_cast<T&>(mStorage).~T();
}

template <typename T>
inline Maybe<typename std::remove_reference<T>::type> make_value(T&& value) {
    return Maybe<typename std::remove_reference<T>::type>(std::forward<T>(value));
}

template <typename T>
inline Maybe<T> make_nothing() {
    return Maybe<T>();
}

} // namespace aapt

#endif // AAPT_MAYBE_H
