// { dg-options "-std=gnu++20" } // { dg-do run { target c++20 } } #include #include template bool equals(std::basic_format_arg fmt_arg, T expected) { return std::visit_format_arg([=](auto arg_val) { if constexpr (std::is_same_v) return arg_val == expected; else return false; }, fmt_arg); } void test_empty() { std::format_args args = std::make_format_args(); VERIFY(!args.get(0)); VERIFY(!args.get(1)); VERIFY(!args.get((std::size_t)-1)); VERIFY(equals(args.get(0), std::monostate{})); std::format_args cargs = std::make_format_args(); VERIFY(!cargs.get(0)); VERIFY(equals(cargs.get(0), std::monostate{})); std::wformat_args wargs = std::make_wformat_args(); VERIFY(!wargs.get(0)); VERIFY(equals(wargs.get(0), std::monostate{})); } enum E { ByGum }; template<> struct std::formatter : std::formatter { using std::formatter::parse; std::format_context::iterator format(E e, std::format_context& fc) const { return std::formatter::format((int)e, fc); } }; void test_args() { bool b = false; int i = 1; char c = '2'; double d = 3.4; auto store = std::make_format_args(b, i, c, d); std::format_args args = store; VERIFY(equals(args.get(0), false)); VERIFY(equals(args.get(1), 1)); VERIFY(equals(args.get(2), '2')); VERIFY(equals(args.get(3), 3.4)); VERIFY(!args.get(4)); long l = 5L; unsigned long long ull = 6ULL; float f = 7.8f; auto cstore = std::make_format_args(l, ull, f); std::format_args cargs = cstore; if constexpr (sizeof(long) == sizeof(int)) VERIFY(equals(cargs.get(0), 5)); else VERIFY(equals(cargs.get(0), 5LL)); VERIFY(equals(cargs.get(1), 6ULL)); VERIFY(equals(cargs.get(2), 7.8f)); VERIFY(!cargs.get(3)); std::string s = "tenfour"; VERIFY(equals(std::format_args(std::make_format_args(s)).get(0), std::string_view("tenfour"))); char nine = '9'; wchar_t ten = L'X'; // This needs to be on the stack so that testing pointer equality works. wchar_t eleven[] = L"eleven"; long double twelve13 = 12.13L; std::wstring tenfour = L"tenfour"; auto wstore = std::make_wformat_args(nine, ten, eleven, twelve13, tenfour); std::wformat_args wargs = wstore; VERIFY(equals(wargs.get(0), static_cast('9'))); VERIFY(equals(wargs.get(1), L'X')); VERIFY(equals(wargs.get(2), static_cast(eleven))); VERIFY(equals(wargs.get(3), 12.13L)); VERIFY(equals(wargs.get(4), std::wstring_view(tenfour))); VERIFY(!wargs.get(5)); std::nullptr_t null; E eebygum = E::ByGum; auto another_store = std::make_format_args(null, eebygum); args = another_store; VERIFY(equals(args.get(0), static_cast(nullptr))); using handle = std::basic_format_arg::handle; auto is_handle = [](T) { return std::is_same_v; }; VERIFY(std::visit_format_arg(is_handle, args.get(1))); } int main() { test_empty(); test_args(); }