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