xref: /llvm-project/libcxx/test/std/utilities/format/format.functions/P2418.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
11 
12 // TODO FMT This test should not require std::to_chars(floating-point)
13 // XFAIL: availability-fp_to_chars-missing
14 
15 // Tests whether a move only type can be formatted. This is required by
16 // P2418R2 "Add support for std::generator-like types to std::format"
17 
18 // <format>
19 
20 #include <format>
21 #include <cassert>
22 
23 #include "MoveOnly.h"
24 #include "make_string.h"
25 #include "test_macros.h"
26 
27 #ifndef TEST_HAS_NO_LOCALIZATION
28 #  include <locale>
29 #endif
30 
31 #define SV(S) MAKE_STRING_VIEW(CharT, S)
32 
33 template <class CharT>
34 struct std::formatter<MoveOnly, CharT> : std::formatter<int, CharT> {
35   auto format(const MoveOnly& m, auto& ctx) const -> decltype(ctx.out()) {
36     return std::formatter<int, CharT>::format(m.get(), ctx);
37   }
38 };
39 
40 template <class CharT>
41 static void test() {
42   MoveOnly m{10};
43   CharT buffer[10];
44 #ifndef TEST_HAS_NO_LOCALIZATION
45   std::locale loc;
46 #endif
47 
48   assert(std::format(SV("{}"), MoveOnly{}) == SV("1"));
49 
50   assert(std::format(SV("{}"), m) == SV("10"));
51   assert(m.get() == 10);
52 
53   assert(std::format(SV("{}"), std::move(m)) == SV("10"));
54   assert(m.get() == 10);
55 
56 #ifndef TEST_HAS_NO_LOCALIZATION
57   assert(std::format(loc, SV("{}"), MoveOnly{}) == SV("1"));
58 
59   assert(std::format(loc, SV("{}"), m) == SV("10"));
60   assert(m.get() == 10);
61 
62   assert(std::format(loc, SV("{}"), std::move(m)) == SV("10"));
63   assert(m.get() == 10);
64 #endif
65 
66   assert(std::format_to(buffer, SV("{}"), MoveOnly{}) == &buffer[1]);
67 
68   assert(std::format_to(buffer, SV("{}"), m) == &buffer[2]);
69   assert(m.get() == 10);
70 
71   assert(std::format_to(buffer, SV("{}"), std::move(m)) == &buffer[2]);
72   assert(m.get() == 10);
73 
74 #ifndef TEST_HAS_NO_LOCALIZATION
75   assert(std::format_to(buffer, loc, SV("{}"), MoveOnly{}) == &buffer[1]);
76 
77   assert(std::format_to(buffer, loc, SV("{}"), m) == &buffer[2]);
78   assert(m.get() == 10);
79 
80   assert(std::format_to(buffer, loc, SV("{}"), std::move(m)) == &buffer[2]);
81   assert(m.get() == 10);
82 #endif
83 
84   assert(std::format_to_n(buffer, 5, SV("{}"), MoveOnly{}).out == &buffer[1]);
85 
86   assert(std::format_to_n(buffer, 5, SV("{}"), m).out == &buffer[2]);
87   assert(m.get() == 10);
88 
89   assert(std::format_to_n(buffer, 5, SV("{}"), std::move(m)).out == &buffer[2]);
90   assert(m.get() == 10);
91 
92 #ifndef TEST_HAS_NO_LOCALIZATION
93   assert(std::format_to_n(buffer, 5, loc, SV("{}"), MoveOnly{}).out == &buffer[1]);
94 
95   assert(std::format_to_n(buffer, 5, loc, SV("{}"), m).out == &buffer[2]);
96   assert(m.get() == 10);
97 
98   assert(std::format_to_n(buffer, 5, loc, SV("{}"), std::move(m)).out == &buffer[2]);
99   assert(m.get() == 10);
100 #endif
101 
102   assert(std::formatted_size(SV("{}"), MoveOnly{}) == 1);
103 
104   assert(std::formatted_size(SV("{}"), m) == 2);
105   assert(m.get() == 10);
106 
107   assert(std::formatted_size(SV("{}"), std::move(m)) == 2);
108   assert(m.get() == 10);
109 
110 #ifndef TEST_HAS_NO_LOCALIZATION
111   assert(std::formatted_size(loc, SV("{}"), MoveOnly{}) == 1);
112 
113   assert(std::formatted_size(loc, SV("{}"), m) == 2);
114   assert(m.get() == 10);
115 
116   assert(std::formatted_size(loc, SV("{}"), std::move(m)) == 2);
117   assert(m.get() == 10);
118 #endif
119 }
120 
121 int main(int, char**) {
122   test<char>();
123 
124 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
125   test<wchar_t>();
126 #endif
127 
128   return 0;
129 }
130