summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/std/format/arguments/args.cc
blob: ae2eab6d5600762d87a983c95e7e24882b23cb92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// { dg-options "-std=gnu++20" }
// { dg-do run { target c++20 } }

#include <format>
#include <testsuite_hooks.h>

template<typename Ctx, typename T>
bool equals(std::basic_format_arg<Ctx> fmt_arg, T expected) {
  return std::visit_format_arg([=](auto arg_val) {
    if constexpr (std::is_same_v<decltype(arg_val), T>)
      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<std::format_context>();
  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<E> : std::formatter<int>
{
  using std::formatter<int>::parse;

  std::format_context::iterator
  format(E e, std::format_context& fc) const
  { return std::formatter<int>::format((int)e, fc); }
};

void
test_args()
{
  auto store = std::make_format_args(false, 1, '2', 3.4);
  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));

  auto cstore = std::make_format_args<std::format_context>(5L, 6ULL, 7.8f);
  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));

  VERIFY(equals(std::format_args(std::make_format_args(std::string("tenfour"))).get(0), std::string_view("tenfour")));

  // This needs to be on the stack so that testing pointer equality works.
  wchar_t eleven[] = L"eleven";
  // This needs to be on the stack so that the wstring_view doesn't dangle.
  std::wstring tenfour = L"tenfour";

  auto wstore = std::make_wformat_args('9', L'X', eleven, 12.13L, tenfour);
  std::wformat_args wargs = wstore;
  VERIFY(equals(wargs.get(0), static_cast<wchar_t>('9')));
  VERIFY(equals(wargs.get(1), L'X'));
  VERIFY(equals(wargs.get(2), static_cast<const wchar_t*>(eleven)));
  VERIFY(equals(wargs.get(3), 12.13L));
  VERIFY(equals(wargs.get(4), std::wstring_view(tenfour)));
  VERIFY(!wargs.get(5));

  auto another_store = std::make_format_args(nullptr, E::ByGum);
  args = another_store;
  VERIFY(equals(args.get(0), static_cast<const void*>(nullptr)));
  using handle = std::basic_format_arg<std::format_context>::handle;
  auto is_handle = []<typename T>(T) { return std::is_same_v<T, handle>; };
  VERIFY(std::visit_format_arg(is_handle, args.get(1)));
}

int main()
{
  test_empty();
  test_args();
}