// -*- C++ -*-
//===--------------------------- format -----------------------------------===//
//
// 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
#define _LIBCPP_FORMAT

/*

namespace std {
  // [format.context], class template basic_format_context
  template<class Out, class charT>
  class basic_format_context {
    basic_format_args<basic_format_context> args_;      // exposition only
    Out out_;                                           // exposition only

  public:
    using iterator = Out;
    using char_type = charT;
    template<class T> using formatter_type = formatter<T, charT>;

    basic_format_arg<basic_format_context> arg(size_t id) const;
    std::locale locale();

    iterator out();
    void advance_to(iterator it);
  };
  using format_context = basic_format_context<unspecified, char>;
  using wformat_context = basic_format_context<unspecified, wchar_t>;

  // [format.args], class template basic_format_args
  template<class Context>
  class basic_format_args {
    size_t size_;                               // exposition only
    const basic_format_arg<Context>* data_;     // exposition only

  public:
    basic_format_args() noexcept;

    template<class... Args>
      basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;

    basic_format_arg<Context> get(size_t i) const noexcept;
  };
  using format_args = basic_format_args<format_context>;
  using wformat_args = basic_format_args<wformat_context>;


  template<class Out, class charT>
    using format_args_t = basic_format_args<basic_format_context<Out, charT>>;

  // [format.functions], formatting functions
  template<class... Args>
    string format(string_view fmt, const Args&... args);
  template<class... Args>
    wstring format(wstring_view fmt, const Args&... args);
  template<class... Args>
    string format(const locale& loc, string_view fmt, const Args&... args);
  template<class... Args>
    wstring format(const locale& loc, wstring_view fmt, const Args&... args);

  string vformat(string_view fmt, format_args args);
  wstring vformat(wstring_view fmt, wformat_args args);
  string vformat(const locale& loc, string_view fmt, format_args args);
  wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);

  template<class Out, class... Args>
    Out format_to(Out out, string_view fmt, const Args&... args);
  template<class Out, class... Args>
    Out format_to(Out out, wstring_view fmt, const Args&... args);
  template<class Out, class... Args>
    Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args);
  template<class Out, class... Args>
    Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);

  template<class Out>
    Out vformat_to(Out out, string_view fmt,
                   format_args_t<type_identity_t<Out>, char> args);
  template<class Out>
    Out vformat_to(Out out, wstring_view fmt,
                   format_args_t<type_identity_t<Out>, wchar_t> args);
  template<class Out>
    Out vformat_to(Out out, const locale& loc, string_view fmt,
                   format_args_t<type_identity_t<Out>, char> args);
  template<class Out>
    Out vformat_to(Out out, const locale& loc, wstring_view fmt,
                   format_args_t<type_identity_t<Out>, wchar_t> args);

  template<class Out> struct format_to_n_result {
    Out out;
    iter_difference_t<Out> size;
  };

 template<class Out, class... Args>
    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
                                        string_view fmt, const Args&... args);
  template<class Out, class... Args>
    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
                                        wstring_view fmt, const Args&... args);
  template<class Out, class... Args>
    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
                                        const locale& loc, string_view fmt,
                                        const Args&... args);
  template<class Out, class... Args>
    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
                                        const locale& loc, wstring_view fmt,
                                        const Args&... args);

  template<class... Args>
    size_t formatted_size(string_view fmt, const Args&... args);
  template<class... Args>
    size_t formatted_size(wstring_view fmt, const Args&... args);
  template<class... Args>
    size_t formatted_size(const locale& loc, string_view fmt, const Args&... args);
  template<class... Args>
    size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);

  // [format.formatter], formatter
  template<> struct formatter<char, char>;
  template<> struct formatter<char, wchar_t>;
  template<> struct formatter<wchar_t, wchar_t>;

  template<> struct formatter<charT*, charT>;
  template<> struct formatter<const charT*, charT>;
  template<size_t N> struct formatter<const charT[N], charT>;
  template<class traits, class Allocator>
    struct formatter<basic_string<charT, traits, Allocator>, charT>;
  template<class traits>
    struct formatter<basic_string_view<charT, traits>, charT>;

  // [format.parse.ctx], class template basic_format_parse_context
  template<class charT>
  class basic_format_parse_context {
  public:
    using char_type = charT;
    using const_iterator = typename basic_string_view<charT>::const_iterator;
    using iterator = const_iterator;

  private:
    iterator begin_;                                    // exposition only
    iterator end_;                                      // exposition only
    enum indexing { unknown, manual, automatic };       // exposition only
    indexing indexing_;                                 // exposition only
    size_t next_arg_id_;                                // exposition only
    size_t num_args_;                                   // exposition only

  public:
    constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
                                                  size_t num_args = 0) noexcept;
    basic_format_parse_context(const basic_format_parse_context&) = delete;
    basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;

    constexpr const_iterator begin() const noexcept;
    constexpr const_iterator end() const noexcept;
    constexpr void advance_to(const_iterator it);

    constexpr size_t next_arg_id();
    constexpr void check_arg_id(size_t id);
  };
  using format_parse_context = basic_format_parse_context<char>;
  using wformat_parse_context = basic_format_parse_context<wchar_t>;

  // [format.arguments], arguments
  // [format.arg], class template basic_format_arg
  template<class Context>
  class basic_format_arg {
  public:
    class handle;

  private:
    using char_type = typename Context::char_type;                              // exposition only

    variant<monostate, bool, char_type,
            int, unsigned int, long long int, unsigned long long int,
            float, double, long double,
            const char_type*, basic_string_view<char_type>,
            const void*, handle> value;                                         // exposition only

    template<class T> explicit basic_format_arg(const T& v) noexcept;           // exposition only
    explicit basic_format_arg(float n) noexcept;                                // exposition only
    explicit basic_format_arg(double n) noexcept;                               // exposition only
    explicit basic_format_arg(long double n) noexcept;                          // exposition only
    explicit basic_format_arg(const char_type* s);                              // exposition only

    template<class traits>
      explicit basic_format_arg(
        basic_string_view<char_type, traits> s) noexcept;                       // exposition only

    template<class traits, class Allocator>
      explicit basic_format_arg(
        const basic_string<char_type, traits, Allocator>& s) noexcept;          // exposition only

    explicit basic_format_arg(nullptr_t) noexcept;                              // exposition only

    template<class T>
      explicit basic_format_arg(const T* p) noexcept;                           // exposition only

  public:
    basic_format_arg() noexcept;

    explicit operator bool() const noexcept;
  };

  template<class Visitor, class Context>
    see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);

  // [format.arg.store], class template format-arg-store
  template<class Context, class... Args>
  struct format-arg-store {      // exposition only
    array<basic_format_arg<Context>, sizeof...(Args)> args;
  };

  template<class Context = format_context, class... Args>
    format-arg-store<Context, Args...>
      make_format_args(const Args&... args);
  template<class... Args>
    format-arg-store<wformat_context, Args...>
      make_wformat_args(const Args&... args);

  // [format.error], class format_error
  class format_error : public runtime_error {
  public:
    explicit format_error(const string& what_arg);
    explicit format_error(const char* what_arg);
  };

  // [format.parse.ctx], class template basic_format_parse_context
  template<class charT>
  class basic_format_parse_context {
  public:
    using char_type = charT;
    using const_iterator = typename basic_string_view<charT>::const_iterator;
    using iterator = const_iterator;

  private:
    iterator begin_;                                    // exposition only
    iterator end_;                                      // exposition only
    enum indexing { unknown, manual, automatic };       // exposition only
    indexing indexing_;                                 // exposition only
    size_t next_arg_id_;                                // exposition only
    size_t num_args_;                                   // exposition only

  public:
    constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
                                                  size_t num_args = 0) noexcept;
    basic_format_parse_context(const basic_format_parse_context&) = delete;
    basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;

    constexpr const_iterator begin() const noexcept;
    constexpr const_iterator end() const noexcept;
    constexpr void advance_to(const_iterator it);

    constexpr size_t next_arg_id();
    constexpr void check_arg_id(size_t id);
  };
  using format_parse_context = basic_format_parse_context<char>;
  using wformat_parse_context = basic_format_parse_context<wchar_t>;
}

*/

// Make sure all feature-test macros are available.
#include <version>
// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)

#include <__config>
#include <__debug>
#include <__format/format_arg.h>
#include <__format/format_args.h>
#include <__format/format_context.h>
#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__format/format_parse_context.h>
#include <__format/format_string.h>
#include <__format/formatter.h>
#include <__format/formatter_bool.h>
#include <__format/formatter_char.h>
#include <__format/formatter_integer.h>
#include <__format/formatter_string.h>
#include <__format/parser_std_format_spec.h>
#include <__variant/monostate.h>
#include <array>
#include <concepts>
#include <string>
#include <string_view>
#include <type_traits>

#ifndef _LIBCPP_HAS_NO_LOCALIZATION
#include <locale>
#endif

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

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER > 17

// TODO FMT Remove this once we require compilers with proper C++20 support.
// If the compiler has no concepts support, the format header will be disabled.
// Without concepts support enable_if needs to be used and that too much effort
// to support compilers with partial C++20 support.
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)

// TODO FMT Evaluate which templates should be external templates. This
// improves the efficiency of the header. However since the header is still
// under heavy development and not all classes are stable it makes no sense
// to do this optimization now.

using format_args = basic_format_args<format_context>;
using wformat_args = basic_format_args<wformat_context>;

template <class _OutIt, class _CharT>
using format_args_t = basic_format_args<basic_format_context<_OutIt, _CharT>>;

template <class _Context, class... _Args>
struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
  // TODO FMT Use a built-in array.
  array<basic_format_arg<_Context>, sizeof...(_Args)> __args;
};

template <class _Context = format_context, class... _Args>
_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...>
make_format_args(const _Args&... __args) {
  return {basic_format_arg<_Context>(__args)...};
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
make_wformat_args(const _Args&... __args) {
  return _VSTD::make_format_args<wformat_context>(__args...);
}
namespace __format {

template <class _Tp, class _CharT>
requires(is_arithmetic_v<_Tp> &&
         !same_as<_Tp, bool>) struct _LIBCPP_HIDE_FROM_ABI
    __formatter_arithmetic {
  _LIBCPP_HIDE_FROM_ABI
  auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) {
    // TODO FMT Implement
    return __parse_ctx.begin();
  }

  _LIBCPP_HIDE_FROM_ABI
  auto format(_Tp __value, auto& __ctx) -> decltype(__ctx.out()) {
    return __handle_format(__value, __ctx);
  }

private:
  template <class _Uv>
  _LIBCPP_HIDDEN static string
  __convert(_Uv __value) requires(same_as<_CharT, char>) {
    return _VSTD::to_string(__value);
  }
  template <class _Uv>
  _LIBCPP_HIDDEN static wstring
  __convert(_Uv __value) requires(same_as<_CharT, wchar_t>) {
    return _VSTD::to_wstring(__value);
  }

  template <class _Uv>
  _LIBCPP_HIDDEN auto __handle_format(_Uv __value, auto& __ctx)
      -> decltype(__ctx.out())
  {
    // TODO FMT Implement using formatting arguments
    // TODO FMT Improve PoC since using std::to_string is inefficient.
    // Note the code doesn't use std::string::iterator since the unit tests
    // test with debug iterators and they fail with strings created from
    // std::to_string.
    auto __str = __convert(__value);
    auto __out_it = __ctx.out();
    for (size_t __i = 0, __e = __str.size(); __i != __e; ++__i)
      *__out_it++ = __str[__i];
    return __out_it;
  }
};
} // namespace __format

// These specializations are helper stubs and not proper formatters.
// TODO FMT Implement the proper formatter specializations.

// Floating point types.
// TODO FMT There are no replacements for the floating point stubs due to not
// having floating point support in std::to_chars yet. These stubs aren't
// removed since they are useful for developing the real versions.
// Ultimately the stubs should be implemented properly and this code can be
// removed.
#if 0
template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT>
    : public __format::__formatter_arithmetic<float, _CharT> {};
template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
    formatter<double, _CharT>
    : public __format::__formatter_arithmetic<double, _CharT> {};
template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
    formatter<long double, _CharT>
    : public __format::__formatter_arithmetic<long double, _CharT> {};
#endif

namespace __format {

template <class _CharT, class _ParseCtx, class _Ctx>
_LIBCPP_HIDE_FROM_ABI const _CharT*
__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
                           _ParseCtx& __parse_ctx, _Ctx& __ctx) {
  __format::__parse_number_result __r =
      __format::__parse_arg_id(__begin, __end, __parse_ctx);

  switch (*__r.__ptr) {
  case _CharT(':'):
    // The arg-id has a format-specifier, advance the input to the format-spec.
    __parse_ctx.advance_to(__r.__ptr + 1);
    break;
  case _CharT('}'):
    // The arg-id has no format-specifier.
    __parse_ctx.advance_to(__r.__ptr);
    break;
  default:
    __throw_format_error(
        "The replacement field arg-id should terminate at a ':' or '}'");
  }

  _VSTD::visit_format_arg(
      [&](auto __arg) {
        if constexpr (same_as<decltype(__arg), monostate>)
          __throw_format_error("Argument index out of bounds");
        else {
          formatter<decltype(__arg), _CharT> __formatter;
          __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
          __ctx.advance_to(__formatter.format(__arg, __ctx));
        }
      },
      __ctx.arg(__r.__value));

  __begin = __parse_ctx.begin();
  if (__begin == __end || *__begin != _CharT('}'))
    __throw_format_error("The replacement field misses a terminating '}'");

  return ++__begin;
}

template <class _ParseCtx, class _Ctx>
_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator
__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
  using _CharT = typename _ParseCtx::char_type;
  static_assert(same_as<typename _Ctx::char_type, _CharT>);

  const _CharT* __begin = __parse_ctx.begin();
  const _CharT* __end = __parse_ctx.end();
  typename _Ctx::iterator __out_it = __ctx.out();
  while (__begin != __end) {
    switch (*__begin) {
    case _CharT('{'):
      ++__begin;
      if (__begin == __end)
        __throw_format_error("The format string terminates at a '{'");

      if (*__begin != _CharT('{')) [[likely]] {
        __ctx.advance_to(_VSTD::move(__out_it));
        __begin =
            __handle_replacement_field(__begin, __end, __parse_ctx, __ctx);
        __out_it = __ctx.out();

        // The output is written and __begin points to the next character. So
        // start the next iteration.
        continue;
      }
      // The string is an escape character.
      break;

    case _CharT('}'):
      ++__begin;
      if (__begin == __end || *__begin != _CharT('}'))
        __throw_format_error(
            "The format string contains an invalid escape sequence");

      break;
    }

    // Copy the character to the output verbatim.
    *__out_it++ = *__begin++;
  }
  return __out_it;
}

} // namespace __format

template <class _OutIt, class _CharT>
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
    __vformat_to(_OutIt __out_it, basic_string_view<_CharT> __fmt,
                 format_args_t<type_identity_t<_OutIt>, _CharT> __args) {
  return __format::__vformat_to(
      basic_format_parse_context{__fmt, __args.__size()},
      _VSTD::__format_context_create(_VSTD::move(__out_it), __args));
}

template <output_iterator<const char&> _OutIt>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
vformat_to(_OutIt __out_it, string_view __fmt,
           format_args_t<type_identity_t<_OutIt>, char> __args) {
  return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
}

template <output_iterator<const wchar_t&> _OutIt>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
vformat_to(_OutIt __out_it, wstring_view __fmt,
           format_args_t<type_identity_t<_OutIt>, wchar_t> __args) {
  return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
}

template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) {
  return _VSTD::vformat_to(
      _VSTD::move(__out_it), __fmt,
      _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...));
}

template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) {
  return _VSTD::vformat_to(
      _VSTD::move(__out_it), __fmt,
      _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>(
          __args...));
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
vformat(string_view __fmt, format_args __args) {
  string __res;
  _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
  return __res;
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
vformat(wstring_view __fmt, wformat_args __args) {
  wstring __res;
  _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
  return __res;
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
format(string_view __fmt, const _Args&... __args) {
  return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
format(wstring_view __fmt, const _Args&... __args) {
  return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
}

template <class _OutIt>
struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
  _OutIt out;
  iter_difference_t<_OutIt> size;
};

template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt,
            const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  string __str = _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
  iter_difference_t<_OutIt> __s = __str.size();
  iter_difference_t<_OutIt> __m =
      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
  return {_VSTD::move(__out_it), __s};
}

template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt,
            const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  wstring __str = _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
  iter_difference_t<_OutIt> __s = __str.size();
  iter_difference_t<_OutIt> __m =
      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
  return {_VSTD::move(__out_it), __s};
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
formatted_size(string_view __fmt, const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size();
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
formatted_size(wstring_view __fmt, const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size();
}

#ifndef _LIBCPP_HAS_NO_LOCALIZATION

template <class _OutIt, class _CharT>
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
    __vformat_to(_OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt,
                 format_args_t<type_identity_t<_OutIt>, _CharT> __args) {
  return __format::__vformat_to(
      basic_format_parse_context{__fmt, __args.__size()},
      _VSTD::__format_context_create(_VSTD::move(__out_it), __args,
                                     _VSTD::move(__loc)));
}

template <output_iterator<const char&> _OutIt>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
vformat_to(_OutIt __out_it, locale __loc, string_view __fmt,
           format_args_t<type_identity_t<_OutIt>, char> __args) {
  return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
                             __args);
}

template <output_iterator<const wchar_t&> _OutIt>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt,
           format_args_t<type_identity_t<_OutIt>, wchar_t> __args) {
  return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
                             __args);
}

template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
    _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) {
  return _VSTD::vformat_to(
      _VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
      _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...));
}

template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
    _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) {
  return _VSTD::vformat_to(
      _VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
      _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>(
          __args...));
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
vformat(locale __loc, string_view __fmt, format_args __args) {
  string __res;
  _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
                    __args);
  return __res;
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
  wstring __res;
  _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
                    __args);
  return __res;
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
format(locale __loc, string_view __fmt, const _Args&... __args) {
  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
                        _VSTD::make_format_args(__args...));
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
format(locale __loc, wstring_view __fmt, const _Args&... __args) {
  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
                        _VSTD::make_wformat_args(__args...));
}

template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
            string_view __fmt, const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  string __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
                                _VSTD::make_format_args(__args...));
  iter_difference_t<_OutIt> __s = __str.size();
  iter_difference_t<_OutIt> __m =
      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
  return {_VSTD::move(__out_it), __s};
}

template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
            wstring_view __fmt, const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  wstring __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
                                 _VSTD::make_wformat_args(__args...));
  iter_difference_t<_OutIt> __s = __str.size();
  iter_difference_t<_OutIt> __m =
      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
  return {_VSTD::move(__out_it), __s};
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
formatted_size(locale __loc, string_view __fmt, const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
                        _VSTD::make_format_args(__args...))
      .size();
}

template <class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
formatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) {
  // TODO FMT Improve PoC: using std::string is inefficient.
  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
                        _VSTD::make_wformat_args(__args...))
      .size();
}

#endif // _LIBCPP_HAS_NO_LOCALIZATION

#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
#endif //_LIBCPP_STD_VER > 17

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)

#endif // _LIBCPP_FORMAT
