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

/*

namespace std {
  // [format.context], class template basic_format_context
  template<class Out, class charT> class basic_format_context;
  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;
  using format_args = basic_format_args<format_context>;
  using wformat_args = basic_format_args<wformat_context>;

  // [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 args);
  template<class Out>
    Out vformat_to(Out out, wstring_view fmt, wformat_args args);
  template<class Out>
    Out vformat_to(Out out, const locale& loc, string_view fmt,
                   format_args char> args);
  template<class Out>
    Out vformat_to(Out out, const locale& loc, wstring_view fmt,
                   wformat_args 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<class T, class charT = char> struct formatter;

  // [format.parse.ctx], class template basic_format_parse_context
  template<class charT> class basic_format_parse_context;
  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;

  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

  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;
}

*/

#include <__assert> // all public C++ headers provide the assertion handler
// 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 <__algorithm/clamp.h>
#include <__config>
#include <__debug>
#include <__format/buffer.h>
#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/format_to_n_result.h>
#include <__format/formatter.h>
#include <__format/formatter_bool.h>
#include <__format/formatter_char.h>
#include <__format/formatter_floating_point.h>
#include <__format/formatter_integer.h>
#include <__format/formatter_pointer.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_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER > 17

// TODO FMT Move the implementation in this file to its own granular headers.

// 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>;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
using wformat_args = basic_format_args<wformat_context>;
#endif

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)...};
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
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...);
}
#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 if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
          __arg.format(__parse_ctx, __ctx);
        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, class _FormatOutIt>
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
    __vformat_to(
        _OutIt __out_it, basic_string_view<_CharT> __fmt,
        basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
  if constexpr (same_as<_OutIt, _FormatOutIt>)
    return _VSTD::__format::__vformat_to(
        basic_format_parse_context{__fmt, __args.__size()},
        _VSTD::__format_context_create(_VSTD::move(__out_it), __args));
  else {
    __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)};
    _VSTD::__format::__vformat_to(
        basic_format_parse_context{__fmt, __args.__size()},
        _VSTD::__format_context_create(__buffer.make_output_iterator(),
                                       __args));
    return _VSTD::move(__buffer).out();
  }
}

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

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
  return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
}
#endif

template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _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(__args...));
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _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_wformat_args(__args...));
}
#endif

_LIBCPP_ALWAYS_INLINE 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;
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
_LIBCPP_ALWAYS_INLINE 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;
}
#endif

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

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

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};
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
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};
}
#endif

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();
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
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();
}
#endif

#ifndef _LIBCPP_HAS_NO_LOCALIZATION

template <class _OutIt, class _CharT, class _FormatOutIt>
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
    __vformat_to(
        _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt,
        basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
  if constexpr (same_as<_OutIt, _FormatOutIt>)
    return _VSTD::__format::__vformat_to(
        basic_format_parse_context{__fmt, __args.__size()},
        _VSTD::__format_context_create(_VSTD::move(__out_it), __args,
                                       _VSTD::move(__loc)));
  else {
    __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)};
    _VSTD::__format::__vformat_to(
        basic_format_parse_context{__fmt, __args.__size()},
        _VSTD::__format_context_create(__buffer.make_output_iterator(),
                                       __args, _VSTD::move(__loc)));
    return _VSTD::move(__buffer).out();
  }
}

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

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
    _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
  return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
                             __args);
}
#endif

template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _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(__args...));
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _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_wformat_args(__args...));
}
#endif

_LIBCPP_ALWAYS_INLINE 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;
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
_LIBCPP_ALWAYS_INLINE 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;
}
#endif

template <class... _Args>
_LIBCPP_ALWAYS_INLINE _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...));
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _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...));
}
#endif

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};
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
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};
}
#endif

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();
}

#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
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

#endif // _LIBCPP_HAS_NO_LOCALIZATION

#endif //_LIBCPP_STD_VER > 17

_LIBCPP_END_NAMESPACE_STD

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)

#endif // _LIBCPP_FORMAT
