xref: /llvm-project/libcxx/test/std/utilities/format/format.tuple/format.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1eb6e13cbSMark de Wever //===----------------------------------------------------------------------===//
2*6a54dfbfSLouis Dionne //
3eb6e13cbSMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4eb6e13cbSMark de Wever // See https://llvm.org/LICENSE.txt for license information.
5eb6e13cbSMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6eb6e13cbSMark de Wever //
7eb6e13cbSMark de Wever //===----------------------------------------------------------------------===//
8eb6e13cbSMark de Wever 
9eb6e13cbSMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10eb6e13cbSMark de Wever 
11520c7fbbSLouis Dionne // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12af5fc4b4SMark de Wever 
13eb6e13cbSMark de Wever // <format>
14eb6e13cbSMark de Wever 
15eb6e13cbSMark de Wever // template<class charT, formattable<charT>... Ts>
16eb6e13cbSMark de Wever //   struct formatter<pair-or-tuple<Ts...>, charT>
17eb6e13cbSMark de Wever 
18eb6e13cbSMark de Wever // template<class FormatContext>
19eb6e13cbSMark de Wever //   typename FormatContext::iterator
20eb6e13cbSMark de Wever //     format(see below& elems, FormatContext& ctx) const;
21eb6e13cbSMark de Wever 
22eb6e13cbSMark de Wever // Note this tests the basics of this function. It's tested in more detail in
23eb6e13cbSMark de Wever // the format functions tests.
24eb6e13cbSMark de Wever 
25eb6e13cbSMark de Wever #include <cassert>
26eb6e13cbSMark de Wever #include <concepts>
27eb6e13cbSMark de Wever #include <format>
289c8f3409SMark de Wever #include <iterator>
29eb6e13cbSMark de Wever #include <tuple>
30eb6e13cbSMark de Wever #include <utility>
31eb6e13cbSMark de Wever 
329b43aedeSMark de Wever #include "assert_macros.h"
339b43aedeSMark de Wever #include "format.functions.common.h"
349b43aedeSMark de Wever #include "make_string.h"
35eb6e13cbSMark de Wever #include "test_format_context.h"
36eb6e13cbSMark de Wever #include "test_macros.h"
37eb6e13cbSMark de Wever 
38eb6e13cbSMark de Wever #define SV(S) MAKE_STRING_VIEW(CharT, S)
39eb6e13cbSMark de Wever 
40eb6e13cbSMark de Wever template <class StringViewT, class Arg>
41eb6e13cbSMark de Wever void test(StringViewT expected, Arg arg) {
42eb6e13cbSMark de Wever   using CharT      = typename StringViewT::value_type;
43eb6e13cbSMark de Wever   using String     = std::basic_string<CharT>;
44eb6e13cbSMark de Wever   using OutIt      = std::back_insert_iterator<String>;
45eb6e13cbSMark de Wever   using FormatCtxT = std::basic_format_context<OutIt, CharT>;
46eb6e13cbSMark de Wever 
47eb6e13cbSMark de Wever   const std::formatter<Arg, CharT> formatter;
48eb6e13cbSMark de Wever 
49eb6e13cbSMark de Wever   String result;
50eb6e13cbSMark de Wever   OutIt out             = std::back_inserter(result);
51eb6e13cbSMark de Wever   FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
52eb6e13cbSMark de Wever   formatter.format(arg, format_ctx);
53eb6e13cbSMark de Wever   assert(result == expected);
54eb6e13cbSMark de Wever }
55eb6e13cbSMark de Wever 
56eb6e13cbSMark de Wever template <class CharT>
579b43aedeSMark de Wever void test_assure_parse_is_called(std::basic_string_view<CharT> fmt) {
589b43aedeSMark de Wever   using String     = std::basic_string<CharT>;
599b43aedeSMark de Wever   using OutIt      = std::back_insert_iterator<String>;
609b43aedeSMark de Wever   using FormatCtxT = std::basic_format_context<OutIt, CharT>;
619b43aedeSMark de Wever   std::pair<parse_call_validator, parse_call_validator> arg;
629b43aedeSMark de Wever 
639b43aedeSMark de Wever   String result;
649b43aedeSMark de Wever   OutIt out             = std::back_inserter(result);
659b43aedeSMark de Wever   FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
669b43aedeSMark de Wever 
679b43aedeSMark de Wever   std::formatter<decltype(arg), CharT> formatter;
689b43aedeSMark de Wever   std::basic_format_parse_context<CharT> ctx{fmt};
699b43aedeSMark de Wever 
709b43aedeSMark de Wever   formatter.parse(ctx);
719b43aedeSMark de Wever   formatter.format(arg, format_ctx);
729b43aedeSMark de Wever }
739b43aedeSMark de Wever 
749b43aedeSMark de Wever template <class CharT>
759b43aedeSMark de Wever void test_assure_parse_is_called() {
769b43aedeSMark de Wever   using String     = std::basic_string<CharT>;
779b43aedeSMark de Wever   using OutIt      = std::back_insert_iterator<String>;
789b43aedeSMark de Wever   using FormatCtxT = std::basic_format_context<OutIt, CharT>;
799b43aedeSMark de Wever   std::pair<parse_call_validator, parse_call_validator> arg;
809b43aedeSMark de Wever 
819b43aedeSMark de Wever   String result;
829b43aedeSMark de Wever   OutIt out = std::back_inserter(result);
83c20d81bdSLouis Dionne   [[maybe_unused]] FormatCtxT format_ctx =
84c20d81bdSLouis Dionne       test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
859b43aedeSMark de Wever 
869b43aedeSMark de Wever   { // parse not called
879b43aedeSMark de Wever     [[maybe_unused]] const std::formatter<decltype(arg), CharT> formatter;
889b43aedeSMark de Wever     TEST_THROWS_TYPE(parse_call_validator::parse_function_not_called, formatter.format(arg, format_ctx));
899b43aedeSMark de Wever   }
909b43aedeSMark de Wever 
919b43aedeSMark de Wever   test_assure_parse_is_called(SV("5"));
929b43aedeSMark de Wever   test_assure_parse_is_called(SV("n"));
939b43aedeSMark de Wever   test_assure_parse_is_called(SV("m"));
949b43aedeSMark de Wever   test_assure_parse_is_called(SV("5n"));
959b43aedeSMark de Wever   test_assure_parse_is_called(SV("5m"));
969b43aedeSMark de Wever }
979b43aedeSMark de Wever 
989b43aedeSMark de Wever template <class CharT>
99eb6e13cbSMark de Wever void test() {
100eb6e13cbSMark de Wever   test(SV("(1)"), std::tuple<int>{1});
101eb6e13cbSMark de Wever   test(SV("(1, 1)"), std::tuple<int, CharT>{1, CharT('1')});
102eb6e13cbSMark de Wever   test(SV("(1, 1)"), std::pair<int, CharT>{1, CharT('1')});
1033d334df5SLouis Dionne   test(SV("(1, 1, true)"), std::tuple<int, CharT, bool>{1, CharT('1'), true});
1049b43aedeSMark de Wever 
1059b43aedeSMark de Wever   test_assure_parse_is_called<CharT>();
106eb6e13cbSMark de Wever }
107eb6e13cbSMark de Wever 
108eb6e13cbSMark de Wever void test() {
109eb6e13cbSMark de Wever   test<char>();
110eb6e13cbSMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS
111eb6e13cbSMark de Wever   test<wchar_t>();
112eb6e13cbSMark de Wever #endif
113eb6e13cbSMark de Wever }
114eb6e13cbSMark de Wever 
115eb6e13cbSMark de Wever int main(int, char**) {
116eb6e13cbSMark de Wever   test();
117eb6e13cbSMark de Wever 
118eb6e13cbSMark de Wever   return 0;
119eb6e13cbSMark de Wever }
120