1//===----------------------------------------------------------------------===//
2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3// See https://llvm.org/LICENSE.txt for license information.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7
8// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9
10// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
11
12// <format>
13
14// template<ranges::input_range R, class charT>
15// struct range-default-formatter<range_format::map, R, charT>
16
17// template<class FormatContext>
18// typename FormatContext::iterator
19// format(const T& ref, FormatContext& ctx) const;
20
21// Note this tests the basics of this function. It's tested in more detail in
22// the format.functions test.
23
24#include <cassert>
25#include <concepts>
26#include <format>
27#include <iterator>
28#include <map>
29
30#include "assert_macros.h"
31#include "format.functions.common.h"
32#include "test_format_context.h"
33#include "test_macros.h"
34#include "make_string.h"
35
36#define SV(S) MAKE_STRING_VIEW(CharT, S)
37
38template <class StringViewT>
39void test_format(StringViewT expected, std::map<int, int> arg) {
40 using CharT = typename StringViewT::value_type;
41 using String = std::basic_string<CharT>;
42 using OutIt = std::back_insert_iterator<String>;
43 using FormatCtxT = std::basic_format_context<OutIt, CharT>;
44
45 std::formatter<std::map<int, int>, CharT> formatter;
46
47 String result;
48 OutIt out = std::back_inserter(result);
49 FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
50 formatter.format(arg, format_ctx);
51 assert(result == expected);
52}
53
54template <class CharT>
55void test_assure_parse_is_called(std::basic_string_view<CharT> fmt) {
56 using String = std::basic_string<CharT>;
57 using OutIt = std::back_insert_iterator<String>;
58 using FormatCtxT = std::basic_format_context<OutIt, CharT>;
59 std::map<parse_call_validator, parse_call_validator> arg{{parse_call_validator{}, parse_call_validator{}}};
60
61 String result;
62 OutIt out = std::back_inserter(result);
63 FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
64
65 std::formatter<decltype(arg), CharT> formatter;
66 std::basic_format_parse_context<CharT> ctx{fmt};
67
68 formatter.parse(ctx);
69 formatter.format(arg, format_ctx);
70}
71
72template <class CharT>
73void test_assure_parse_is_called() {
74 using String = std::basic_string<CharT>;
75 using OutIt = std::back_insert_iterator<String>;
76 using FormatCtxT = std::basic_format_context<OutIt, CharT>;
77 std::map<parse_call_validator, parse_call_validator> arg{{parse_call_validator{}, parse_call_validator{}}};
78
79 String result;
80 OutIt out = std::back_inserter(result);
81 [[maybe_unused]] FormatCtxT format_ctx =
82 test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
83
84 { // parse not called
85 [[maybe_unused]] const std::formatter<decltype(arg), CharT> formatter;
86 TEST_THROWS_TYPE(parse_call_validator::parse_function_not_called, formatter.format(arg, format_ctx));
87 }
88
89 test_assure_parse_is_called(SV("5"));
90 test_assure_parse_is_called(SV("n"));
91 test_assure_parse_is_called(SV("m"));
92 test_assure_parse_is_called(SV("5n"));
93 test_assure_parse_is_called(SV("5m"));
94}
95
96template <class CharT>
97void test_fmt() {
98 test_format(SV("{1: 42}"), std::map<int, int>{{1, 42}});
99 test_format(SV("{0: 99}"), std::map<int, int>{{0, 99}});
100
101 test_assure_parse_is_called<CharT>();
102}
103
104void test() {
105 test_fmt<char>();
106#ifndef TEST_HAS_NO_WIDE_CHARACTERS
107 test_fmt<wchar_t>();
108#endif
109}
110
111int main(int, char**) {
112 test();
113
114 return 0;
115}
116

source code of libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.pass.cpp