From: Patrick Palka Date: Thu, 28 May 2026 14:39:32 +0000 (-0400) Subject: libstdc++: Fix availability of flat_meow::operator=(initializer_list) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c345d6afd9a9b331cb679b82e89213deb8f8a69a;p=thirdparty%2Fgcc.git libstdc++: Fix availability of flat_meow::operator=(initializer_list) This assignment operator was not being brought in from the private base class causing assignments from {...} to be inefficiently treated as construction + move assignment. libstdc++-v3/ChangeLog: * include/std/flat_map (flat_map): Bring in operator= from _Flat_map_base. (flat_multimap): Likewise. * include/std/flat_set (flat_set): Bring in operator= from _Flat_set_base. (flat_multiset): Likewise. * testsuite/23_containers/flat_map/1.cc (test11): Simplify by using = {...}. (test12): New test. * testsuite/23_containers/flat_multimap/1.cc (test10): Simplify by using = {...}. (test11): New test. * testsuite/23_containers/flat_multiset/1.cc (test10): Simplify by using = {...}. (test11): New test. * testsuite/23_containers/flat_set/1.cc (test10): Simplify by using = {...}. (test11): New test. Reviewed-by: Tomasz KamiƄski Reviewed-by: Jonathan Wakely --- diff --git a/libstdc++-v3/include/std/flat_map b/libstdc++-v3/include/std/flat_map index f06c75a16f6..b82d41b4f5e 100644 --- a/libstdc++-v3/include/std/flat_map +++ b/libstdc++-v3/include/std/flat_map @@ -1275,6 +1275,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // constructors using _Impl::_Impl; + // operator=(initializer_list) + // Although this also brings in the base move/copy assignment operators, + // they will be hidden by our synthesized ones. + using _Impl::operator=; + // iterators using _Impl::begin; using _Impl::end; @@ -1628,6 +1633,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // constructors using _Impl::_Impl; + // operator=(initializer_list) + // Although this also brings in the base move/copy assignment operators, + // they will be hidden by our synthesized ones. + using _Impl::operator=; + // iterators using _Impl::begin; using _Impl::end; diff --git a/libstdc++-v3/include/std/flat_set b/libstdc++-v3/include/std/flat_set index e92559949eb..2f204cc08bf 100644 --- a/libstdc++-v3/include/std/flat_set +++ b/libstdc++-v3/include/std/flat_set @@ -967,6 +967,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // constructors using _Impl::_Impl; + // operator=(initializer_list) + // Although this also brings in the base move/copy assignment operators, + // they will be hidden by our synthesized ones. + using _Impl::operator=; + // iterators using _Impl::begin; using _Impl::end; @@ -1115,6 +1120,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // constructors using _Impl::_Impl; + // operator=(initializer_list) + // Although this also brings in the base move/copy assignment operators, + // they will be hidden by our synthesized ones. + using _Impl::operator=; + // iterators using _Impl::begin; using _Impl::end; diff --git a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc index 7e22e0366ec..0cd06b72e96 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc @@ -351,8 +351,7 @@ test11() } // Verify invariant preservation upon throwing move assignment. - source.clear(); - source.insert({{1, 100}, {2, 200}}); + source = {{1, 100}, {2, 200}}; flat_map target; target.insert({{3, 300}, {4, 400}}); try @@ -367,10 +366,8 @@ test11() } // Verify invariant preservation upon throwing swap. - source.clear(); - source.insert({{1, 100}, {2, 200}}); - target.clear(); - target.insert({{3, 300}, {4, 400}}); + source = {{1, 100}, {2, 200}}; + target = {{3, 300}, {4, 400}}; try { source.swap(target); @@ -396,6 +393,18 @@ test12() VERIFY( std::ranges::equal(m.values(), (int[]){100, 200, 300}) ); } +void +test13() +{ + // Verify usability of flat_map::operator=(initializer_list). + throwing_vector::throw_on_move = true; + std::flat_map, throwing_vector> s; + std::initializer_list> il = {{2, 1}, {3, 2}, {1, 3}}; + s = il; + VERIFY( std::ranges::equal(s.keys(), (int[]){1, 2, 3}) ); + VERIFY( std::ranges::equal(s.values(), (int[]){3, 1, 2}) ); +} + void test() { @@ -415,6 +424,7 @@ test() test11(); test11(); test12(); + test13(); } constexpr @@ -435,6 +445,7 @@ test_constexpr() #endif // test11() is non-constexpr test12(); + // test13() is non-constexpr return true; } diff --git a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc index 48688b7583e..a070c5ef091 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc @@ -304,8 +304,7 @@ test10() } // Verify invariant preservation upon throwing move assignment. - source.clear(); - source.insert({{1, 100}, {2, 200}}); + source = {{1, 100}, {2, 200}}; flat_multimap target; target.insert({{3, 300}, {4, 400}}); try @@ -320,10 +319,8 @@ test10() } // Verify invariant preservation upon throwing swap. - source.clear(); - source.insert({{1, 100}, {2, 200}}); - target.clear(); - target.insert({{3, 300}, {4, 400}}); + source = {{1, 100}, {2, 200}}; + target = {{3, 300}, {4, 400}}; try { source.swap(target); @@ -349,6 +346,18 @@ test11() VERIFY( std::ranges::equal(m.values(), (int[]){100, 200, 300}) ); } +void +test12() +{ + // Verify usability of flat_multimap::operator=(initializer_list). + throwing_vector::throw_on_move = true; + std::flat_multimap, throwing_vector> s; + std::initializer_list> il = {{2, 1}, {3, 2}, {1, 3}}; + s = il; + VERIFY( std::ranges::equal(s.keys(), (int[]){1, 2, 3}) ); + VERIFY( std::ranges::equal(s.values(), (int[]){3, 1, 2}) ); +} + void test() { @@ -366,6 +375,7 @@ test() test10(); test10(); test11(); + test12(); } constexpr @@ -382,6 +392,7 @@ test_constexpr() test09(); // test10() is non-constexpr test11(); + // test12() is non-constexpr return true; } diff --git a/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc b/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc index 4544adb5077..eea53733f6d 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc @@ -289,6 +289,8 @@ struct throwing_vector : std::vector throw std::runtime_error("move assign"); return *this; } + + using std::vector::operator=; }; void @@ -312,8 +314,7 @@ test10() } // Verify invariant preservation upon throwing move assignment. - source.clear(); - source.insert({1, 2}); + source = {1, 2}; flat_multiset target = {3, 4}; try { @@ -327,10 +328,8 @@ test10() } // Verify invariant preservation upon throwing swap. - source.clear(); - source.insert({1, 2}); - target.clear(); - target.insert({3, 4}); + source = {1, 2}; + target = {3, 4}; try { source.swap(target); @@ -355,6 +354,17 @@ test11() VERIFY( std::ranges::equal(m, (int[]){1, 2, 3}) ); } +void +test12() +{ + // Verify usability of flat_multiset::operator=(initializer_list). + throwing_vector::throw_on_move = true; + std::flat_multiset, throwing_vector> s; + std::initializer_list il = {2, 3, 1}; + s = il; + VERIFY( std::ranges::equal(s, (int[]){1, 2, 3}) ); +} + void test() { @@ -370,6 +380,7 @@ test() test09(); test10(); test11(); + test12(); } constexpr @@ -386,6 +397,7 @@ test_constexpr() test09(); // test10() is non-constexpr test11(); + // test12() is non-constexpr return true; } diff --git a/libstdc++-v3/testsuite/23_containers/flat_set/1.cc b/libstdc++-v3/testsuite/23_containers/flat_set/1.cc index ac12815bd0d..116ccdcb48d 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_set/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_set/1.cc @@ -301,6 +301,8 @@ struct throwing_vector : std::vector throw std::runtime_error("move assign"); return *this; } + + using std::vector::operator=; }; void @@ -324,8 +326,7 @@ test10() } // Verify invariant preservation upon throwing move assignment. - source.clear(); - source.insert({1, 2}); + source = {1, 2}; flat_set target = {3, 4}; try { @@ -339,10 +340,8 @@ test10() } // Verify invariant preservation upon throwing swap. - source.clear(); - source.insert({1, 2}); - target.clear(); - target.insert({3, 4}); + source = {1, 2}; + target = {3, 4}; try { source.swap(target); @@ -367,6 +366,17 @@ test11() VERIFY( std::ranges::equal(m, (int[]){1, 2, 3}) ); } +void +test12() +{ + // Verify usability of flat_set::operator=(initializer_list). + throwing_vector::throw_on_move = true; + std::flat_set, throwing_vector> s; + std::initializer_list il = {2, 3, 1}; + s = il; + VERIFY( std::ranges::equal(s, (int[]){1, 2, 3}) ); +} + void test() { @@ -382,6 +392,7 @@ test() test09(); test10(); test11(); + test12(); } constexpr @@ -398,6 +409,7 @@ test_constexpr() test09(); // test10() is non-constexpr test11(); + // test12() is non-constexpr return true; }