//===- FormatVariadicDetails.h - Helpers for FormatVariadic.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 LLVM_SUPPORT_FORMATVARIADIC_DETAILS_H
#define LLVM_SUPPORT_FORMATVARIADIC_DETAILS_H

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"

#include <type_traits>

namespace llvm {
template <typename T, typename Enable = void> struct format_provider {};
class Error;

namespace detail {
class format_adapter {
  virtual void anchor();

protected:
  virtual ~format_adapter() {}

public:
  virtual void format(raw_ostream &S, StringRef Options) = 0;
};

template <typename T> class provider_format_adapter : public format_adapter {
  T Item;

public:
  explicit provider_format_adapter(T &&Item) : Item(std::forward<T>(Item)) {}

  void format(llvm::raw_ostream &S, StringRef Options) override {
    format_provider<typename std::decay<T>::type>::format(Item, S, Options);
  }
};

template <typename T>
class stream_operator_format_adapter : public format_adapter {
  T Item;

public:
  explicit stream_operator_format_adapter(T &&Item)
      : Item(std::forward<T>(Item)) {}

  void format(llvm::raw_ostream &S, StringRef Options) override { S << Item; }
};

template <typename T> class missing_format_adapter;

// Test if format_provider<T> is defined on T and contains a member function
// with the signature:
//   static void format(const T&, raw_stream &, StringRef);
//
template <class T> class has_FormatProvider {
public:
  using Decayed = typename std::decay<T>::type;
  typedef void (*Signature_format)(const Decayed &, llvm::raw_ostream &,
                                   StringRef);

  template <typename U>
  static char test(SameType<Signature_format, &U::format> *);

  template <typename U> static double test(...);

  static bool const value =
      (sizeof(test<llvm::format_provider<Decayed>>(nullptr)) == 1);
};

// Test if raw_ostream& << T -> raw_ostream& is findable via ADL.
template <class T> class has_StreamOperator {
public:
  using ConstRefT = const typename std::decay<T>::type &;

  template <typename U>
  static char test(typename std::enable_if<
                   std::is_same<decltype(std::declval<llvm::raw_ostream &>()
                                         << std::declval<U>()),
                                llvm::raw_ostream &>::value,
                   int *>::type);

  template <typename U> static double test(...);

  static bool const value = (sizeof(test<ConstRefT>(nullptr)) == 1);
};

// Simple template that decides whether a type T should use the member-function
// based format() invocation.
template <typename T>
struct uses_format_member
    : public std::integral_constant<
          bool,
          std::is_base_of<format_adapter,
                          typename std::remove_reference<T>::type>::value> {};

// Simple template that decides whether a type T should use the format_provider
// based format() invocation.  The member function takes priority, so this test
// will only be true if there is not ALSO a format member.
template <typename T>
struct uses_format_provider
    : public std::integral_constant<
          bool, !uses_format_member<T>::value && has_FormatProvider<T>::value> {
};

// Simple template that decides whether a type T should use the operator<<
// based format() invocation.  This takes last priority.
template <typename T>
struct uses_stream_operator
    : public std::integral_constant<bool, !uses_format_member<T>::value &&
                                              !uses_format_provider<T>::value &&
                                              has_StreamOperator<T>::value> {};

// Simple template that decides whether a type T has neither a member-function
// nor format_provider based implementation that it can use.  Mostly used so
// that the compiler spits out a nice diagnostic when a type with no format
// implementation can be located.
template <typename T>
struct uses_missing_provider
    : public std::integral_constant<bool, !uses_format_member<T>::value &&
                                              !uses_format_provider<T>::value &&
                                              !uses_stream_operator<T>::value> {
};

template <typename T>
typename std::enable_if<uses_format_member<T>::value, T>::type
build_format_adapter(T &&Item) {
  return std::forward<T>(Item);
}

template <typename T>
typename std::enable_if<uses_format_provider<T>::value,
                        provider_format_adapter<T>>::type
build_format_adapter(T &&Item) {
  return provider_format_adapter<T>(std::forward<T>(Item));
}

template <typename T>
typename std::enable_if<uses_stream_operator<T>::value,
                        stream_operator_format_adapter<T>>::type
build_format_adapter(T &&Item) {
  // If the caller passed an Error by value, then stream_operator_format_adapter
  // would be responsible for consuming it.
  // Make the caller opt into this by calling fmt_consume().
  static_assert(
      !std::is_same<llvm::Error, typename std::remove_cv<T>::type>::value,
      "llvm::Error-by-value must be wrapped in fmt_consume() for formatv");
  return stream_operator_format_adapter<T>(std::forward<T>(Item));
}

template <typename T>
typename std::enable_if<uses_missing_provider<T>::value,
                        missing_format_adapter<T>>::type
build_format_adapter(T &&Item) {
  return missing_format_adapter<T>();
}
}
}

#endif
