xref: /llvm-project/libcxx/test/std/utilities/format/format.functions/P2418.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1606e2808SMark de Wever //===----------------------------------------------------------------------===//
2*6a54dfbfSLouis Dionne //
3606e2808SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4606e2808SMark de Wever // See https://llvm.org/LICENSE.txt for license information.
5606e2808SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6606e2808SMark de Wever //
7606e2808SMark de Wever //===----------------------------------------------------------------------===//
8606e2808SMark de Wever 
9606e2808SMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17
10520c7fbbSLouis Dionne // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
11606e2808SMark de Wever 
123d334df5SLouis Dionne // TODO FMT This test should not require std::to_chars(floating-point)
13f0fc8c48SLouis Dionne // XFAIL: availability-fp_to_chars-missing
143d334df5SLouis Dionne 
15606e2808SMark de Wever // Tests whether a move only type can be formatted. This is required by
16606e2808SMark de Wever // P2418R2 "Add support for std::generator-like types to std::format"
17606e2808SMark de Wever 
18606e2808SMark de Wever // <format>
19606e2808SMark de Wever 
20606e2808SMark de Wever #include <format>
21606e2808SMark de Wever #include <cassert>
22606e2808SMark de Wever 
23606e2808SMark de Wever #include "MoveOnly.h"
24606e2808SMark de Wever #include "make_string.h"
25606e2808SMark de Wever #include "test_macros.h"
26606e2808SMark de Wever 
27606e2808SMark de Wever #ifndef TEST_HAS_NO_LOCALIZATION
28606e2808SMark de Wever #  include <locale>
29606e2808SMark de Wever #endif
30606e2808SMark de Wever 
31606e2808SMark de Wever #define SV(S) MAKE_STRING_VIEW(CharT, S)
32606e2808SMark de Wever 
33606e2808SMark de Wever template <class CharT>
34606e2808SMark de Wever struct std::formatter<MoveOnly, CharT> : std::formatter<int, CharT> {
35a1beb0a3SMark de Wever   auto format(const MoveOnly& m, auto& ctx) const -> decltype(ctx.out()) {
36606e2808SMark de Wever     return std::formatter<int, CharT>::format(m.get(), ctx);
37606e2808SMark de Wever   }
38606e2808SMark de Wever };
39606e2808SMark de Wever 
40606e2808SMark de Wever template <class CharT>
41606e2808SMark de Wever static void test() {
42606e2808SMark de Wever   MoveOnly m{10};
43606e2808SMark de Wever   CharT buffer[10];
44606e2808SMark de Wever #ifndef TEST_HAS_NO_LOCALIZATION
45606e2808SMark de Wever   std::locale loc;
46606e2808SMark de Wever #endif
47606e2808SMark de Wever 
48606e2808SMark de Wever   assert(std::format(SV("{}"), MoveOnly{}) == SV("1"));
49606e2808SMark de Wever 
50606e2808SMark de Wever   assert(std::format(SV("{}"), m) == SV("10"));
51606e2808SMark de Wever   assert(m.get() == 10);
52606e2808SMark de Wever 
53606e2808SMark de Wever   assert(std::format(SV("{}"), std::move(m)) == SV("10"));
54606e2808SMark de Wever   assert(m.get() == 10);
55606e2808SMark de Wever 
56606e2808SMark de Wever #ifndef TEST_HAS_NO_LOCALIZATION
57606e2808SMark de Wever   assert(std::format(loc, SV("{}"), MoveOnly{}) == SV("1"));
58606e2808SMark de Wever 
59606e2808SMark de Wever   assert(std::format(loc, SV("{}"), m) == SV("10"));
60606e2808SMark de Wever   assert(m.get() == 10);
61606e2808SMark de Wever 
62606e2808SMark de Wever   assert(std::format(loc, SV("{}"), std::move(m)) == SV("10"));
63606e2808SMark de Wever   assert(m.get() == 10);
64606e2808SMark de Wever #endif
65606e2808SMark de Wever 
66606e2808SMark de Wever   assert(std::format_to(buffer, SV("{}"), MoveOnly{}) == &buffer[1]);
67606e2808SMark de Wever 
68606e2808SMark de Wever   assert(std::format_to(buffer, SV("{}"), m) == &buffer[2]);
69606e2808SMark de Wever   assert(m.get() == 10);
70606e2808SMark de Wever 
71606e2808SMark de Wever   assert(std::format_to(buffer, SV("{}"), std::move(m)) == &buffer[2]);
72606e2808SMark de Wever   assert(m.get() == 10);
73606e2808SMark de Wever 
74606e2808SMark de Wever #ifndef TEST_HAS_NO_LOCALIZATION
75606e2808SMark de Wever   assert(std::format_to(buffer, loc, SV("{}"), MoveOnly{}) == &buffer[1]);
76606e2808SMark de Wever 
77606e2808SMark de Wever   assert(std::format_to(buffer, loc, SV("{}"), m) == &buffer[2]);
78606e2808SMark de Wever   assert(m.get() == 10);
79606e2808SMark de Wever 
80606e2808SMark de Wever   assert(std::format_to(buffer, loc, SV("{}"), std::move(m)) == &buffer[2]);
81606e2808SMark de Wever   assert(m.get() == 10);
82606e2808SMark de Wever #endif
83606e2808SMark de Wever 
84606e2808SMark de Wever   assert(std::format_to_n(buffer, 5, SV("{}"), MoveOnly{}).out == &buffer[1]);
85606e2808SMark de Wever 
86606e2808SMark de Wever   assert(std::format_to_n(buffer, 5, SV("{}"), m).out == &buffer[2]);
87606e2808SMark de Wever   assert(m.get() == 10);
88606e2808SMark de Wever 
89606e2808SMark de Wever   assert(std::format_to_n(buffer, 5, SV("{}"), std::move(m)).out == &buffer[2]);
90606e2808SMark de Wever   assert(m.get() == 10);
91606e2808SMark de Wever 
92606e2808SMark de Wever #ifndef TEST_HAS_NO_LOCALIZATION
93606e2808SMark de Wever   assert(std::format_to_n(buffer, 5, loc, SV("{}"), MoveOnly{}).out == &buffer[1]);
94606e2808SMark de Wever 
95606e2808SMark de Wever   assert(std::format_to_n(buffer, 5, loc, SV("{}"), m).out == &buffer[2]);
96606e2808SMark de Wever   assert(m.get() == 10);
97606e2808SMark de Wever 
98606e2808SMark de Wever   assert(std::format_to_n(buffer, 5, loc, SV("{}"), std::move(m)).out == &buffer[2]);
99606e2808SMark de Wever   assert(m.get() == 10);
100606e2808SMark de Wever #endif
101606e2808SMark de Wever 
102606e2808SMark de Wever   assert(std::formatted_size(SV("{}"), MoveOnly{}) == 1);
103606e2808SMark de Wever 
104606e2808SMark de Wever   assert(std::formatted_size(SV("{}"), m) == 2);
105606e2808SMark de Wever   assert(m.get() == 10);
106606e2808SMark de Wever 
107606e2808SMark de Wever   assert(std::formatted_size(SV("{}"), std::move(m)) == 2);
108606e2808SMark de Wever   assert(m.get() == 10);
109606e2808SMark de Wever 
110606e2808SMark de Wever #ifndef TEST_HAS_NO_LOCALIZATION
111606e2808SMark de Wever   assert(std::formatted_size(loc, SV("{}"), MoveOnly{}) == 1);
112606e2808SMark de Wever 
113606e2808SMark de Wever   assert(std::formatted_size(loc, SV("{}"), m) == 2);
114606e2808SMark de Wever   assert(m.get() == 10);
115606e2808SMark de Wever 
116606e2808SMark de Wever   assert(std::formatted_size(loc, SV("{}"), std::move(m)) == 2);
117606e2808SMark de Wever   assert(m.get() == 10);
118606e2808SMark de Wever #endif
119606e2808SMark de Wever }
120606e2808SMark de Wever 
121606e2808SMark de Wever int main(int, char**) {
122606e2808SMark de Wever   test<char>();
123606e2808SMark de Wever 
124606e2808SMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS
125606e2808SMark de Wever   test<wchar_t>();
126606e2808SMark de Wever #endif
127606e2808SMark de Wever 
128606e2808SMark de Wever   return 0;
129606e2808SMark de Wever }
130