aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
blob: cd4b116ac1c0c08ae55794ec7d5b009945eb21d5 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// { dg-additional-options "-lstdc++exp" { target { *-*-mingw* } } }
// { dg-do run { target c++23 } }
// { dg-require-fileio "" }

#include <ostream>
#include <spanstream>
#include <string_view>
#include <iostream>
#include <iomanip>
#include <testsuite_hooks.h>

void
test_print_ostream()
{
  char buf[64];
  std::spanstream os(buf);
  std::print(os, "File under '{}' for {}", 'O', "OUT OF FILE");
  std::string_view txt(os.span());
  VERIFY( txt == "File under 'O' for OUT OF FILE" );
}

void
test_println_ostream()
{
  char buf[64];
  std::spanstream os(buf);
  std::println(os, "{} Lineman was a song I once heard", "Wichita");
  std::string_view txt(os.span());
  VERIFY( txt == "Wichita Lineman was a song I once heard\n" );
}

void
test_print_raw()
{
  char buf[64];
  std::spanstream os(buf);
  std::print(os, "{}", '\xa3'); // Not a valid UTF-8 string.
  std::string_view txt(os.span());
  // Invalid UTF-8 should be written out unchanged if the ostream is not
  // connected to a tty:
  VERIFY( txt == "\xa3" );
}

void
test_print_no_padding()
{
  // [ostream.formatted.print] does not say this function "determines padding",
  // see https://gcc.gnu.org/pipermail/gcc-patches/2023-December/640680.html
  char buf[64];
  std::spanstream os(buf);
  os << std::setw(60) << std::setfill('?') << std::right; // should be ignored
  std::print(os, "{} Luftballons", 99);
  std::string_view txt(os.span());
  VERIFY( txt == "99 Luftballons" );
}

void
test_vprint_nonunicode()
{
  std::ostream out(std::cout.rdbuf());
  std::vprint_nonunicode(out, "{0} in \xc0 {0} out\n",
      std::make_format_args("garbage"));
  // { dg-output "garbage in . garbage out" }
}

struct brit_punc : std::numpunct<char>
{
  std::string do_grouping() const override { return "\3\3"; }
  char do_thousands_sep() const override { return ','; }
  std::string do_truename() const override { return "yes mate"; }
  std::string do_falsename() const override { return "nah bruv"; }
};

void
test_locale()
{
  struct stream_punc : std::numpunct<char>
  {
    std::string do_grouping() const override { return "\2\2"; }
    char do_thousands_sep() const override { return '~'; }
  };

  // The default C locale.
  std::locale cloc = std::locale::classic();
  // A custom locale using comma digit separators.
  std::locale bloc(cloc, new stream_punc);

  {
    std::ostringstream os;
    std::print(os, "{:L} {}", 12345, 6789);
    VERIFY(os.str() == "12345 6789");
  }
  {
    std::ostringstream os;
    std::print(os, "{}", 42);
    VERIFY(os.str() == "42");
  }
  {
    std::ostringstream os;
    os.imbue(bloc);
    std::print(os, "{:L} {}", 12345, 6789);
    VERIFY(os.str() == "1~23~45 6789");
  }
}

void
test_errors()
{
  // Failure to generate output is reported by setting badbit.
  std::stringstream in(std::ios::in);
  std::print(in, "{}", "nope"); // No exception here.
  VERIFY(in.bad());
#ifdef __cpp_exceptions
  in.clear();
  in.exceptions(std::ios::badbit);
  try
  {
    std::print(in, "{}", "nope"); // Should throw now.
    VERIFY(false);
  }
  catch (const std::ios::failure&)
  {
  }

  // An exception thrown when formatting the string is propagated
  // without setting badbit.
  std::ostringstream out;
  try
  {
    std::vprint_nonunicode(out, "{}", std::make_format_args());
    VERIFY(false);
  }
  catch (const std::format_error&)
  {
  }
  VERIFY(out.good());
#endif
}

int main()
{
  test_print_ostream();
  test_println_ostream();
  test_print_raw();
  test_print_no_padding();
  test_vprint_nonunicode();
  test_locale();
  test_errors();
}