//===--- status.h - Status and Expected classes -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef ACXXEL_STATUS_H
#define ACXXEL_STATUS_H

#include <cassert>
#include <string>

// The clang compiler supports annotating class declarations with the
// warn_unused_result attribute, and this has the meaning that whenever that
// type is returned from a function, the function is marked as
// warn_unused_result.
//
// The gcc compiler does not support warn_unused_result for classes, only for
// functions, so we only use this feature with clang.
#ifdef __clang__
#define ACXXEL_WARN_UNUSED_RESULT_TYPE __attribute__((warn_unused_result))
#else
#define ACXXEL_WARN_UNUSED_RESULT_TYPE
#endif

namespace acxxel {

/// Status type.
///
/// May represent failure with a string error message, or may indicate success.
class ACXXEL_WARN_UNUSED_RESULT_TYPE Status {
public:
  /// Creates a Status representing success.
  Status() : HasMessage(false) {}

  /// Creates a Status representing failure with the given error message.
  explicit Status(const std::string &Message)
      : HasMessage(true), Message(Message) {}

  Status(const Status &) = default;

  Status &operator=(const Status &) = default;

  Status(Status &&) noexcept = default;

  // Cannot use default because the move assignment operator for std::string is
  // not marked noexcept.
  Status &operator=(Status &&That) noexcept {
    HasMessage = That.HasMessage;
    Message = std::move(That.Message);
    return *this;
  }

  ~Status() = default;

  /// Returns true if this Status represents failure. Otherwise, returns false.
  bool isError() const { return HasMessage; }

  /// Returns true if this Status represents success. Otherwise, returns false.
  operator bool() const { return !HasMessage; }

  /// Gets a reference to the error message for this Status.
  ///
  /// Should only be called if isError() returns true.
  const std::string &getMessage() const { return Message; }

private:
  bool HasMessage;
  std::string Message;
};

class ExpectedBase {
protected:
  enum class State {
    SUCCESS,
    FAILURE,
    MOVED,
  };
};

/// Either a value of type T or a Status representing failure.
template <typename T> class Expected : public ExpectedBase {
public:
  /// Creates an Expected representing failure with the given Error status.
  // Intentionally implicit.
  Expected(Status AnError)
      : TheState(State::FAILURE), TheError(std::move(AnError)) {
    assert(AnError.isError() && "constructing an error Expected value from a "
                                "success status is not allowed");
  }

  /// Creates an Expected representing success with the given value.
  // Intentionally implicit.
  Expected(T Value) : TheState(State::SUCCESS), TheValue(std::move(Value)) {}

  Expected(const Expected &That) : TheState(That.TheState) {
    switch (TheState) {
    case State::SUCCESS:
      new (&TheValue) T(That.TheValue);
      break;
    case State::FAILURE:
      new (&TheError) Status(That.TheError);
      break;
    case State::MOVED:
      // Nothing to do in this case.
      break;
    }
  }

  Expected &operator=(Expected That) {
    TheState = That.TheState;
    switch (TheState) {
    case State::SUCCESS:
      new (&TheValue) T(std::move(That.TheValue));
      break;
    case State::FAILURE:
      new (&TheError) Status(std::move(That.TheError));
      break;
    case State::MOVED:
      // Nothing to do in this case.
      break;
    }
    return *this;
  }

  Expected(Expected &&That) noexcept : TheState(That.TheState) {
    switch (TheState) {
    case State::SUCCESS:
      new (&TheValue) T(std::move(That.TheValue));
      break;
    case State::FAILURE:
      new (&TheError) Status(std::move(That.TheError));
      break;
    case State::MOVED:
      // Nothing to do in this case.
      break;
    }
    That.TheState = State::MOVED;
  }

  template <typename U>
  Expected(const Expected<U> &That) : TheState(That.TheState) {
    switch (TheState) {
    case State::SUCCESS:
      new (&TheValue) T(That.TheValue);
      break;
    case State::FAILURE:
      new (&TheError) Status(That.TheError);
      break;
    case State::MOVED:
      // Nothing to do in this case.
      break;
    }
  }

  template <typename U> Expected(Expected<U> &&That) : TheState(That.TheState) {
    switch (TheState) {
    case State::SUCCESS:
      new (&TheValue) T(std::move(That.TheValue));
      break;
    case State::FAILURE:
      new (&TheError) Status(std::move(That.TheError));
      break;
    case State::MOVED:
      // Nothing to do in this case.
      break;
    }
  }

  ~Expected() {
    switch (TheState) {
    case State::SUCCESS:
      TheValue.~T();
      break;
    case State::FAILURE:
      TheError.~Status();
      break;
    case State::MOVED:
      // Nothing to do for this case.
      break;
    }
  }

  /// Returns true if this instance represents failure.
  bool isError() const { return TheState != State::SUCCESS; }

  /// Gets a reference to the Status object.
  ///
  /// Should only be called if isError() returns true.
  const Status &getError() const {
    assert(isError());
    return TheError;
  }

  /// Gets a const reference to the value object.
  ///
  /// Should only be called if isError() returns false.
  const T &getValue() const {
    assert(!isError());
    return TheValue;
  }

  /// Gets a reference to the value object.
  ///
  /// Should only be called if isError() returns false.
  T &getValue() {
    assert(!isError());
    return TheValue;
  }

  /// Takes the value from this object by moving it to the return value.
  ///
  /// Should only be called if isError() returns false.
  T takeValue() {
    assert(!isError());
    TheState = State::MOVED;
    return std::move(TheValue);
  }

private:
  template <typename U> friend class Expected;

  State TheState;

  union {
    T TheValue;
    Status TheError;
  };
};

} // namespace acxxel

#endif // ACXXEL_STATUS_H
