// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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 STARBOARD_COMMON_OPTIONAL_H_
#define STARBOARD_COMMON_OPTIONAL_H_

#include <algorithm>
#include <iosfwd>

#include "starboard/configuration.h"
#include "starboard/export.h"
#include "starboard/log.h"
#include "starboard/memory.h"

namespace starboard {

// This class is based off of std::experimental::optional:
//   http://en.cppreference.com/w/cpp/experimental/optional
//
// It is a template class where instances parameterized by type T contain
// memory for an instance of type T, but it may or may not be constructed.
// If it is not constructed, it cannot be accessed, and if it is, it can
// be accessed.  This allows one to check if the inner object exists or not
// before using it, and is useful for functions that may or may not return
// a value.  Note that the memory for the object is stored internally, so
// no heap allocations are made over the course of construction and destruction
// of the internal object (unless the internal object allocates memory within
// its constructor).
//
// Some functionality is left out.  For example, most C++11 functionality
// is not implemented, since we would like this to be friendly to non-C++11
// compilers.
//
// In the future, if C++11 functionality is needed, it can be implemented
// and surrounded by preprocessor guards to maintain compatibility with non
// C++11 compilers.
//

// The nullopt_t type is used as a signal for an empty optional.  If any
// optional is assigned the value of nullopt, it will be disengaged.
// For example,
//   starboard::optional<int> my_int_optional(5);
//   EXPECT_FALSE(!my_int_optional);
//   my_int_optional = starboard::nullopt;
//   EXPECT_TRUE(!my_int_optional);
//
struct nullopt_t {
  nullopt_t() {}
};
extern const nullopt_t nullopt;

// The in_place_t type is used to signal in-place construction of the internal
// object.  This is used by the in place constructor of optional, which forwards
// its parameters to the internal object's constructor.
// For example,
//   class Foo {
//    public:
//     Foo(int x, int y) { x_ = x; y_ = y; }
//     int x() const { return x_; }
//     int y() const { return y_; }
//
//    private:
//     int x_;
//     int y_;
//   };
//
//   ...
//
//   base::optional<Foo> my_foo(base::in_place, 2, 3);
//   EXPECT_FALSE(!my_foo);
//   EXPECT_EQ(2, my_foo->x());
//   EXPECT_EQ(3, my_foo->y());
//
struct in_place_t {
  in_place_t() {}
};
extern const in_place_t in_place;

template <typename T>
class SB_EXPORT optional {
 public:
  // Construction via the default constructor results in an optional that is
  // not engaged.
  optional() { InitializeAsDisengaged(); }

  optional(nullopt_t) { InitializeAsDisengaged(); }  // NOLINT(runtime/explicit)

  // This non-explicit singleton constructor is provided so users can pass in a
  // T wherever a optional<T> is expected.
  optional(const T& value) { SetValue(value); }  // NOLINT(runtime/explicit)

  optional(const optional<T>& other) {  // NOLINT(runtime/explicit)
    if (other.engaged_) {
      SetValue(other.value());
    } else {
      InitializeAsDisengaged();
    }
  }

  // Move constructor.
  // NOLINTNEXTLINE(runtime/explicit)
  optional(optional&& other) {  // NOLINT(build/c++11)
    if (other.engaged_) {
      SetValue(std::move(other.value()));
    } else {
      InitializeAsDisengaged();
    }
  }

  // Move value constructor.
  // NOLINTNEXTLINE(runtime/explicit)
  optional(T&& other) {  // NOLINT(build/c++11)
    SetValue(std::move(other));
  }

  // Destruct contained object upon optional's destruction.
  ~optional() { EnsureDisengaged(); }

  // Disengages the optional, calling the destructor of the contained object
  // if it is engaged.
  optional<T>& operator=(nullopt_t) {
    EnsureDisengaged();
    return *this;
  }

  // Reassigns the underlying optional to value passed in on the right hand
  // side.  This will destruct the lhs contained object first if it exists.
  template <typename U>
  optional<T>& operator=(const U& other) {
    if (engaged_) {
      value() = other;
    } else {
      SetValue(other);
    }
    return *this;
  }

  // Copy assignment.
  optional<T>& operator=(const optional<T>& other) {
    if (engaged_ && other.engaged_) {
      value() = other.value();
    } else if (!engaged_ && other.engaged_) {
      SetValue(other.value());
    } else if (engaged_ && !other.engaged_) {
      EnsureDisengaged();
    }
    // Do nothing if lhs and rhs are both not engaged.
    return *this;
  }

  // Move value assignment.
  optional<T>& operator=(T&& other) {  // NOLINT(build/c++11)
    if (engaged_) {
      value() = std::move(other);
    } else {
      SetValue(std::move(other));
    }
    return *this;
  }

  // Move optional assignment.
  optional<T>& operator=(optional&& other) {  // NOLINT(build/c++11)
    if (engaged_ && other.engaged_) {
      value() = std::move(other.value());
    } else if (!engaged_ && other.engaged_) {
      SetValue(std::move(other.value()));
    } else if (engaged_ && !other.engaged_) {
      EnsureDisengaged();
    }
    // Do nothing if lhs and rhs are both not engaged.
    return *this;
  }

// Overloaded conversion to bool operator for determining whether the optional
// is engaged or not.  It returns true if the optional is engaged, and false
// otherwise.
#if (defined(_MSC_VER) && (_MSC_VER < 1800)) || \
    (defined(__GNUC__) &&                       \
     (__GNUC__ < 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))))
  // MSVC 2012 does not support explicit cast operators.
  // http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx

  // For any compiler that doesn't support explicit bool operators, we instead
  // use the Safe Bool Idiom: http://www.artima.com/cppsource/safebool.html
 private:
  // The type of SafeBoolIdiomType (pointer to data member of a private type) is
  // limited in functionality so much that the only thing a user can do with it
  // is test for null, or apply to operator==/operator!=.  Since both operators
  // == and != are already overloaded for optional, this leaves null tests,
  // which we use for boolean testing.
  class PrivateSafeBoolIdiomFakeMemberType;
  typedef PrivateSafeBoolIdiomFakeMemberType optional::*SafeBoolIdiomType;

 public:
  operator const SafeBoolIdiomType() const {
    // If we wish to return true, we cast engaged_ to our private type giving
    // a non-null pointer to data member.  Otherwise, we return NULL.  The
    // only thing the user can do with the return type is test for NULL.
    return engaged_
               ? reinterpret_cast<const SafeBoolIdiomType>(&optional::engaged_)
               : NULL;
  }
#else
  explicit operator bool() const { return engaged_; }
#endif

  // Dereferences the internal object.
  const T* operator->() const { return &(value()); }

  T* operator->() { return &(value()); }

  const T& operator*() const { return value(); }

  T& operator*() { return value(); }

  // Dereferences and returns the internal object.
  const T& value() const {
    SB_DCHECK(engaged_)
        << "Attempted to access object in a disengaged optional.";
    return *static_cast<const T*>(void_value());
  }

  T& value() {
    SB_DCHECK(engaged_)
        << "Attempted to access object in a disengaged optional.";
    return *static_cast<T*>(void_value());
  }

  template <typename U>
  T value_or(const U& value) const {
    if (engaged_) {
      return this->value();
    } else {
      return value;
    }
  }

  // Swaps the values of two optionals.
  void swap(optional<T>& other) {
    if (engaged_ && other.engaged_) {
      // Swap the value contents with each other.
      std::swap(value(), other.value());
    } else if (engaged_) {
      other.SetValue(std::move(value()));
      EnsureDisengaged();
    } else if (other.engaged_) {
      SetValue(std::move(other.value()));
      other.EnsureDisengaged();
    }
    // If both the lhs and rhs are not engaged, we do nothing.
  }

// Include the pump.py-generated declaration and implementation for the
// forwarding constructor and emplace.
#include "starboard/common/optional_internal.h"

 private:
  // Sets a non-engaged optional to a specified value, and marks it as engaged.
  void SetValue(T&& value) {  // NOLINT(build/c++11)
    new (void_value()) T(std::move(value));
    engaged_ = true;
#if !defined(NDEBUG)
    value_ptr_ = static_cast<const T*>(void_value());
#endif
  }

  // Sets a non-engaged optional to a specified value, and marks it as engaged.
  template <typename U>
  void SetValue(const U& value) {
    new (void_value()) T(value);
    engaged_ = true;
#if !defined(NDEBUG)
    value_ptr_ = static_cast<const T*>(void_value());
#endif
  }

  // If an optional is engaged, it destructs the wrapped value and marks the
  // optional as disengaged.  Does nothing to a disengaged optional.
  void EnsureDisengaged() {
    if (engaged_) {
      static_cast<T*>(void_value())->~T();
      engaged_ = false;
#if !defined(NDEBUG)
      value_ptr_ = NULL;
#endif
    }
  }

  // Called upon object construction to initialize the object into a disengaged
  // state.
  void InitializeAsDisengaged() {
    engaged_ = false;
#if !defined(NDEBUG)
    value_ptr_ = NULL;
#endif
  }

  const void* void_value() const {
    return reinterpret_cast<const void*>(value_memory_);
  }
  void* void_value() { return reinterpret_cast<void*>(value_memory_); }

  // The actual memory reserved for the object that may or may not exist.
  SB_ALIGNAS(SB_ALIGNOF(T)) uint8_t value_memory_[sizeof(T)];
  // This boolean tracks whether or not the object is constructed yet or not.
  bool engaged_;
#if !defined(NDEBUG)
  // In debug builds, this member makes it easy to inspect the value contained
  // in the optional via a debugger.
  const T* value_ptr_;
#endif
};

// Comparison between 2 optionals
template <typename T>
inline bool operator==(const optional<T>& lhs, const optional<T>& rhs) {
  if (!lhs) {
    return !rhs;
  }

  return rhs == lhs.value();
}

template <typename T>
inline bool operator<(const optional<T>& lhs, const optional<T>& rhs) {
  if (lhs && rhs) {
    return lhs.value() < rhs.value();
  } else {
    // Handle all other cases simply in terms of whether the optionals are
    // engaged or not.
    return static_cast<bool>(lhs) < static_cast<bool>(rhs);
  }
}

// Comparison with nullopt_t
template <typename T>
inline bool operator==(nullopt_t, const optional<T>& rhs) {
  return !rhs;
}

template <typename T>
inline bool operator==(const optional<T>& lhs, nullopt_t rhs) {
  return rhs == lhs;
}

template <typename T>
inline bool operator<(const optional<T>& /* lhs */, nullopt_t) {
  return false;
}

template <typename T>
inline bool operator<(nullopt_t, const optional<T>& rhs) {
  return static_cast<bool>(rhs);
}

// Comparison between an optional and a value
template <typename T>
inline bool operator==(const optional<T>& lhs, const T& rhs) {
  return (!lhs ? false : lhs.value() == rhs);
}

template <typename T>
inline bool operator==(const T& lhs, const optional<T>& rhs) {
  return rhs == lhs;
}

template <typename T>
inline bool operator<(const T& lhs, const optional<T>& rhs) {
  return rhs && lhs < rhs.value();
}

template <typename T>
inline bool operator<(const optional<T>& lhs, const T& rhs) {
  return !lhs || lhs.value() < rhs;
}

// This is a convenient but non-standard method, do not rely on it if you expect
// the compatibility with upcoming C++ versions.
template <typename T>
inline std::ostream& operator<<(std::ostream& stream,
                                const optional<T>& maybe_value) {
  if (maybe_value) {
    stream << *maybe_value;
  } else {
    stream << "nullopt";
  }
  return stream;
}

template <typename T>
optional<T> make_optional(const T& value) {
  return optional<T>(value);
}

}  // namespace starboard

namespace std {

template <typename T>
struct hash<::starboard::optional<T> > {
 public:
  size_t operator()(const ::starboard::optional<T>& value) const {
    return (value ? value_hash_(value.value()) : 0);
  }

 private:
  hash<T> value_hash_;
};

template <typename T>
void swap(::starboard::optional<T>& lhs, ::starboard::optional<T>& rhs) {
  lhs.swap(rhs);
}

}  // namespace std

#endif  // STARBOARD_COMMON_OPTIONAL_H_
