aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/std
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/testsuite/std')
-rw-r--r--libstdc++-v3/testsuite/std/format/functions/format.cc8
-rw-r--r--libstdc++-v3/testsuite/std/ranges/concat/1.cc74
-rw-r--r--libstdc++-v3/testsuite/std/ranges/range.cc6
-rw-r--r--libstdc++-v3/testsuite/std/time/leap_seconds/io.cc56
-rw-r--r--libstdc++-v3/testsuite/std/time/tzdb/1.cc12
-rw-r--r--libstdc++-v3/testsuite/std/time/tzdb/links.cc215
6 files changed, 371 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc
index 4499397aaf9..78cc1ab482a 100644
--- a/libstdc++-v3/testsuite/std/format/functions/format.cc
+++ b/libstdc++-v3/testsuite/std/format/functions/format.cc
@@ -248,6 +248,14 @@ test_locale()
s = std::format(cloc, "{:05L}", -1.0); // PR libstdc++/110968
VERIFY( s == "-0001" );
+ // PR libstdc++/114863 grouping applied to nan and inf
+ double inf = std::numeric_limits<double>::infinity();
+ s = std::format(eloc, "{0:Le} {0:Lf} {0:Lg}", -inf);
+ VERIFY( s == "-inf -inf -inf" );
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ s = std::format(eloc, "{0:Le} {0:Lf} {0:Lg}", -nan);
+ VERIFY( s == "-nan -nan -nan" );
+
// Restore
std::locale::global(cloc);
}
diff --git a/libstdc++-v3/testsuite/std/ranges/concat/1.cc b/libstdc++-v3/testsuite/std/ranges/concat/1.cc
new file mode 100644
index 00000000000..6ffe28ece51
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/concat/1.cc
@@ -0,0 +1,74 @@
+// { dg-do run { target c++26 } }
+// { dg-add-options no_pch }
+
+#include <ranges>
+
+#if __cpp_lib_ranges_concat != 202403L
+# error "Feature-test macro __cpp_lib_ranges_concat has wrong value in <ranges>"
+#endif
+
+#include <algorithm>
+#include <vector>
+#include <array>
+#include <utility>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+
+namespace ranges = std::ranges;
+namespace views = std::views;
+
+constexpr bool
+test01()
+{
+ std::vector<int> v1{1, 2, 3}, v2{4, 5}, v3{};
+ std::array a{6, 7, 8};
+ auto s = views::single(9);
+
+ auto v = views::concat(v1, v2, v3, a, s);
+ VERIFY( ranges::size(v) == 9 );
+ VERIFY( ranges::size(std::as_const(v)) == 9 );
+ VERIFY( ranges::equal(v, views::iota(1, 10)) );
+ VERIFY( ranges::equal(v | views::reverse,
+ views::iota(1, 10) | views::reverse) );
+
+ auto it0 = v.begin();
+ auto cit = std::as_const(v).begin();
+ VERIFY( it0 == it0 );
+ VERIFY( cit == cit );
+ VERIFY( it0 == cit );
+ for (int i = 0; i < 10; i++)
+ {
+ VERIFY( it0 + i - it0 == i );
+ VERIFY( it0 + i - (it0 + 1) == i - 1 );
+ VERIFY( it0 + i - (it0 + 3) == i - 3 );
+ VERIFY( it0 + i - (it0 + 5) == i - 5 );
+ VERIFY( it0 + i - i + i == it0 + i );
+ VERIFY( it0 + i - (it0 + i) == 0 );
+ }
+ VERIFY( std::default_sentinel - it0 == 9 );
+ VERIFY( it0 + 9 == std::default_sentinel );
+
+ auto it5 = it0+5;
+ ranges::iter_swap(it0, it5);
+ VERIFY( *it0 == 6 && *it5 == 1 );
+ ranges::iter_swap(it0, it5);
+ *it0 = ranges::iter_move(it0);
+ return true;
+}
+
+void
+test02()
+{
+ int x[] = {1, 2, 3, 4, 5};
+ __gnu_test::test_input_range rx(x);
+ auto v = views::concat(views::single(0), rx, views::empty<int>);
+ static_assert(!ranges::forward_range<decltype(v)>);
+ VERIFY( ranges::equal(v | views::drop(1), x) );
+}
+
+int
+main()
+{
+ static_assert(test01());
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/range.cc b/libstdc++-v3/testsuite/std/ranges/range.cc
index 18435659137..760f6ffacfd 100644
--- a/libstdc++-v3/testsuite/std/ranges/range.cc
+++ b/libstdc++-v3/testsuite/std/ranges/range.cc
@@ -83,3 +83,9 @@ static_assert( same_as<std::ranges::range_rvalue_reference_t<I>,
char&&> );
static_assert( same_as<std::ranges::range_rvalue_reference_t<O>,
WritableObject<char>> );
+
+// LWG 3860. range_common_reference_t is missing
+static_assert( same_as<std::ranges::range_common_reference_t<C>,
+ char&> );
+static_assert( same_as<std::ranges::range_common_reference_t<I>,
+ char&> );
diff --git a/libstdc++-v3/testsuite/std/time/leap_seconds/io.cc b/libstdc++-v3/testsuite/std/time/leap_seconds/io.cc
new file mode 100644
index 00000000000..511fafdd1a0
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/time/leap_seconds/io.cc
@@ -0,0 +1,56 @@
+// { dg-do run { target c++20 } }
+// { dg-require-effective-target tzdb }
+// { dg-require-effective-target cxx11_abi }
+
+#include <chrono>
+#include <sstream>
+#include <format>
+#include <testsuite_hooks.h>
+
+void
+test_output()
+{
+ using namespace std::chrono;
+
+ std::ostringstream out;
+ out << '\n';
+
+ for (auto& l : get_tzdb().leap_seconds)
+ if (l <= sys_days{2018y/March/17d})
+ out << l.date() << ": " << l.value() << '\n';
+
+ VERIFY( out.str() == R"(
+1972-07-01 00:00:00: 1s
+1973-01-01 00:00:00: 1s
+1974-01-01 00:00:00: 1s
+1975-01-01 00:00:00: 1s
+1976-01-01 00:00:00: 1s
+1977-01-01 00:00:00: 1s
+1978-01-01 00:00:00: 1s
+1979-01-01 00:00:00: 1s
+1980-01-01 00:00:00: 1s
+1981-07-01 00:00:00: 1s
+1982-07-01 00:00:00: 1s
+1983-07-01 00:00:00: 1s
+1985-07-01 00:00:00: 1s
+1988-01-01 00:00:00: 1s
+1990-01-01 00:00:00: 1s
+1991-01-01 00:00:00: 1s
+1992-07-01 00:00:00: 1s
+1993-07-01 00:00:00: 1s
+1994-07-01 00:00:00: 1s
+1996-01-01 00:00:00: 1s
+1997-07-01 00:00:00: 1s
+1999-01-01 00:00:00: 1s
+2006-01-01 00:00:00: 1s
+2009-01-01 00:00:00: 1s
+2012-07-01 00:00:00: 1s
+2015-07-01 00:00:00: 1s
+2017-01-01 00:00:00: 1s
+)" );
+}
+
+int main()
+{
+ test_output();
+}
diff --git a/libstdc++-v3/testsuite/std/time/tzdb/1.cc b/libstdc++-v3/testsuite/std/time/tzdb/1.cc
index cf9df952577..796f3a8b425 100644
--- a/libstdc++-v3/testsuite/std/time/tzdb/1.cc
+++ b/libstdc++-v3/testsuite/std/time/tzdb/1.cc
@@ -47,6 +47,18 @@ test_locate()
VERIFY( db.locate_zone(db.current_zone()->name()) == db.current_zone() );
}
+void
+test_all_zones()
+{
+ const tzdb& db = get_tzdb();
+
+ for (const auto& zone : db.zones)
+ VERIFY( locate_zone(zone.name())->name() == zone.name() );
+
+ for (const auto& link : db.links)
+ VERIFY( locate_zone(link.name()) == locate_zone(link.target()) );
+}
+
int main()
{
test_version();
diff --git a/libstdc++-v3/testsuite/std/time/tzdb/links.cc b/libstdc++-v3/testsuite/std/time/tzdb/links.cc
new file mode 100644
index 00000000000..0ba214846c6
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/time/tzdb/links.cc
@@ -0,0 +1,215 @@
+// { dg-do run { target c++20 } }
+// { dg-require-effective-target tzdb }
+// { dg-require-effective-target cxx11_abi }
+// { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } }
+
+#include <chrono>
+#include <fstream>
+#include <testsuite_hooks.h>
+
+static bool override_used = false;
+
+namespace __gnu_cxx
+{
+ const char* zoneinfo_dir_override() {
+ override_used = true;
+ return "./";
+ }
+}
+
+using namespace std::chrono;
+
+void
+test_link_chains()
+{
+ std::ofstream("tzdata.zi") << R"(# version test_1
+Link Greenwich G_M_T
+Link Etc/GMT Greenwich
+Zone Etc/GMT 0 - GMT
+Zone A_Zone 1 - ZON
+Link A_Zone L1
+Link L1 L2
+Link L2 L3
+Link L3 L4
+Link L4 L5
+Link L5 L6
+Link L3 L7
+)";
+
+ const auto& db = reload_tzdb();
+ VERIFY( override_used ); // If this fails then XFAIL for the target.
+ VERIFY( db.version == "test_1" );
+
+ // Simple case of a link with a zone as its target.
+ VERIFY( locate_zone("Greenwich")->name() == "Etc/GMT" );
+ // Chains of links, where the target may be another link.
+ VERIFY( locate_zone("G_M_T")->name() == "Etc/GMT" );
+ VERIFY( locate_zone("L1")->name() == "A_Zone" );
+ VERIFY( locate_zone("L2")->name() == "A_Zone" );
+ VERIFY( locate_zone("L3")->name() == "A_Zone" );
+ VERIFY( locate_zone("L4")->name() == "A_Zone" );
+ VERIFY( locate_zone("L5")->name() == "A_Zone" );
+ VERIFY( locate_zone("L6")->name() == "A_Zone" );
+ VERIFY( locate_zone("L7")->name() == "A_Zone" );
+}
+
+void
+test_bad_links()
+{
+ // The zic(8) man page says
+ // > the behavior is unspecified if multiple zone or link lines
+ // > define the same name"
+ // For libstdc++ the expected behaviour is described and tested below.
+ std::ofstream("tzdata.zi") << R"(# version test_2
+Zone A_Zone 1 - ZA
+Zone B_Zone 2 - ZB
+Link A_Zone B_Zone
+Link B_Zone C_Link
+Link C_Link D_Link
+Link D_Link E_Link
+)";
+
+ const auto& db2 = reload_tzdb();
+ VERIFY( override_used ); // If this fails then XFAIL for the target.
+ VERIFY( db2.version == "test_2" );
+
+ // The standard requires locate_zone(name) to search for a zone first,
+ // so this finds the zone B_Zone, not the link that points to zone A_Zone.
+ VERIFY( locate_zone("B_Zone")->name() == "B_Zone" );
+ // And libstdc++ does the same at every step when following chained links:
+ VERIFY( locate_zone("C_Link")->name() == "B_Zone" );
+ VERIFY( locate_zone("D_Link")->name() == "B_Zone" );
+ VERIFY( locate_zone("E_Link")->name() == "B_Zone" );
+
+ // The zic(8) man page says
+ // > the behavior is unspecified if a chain of one or more links
+ // > does not terminate in a Zone name.
+ // For libstdc++ we throw std::runtime_error if locate_zone finds an
+ // unterminated chain, including the case of a chain that includes a cycle.
+ std::ofstream("tzdata.zi") << R"(# version test_3
+Zone A_Zone 1 - ZON
+Link A_Zone GoodLink
+Link No_Zone BadLink
+Link LinkSelf LinkSelf
+Link LinkSelf Link1
+Link Link1 Link2
+Link Cycle2_A Cycle2_B
+Link Cycle2_B Cycle2_A
+Link Cycle3_A Cycle3_B
+Link Cycle3_B Cycle3_C
+Link Cycle3_C Cycle3_A
+Link Cycle3_C Cycle3_D
+Link Cycle4_A Cycle4_B
+Link Cycle4_B Cycle4_C
+Link Cycle4_C Cycle4_D
+Link Cycle4_D Cycle4_A
+)";
+
+ const auto& db3 = reload_tzdb();
+ VERIFY( db3.version == "test_3" );
+
+ // Lookup for valid links should still work even if other links are bad.
+ VERIFY( locate_zone("GoodLink")->name() == "A_Zone" );
+
+#if __cpp_exceptions
+ try {
+ locate_zone("BadLink");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("cannot locate zone: BadLink") );
+ }
+
+ // LinkSelf forms a link cycle with itself.
+ try {
+ locate_zone("LinkSelf");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: LinkSelf") );
+ }
+
+ // Any chain that leads to LinkSelf reaches a cycle.
+ try {
+ locate_zone("Link1");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Link1") );
+ }
+
+ try {
+ locate_zone("Link2");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Link2") );
+ }
+
+ // Cycle2_A and Cycle2_B form a cycle of length two.
+ try {
+ locate_zone("Cycle2_A");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Cycle2_A") );
+ }
+
+ try {
+ locate_zone("Cycle2_B");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Cycle2_B") );
+ }
+
+ // Cycle3_A, Cycle3_B and Cycle3_C form a cycle of length three.
+ try {
+ locate_zone("Cycle3_A");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Cycle3_A") );
+ }
+
+ try {
+ locate_zone("Cycle3_B");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Cycle3_B") );
+ }
+
+ try {
+ locate_zone("Cycle3_C");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Cycle3_C") );
+ }
+
+ // Cycle3_D isn't part of the cycle, but it leads to it.
+ try {
+ locate_zone("Cycle3_D");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Cycle3_D") );
+ }
+
+ // Cycle4_* links form a cycle of length four.
+ try {
+ locate_zone("Cycle4_A");
+ VERIFY( false );
+ } catch (const std::runtime_error& e) {
+ std::string_view what(e.what());
+ VERIFY( what.ends_with("link cycle: Cycle4_A") );
+ }
+#endif
+}
+
+int main()
+{
+ test_link_chains();
+ test_bad_links();
+}