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