130 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME11 12// TODO FMT This test should not require std::to_chars(floating-point)13// XFAIL: availability-fp_to_chars-missing14 15// Tests whether a move only type can be formatted. This is required by16// 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_LOCALIZATION28# include <locale>29#endif30 31#define SV(S) MAKE_STRING_VIEW(CharT, S)32 33template <class CharT>34struct 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 40template <class CharT>41static void test() {42 MoveOnly m{10};43 CharT buffer[10];44#ifndef TEST_HAS_NO_LOCALIZATION45 std::locale loc;46#endif47 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_LOCALIZATION57 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#endif65 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_LOCALIZATION75 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#endif83 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_LOCALIZATION93 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#endif101 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_LOCALIZATION111 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#endif119}120 121int main(int, char**) {122 test<char>();123 124#ifndef TEST_HAS_NO_WIDE_CHARACTERS125 test<wchar_t>();126#endif127 128 return 0;129}130