/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_RTC_BASE_OPTIONAL_H_
#define WEBRTC_RTC_BASE_OPTIONAL_H_

#include <algorithm>
#include <memory>
#include <utility>

#ifdef UNIT_TEST
#include <iomanip>
#include <ostream>
#endif  // UNIT_TEST

#include "webrtc/api/array_view.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/sanitizer.h"

namespace rtc {

namespace optional_internal {

#if RTC_HAS_ASAN

// This is a non-inlined function. The optimizer can't see inside it.  It
// prevents the compiler from generating optimized code that reads value_ even
// if it is unset. Although safe, this causes memory sanitizers to complain.
void* FunctionThatDoesNothingImpl(void*);

template <typename T>
inline T* FunctionThatDoesNothing(T* x) {
  return reinterpret_cast<T*>(
      FunctionThatDoesNothingImpl(reinterpret_cast<void*>(x)));
}

#else

template <typename T>
inline T* FunctionThatDoesNothing(T* x) { return x; }

#endif

}  // namespace optional_internal

// Simple std::optional-wannabe. It either contains a T or not.
//
// A moved-from Optional<T> may only be destroyed, and assigned to if T allows
// being assigned to after having been moved from. Specifically, you may not
// assume that it just doesn't contain a value anymore.
//
// Examples of good places to use Optional:
//
// - As a class or struct member, when the member doesn't always have a value:
//     struct Prisoner {
//       std::string name;
//       Optional<int> cell_number;  // Empty if not currently incarcerated.
//     };
//
// - As a return value for functions that may fail to return a value on all
//   allowed inputs. For example, a function that searches an array might
//   return an Optional<size_t> (the index where it found the element, or
//   nothing if it didn't find it); and a function that parses numbers might
//   return Optional<double> (the parsed number, or nothing if parsing failed).
//
// Examples of bad places to use Optional:
//
// - As a return value for functions that may fail because of disallowed
//   inputs. For example, a string length function should not return
//   Optional<size_t> so that it can return nothing in case the caller passed
//   it a null pointer; the function should probably use RTC_[D]CHECK instead,
//   and return plain size_t.
//
// - As a return value for functions that may fail to return a value on all
//   allowed inputs, but need to tell the caller what went wrong. Returning
//   Optional<double> when parsing a single number as in the example above
//   might make sense, but any larger parse job is probably going to need to
//   tell the caller what the problem was, not just that there was one.
//
// - As a non-mutable function argument. When you want to pass a value of a
//   type T that can fail to be there, const T* is almost always both fastest
//   and cleanest. (If you're *sure* that the the caller will always already
//   have an Optional<T>, const Optional<T>& is slightly faster than const T*,
//   but this is a micro-optimization. In general, stick to const T*.)
//
// TODO(kwiberg): Get rid of this class when the standard library has
// std::optional (and we're allowed to use it).
template <typename T>
class Optional final {
 public:
  // Construct an empty Optional.
  Optional() : has_value_(false), empty_('\0') {
    PoisonValue();
  }

  // Construct an Optional that contains a value.
  explicit Optional(const T& value) : has_value_(true) {
    new (&value_) T(value);
  }
  explicit Optional(T&& value) : has_value_(true) {
    new (&value_) T(std::move(value));
  }

  // Copy constructor: copies the value from m if it has one.
  Optional(const Optional& m) : has_value_(m.has_value_) {
    if (has_value_)
      new (&value_) T(m.value_);
    else
      PoisonValue();
  }

  // Move constructor: if m has a value, moves the value from m, leaving m
  // still in a state where it has a value, but a moved-from one (the
  // properties of which depends on T; the only general guarantee is that we
  // can destroy m).
  Optional(Optional&& m) : has_value_(m.has_value_) {
    if (has_value_)
      new (&value_) T(std::move(m.value_));
    else
      PoisonValue();
  }

  ~Optional() {
    if (has_value_)
      value_.~T();
    else
      UnpoisonValue();
  }

  // Copy assignment. Uses T's copy assignment if both sides have a value, T's
  // copy constructor if only the right-hand side has a value.
  Optional& operator=(const Optional& m) {
    if (m.has_value_) {
      if (has_value_) {
        value_ = m.value_;  // T's copy assignment.
      } else {
        UnpoisonValue();
        new (&value_) T(m.value_);  // T's copy constructor.
        has_value_ = true;
      }
    } else {
      reset();
    }
    return *this;
  }

  // Move assignment. Uses T's move assignment if both sides have a value, T's
  // move constructor if only the right-hand side has a value. The state of m
  // after it's been moved from is as for the move constructor.
  Optional& operator=(Optional&& m) {
    if (m.has_value_) {
      if (has_value_) {
        value_ = std::move(m.value_);  // T's move assignment.
      } else {
        UnpoisonValue();
        new (&value_) T(std::move(m.value_));  // T's move constructor.
        has_value_ = true;
      }
    } else {
      reset();
    }
    return *this;
  }

  // Swap the values if both m1 and m2 have values; move the value if only one
  // of them has one.
  friend void swap(Optional& m1, Optional& m2) {
    if (m1.has_value_) {
      if (m2.has_value_) {
        // Both have values: swap.
        using std::swap;
        swap(m1.value_, m2.value_);
      } else {
        // Only m1 has a value: move it to m2.
        m2.UnpoisonValue();
        new (&m2.value_) T(std::move(m1.value_));
        m1.value_.~T();  // Destroy the moved-from value.
        m1.has_value_ = false;
        m2.has_value_ = true;
        m1.PoisonValue();
      }
    } else if (m2.has_value_) {
      // Only m2 has a value: move it to m1.
      m1.UnpoisonValue();
      new (&m1.value_) T(std::move(m2.value_));
      m2.value_.~T();  // Destroy the moved-from value.
      m1.has_value_ = true;
      m2.has_value_ = false;
      m2.PoisonValue();
    }
  }

  // Destroy any contained value. Has no effect if we have no value.
  void reset() {
    if (!has_value_)
      return;
    value_.~T();
    has_value_ = false;
    PoisonValue();
  }

  template <class... Args>
  void emplace(Args&&... args) {
    if (has_value_)
      value_.~T();
    else
      UnpoisonValue();
    new (&value_) T(std::forward<Args>(args)...);
    has_value_ = true;
  }

  // Conversion to bool to test if we have a value.
  explicit operator bool() const { return has_value_; }
  bool has_value() const { return has_value_; }

  // Dereferencing. Only allowed if we have a value.
  const T* operator->() const {
    RTC_DCHECK(has_value_);
    return &value_;
  }
  T* operator->() {
    RTC_DCHECK(has_value_);
    return &value_;
  }
  const T& operator*() const {
    RTC_DCHECK(has_value_);
    return value_;
  }
  T& operator*() {
    RTC_DCHECK(has_value_);
    return value_;
  }
  const T& value() const {
    RTC_DCHECK(has_value_);
    return value_;
  }
  T& value() {
    RTC_DCHECK(has_value_);
    return value_;
  }

  // Dereference with a default value in case we don't have a value.
  const T& value_or(const T& default_val) const {
    // The no-op call prevents the compiler from generating optimized code that
    // reads value_ even if !has_value_, but only if FunctionThatDoesNothing is
    // not completely inlined; see its declaration.).
    return has_value_ ? *optional_internal::FunctionThatDoesNothing(&value_)
                      : default_val;
  }

  // Dereference and move value.
  T MoveValue() {
    RTC_DCHECK(has_value_);
    return std::move(value_);
  }

  // Equality tests. Two Optionals are equal if they contain equivalent values,
  // or if they're both empty.
  friend bool operator==(const Optional& m1, const Optional& m2) {
    return m1.has_value_ && m2.has_value_ ? m1.value_ == m2.value_
                                          : m1.has_value_ == m2.has_value_;
  }
  friend bool operator==(const Optional& opt, const T& value) {
    return opt.has_value_ && opt.value_ == value;
  }
  friend bool operator==(const T& value, const Optional& opt) {
    return opt.has_value_ && value == opt.value_;
  }

  friend bool operator!=(const Optional& m1, const Optional& m2) {
    return m1.has_value_ && m2.has_value_ ? m1.value_ != m2.value_
                                          : m1.has_value_ != m2.has_value_;
  }
  friend bool operator!=(const Optional& opt, const T& value) {
    return !opt.has_value_ || opt.value_ != value;
  }
  friend bool operator!=(const T& value, const Optional& opt) {
    return !opt.has_value_ || value != opt.value_;
  }

 private:
  // Tell sanitizers that value_ shouldn't be touched.
  void PoisonValue() {
    rtc::AsanPoison(rtc::MakeArrayView(&value_, 1));
    rtc::MsanMarkUninitialized(rtc::MakeArrayView(&value_, 1));
  }

  // Tell sanitizers that value_ is OK to touch again.
  void UnpoisonValue() {
    rtc::AsanUnpoison(rtc::MakeArrayView(&value_, 1));
  }

  bool has_value_;  // True iff value_ contains a live value.
  union {
    // empty_ exists only to make it possible to initialize the union, even when
    // it doesn't contain any data. If the union goes uninitialized, it may
    // trigger compiler warnings.
    char empty_;
    // By placing value_ in a union, we get to manage its construction and
    // destruction manually: the Optional constructors won't automatically
    // construct it, and the Optional destructor won't automatically destroy
    // it. Basically, this just allocates a properly sized and aligned block of
    // memory in which we can manually put a T with placement new.
    T value_;
  };
};

#ifdef UNIT_TEST
namespace optional_internal {

// Checks if there's a valid PrintTo(const T&, std::ostream*) call for T.
template <typename T>
struct HasPrintTo {
 private:
  struct No {};

  template <typename T2>
  static auto Test(const T2& obj)
      -> decltype(PrintTo(obj, std::declval<std::ostream*>()));

  template <typename>
  static No Test(...);

 public:
  static constexpr bool value =
      !std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value;
};

// Checks if there's a valid operator<<(std::ostream&, const T&) call for T.
template <typename T>
struct HasOstreamOperator {
 private:
  struct No {};

  template <typename T2>
  static auto Test(const T2& obj)
      -> decltype(std::declval<std::ostream&>() << obj);

  template <typename>
  static No Test(...);

 public:
  static constexpr bool value =
      !std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value;
};

// Prefer using PrintTo to print the object.
template <typename T>
typename std::enable_if<HasPrintTo<T>::value, void>::type OptionalPrintToHelper(
    const T& value,
    std::ostream* os) {
  PrintTo(value, os);
}

// Fall back to operator<<(std::ostream&, ...) if it exists.
template <typename T>
typename std::enable_if<HasOstreamOperator<T>::value && !HasPrintTo<T>::value,
                        void>::type
OptionalPrintToHelper(const T& value, std::ostream* os) {
  *os << value;
}

inline void OptionalPrintObjectBytes(const unsigned char* bytes,
                                     size_t size,
                                     std::ostream* os) {
  *os << "<optional with " << size << "-byte object [";
  for (size_t i = 0; i != size; ++i) {
    *os << (i == 0 ? "" : ((i & 1) ? "-" : " "));
    *os << std::hex << std::setw(2) << std::setfill('0')
        << static_cast<int>(bytes[i]);
  }
  *os << "]>";
}

// As a final back-up, just print the contents of the objcets byte-wise.
template <typename T>
typename std::enable_if<!HasOstreamOperator<T>::value && !HasPrintTo<T>::value,
                        void>::type
OptionalPrintToHelper(const T& value, std::ostream* os) {
  OptionalPrintObjectBytes(reinterpret_cast<const unsigned char*>(&value),
                           sizeof(value), os);
}

}  // namespace optional_internal

// PrintTo is used by gtest to print out the results of tests. We want to ensure
// the object contained in an Optional can be printed out if it's set, while
// avoiding touching the object's storage if it is undefined.
template <typename T>
void PrintTo(const rtc::Optional<T>& opt, std::ostream* os) {
  if (opt) {
    optional_internal::OptionalPrintToHelper(*opt, os);
  } else {
    *os << "<empty optional>";
  }
}

#endif  // UNIT_TEST

}  // namespace rtc

#endif  // WEBRTC_RTC_BASE_OPTIONAL_H_
