blob: c3ae180b32b79cdac50055563af40150111efb7f [file] [log] [blame]
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
// { dg-timeout-factor 2 }
#include <chrono>
#include <sstream>
#include <testsuite_hooks.h>
void
test_ostream()
{
using std::ostringstream;
using namespace std::chrono;
ostringstream ss;
ss << January/14 << ' ' << February/30 << ' ' << March/34;
VERIFY( ss.str() == "Jan/14 Feb/30 Mar/34 is not a valid day" );
ss.str("");
ss.imbue(std::locale(ISO_8859(15,fr_FR)));
ss << July/27;
VERIFY( ss.str() == "juil./27" );
}
void
test_format()
{
using namespace std::chrono;
std::locale loc_fr(ISO_8859(15,fr_FR));
auto s = std::format("{:%b%%%B%t%m%n %d%%%e}", month(1)/day(3));
VERIFY( s == "Jan%January\t01\n 03% 3" );
s = std::format(loc_fr, "{:L%b%%%B%t%m%n %d%%%e}", month(1)/day(3));
VERIFY( s == "janv.%janvier\t01\n 03% 3");
s = std::format("{0:%m/%d} {0}", month(10)/day(13));
VERIFY( s == "10/13 Oct/13" );
s = std::format("{0:%m/%d} {0}", month(13)/day(34));
VERIFY( s == "13/34 13 is not a valid month/34 is not a valid day" );
std::string_view specs = "aAbBcCdDeFgGhHIjmMpqQrRSTuUVwWxXyYzZ";
std::string_view my_specs = "bBdehm";
for (char c : specs)
{
char fmt[] = { '{', ':', '%', c, '}' };
try
{
auto md = month(1)/day(10);
(void) std::vformat(std::string_view(fmt, 5), std::make_format_args(md));
// The call above should throw for any conversion-spec not in my_specs:
VERIFY(my_specs.find(c) != my_specs.npos);
}
catch (const std::format_error& e)
{
VERIFY(my_specs.find(c) == my_specs.npos);
std::string_view s = e.what();
// Libstdc++-specific message:
VERIFY(s.find("format argument does not contain the information "
"required by the chrono-specs") != s.npos);
}
}
}
void
test_parse()
{
using namespace std::chrono;
std::istringstream is;
month_day md{};
is.str("jul 0123");
VERIFY( is >> parse("%B %3e", md) );
VERIFY( ! is.eof() );
VERIFY( is.peek() == '3' );
VERIFY( md == July/12 );
is.str("August 11");
VERIFY( is >> parse("%b %d", md) );
VERIFY( ! is.eof() );
VERIFY( md == August/11 );
is.clear();
is.str("012");
VERIFY( is >> parse("%m%2d", md) );
VERIFY( is.eof() );
VERIFY( md == January/2 );
is.clear();
is.str("012/311");
VERIFY( is >> parse("%4m/%d", md) );
VERIFY( ! is.eof() );
VERIFY( md == December/31 );
is.clear();
is.str("2023-7-31");
VERIFY( is >> parse("%F", md) );
VERIFY( ! is.eof() );
VERIFY( md == July/31 );
md = month(13)/day(32);
is.clear();
is.str("2023-13-1");
VERIFY( ! (is >> parse("%F", md)) );
VERIFY( is.eof() );
VERIFY( md == month(13)/day(32) );
md = month(13)/day(33);
is.clear();
is.str("2023-6-31");
VERIFY( ! (is >> parse("%F", md)) ); // June only has 30 days.
VERIFY( ! is.eof() );
VERIFY( md == month(13)/day(33) );
md = month(13)/day(34);
is.clear();
is.str("6-31");
VERIFY( ! (is >> parse("%m-%d", md)) ); // June only has 30 days in any year.
VERIFY( ! is.eof() );
VERIFY( md == month(13)/day(34) );
md = month(13)/day(35);
is.clear();
is.str("2023-2-29");
VERIFY( ! (is >> parse("%Y-%m-%e", md)) ); // Feb only has 28 days in 2023.
VERIFY( ! is.eof() );
VERIFY( md == month(13)/day(35) );
is.clear();
is.str("2-29");
VERIFY( is >> parse("%m-%d", md) ); // But Feb has 29 days in some years.
VERIFY( ! is.eof() );
VERIFY( md == February/29 );
is.clear();
is.str("2023-W32-5");
VERIFY( is >> parse("%G-W%V-%u", md) );
VERIFY( ! is.eof() );
VERIFY( md == August/11 );
}
int main()
{
test_ostream();
test_format();
test_parse();
}