// -*- 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 _LIBCPP___FORMAT_FORMAT_ARG_H
#define _LIBCPP___FORMAT_FORMAT_ARG_H

#include <__assert>
#include <__concepts/arithmetic.h>
#include <__config>
#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__format/format_parse_context.h>
#include <__functional/invoke.h>
#include <__memory/addressof.h>
#include <__utility/forward.h>
#include <__utility/unreachable.h>
#include <__variant/monostate.h>
#include <string>
#include <string_view>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER > 17

namespace __format {
/// The type stored in @ref basic_format_arg.
///
/// @note The 128-bit types are unconditionally in the list to avoid the values
/// of the enums to depend on the availability of 128-bit integers.
///
/// @note The value is stored as a 5-bit value in the __packed_arg_t_bits. This
/// limits the maximum number of elements to 32.
/// When modifying update the test
/// test/libcxx/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp
/// It could be packed in 4-bits but that means a new type directly becomes an
/// ABI break. The packed type is 64-bit so this reduces the maximum number of
/// packed elements from 16 to 12.
///
/// @note Some members of this enum are an extension. These extensions need
/// special behaviour in visit_format_arg. There they need to be wrapped in a
/// handle to satisfy the user observable behaviour. The internal function
/// __visit_format_arg doesn't do this wrapping. So in the format functions
/// this function is used to avoid unneeded overhead.
enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t {
  __none,
  __boolean,
  __char_type,
  __int,
  __long_long,
  __i128, // extension
  __unsigned,
  __unsigned_long_long,
  __u128, // extension
  __float,
  __double,
  __long_double,
  __const_char_type_ptr,
  __string_view,
  __ptr,
  __handle
};

inline constexpr unsigned __packed_arg_t_bits = 5;
inline constexpr uint8_t __packed_arg_t_mask = 0x1f;

inline constexpr unsigned __packed_types_storage_bits = 64;
inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits;

_LIBCPP_HIDE_FROM_ABI
constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= __packed_types_max; }

_LIBCPP_HIDE_FROM_ABI
constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) {
  _LIBCPP_ASSERT(__id <= __packed_types_max, "");

  if (__id > 0)
    __types >>= __id * __packed_arg_t_bits;

  return static_cast<__format::__arg_t>(__types & __packed_arg_t_mask);
}

} // namespace __format

// This function is not user obervable, so it can directly use the non-standard
// types of the "variant". See __arg_t for more details.
template <class _Visitor, class _Context>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
__visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
  switch (__arg.__type_) {
  case __format::__arg_t::__none:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__monostate_);
  case __format::__arg_t::__boolean:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__boolean_);
  case __format::__arg_t::__char_type:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__char_type_);
  case __format::__arg_t::__int:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__int_);
  case __format::__arg_t::__long_long:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_long_);
  case __format::__arg_t::__i128:
#  ifndef _LIBCPP_HAS_NO_INT128
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__i128_);
#  else
    __libcpp_unreachable();
#  endif
  case __format::__arg_t::__unsigned:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_);
  case __format::__arg_t::__unsigned_long_long:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_);
  case __format::__arg_t::__u128:
#  ifndef _LIBCPP_HAS_NO_INT128
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__u128_);
#  else
    __libcpp_unreachable();
#  endif
  case __format::__arg_t::__float:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__float_);
  case __format::__arg_t::__double:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__double_);
  case __format::__arg_t::__long_double:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_double_);
  case __format::__arg_t::__const_char_type_ptr:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_);
  case __format::__arg_t::__string_view:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__string_view_);
  case __format::__arg_t::__ptr:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__ptr_);
  case __format::__arg_t::__handle:
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis),
                         typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_});
  }

  __libcpp_unreachable();
}

/// Contains the values used in basic_format_arg.
///
/// This is a separate type so it's possible to store the values and types in
/// separate arrays.
template <class _Context>
class __basic_format_arg_value {
  using _CharT = typename _Context::char_type;

public:
  /// Contains the implementation for basic_format_arg::handle.
  struct __handle {
    template <class _Tp>
    _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept
        : __ptr_(_VSTD::addressof(__v)),
          __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) {
            using _Dp = remove_cvref_t<_Tp>;
            using _Formatter = typename _Context::template formatter_type<_Dp>;
            constexpr bool __const_formattable =
                requires { _Formatter().format(std::declval<const _Dp&>(), std::declval<_Context&>()); };
            using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>;

            static_assert(__const_formattable || !is_const_v<remove_reference_t<_Tp>>, "Mandated by [format.arg]/18");

            _Formatter __f;
            __parse_ctx.advance_to(__f.parse(__parse_ctx));
            __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Dp*>(__ptr)), __ctx));
          }) {}

    const void* __ptr_;
    void (*__format_)(basic_format_parse_context<_CharT>&, _Context&, const void*);
  };

  union {
    monostate __monostate_;
    bool __boolean_;
    _CharT __char_type_;
    int __int_;
    unsigned __unsigned_;
    long long __long_long_;
    unsigned long long __unsigned_long_long_;
#  ifndef _LIBCPP_HAS_NO_INT128
    __int128_t __i128_;
    __uint128_t __u128_;
#  endif
    float __float_;
    double __double_;
    long double __long_double_;
    const _CharT* __const_char_type_ptr_;
    basic_string_view<_CharT> __string_view_;
    const void* __ptr_;
    __handle __handle_;
  };

  // These constructors contain the exact storage type used. If adjustments are
  // required, these will be done in __create_format_arg.

  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value() noexcept : __monostate_() {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(bool __value) noexcept : __boolean_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(_CharT __value) noexcept : __char_type_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(int __value) noexcept : __int_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned __value) noexcept : __unsigned_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long long __value) noexcept : __long_long_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned long long __value) noexcept
      : __unsigned_long_long_(__value) {}
#  ifndef _LIBCPP_HAS_NO_INT128
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__int128_t __value) noexcept : __i128_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__uint128_t __value) noexcept : __u128_(__value) {}
#  endif
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(float __value) noexcept : __float_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(double __value) noexcept : __double_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long double __value) noexcept : __long_double_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const _CharT* __value) noexcept : __const_char_type_ptr_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept
      : __string_view_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {}
  _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept
      // TODO FMT Investigate why it doesn't work without the forward.
      : __handle_(std::forward<__handle>(__value)) {}
};

template <class _Context>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg {
public:
  class _LIBCPP_TEMPLATE_VIS handle;

  _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept
      : __type_{__format::__arg_t::__none} {}

  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept {
    return __type_ != __format::__arg_t::__none;
  }

private:
  using char_type = typename _Context::char_type;

  // TODO FMT Implement constrain [format.arg]/4
  // Constraints: The template specialization
  //   typename Context::template formatter_type<T>
  // meets the Formatter requirements ([formatter.requirements]).  The extent
  // to which an implementation determines that the specialization meets the
  // Formatter requirements is unspecified, except that as a minimum the
  // expression
  //   typename Context::template formatter_type<T>()
  //    .format(declval<const T&>(), declval<Context&>())
  // shall be well-formed when treated as an unevaluated operand.

public:
  __basic_format_arg_value<_Context> __value_;
  __format::__arg_t __type_;

  _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(__format::__arg_t __type,
                                                  __basic_format_arg_value<_Context> __value) noexcept
      : __value_(__value), __type_(__type) {}
};

template <class _Context>
class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle {
public:
  _LIBCPP_HIDE_FROM_ABI
  void format(basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx) const {
    __handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_);
  }

  _LIBCPP_HIDE_FROM_ABI explicit handle(typename __basic_format_arg_value<_Context>::__handle& __handle) noexcept
      : __handle_(__handle) {}

private:
  typename __basic_format_arg_value<_Context>::__handle& __handle_;
};

// This function is user facing, so it must wrap the non-standard types of
// the "variant" in a handle to stay conforming. See __arg_t for more details.
template <class _Visitor, class _Context>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
  switch (__arg.__type_) {
#  ifndef _LIBCPP_HAS_NO_INT128
  case __format::__arg_t::__i128: {
    typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_};
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
  }

  case __format::__arg_t::__u128: {
    typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_};
    return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
  }
#  endif
  default:
    return _VSTD::__visit_format_arg(_VSTD::forward<_Visitor>(__vis), __arg);
  }
}

#endif //_LIBCPP_STD_VER > 17

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___FORMAT_FORMAT_ARG_H
