//===-- include/flang/Common/unwrap.h ---------------------------*- 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 FORTRAN_COMMON_UNWRAP_H_
#define FORTRAN_COMMON_UNWRAP_H_

#include "indirection.h"
#include "reference-counted.h"
#include "reference.h"
#include <memory>
#include <optional>
#include <type_traits>
#include <variant>

// Given a nest of variants, optionals, &/or pointers, Unwrap<>() isolates
// a packaged value of a specific type if it is present and returns a pointer
// thereto; otherwise, it returns a null pointer.  It's analogous to
// std::get_if<>() but it accepts a reference argument and is recursive.
// The target type parameter cannot be omitted.
//
// Be advised: If the target type parameter is not const-qualified, but the
// isolated value is const-qualified, the result of Unwrap<> will be a
// pointer to a const-qualified value.
//
// Further: const-qualified alternatives in instances of non-const-qualified
// variants will not be returned from Unwrap if the target type is not
// const-qualified.
//
// UnwrapCopy<>() is a variation of Unwrap<>() that returns an optional copy
// of the value if one is present with the desired type.

namespace Fortran::common {

// Utility: Produces "const A" if B is const and A is not already so.
template <typename A, typename B>
using Constify = std::conditional_t<std::is_const_v<B> && !std::is_const_v<A>,
    std::add_const_t<A>, A>;

// Unwrap's mutually-recursive template functions are packaged in a struct
// to avoid a need for prototypes.
struct UnwrapperHelper {

  // Base case
  template <typename A, typename B>
  static auto Unwrap(B &x) -> Constify<A, B> * {
    if constexpr (std::is_same_v<std::decay_t<A>, std::decay_t<B>>) {
      return &x;
    } else {
      return nullptr;
    }
  }

  // Implementations of specializations
  template <typename A, typename B>
  static auto Unwrap(B *p) -> Constify<A, B> * {
    if (p) {
      return Unwrap<A>(*p);
    } else {
      return nullptr;
    }
  }

  template <typename A, typename B>
  static auto Unwrap(const std::unique_ptr<B> &p) -> Constify<A, B> * {
    if (p.get()) {
      return Unwrap<A>(*p);
    } else {
      return nullptr;
    }
  }

  template <typename A, typename B>
  static auto Unwrap(const std::shared_ptr<B> &p) -> Constify<A, B> * {
    if (p.get()) {
      return Unwrap<A>(*p);
    } else {
      return nullptr;
    }
  }

  template <typename A, typename B>
  static auto Unwrap(std::optional<B> &x) -> Constify<A, B> * {
    if (x) {
      return Unwrap<A>(*x);
    } else {
      return nullptr;
    }
  }

  template <typename A, typename B>
  static auto Unwrap(const std::optional<B> &x) -> Constify<A, B> * {
    if (x) {
      return Unwrap<A>(*x);
    } else {
      return nullptr;
    }
  }

  template <typename A, typename... Bs>
  static A *Unwrap(std::variant<Bs...> &u) {
    return std::visit(
        [](auto &x) -> A * {
          using Ty = std::decay_t<decltype(Unwrap<A>(x))>;
          if constexpr (!std::is_const_v<std::remove_pointer_t<Ty>> ||
              std::is_const_v<A>) {
            return Unwrap<A>(x);
          }
          return nullptr;
        },
        u);
  }

  template <typename A, typename... Bs>
  static auto Unwrap(const std::variant<Bs...> &u) -> std::add_const_t<A> * {
    return std::visit(
        [](const auto &x) -> std::add_const_t<A> * { return Unwrap<A>(x); }, u);
  }

  template <typename A, typename B>
  static auto Unwrap(const Reference<B> &ref) -> Constify<A, B> * {
    return Unwrap<A>(*ref);
  }

  template <typename A, typename B, bool COPY>
  static auto Unwrap(const Indirection<B, COPY> &p) -> Constify<A, B> * {
    return Unwrap<A>(*p);
  }

  template <typename A, typename B>
  static auto Unwrap(const CountedReference<B> &p) -> Constify<A, B> * {
    if (p.get()) {
      return Unwrap<A>(*p);
    } else {
      return nullptr;
    }
  }
};

template <typename A, typename B> auto Unwrap(B &x) -> Constify<A, B> * {
  return UnwrapperHelper::Unwrap<A>(x);
}

// Returns a copy of a wrapped value, if present, otherwise a vacant optional.
template <typename A, typename B> std::optional<A> UnwrapCopy(const B &x) {
  if (const A * p{Unwrap<A>(x)}) {
    return std::make_optional<A>(*p);
  } else {
    return std::nullopt;
  }
}
} // namespace Fortran::common
#endif // FORTRAN_COMMON_UNWRAP_H_
