aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2016-10-04 14:05:48 +0000
committerMartin Jambor <mjambor@suse.cz>2016-10-04 14:05:48 +0000
commita5ad06150ad26c32138621126e4c365abe3e6332 (patch)
treeea68704f07efd32ea3189869ac807f682f7a7e98 /libstdc++-v3
parent37ba4e6d655bfdb78f1c4cd481801d6769b74898 (diff)
Merged trunk revision 240707 into the hsa branch
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/hsa@240745 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog459
-rw-r--r--libstdc++-v3/Makefile.in1
-rw-r--r--libstdc++-v3/acinclude.m415
-rw-r--r--libstdc++-v3/config.h.in2
-rw-r--r--libstdc++-v3/config/cpu/m68k/atomicity.h3
-rwxr-xr-xlibstdc++-v3/configure40
-rw-r--r--libstdc++-v3/configure.ac7
-rw-r--r--libstdc++-v3/configure.host4
-rw-r--r--libstdc++-v3/doc/Makefile.in1
-rw-r--r--libstdc++-v3/doc/html/manual/bugs.html4
-rw-r--r--libstdc++-v3/doc/html/manual/profile_mode_devel.html2
-rw-r--r--libstdc++-v3/doc/html/manual/status.html20
-rw-r--r--libstdc++-v3/doc/xml/manual/intro.xml7
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2017.xml18
-rw-r--r--libstdc++-v3/include/Makefile.am4
-rw-r--r--libstdc++-v3/include/Makefile.in5
-rw-r--r--libstdc++-v3/include/bits/basic_string.h26
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc2
-rw-r--r--libstdc++-v3/include/bits/hashtable.h141
-rw-r--r--libstdc++-v3/include/bits/node_handle.h330
-rw-r--r--libstdc++-v3/include/bits/range_access.h4
-rw-r--r--libstdc++-v3/include/bits/std_abs.h107
-rw-r--r--libstdc++-v3/include/bits/stl_construct.h45
-rw-r--r--libstdc++-v3/include/bits/stl_map.h86
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h85
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h84
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h246
-rw-r--r--libstdc++-v3/include/bits/stl_set.h84
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h197
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h185
-rw-r--r--libstdc++-v3/include/bits/unordered_map.h184
-rw-r--r--libstdc++-v3/include/bits/unordered_set.h178
-rw-r--r--libstdc++-v3/include/bits/uses_allocator.h11
-rw-r--r--libstdc++-v3/include/c_global/cmath72
-rw-r--r--libstdc++-v3/include/c_global/cstdio2
-rw-r--r--libstdc++-v3/include/c_global/cstdlib28
-rw-r--r--libstdc++-v3/include/c_std/cstdio2
-rw-r--r--libstdc++-v3/include/debug/bitset15
-rw-r--r--libstdc++-v3/include/debug/map.h46
-rw-r--r--libstdc++-v3/include/debug/multimap.h34
-rw-r--r--libstdc++-v3/include/debug/multiset.h34
-rw-r--r--libstdc++-v3/include/debug/safe_base.h13
-rw-r--r--libstdc++-v3/include/debug/safe_container.h7
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.h2
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.tcc1
-rw-r--r--libstdc++-v3/include/debug/safe_unordered_base.h17
-rw-r--r--libstdc++-v3/include/debug/set.h45
-rw-r--r--libstdc++-v3/include/debug/unordered_map94
-rw-r--r--libstdc++-v3/include/debug/unordered_set93
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_fwd.h2
-rw-r--r--libstdc++-v3/include/experimental/numeric22
-rw-r--r--libstdc++-v3/include/ext/rc_string_base.h5
-rw-r--r--libstdc++-v3/include/parallel/algo.h2167
-rw-r--r--libstdc++-v3/include/std/chrono2
-rw-r--r--libstdc++-v3/include/std/functional3
-rw-r--r--libstdc++-v3/include/std/optional86
-rw-r--r--libstdc++-v3/include/std/tuple96
-rw-r--r--libstdc++-v3/include/std/type_traits7
-rw-r--r--libstdc++-v3/include/std/variant79
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in1
-rw-r--r--libstdc++-v3/libsupc++/hash_bytes.cc2
-rw-r--r--libstdc++-v3/po/Makefile.in1
-rw-r--r--libstdc++-v3/python/Makefile.in1
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py92
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/xmethods.py23
-rw-r--r--libstdc++-v3/src/Makefile.am4
-rw-r--r--libstdc++-v3/src/Makefile.in5
-rw-r--r--libstdc++-v3/src/c++11/Makefile.in1
-rw-r--r--libstdc++-v3/src/c++11/debug.cc105
-rw-r--r--libstdc++-v3/src/c++98/Makefile.in1
-rw-r--r--libstdc++-v3/src/filesystem/Makefile.in1
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc30
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/searchers.cc6
-rw-r--r--libstdc++-v3/testsuite/20_util/optional/77288.cc405
-rw-r--r--libstdc++-v3/testsuite/20_util/optional/assignment/7.cc31
-rw-r--r--libstdc++-v3/testsuite/20_util/optional/cons/77727.cc51
-rw-r--r--libstdc++-v3/testsuite/20_util/optional/cons/value.cc12
-rw-r--r--libstdc++-v3/testsuite/20_util/optional/observers/6.cc39
-rw-r--r--libstdc++-v3/testsuite/20_util/pair/traits.cc76
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc183
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc244
-rw-r--r--libstdc++-v3/testsuite/20_util/variant/compile.cc62
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/56166.cc93
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/operations/compare/char/1.cc4
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/modifiers/extract.cc147
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/modifiers/merge.cc147
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/modifiers/extract.cc141
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/modifiers/merge.cc119
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/modifiers/extract.cc129
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/modifiers/merge.cc117
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/modifiers/extract.cc138
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/modifiers/merge.cc143
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/extract.cc148
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/merge.cc140
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/extract.cc138
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/merge.cc123
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/extract.cc128
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/merge.cc121
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/extract.cc140
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/merge.cc140
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc42
-rw-r--r--libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc39
-rw-r--r--libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192_neg.cc29
-rw-r--r--libstdc++-v3/testsuite/26_numerics/headers/cmath/hypot.cc138
-rw-r--r--libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc34
-rw-r--r--libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc29
-rw-r--r--libstdc++-v3/testsuite/27_io/headers/cstdio/functions_neg.cc25
-rw-r--r--libstdc++-v3/testsuite/Makefile.in1
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc111
-rw-r--r--libstdc++-v3/testsuite/experimental/numeric/77801.cc22
-rw-r--r--libstdc++-v3/testsuite/experimental/numeric/gcd.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/numeric/lcm.cc3
-rw-r--r--libstdc++-v3/testsuite/ext/vstring/modifiers/clear/56166.cc96
-rw-r--r--libstdc++-v3/testsuite/lib/gdb-test.exp6
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc108
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_fs.h21
118 files changed, 8298 insertions, 1607 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 70ff276beb4..be41539547d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,462 @@
+2016-09-30 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/77795
+ * acinclude.m4 (GLIBCXX_CHECK_STDIO_PROTO): Use -std=gnu++11 to check
+ for gets.
+ * config.h.in: Regenerate.
+ * configure: Regenerate.
+ * include/c_global/cstdio [!_GLIBCXX_HAVE_GETS] (gets): Only declare
+ for C++98 and C++11.
+ * include/c_std/cstdio [!_GLIBCXX_HAVE_GETS] (gets): Likewise.
+ * testsuite/27_io/headers/cstdio/functions_neg.cc: New test.
+
+ * doc/xml/manual/intro.xml: Document LWG 2192 changes.
+ * doc/html/*: Regenerate.
+ * include/Makefile.am: Add bits/std_abs.h.
+ * include/Makefile.in: Regenerate.
+ * include/bits/std_abs.h: New header defining all required overloads
+ of std::abs in one place (LWG 2294).
+ * include/c_global/cmath (abs(double), abs(float), abs(long double)):
+ Move to bits/std_abs.h.
+ (abs<_Tp>(_Tp)): Remove.
+ * include/c_global/cstdlib (abs(long), abs(long long), abs(__int<N>)):
+ Move to bits/std_abs.h.
+ * testsuite/26_numerics/headers/cmath/dr2192.cc: New test.
+ * testsuite/26_numerics/headers/cmath/dr2192_neg.cc: New test.
+ * testsuite/26_numerics/headers/cstdlib/dr2192.cc: New test.
+ * testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc: New test.
+
+ PR libstdc++/77801
+ * include/experimental/numeric: Include <numeric>.
+ (__abs): Define.
+ (gcd, lcm): Use __abs instead of std::abs.
+ * testsuite/experimental/numeric/77801.cc: New test.
+ * testsuite/experimental/numeric/gcd.cc: Test unsigned inputs.
+ * testsuite/experimental/numeric/lcm.cc: Likewise.
+
+2016-09-29 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Make optional::reset noexcept, make optional::value
+ work in constant expressions.
+ * include/std/optional (_M_get): Make constexpr.
+ (reset): Make noexcept.
+ * testsuite/20_util/optional/assignment/7.cc: New.
+ * testsuite/20_util/optional/observers/6.cc: New.
+
+2016-09-29 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/c_global/cmath (hypot, __hypot3): Move C++17 overloads
+ outside _GLIBCXX_USE_C99_MATH_TR1 condition.
+
+2016-09-29 Alan Modra <amodra@gmail.com>
+
+ * configure.ac (LONG_DOUBLE_COMPAT_FLAGS): New ACSUBST.
+ * src/Makefile.am (compatibility-ldbl.o, compatibility-ldbl.lo):
+ Use LONG_DOUBLE_COMPAT_FLAGS.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * doc/Makefile.in: Regenerate.
+ * include/Makefile.in: Regenerate.
+ * libsupc++/Makefile.in: Regenerate.
+ * po/Makefile.in: Regenerate.
+ * python/Makefile.in: Regenerate.
+ * src/Makefile.in: Regenerate.
+ * src/c++11/Makefile.in: Regenerate.
+ * src/c++98/Makefile.in: Regenerate.
+ * src/filesystem/Makefile.in: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+
+2016-09-28 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/chrono (system_clock): Fix typo in comment.
+
+ * include/experimental/bits/fs_fwd.h (file_time_type): Simplify
+ definition.
+ * src/filesystem/ops.cc (file_time): Take error_code parameter and
+ check for overflow.
+ (do_copy_file, last_write_time): Pass error_code in file_time calls.
+ * testsuite/experimental/filesystem/operations/last_write_time.cc:
+ New.
+ * testsuite/util/testsuite_fs.h (scoped_file): Define RAII helper.
+
+ PR libstdc++/77686
+ * include/std/functional (_Any_data): Add may_alias attribute.
+
+2016-09-27 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/xml/manual/status_cxx2017.xml: Update status.
+ * doc/html/*: Regenerate.
+ * include/std/functional (__cpp_lib_boyer_moore_searcher): Define.
+ * testsuite/20_util/function_objects/searchers.cc: Test feature macro.
+
+ * doc/xml/manual/status_cxx2017.xml: Update status.
+ * include/c_global/cmath (hypot): Add three-dimensional overloads.
+ * testsuite/26_numerics/headers/cmath/hypot.cc: New.
+
+2016-09-26 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/77727
+ * include/std/optional (optional(const optional<_Up>&)):
+ Default-initialize the base and use emplace.
+ (optional(optional<_Up>&&)): Likewise.
+ * testsuite/20_util/optional/cons/77727.cc: New.
+
+2016-09-26 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/debug/safe_base.h
+ (_Safe_iterator_base::_M_detach_single): Make public.
+
+2016-09-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/range_access.h (__cpp_lib_array_constexpr): Do not
+ redefine macro defined in <bits/stl_iterator.h>.
+
+ * include/bits/stl_map.h (map::extract(const_iterator)): Assert that
+ iterator is not past-the-end.
+ * include/bits/stl_multimap.h (multimap::extract(const_iterator)):
+ Likewise.
+ * include/bits/stl_multiset.h (multiset::extract(const_iterator)):
+ Likewise.
+ * include/bits/stl_set.h (set::extract(const_iterator)): Likewise.
+ * include/bits/unordered_map.h (unordered_map::extract(const_iterator))
+ (unordered_multimap::extract(const_iterator)): Likewise.
+ * include/bits/unordered_set.h (unordered_set::extract(const_iterator))
+ (unordered_multiset::extract(const_iterator)): Likewise.
+
+2016-09-26 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/77717
+ * testsuite/21_strings/basic_string_view/operations/compare/char/1.cc:
+ Fix an out-of-bounds access.
+
+2016-09-26 Marek Polacek <polacek@redhat.com>
+
+ PR c/7652
+ * libsupc++/hash_bytes.cc: Add [[gnu::fallthrough]].
+
+2016-09-25 François Dumont <fdumont@gcc.gnu.org>
+
+ * src/c++11/debug.cc: Include debug/vector. Include cctype. Remove
+ functional.
+ (get_safe_base_mutex): Get mutex based on address lowest non nil bits.
+ * testsuite/23_containers/vector/debug/mutex_association.cc: New.
+
+ * include/debug/bitset (bitset::reference::reference(const _Base_ref&,
+ bitset*)): Remove __unused__ attribute.
+ * include/debug/safe_base.h (_Safe_iterator_base): Make
+ _Safe_sequence_base a friend.
+ (_Safe_iterator_base::_M_attach): Make protected.
+ (_Safe_iterator_base::_M_attach_single): Likewise.
+ (_Safe_iterator_base::_M_detach): Likewise.
+ (_Safe_iterator_base::_M_detach_single): Likewise.
+ (_Safe_sequence_base): Make _Safe_iterator_base a friend.
+ (_Safe_sequence_base::_Safe_sequence_base(_Safe_sequence_base&&)): New.
+ (_Safe_sequence_base::_M_swap): Make protected.
+ (_Safe_sequence_base::_M_attach): Make private.
+ (_Safe_sequence_base::_M_attach_single): Likewise.
+ (_Safe_sequence_base::_M_detach): Likewise.
+ (_Safe_sequence_base::_M_detach_single): Likewise.
+ * include/debug/safe_container.h
+ (_Safe_container::_Safe_container(_Safe_container&&)): Make default.
+ * include/debug/safe_iterator.h
+ (_Safe_iterator::operator++()): Name __scoped_lock instance.
+ * include/debug/safe_iterator.tcc: Remove trailing line.
+ * include/debug/safe_unordered_base.h
+ (_Safe_local_iterator_base::_M_attach): Make protected.
+ (_Safe_local_iterator_base::_M_attach_single): Likewise.
+ (_Safe_local_iterator_base::_M_detach): Likewise.
+ (_Safe_local_iterator_base::_M_detach_single): Likewise.
+ (_Safe_unordered_container_base): Make _Safe_local_iterator_base friend.
+ (_Safe_unordered_container_base::_M_attach_local): Make private.
+ (_Safe_unordered_container_base::_M_attach_local_single): Likewise.
+ (_Safe_unordered_container_base::_M_detach_local): Likewise.
+ (_Safe_unordered_container_base::_M_detach_local_single): Likewise.
+
+ * include/parallel/algo.h: Generalize usage of std::__iterator_category.
+ Adjust whitespaces.
+
+2016-09-23 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/56166
+ PR libstdc++/77582
+ * include/bits/basic_string.h (basic_string::clear()): Drop reference
+ and use empty rep.
+ * include/ext/rc_string_base.h (__rc_string_base::_M_clear()):
+ Likewise.
+ * testsuite/21_strings/basic_string/56166.cc: New.
+ * testsuite/ext/vstring/modifiers/clear/56166.cc: New.
+
+ * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI]
+ (basic_string::erase(size_type, size_type)): Add fast path for
+ truncating the string, by calling _M_set_length directly.
+ (basic_string::erase(__const_iterator, __const_iterator)): Likewise.
+ * include/bits/basic_string.tcc [_GLIBCXX_USE_CXX11_ABI]
+ (basic_string::resize(size_type, _CharT)): Likewise.
+
+2016-09-22 Jason Merrill <jason@redhat.com>
+
+ * configure.ac: Define HAVE_MEMALIGN for newlib.
+
+2015-09-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config/cpu/m68k/atomicity.h: Adjust comment.
+ * acinclude.m4 (GLIBCXX_ENABLE_ATOMIC_BUILTINS): Honor
+ explicit atomicity_dir setup via configure.host.
+ * configure.host (rtems-*): Set atomicity_dir.
+ * configure: Regenerate.
+
+2016-09-22 Jonathan Wakely <jwakely@redhat.com>
+
+ Implement C++17 node extraction and insertion (P0083R5)
+ * doc/xml/manual/status_cxx2017.xml: Document status.
+ * doc/html/*: Regenerate.
+ * include/Makefile.am: Add bits/node_handle.h and reorder.
+ * include/Makefile.in: Regenerate.
+ * include/bits/hashtable.h (_Hashtable::node_type)
+ (_Hashtable::insert_return_type, _Hashtable::_M_reinsert_node)
+ (_Hashtable::_M_reinsert_node_multi, _Hashtable::extract)
+ (_Hashtable::_M_merge_unique, _Hashtable::_M_merge_multi): Define.
+ (_Hash_merge_helper): Define primary template.
+ * include/bits/node_handle.h: New header.
+ * include/bits/stl_map.h (map): Declare _Rb_tree_merge_helper as
+ friend.
+ (map::node_type, map::insert_return_type, map::extract, map::merge)
+ (map::insert(node_type&&), map::insert(const_iterator, node_type&&)):
+ Define new members.
+ (_Rb_tree_merge_helper): Specialize for map.
+ * include/bits/stl_multimap.h (multimap): Declare _Rb_tree_merge_helper
+ as friend.
+ (multimap::node_type, multimap::extract, multimap::merge)
+ (multimap::insert(node_type&&))
+ (multimap::insert(const_iterator, node_type&&)): Define.
+ (_Rb_tree_merge_helper): Specialize for multimap.
+ * include/bits/stl_multiset.h (multiset): Declare _Rb_tree_merge_helper
+ as friend.
+ (multiset::node_type, multiset::extract, multiset::merge)
+ (multiset::insert(node_type&&))
+ (multiset::insert(const_iterator, node_type&&)): Define.
+ * include/bits/stl_set.h (set): Declare _Rb_tree_merge_helper as
+ friend.
+ (set::node_type, set::insert_return_type, set::extract, set::merge)
+ (set::insert(node_type&&), set::insert(const_iterator, node_type&&)):
+ Define.
+ (_Rb_tree_merge_helper): Specialize for set.
+ * include/bits/stl_tree.h (_Rb_tree): Declare _Rb_tree<> as friend.
+ (_Rb_tree::node_type, _Rb_tree::insert_return_type)
+ (_Rb_tree::_M_reinsert_node_unique, _Rb_tree::_M_reinsert_node_equal)
+ (_Rb_tree::_M_reinsert_node_hint_unique)
+ (_Rb_tree::_M_reinsert_node_hint_equal, _Rb_tree::extract)
+ (_Rb_tree::_M_merge_unique, _Rb_tree::_M_merge_equal): Define.
+ (_Rb_tree_merge_helper): Specialize for multiset.
+ * include/bits/unordered_map.h (unordered_map): Declare
+ unordered_map<> and unordered_multimap<> as friends.
+ (unordered_map::node_type, unordered_map::insert_return_type)
+ (unordered_map::extract, unordered_map::merge)
+ (unordered_map::insert(node_type&&))
+ (unordered_map::insert(const_iterator, node_type&&))
+ (unordered_multimap): Declare _Hash_merge_helper as friend.
+ (unordered_multimap::node_type, unordered_multimap::extract)
+ (unordered_multimap::merge, unordered_multimap::insert(node_type&&))
+ (unordered_multimap::insert(const_iterator, node_type&&)): Define.
+ (_Hash_merge_helper): Specialize for unordered maps and multimaps.
+ * include/bits/unordered_set.h (unordered_set, unordered_multiset):
+ Declare _Hash_merge_helper as friend.
+ (unordered_set::node_type, unordered_set::insert_return_type)
+ (unordered_set::extract, unordered_set::merge)
+ (unordered_set::insert(node_type&&))
+ (unordered_set::insert(const_iterator, node_type&&)): Define.
+ (unordered_multiset::node_type, unordered_multiset::extract)
+ (unordered_multiset::merge, unordered_multiset::insert(node_type&&))
+ (unordered_multiset::insert(const_iterator, node_type&&)): Define.
+ (_Hash_merge_helper): Specialize for unordered sets and multisets.
+ * include/debug/map.h (map): Add using declarations or forwarding
+ functions for new members.
+ * include/debug/map.h (multimap): Likewise.
+ * include/debug/map.h (multiset): Likewise.
+ * include/debug/map.h (set): Likewise.
+ * include/debug/unordered_map (unordered_map, unordered_multimap):
+ Likewise.
+ * include/debug/unordered_set( unordered_set, unordered_multiset):
+ Likewise.
+ * python/libstdcxx/v6/printers.py (get_value_from_aligned_membuf): New
+ helper function.
+ (get_value_from_list_node, get_value_from_Rb_tree_node): Use helper.
+ (StdNodeHandlePrinter): Define printer for node handles.
+ (build_libstdcxx_dictionary): Register StdNodeHandlePrinter.
+ * testsuite/23_containers/map/modifiers/extract.cc: New.
+ * testsuite/23_containers/map/modifiers/merge.cc: New.
+ * testsuite/23_containers/multimap/modifiers/extract.cc: New.
+ * testsuite/23_containers/multimap/modifiers/merge.cc: New.
+ * testsuite/23_containers/multiset/modifiers/extract.cc: New.
+ * testsuite/23_containers/multiset/modifiers/merge.cc: New.
+ * testsuite/23_containers/set/modifiers/extract.cc: New.
+ * testsuite/23_containers/set/modifiers/merge.cc: New.
+ * testsuite/23_containers/unordered_map/modifiers/extract.cc: New.
+ * testsuite/23_containers/unordered_map/modifiers/merge.cc: New.
+ * testsuite/23_containers/unordered_multimap/modifiers/extract.cc:
+ New.
+ * testsuite/23_containers/unordered_multimap/modifiers/merge.cc: New.
+ * testsuite/23_containers/unordered_multiset/modifiers/extract.cc:
+ New.
+ * testsuite/23_containers/unordered_multiset/modifiers/merge.cc: New.
+ * testsuite/23_containers/unordered_set/modifiers/extract.cc: New.
+ * testsuite/23_containers/unordered_set/modifiers/merge.cc: New.
+ * testsuite/23_containers/unordered_set/instantiation_neg.cc: Adjust
+ dg-error lineno.
+ * testsuite/libstdc++-prettyprinters/cxx17.cc: Test node handles.
+
+2016-09-22 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Fix tests on old arm platforms for optional.
+ * testsuite/20_util/optional/77288.cc: Don't use exception_ptr.
+
+2016-09-22 Jonathan Wakely <jwakely@redhat.com>
+
+ * python/libstdcxx/v6/printers.py (StdVariantPrinter): Adjust for
+ recent change to _Variant_storage.
+ * testsuite/libstdc++-prettyprinters/cxx17.cc: Test variant with
+ reference type.
+
+ * include/bits/uses_allocator.h (__uses_allocator_construct): Qualify
+ std::forward and ::new. Cast pointer to void*.
+ * include/std/variant (_Variant_storage, _Union, _Variant_base)
+ (__access, __visit_invoke, variant, visit): Qualify std::forward.
+ * testsuite/20_util/variant/compile.cc: Test for ADL problems.
+
+2016-09-22 Tim Shen <timshen@google.com>
+
+ * include/std/variant (variant::operator=): Fix assignment
+ on references.
+ * testsuite/20_util/variant/compile.cc: Add test.
+
+2016-09-22 Tim Shen <timshen@google.com>
+
+ PR libstdc++/77641
+ * include/std/variant (_Variant_storage::_Variant_storage):
+ Change _Variant_storage's union to be default constructible.
+ * testsuite/20_util/variant/compile.cc: New test.
+
+2016-09-21 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/77288
+ * include/std/optional (__is_optional_impl, __is_optional): Remove.
+ (__converts_from_optional, __assigns_from_optional): New.
+ (optional(_Up&&)): Use is_same instead of __is_optional.
+ (optional(const optional<_Up>&)): Constrain with
+ __converts_from_optional.
+ (optional(optional<_Up>&&)): Likewise.
+ (operator=(_Up&&)): Use is_same instead of __is_optional, check
+ is_same and is_scalar.
+ (operator=(const optional<_Up>&)): Constrain with
+ __converts_from_optional and __assigns_from_optional.
+ (operator=(optional<_Up>&&)): Likewise.
+ * testsuite/20_util/optional/77288.cc: New.
+ * testsuite/20_util/optional/cons/value.cc: Adjust.
+
+2016-09-21 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement LWG 2729 for tuple.
+ * include/std/tuple (_Tuple_impl(_Tuple_impl&&)):
+ Suppress conditionally.
+ (_Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&&)): Likewise.
+ (__is_tuple_impl_trait_impl, __is_tuple_impl_trait): New.
+ (_Tuple_impl(const _Head&)): Constrain.
+ (_Tuple_impl(_UHead&&)): Likewise.
+ (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally.
+ (_Tuple_impl(const _Tuple_impl<_Idx, _UHead>&)): Constrain.
+ (_Tuple_impl(_Tuple_impl<_Idx, _UHead>&&)): Likewise.
+ (operator=(const tuple&)): Enable conditionally.
+ (operator=(tuple&&)): Suppress conditionally.
+ (operator=(const tuple<_UElements...>&)): Constrain.
+ (operator=(tuple<_UElements...>&&)): Likewise.
+ (operator=(const tuple&)): Enable conditionally (2-param tuple).
+ (operator=(tuple&&)): Suppress conditionally (2-param tuple).
+ (operator=(const tuple<_U1, _U2>&)): Constrain.
+ (operator=(tuple<_U1, _U2>&&)): Likewise.
+ (operator=(const pair<_U1, _U2>&)): Likewise.
+ (operator=(pair<_U1, _U2>&&)): Likewise.
+ * testsuite/20_util/tuple/element_access/get_neg.cc: Adjust.
+ * testsuite/20_util/tuple/tuple_traits.cc: New.
+
+2016-09-21 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/77537
+ Implement LWG 2729 for pair.
+ * include/bits/stl_pair.h (_PCC): New.
+ (_ConstructiblePair, _ImplicitlyConvertiblePair):
+ Turn into static member functions of _PCC.
+ (_MoveConstructiblePair, _ImplicitlyMoveConvertiblePair): Likewise.
+ (_PCCP): New.
+ (pair(const _T1&, const _T2&)): Adjust.
+ (_PCCFP): New.
+ (pair(const pair<_U1, _U2>&)): Adjust.
+ (pair(_U1&&, const _T2&)): Likewise.
+ (pair(const _T1&, _U2&&)): Likewise.
+ (pair(_U1&&, _U2&&)): Likewise.
+ (pair(pair<_U1, _U2>&&)): Likewise.
+ (operator=(const pair&)): Make conditionally deleted.
+ (operator=(pair&&)): Make conditionally suppressed.
+ (operator=(const pair<_U1, _U2>&)): Constrain.
+ (operator=(pair<_U1, _U2>&&): Likewise.
+ * include/std/type_traits (__nonesuch): New.
+ * testsuite/20_util/pair/traits.cc: New.
+
+2016-09-20 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/77619
+ * include/bits/stl_construct.h: (_Construct_novalue): New.
+ (_Destroy_n_aux, _Destroy_n): New.
+ * include/bits/stl_uninitialized.h: (type_traits):
+ New include in C++11 mode.
+ (__uninitialized_default_novalue_1): New.
+ (__uninitialized_default_novalue_n_1): Likewise.
+ (__uninitialized_default_novalue): Likewise.
+ (__uninitialized_default_novalue_n): Likewise.
+ (__uninitialized_copy_n_pair): Likewise.
+ (uninitialized_default_construct):
+ Use __uninitialized_default_novalue.
+ (uninitialized_default_construct_n):
+ Use __uninitialized_default_novalue_n.
+ (uninitialized_value_construct): Use __uninitialized_default.
+ (uninitialized_value_construct_n): Use __uninitialized_default_n.
+ (uninitialized_move): Use uninitialized_copy.
+ (uninitialized_move_n): Use __uninitialized_copy_n_pair.
+ (destroy_at): Use _Destroy.
+ (destroy): Likewise.
+ (destroy_n): Likewise.
+ * testsuite/20_util/specialized_algorithms/
+ memory_management_tools/1.cc: Add tests for exceptions,
+ add tests for trivial cases for construct and move.
+
+2016-09-20 Jonathan Wakely <jwakely@redhat.com>
+
+ * python/libstdcxx/v6/xmethods.py (DequeWorkerBase.__init__)
+ (DequeWorkerBase.index, VectorWorkerBase.get): Use // for division.
+
+2016-09-19 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/77645
+ * python/libstdcxx/v6/xmethods.py (DequeWorkerBase.__init__)
+ (DequeWorkerBase.index, VectorWorkerBase.get): Cast results of
+ division to int to work with Python 3.
+
+ * testsuite/lib/gdb-test.exp (gdb-test): Fail if Python error occurs.
+
+ * python/libstdcxx/v6/printers.py (SingleObjContainerPrinter): Allow
+ display_hint to be set by subclasses.
+ (StdVariantPrinter): Use array for display_hint. Adjust output to be
+ more similar to std::any and std::optional output.
+ (register_type_printers): Add type printers for basic_string_view
+ typedefs and experimental::any. Adjust type printers for
+ fundamentals_v1 templates to match fundamentals_v2 and later.
+ * testsuite/libstdc++-prettyprinters/cxx17.cc: New.
+
+ PR libstdc++/77645
+ * python/libstdcxx/v6/xmethods.py (DequeWorkerBase.index): Rename
+ argument.
+ (ListWorkerBase.get_value_from_node): Define new method.
+ (ListFrontWorker.__call__, ListBackWorker.__call__): Use it.
+
2016-09-17 Jonathan Wakely <jwakely@redhat.com>
* python/libstdcxx/v6/printers.py (StdVariantPrinter): Define.
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 3159b714a1a..c29c09c126f 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -191,6 +191,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 6d897bed8b1..d0ee45fb49b 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2153,6 +2153,10 @@ AC_DEFUN([GLIBCXX_CHECK_STDIO_PROTO], [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
+ # Use C++11 because a conforming <stdio.h> won't define gets for C++14,
+ # and we don't need a declaration for C++14 anyway.
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -std=gnu++11"
AC_MSG_CHECKING([for gets declaration])
AC_CACHE_VAL(glibcxx_cv_gets, [
@@ -2168,10 +2172,11 @@ AC_DEFUN([GLIBCXX_CHECK_STDIO_PROTO], [
)])
if test $glibcxx_cv_gets = yes; then
- AC_DEFINE(HAVE_GETS, 1, [Define if gets is available in <stdio.h>.])
+ AC_DEFINE(HAVE_GETS, 1, [Define if gets is available in <stdio.h> before C++14.])
fi
AC_MSG_RESULT($glibcxx_cv_gets)
+ CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
])
@@ -3489,10 +3494,12 @@ EOF
CXXFLAGS="$old_CXXFLAGS"
AC_LANG_RESTORE
- # Set atomicity_dir to builtins if all but the long long test above passes.
- if test "$glibcxx_cv_atomic_bool" = yes \
+ # Set atomicity_dir to builtins if all but the long long test above passes,
+ # or if the builtins were already chosen (e.g. by configure.host).
+ if { test "$glibcxx_cv_atomic_bool" = yes \
&& test "$glibcxx_cv_atomic_short" = yes \
- && test "$glibcxx_cv_atomic_int" = yes; then
+ && test "$glibcxx_cv_atomic_int" = yes; } \
+ || test "$atomicity_dir" = "cpu/generic/atomicity_builtins"; then
AC_DEFINE(_GLIBCXX_ATOMIC_BUILTINS, 1,
[Define if the compiler supports C++11 atomics.])
atomicity_dir=cpu/generic/atomicity_builtins
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 2ab6e0d6a49..63996709ad4 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -183,7 +183,7 @@
/* Define if _Unwind_GetIPInfo is available. */
#undef HAVE_GETIPINFO
-/* Define if gets is available in <stdio.h>. */
+/* Define if gets is available in <stdio.h> before C++14. */
#undef HAVE_GETS
/* Define to 1 if you have the `hypot' function. */
diff --git a/libstdc++-v3/config/cpu/m68k/atomicity.h b/libstdc++-v3/config/cpu/m68k/atomicity.h
index f4213302424..a9ddc6ba3bf 100644
--- a/libstdc++-v3/config/cpu/m68k/atomicity.h
+++ b/libstdc++-v3/config/cpu/m68k/atomicity.h
@@ -48,6 +48,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#elif defined(__rtems__)
+ // This code is only provided for reference. RTEMS uses now the atomic
+ // builtins and libatomic. See configure.host.
+ //
// TAS/JBNE is unsafe on systems with strict priority-based scheduling.
// Disable interrupts, which we can do only from supervisor mode.
_Atomic_word
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 6332c4d7f87..09b73b85891 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -645,6 +645,7 @@ baseline_dir
HWCAP_FLAGS
GLIBCXX_LDBL_COMPAT_FALSE
GLIBCXX_LDBL_COMPAT_TRUE
+LONG_DOUBLE_COMPAT_FLAGS
ENABLE_CXX11_ABI_FALSE
ENABLE_CXX11_ABI_TRUE
glibcxx_cxx98_abi
@@ -11596,7 +11597,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11599 "configure"
+#line 11600 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11702,7 +11703,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11705 "configure"
+#line 11706 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15388,7 +15389,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
# Fake what AC_TRY_COMPILE does.
cat > conftest.$ac_ext << EOF
-#line 15391 "configure"
+#line 15392 "configure"
int main()
{
typedef bool atomic_type;
@@ -15423,7 +15424,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15426 "configure"
+#line 15427 "configure"
int main()
{
typedef short atomic_type;
@@ -15458,7 +15459,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15461 "configure"
+#line 15462 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
@@ -15494,7 +15495,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15497 "configure"
+#line 15498 "configure"
int main()
{
typedef long long atomic_type;
@@ -15538,10 +15539,12 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
- # Set atomicity_dir to builtins if all but the long long test above passes.
- if test "$glibcxx_cv_atomic_bool" = yes \
+ # Set atomicity_dir to builtins if all but the long long test above passes,
+ # or if the builtins were already chosen (e.g. by configure.host).
+ if { test "$glibcxx_cv_atomic_bool" = yes \
&& test "$glibcxx_cv_atomic_short" = yes \
- && test "$glibcxx_cv_atomic_int" = yes; then
+ && test "$glibcxx_cv_atomic_int" = yes; } \
+ || test "$atomicity_dir" = "cpu/generic/atomicity_builtins"; then
$as_echo "#define _GLIBCXX_ATOMIC_BUILTINS 1" >>confdefs.h
@@ -15573,7 +15576,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 15576 "configure"
+#line 15579 "configure"
int main()
{
_Decimal32 d1;
@@ -15615,7 +15618,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 15618 "configure"
+#line 15621 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -15649,7 +15652,7 @@ $as_echo "$enable_int128" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15652 "configure"
+#line 15655 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -18173,6 +18176,10 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+ # Use C++11 because a conforming <stdio.h> won't define gets for C++14,
+ # and we don't need a declaration for C++14 anyway.
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -std=gnu++11"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gets declaration" >&5
$as_echo_n "checking for gets declaration... " >&6; }
@@ -18207,6 +18214,7 @@ $as_echo "#define HAVE_GETS 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_gets" >&5
$as_echo "$glibcxx_cv_gets" >&6; }
+ CXXFLAGS="$ac_save_CXXFLAGS"
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -28822,6 +28830,8 @@ else
$as_echo "#define HAVE_ICONV 1" >>confdefs.h
+ $as_echo "#define HAVE_MEMALIGN 1" >>confdefs.h
+
else
# Base decisions on target environment.
@@ -79340,6 +79350,7 @@ $as_echo "${default_libstdcxx_abi}" >&6; }
ac_ldbl_compat=no
+LONG_DOUBLE_COMPAT_FLAGS="-mlong-double-64"
case "$target" in
powerpc*-*-linux* | \
sparc*-*-linux* | \
@@ -79371,10 +79382,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
$as_echo "#define _GLIBCXX_LONG_DOUBLE_COMPAT 1" >>confdefs.h
port_specific_symbol_files="\$(top_srcdir)/config/os/gnu-linux/ldbl-extra.ver"
+ case "$target" in
+ powerpc*-*-linux*)
+ LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute" ;;
+ esac
fi
esac
+
# Check if assembler supports disabling hardware capability support.
test -z "$HWCAP_FLAGS" && HWCAP_FLAGS=''
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 5657ecb27dc..7d0fafab514 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -324,6 +324,7 @@ else
AC_DEFINE(HAVE_TANHF)
AC_DEFINE(HAVE_ICONV)
+ AC_DEFINE(HAVE_MEMALIGN)
else
GLIBCXX_CROSSCONFIG
fi
@@ -374,6 +375,7 @@ GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI([yes])
GLIBCXX_DEFAULT_ABI
ac_ldbl_compat=no
+LONG_DOUBLE_COMPAT_FLAGS="-mlong-double-64"
case "$target" in
powerpc*-*-linux* | \
sparc*-*-linux* | \
@@ -388,8 +390,13 @@ case "$target" in
AC_DEFINE([_GLIBCXX_LONG_DOUBLE_COMPAT],1,
[Define if compatibility should be provided for -mlong-double-64.])
port_specific_symbol_files="\$(top_srcdir)/config/os/gnu-linux/ldbl-extra.ver"
+ case "$target" in
+ powerpc*-*-linux*)
+ LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute" ;;
+ esac
fi
esac
+AC_SUBST(LONG_DOUBLE_COMPAT_FLAGS)
GLIBCXX_CONDITIONAL(GLIBCXX_LDBL_COMPAT, test $ac_ldbl_compat = yes)
# Check if assembler supports disabling hardware capability support.
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index c0cc3ee1285..eb56ab12d75 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -296,6 +296,10 @@ case "${host_os}" in
os_include_dir="os/qnx/qnx6.1"
c_model=c
;;
+ rtems*)
+ # Use libatomic if necessary and avoid libstdc++ specific atomicity support
+ atomicity_dir="cpu/generic/atomicity_builtins"
+ ;;
solaris2)
# This too-vague configuration does not provide enough information
# to select a ctype include, and thus os_include_dir is a crap shoot.
diff --git a/libstdc++-v3/doc/Makefile.in b/libstdc++-v3/doc/Makefile.in
index 3e729c130e7..c3874f757a4 100644
--- a/libstdc++-v3/doc/Makefile.in
+++ b/libstdc++-v3/doc/Makefile.in
@@ -163,6 +163,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html
index de2ad5f1182..8469c6efa4a 100644
--- a/libstdc++-v3/doc/html/manual/bugs.html
+++ b/libstdc++-v3/doc/html/manual/bugs.html
@@ -411,6 +411,10 @@
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2187" target="_top">2187</a>:
<span class="emphasis"><em><code class="code">vector&lt;bool&gt;</code> is missing <code class="code">emplace</code> and <code class="code">emplace_back</code> member functions</em></span>
</span></dt><dd><p>Add <code class="code">emplace</code> and <code class="code">emplace_back</code> member functions.
+ </p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2192" target="_top">2192</a>:
+ <span class="emphasis"><em>Validity and return type of <code class="code">std::abs(0u)</code> is unclear</em></span>
+ </span></dt><dd><p>Move all declarations to a common header and remove the
+ generic <code class="code">abs</code> which accepted unsigned arguments.
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2196" target="_top">2196</a>:
<span class="emphasis"><em>Specification of <code class="code">is_*[copy/move]_[constructible/assignable]</code> unclear for non-referencable types</em></span>
</span></dt><dd><p>Use the referenceable type concept.
diff --git a/libstdc++-v3/doc/html/manual/profile_mode_devel.html b/libstdc++-v3/doc/html/manual/profile_mode_devel.html
index 2521dd66811..db96f989b24 100644
--- a/libstdc++-v3/doc/html/manual/profile_mode_devel.html
+++ b/libstdc++-v3/doc/html/manual/profile_mode_devel.html
@@ -64,4 +64,4 @@
<code class="code">include/profile/impl/profiler_trace.h</code>. Use
<code class="code">__trace_vector_to_list</code> as an example.
</p><p>Add documentation in file <code class="code">doc/xml/manual/profile_mode.xml</code>.
- </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="profile_mode_impl.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="profile_mode.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="profile_mode_diagnostics.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Implementation Issues </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Diagnostics</td></tr></table></div></body></html>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="profile_mode_impl.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="profile_mode.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="profile_mode_diagnostics.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Implementation Issues </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Diagnostics</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/libstdc++-v3/doc/html/manual/status.html b/libstdc++-v3/doc/html/manual/status.html
index e82739aa1ce..ecc93a947c7 100644
--- a/libstdc++-v3/doc/html/manual/status.html
+++ b/libstdc++-v3/doc/html/manual/status.html
@@ -523,11 +523,11 @@ Feature-testing recommendations for C++</a>.
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0220r1.html" target="_top">
P0220R1
</a>
- </td><td align="center"> No </td><td align="left"> <code class="code">__cpp_lib_shared_ptr_arrays &gt;= 201603</code> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Library Fundamentals V1 TS Components: Searchers </td><td align="left">
+ </td><td align="center"> No </td><td align="left"> <code class="code">__cpp_lib_shared_ptr_arrays &gt;= 201603</code> </td></tr><tr><td align="left"> Library Fundamentals V1 TS Components: Searchers </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0220r1.html" target="_top">
P0220R1
</a>
- </td><td align="center"> No </td><td align="left"> <code class="code">__cpp_lib_boyer_moore_searcher &gt;= 201603</code> </td></tr><tr><td align="left"> Constant View: A proposal for a <code class="code">std::as_const</code> helper function template </td><td align="left">
+ </td><td align="center"> 7 </td><td align="left"> <code class="code">__cpp_lib_boyer_moore_searcher &gt;= 201603</code> </td></tr><tr><td align="left"> Constant View: A proposal for a <code class="code">std::as_const</code> helper function template </td><td align="left">
<a class="link" href="" target="_top">
P0007R1
</a>
@@ -582,19 +582,19 @@ Feature-testing recommendations for C++</a>.
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0005r4.html" target="_top">
P0005R4
</a>
- </td><td align="center"> 7 </td><td align="left"><code class="code">__cpp_lib_not_fn &gt;= 201603</code></td></tr><tr bgcolor="#C8B0B0"><td align="left"> Fixes for <code class="code">not_fn</code> </td><td align="left">
+ </td><td align="center"> 7 </td><td align="left"><code class="code">__cpp_lib_not_fn &gt;= 201603</code></td></tr><tr><td align="left"> Fixes for <code class="code">not_fn</code> </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html" target="_top">
P0358R1
</a>
- </td><td align="center"> No </td><td align="left"> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Fixing a design mistake in the searchers interface in Library Fundamentals </td><td align="left">
+ </td><td align="center"> 7 </td><td align="left"> </td></tr><tr><td align="left"> Fixing a design mistake in the searchers interface in Library Fundamentals </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0253r1.pdf" target="_top">
P0253R1
</a>
- </td><td align="center"> No </td><td align="left"> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Extending memory management tools </td><td align="left">
+ </td><td align="center"> 7 </td><td align="left"> </td></tr><tr><td align="left"> Extending memory management tools </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0040r3.html" target="_top">
P0040R3
</a>
- </td><td align="center"> No </td><td align="left"><code class="code"> </code></td></tr><tr><td align="left"> <code class="code">shared_ptr::weak_type</code></td><td align="left">
+ </td><td align="center"> 7 </td><td align="left"><code class="code"> </code></td></tr><tr><td align="left"> <code class="code">shared_ptr::weak_type</code></td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0163r0.html" target="_top">
P0163R0
</a>
@@ -666,11 +666,11 @@ Feature-testing recommendations for C++</a>.
</a>
</td><td align="center"> 6.1 </td><td align="left"><code class="code"> __cpp_lib_map_try_emplace &gt;= 201411</code>,
<code class="code"> __cpp_lib_unordered_map_try_emplace &gt;= 201411</code>
- </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Splicing Maps and Sets </td><td align="left">
+ </td></tr><tr><td align="left"> Splicing Maps and Sets </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r3.pdf" target="_top">
P0083R3
</a>
- </td><td align="center"> No </td><td align="left"><code class="code"> __cpp_lib_node_extract &gt;= 201606 </code></td></tr><tr><td align="left">Non-member <code class="code">size()</code> and more</td><td align="left">
+ </td><td align="center"> 7 </td><td align="left"><code class="code"> __cpp_lib_node_extract &gt;= 201606 </code></td></tr><tr><td align="left">Non-member <code class="code">size()</code> and more</td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4280.pdf" target="_top">
N4280
</a>
@@ -693,11 +693,11 @@ Feature-testing recommendations for C++</a>.
</a>
</td><td align="center"> No </td><td align="left"><code class="code"> __cpp_lib_gcd &gt;= 201606 </code>,
<code class="code"> __cpp_lib_lcm &gt;= 201606 </code>
- </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Proposal to Introduce a 3-Argument Overload to <code class="code">std::hypot</code> </td><td align="left">
+ </td></tr><tr><td align="left"> Proposal to Introduce a 3-Argument Overload to <code class="code">std::hypot</code> </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0030r1.pdf" target="_top">
P0030R1
</a>
- </td><td align="center"> No </td><td align="left"><code class="code"> __cpp_lib_hypot &gt;= 201603 </code></td></tr><tr><td align="left"> Mathematical Special Functions for C++17 </td><td align="left">
+ </td><td align="center"> 7 </td><td align="left"><code class="code"> __cpp_lib_hypot &gt;= 201603 </code></td></tr><tr><td align="left"> Mathematical Special Functions for C++17 </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0226r1.pdf" target="_top">
P0226R1
</a>
diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml
index 238ab241080..47478513666 100644
--- a/libstdc++-v3/doc/xml/manual/intro.xml
+++ b/libstdc++-v3/doc/xml/manual/intro.xml
@@ -940,6 +940,13 @@ requirements of the license of GCC.
<listitem><para>Add <code>emplace</code> and <code>emplace_back</code> member functions.
</para></listitem></varlistentry>
+ <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2192">2192</link>:
+ <emphasis>Validity and return type of <code>std::abs(0u)</code> is unclear</emphasis>
+ </term>
+ <listitem><para>Move all declarations to a common header and remove the
+ generic <code>abs</code> which accepted unsigned arguments.
+ </para></listitem></varlistentry>
+
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2196">2196</link>:
<emphasis>Specification of <code>is_*[copy/move]_[constructible/assignable]</code> unclear for non-referencable types</emphasis>
</term>
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index ff966272311..feed08514ce 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -171,14 +171,13 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Library Fundamentals V1 TS Components: Searchers </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0220r1.html">
P0220R1
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry> <code>__cpp_lib_boyer_moore_searcher >= 201603</code> </entry>
</row>
@@ -332,38 +331,35 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Fixes for <code>not_fn</code> </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html">
P0358R1
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry/>
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Fixing a design mistake in the searchers interface in Library Fundamentals </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0253r1.pdf">
P0253R1
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry/>
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Extending memory management tools </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0040r3.html">
P0040R3
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry><code> </code></entry>
</row>
@@ -562,14 +558,13 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Splicing Maps and Sets </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r3.pdf">
P0083R3
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry><code> __cpp_lib_node_extract >= 201606 </code></entry>
</row>
@@ -634,14 +629,13 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Proposal to Introduce a 3-Argument Overload to <code>std::hypot</code> </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0030r1.pdf">
P0030R1
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry><code> __cpp_lib_hypot >= 201603 </code></entry>
</row>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 9cd18dfa3b9..4e63fbb438b 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -129,7 +129,7 @@ bits_headers = \
${bits_srcdir}/specfun.h \
${bits_srcdir}/memoryfwd.h \
${bits_srcdir}/move.h \
- ${bits_srcdir}/std_mutex.h \
+ ${bits_srcdir}/node_handle.h \
${bits_srcdir}/ostream.tcc \
${bits_srcdir}/ostream_insert.h \
${bits_srcdir}/parse_numbers.h \
@@ -159,6 +159,8 @@ bits_headers = \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
+ ${bits_srcdir}/std_abs.h \
+ ${bits_srcdir}/std_mutex.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
${bits_srcdir}/stl_bvector.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index d799860d095..8b788b551c4 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -163,6 +163,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
@@ -419,7 +420,7 @@ bits_headers = \
${bits_srcdir}/specfun.h \
${bits_srcdir}/memoryfwd.h \
${bits_srcdir}/move.h \
- ${bits_srcdir}/std_mutex.h \
+ ${bits_srcdir}/node_handle.h \
${bits_srcdir}/ostream.tcc \
${bits_srcdir}/ostream_insert.h \
${bits_srcdir}/parse_numbers.h \
@@ -449,6 +450,8 @@ bits_headers = \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
+ ${bits_srcdir}/std_abs.h \
+ ${bits_srcdir}/std_mutex.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
${bits_srcdir}/stl_bvector.h \
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index e823f132d4e..7a4204e41c8 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -1709,8 +1709,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
basic_string&
erase(size_type __pos = 0, size_type __n = npos)
{
- this->_M_erase(_M_check(__pos, "basic_string::erase"),
- _M_limit(__pos, __n));
+ _M_check(__pos, "basic_string::erase");
+ if (__n == npos)
+ this->_M_set_length(__pos);
+ else if (__n != 0)
+ this->_M_erase(__pos, _M_limit(__pos, __n));
return *this;
}
@@ -1747,7 +1750,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last
&& __last <= end());
const size_type __pos = __first - begin();
- this->_M_erase(__pos, __last - __first);
+ if (__last == end())
+ this->_M_set_length(__pos);
+ else
+ this->_M_erase(__pos, __last - __first);
return iterator(this->_M_data() + __pos);
}
@@ -3684,10 +3690,24 @@ _GLIBCXX_END_NAMESPACE_CXX11
/**
* Erases the string, making it empty.
*/
+#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
+ void
+ clear() _GLIBCXX_NOEXCEPT
+ {
+ if (_M_rep()->_M_is_shared())
+ {
+ _M_rep()->_M_dispose(this->get_allocator());
+ _M_data(_S_empty_rep()._M_refdata());
+ }
+ else
+ _M_rep()->_M_set_length_and_sharable(0);
+ }
+#else
// PR 56166: this should not throw.
void
clear()
{ _M_mutate(0, this->size(), 0); }
+#endif
/**
* Returns true if the %string is empty. Equivalent to
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 0080d2b0e2f..df1e8ddec75 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -351,7 +351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__size < __n)
this->append(__n - __size, __c);
else if (__n < __size)
- this->_M_erase(__n, __size - __n);
+ this->_M_set_length(__n);
}
template<typename _CharT, typename _Traits, typename _Alloc>
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 6d7134a8a30..be67741ab5a 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -33,6 +33,9 @@
#pragma GCC system_header
#include <bits/hashtable_policy.h>
+#if __cplusplus > 201402L
+# include <bits/node_handle.h>
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -308,6 +311,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using const_local_iterator = typename __hashtable_base::
const_local_iterator;
+#if __cplusplus > 201402L
+ using node_type = _Node_handle<_Key, _Value, __node_alloc_type>;
+ using insert_return_type = _Node_insert_return<iterator, node_type>;
+#endif
+
private:
__bucket_type* _M_buckets = &_M_single_bucket;
size_type _M_bucket_count = 1;
@@ -762,6 +770,135 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// DR 1189.
// reserve, if present, comes from _Rehash_base.
+#if __cplusplus > 201402L
+ /// Re-insert an extracted node into a container with unique keys.
+ insert_return_type
+ _M_reinsert_node(node_type&& __nh)
+ {
+ insert_return_type __ret;
+ if (__nh.empty())
+ __ret.position = end();
+ else
+ {
+ __glibcxx_assert(get_allocator() == __nh.get_allocator());
+
+ const key_type& __k = __nh._M_key();
+ __hash_code __code = this->_M_hash_code(__k);
+ size_type __bkt = _M_bucket_index(__k, __code);
+ if (__node_type* __n = _M_find_node(__bkt, __k, __code))
+ {
+ __ret.node = std::move(__nh);
+ __ret.position = iterator(__n);
+ __ret.inserted = false;
+ }
+ else
+ {
+ __ret.position
+ = _M_insert_unique_node(__bkt, __code, __nh._M_ptr);
+ __nh._M_ptr = nullptr;
+ __ret.inserted = true;
+ }
+ }
+ return __ret;
+ }
+
+ /// Re-insert an extracted node into a container with equivalent keys.
+ iterator
+ _M_reinsert_node_multi(const_iterator __hint, node_type&& __nh)
+ {
+ iterator __ret;
+ if (__nh.empty())
+ __ret = end();
+ else
+ {
+ __glibcxx_assert(get_allocator() == __nh.get_allocator());
+
+ auto __code = this->_M_hash_code(__nh._M_key());
+ auto __node = std::exchange(__nh._M_ptr, nullptr);
+ // FIXME: this deallocates the node on exception.
+ __ret = _M_insert_multi_node(__hint._M_cur, __code, __node);
+ }
+ return __ret;
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __node_type* __n = __pos._M_cur;
+ size_t __bkt = _M_bucket_index(__n);
+
+ // Look for previous node to unlink it from the erased one, this
+ // is why we need buckets to contain the before begin to make
+ // this search fast.
+ __node_base* __prev_n = _M_get_previous_node(__bkt, __n);
+
+ if (__prev_n == _M_buckets[__bkt])
+ _M_remove_bucket_begin(__bkt, __n->_M_next(),
+ __n->_M_nxt ? _M_bucket_index(__n->_M_next()) : 0);
+ else if (__n->_M_nxt)
+ {
+ size_type __next_bkt = _M_bucket_index(__n->_M_next());
+ if (__next_bkt != __bkt)
+ _M_buckets[__next_bkt] = __prev_n;
+ }
+
+ __prev_n->_M_nxt = __n->_M_nxt;
+ __n->_M_nxt = nullptr;
+ --_M_element_count;
+ return { __n, this->_M_node_allocator() };
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const _Key& __k)
+ {
+ node_type __nh;
+ auto __pos = find(__k);
+ if (__pos != end())
+ __nh = extract(const_iterator(__pos));
+ return __nh;
+ }
+
+ /// Merge from a compatible container into one with unique keys.
+ template<typename _Compatible_Hashtable>
+ void
+ _M_merge_unique(_Compatible_Hashtable& __src) noexcept
+ {
+ static_assert(is_same_v<typename _Compatible_Hashtable::node_type,
+ node_type>, "Node types are compatible");
+ __glibcxx_assert(get_allocator() == __src.get_allocator());
+
+ for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
+ {
+ auto __pos = __i++;
+ const key_type& __k = this->_M_extract()(__pos._M_cur->_M_v());
+ __hash_code __code = this->_M_hash_code(__k);
+ size_type __bkt = _M_bucket_index(__k, __code);
+ if (_M_find_node(__bkt, __k, __code) == nullptr)
+ {
+ auto __nh = __src.extract(__pos);
+ _M_insert_unique_node(__bkt, __code, __nh._M_ptr);
+ __nh._M_ptr = nullptr;
+ }
+ }
+ }
+
+ /// Merge from a compatible container into one with equivalent keys.
+ template<typename _Compatible_Hashtable>
+ void
+ _M_merge_multi(_Compatible_Hashtable& __src) noexcept
+ {
+ static_assert(is_same_v<typename _Compatible_Hashtable::node_type,
+ node_type>, "Node types are compatible");
+ __glibcxx_assert(get_allocator() == __src.get_allocator());
+
+ this->reserve(size() + __src.size());
+ for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
+ _M_reinsert_node_multi(cend(), __src.extract(__i++));
+ }
+#endif // C++17
+
private:
// Helper rehash method used when keys are unique.
void _M_rehash_aux(size_type __n, std::true_type);
@@ -2078,6 +2215,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_buckets = __new_buckets;
}
+#if __cplusplus > 201402L
+ template<typename, typename, typename> class _Hash_merge_helper { };
+#endif // C++17
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/bits/node_handle.h b/libstdc++-v3/include/bits/node_handle.h
new file mode 100644
index 00000000000..60c28838820
--- /dev/null
+++ b/libstdc++-v3/include/bits/node_handle.h
@@ -0,0 +1,330 @@
+// Node handles for containers -*- C++ -*-
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/node_handle.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly.
+ * @headername{map,set,unordered_map,unordered_set}
+ */
+
+#ifndef _NODE_HANDLE
+#define _NODE_HANDLE 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201402L
+# define __cpp_lib_node_extract 201606
+
+#include <optional>
+#include <tuple>
+#include <bits/alloc_traits.h>
+#include <bits/ptr_traits.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /// Base class for node handle types of maps and sets.
+ template<typename _Val, typename _NodeAlloc>
+ class _Node_handle_common
+ {
+ using _AllocTraits = allocator_traits<_NodeAlloc>;
+
+ public:
+ using allocator_type = __alloc_rebind<_NodeAlloc, _Val>;
+
+ allocator_type
+ get_allocator() const noexcept
+ {
+ __glibcxx_assert(!this->empty());
+ return allocator_type(*_M_alloc);
+ }
+
+ explicit operator bool() const noexcept { return _M_ptr != nullptr; }
+
+ bool empty() const noexcept { return _M_ptr == nullptr; }
+
+ protected:
+ constexpr _Node_handle_common() noexcept : _M_ptr(), _M_alloc() {}
+
+ ~_Node_handle_common() { _M_destroy(); }
+
+ _Node_handle_common(_Node_handle_common&& __nh) noexcept
+ : _M_ptr(__nh._M_ptr), _M_alloc(std::move(__nh._M_alloc))
+ {
+ __nh._M_ptr = nullptr;
+ __nh._M_alloc = nullopt;
+ }
+
+ _Node_handle_common&
+ operator=(_Node_handle_common&& __nh) noexcept
+ {
+ _M_destroy();
+ _M_ptr = __nh._M_ptr;
+ if constexpr (is_move_assignable_v<_NodeAlloc>)
+ {
+ if (_AllocTraits::propagate_on_container_move_assignment::value
+ || !this->_M_alloc)
+ this->_M_alloc = std::move(__nh._M_alloc);
+ else
+ __glibcxx_assert(this->_M_alloc == __nh._M_alloc);
+ }
+ else
+ __glibcxx_assert(_M_alloc);
+ __nh._M_ptr = nullptr;
+ __nh._M_alloc = nullopt;
+ return *this;
+ }
+
+ _Node_handle_common(typename _AllocTraits::pointer __ptr,
+ const _NodeAlloc& __alloc)
+ : _M_ptr(__ptr), _M_alloc(__alloc) { }
+
+ void
+ _M_swap(_Node_handle_common& __nh) noexcept
+ {
+ using std::swap;
+ swap(_M_ptr, __nh._M_ptr);
+ if (_AllocTraits::propagate_on_container_swap
+ || !_M_alloc || !__nh._M_alloc)
+ _M_alloc.swap(__nh._M_alloc);
+ else
+ __glibcxx_assert(_M_alloc == __nh._M_alloc);
+ }
+
+ private:
+ void
+ _M_destroy() noexcept
+ {
+ if (_M_ptr != nullptr)
+ {
+ allocator_type __alloc(*_M_alloc);
+ allocator_traits<allocator_type>::destroy(__alloc,
+ _M_ptr->_M_valptr());
+ _AllocTraits::deallocate(*_M_alloc, _M_ptr, 1);
+ }
+ }
+
+ protected:
+ typename _AllocTraits::pointer _M_ptr;
+ private:
+ optional<_NodeAlloc> _M_alloc;
+
+ template<typename _Key2, typename _Value2, typename _KeyOfValue,
+ typename _Compare, typename _ValueAlloc>
+ friend class _Rb_tree;
+ };
+
+ /// Node handle type for maps.
+ template<typename _Key, typename _Value, typename _NodeAlloc>
+ class _Node_handle : public _Node_handle_common<_Value, _NodeAlloc>
+ {
+ public:
+ constexpr _Node_handle() noexcept = default;
+ ~_Node_handle() = default;
+ _Node_handle(_Node_handle&&) noexcept = default;
+
+ _Node_handle&
+ operator=(_Node_handle&&) noexcept = default;
+
+ using key_type = _Key;
+ using mapped_type = typename _Value::second_type;
+
+ key_type&
+ key() const noexcept
+ {
+ __glibcxx_assert(!this->empty());
+ return *_M_pkey;
+ }
+
+ mapped_type&
+ mapped() const noexcept
+ {
+ __glibcxx_assert(!this->empty());
+ return *_M_pmapped;
+ }
+
+ void
+ swap(_Node_handle& __nh) noexcept
+ {
+ this->_M_swap(__nh);
+ using std::swap;
+ swap(_M_pkey, __nh._M_pkey);
+ swap(_M_pmapped, __nh._M_pmapped);
+ }
+
+ friend void
+ swap(_Node_handle& __x, _Node_handle& __y)
+ noexcept(noexcept(__x.swap(__y)))
+ { __x.swap(__y); }
+
+ private:
+ using _AllocTraits = allocator_traits<_NodeAlloc>;
+
+ using _PtrTraits = pointer_traits<typename _NodeAlloc::pointer>;
+
+ _Node_handle(typename _AllocTraits::pointer __ptr,
+ const _NodeAlloc& __alloc)
+ : _Node_handle_common<_Value, _NodeAlloc>(__ptr, __alloc)
+ {
+ if (__ptr)
+ {
+ auto& __key = const_cast<_Key&>(__ptr->_M_valptr()->first);
+ _M_pkey = _S_pointer_to(__key);
+ _M_pmapped = _S_pointer_to(__ptr->_M_valptr()->second);
+ }
+ else
+ {
+ _M_pkey = nullptr;
+ _M_pmapped = nullptr;
+ }
+ }
+
+ template<typename _Tp>
+ using __pointer = __ptr_rebind<typename _AllocTraits::pointer, _Tp>;
+
+ __pointer<_Key> _M_pkey = nullptr;
+ __pointer<typename _Value::second_type> _M_pmapped = nullptr;
+
+ template<typename _Tp>
+ __pointer<_Tp>
+ _S_pointer_to(_Tp& __obj)
+ { return pointer_traits<__pointer<_Tp>>::pointer_to(__obj); }
+
+ const key_type&
+ _M_key() const noexcept { return key(); }
+
+ template<typename _Key2, typename _Value2, typename _KeyOfValue,
+ typename _Compare, typename _ValueAlloc>
+ friend class _Rb_tree;
+
+ template<typename _Key2, typename _Value2, typename _ValueAlloc,
+ typename _ExtractKey, typename _Equal,
+ typename _H1, typename _H2, typename _Hash,
+ typename _RehashPolicy, typename _Traits>
+ friend class _Hashtable;
+ };
+
+ /// Node handle type for sets.
+ template<typename _Value, typename _NodeAlloc>
+ class _Node_handle<_Value, _Value, _NodeAlloc>
+ : public _Node_handle_common<_Value, _NodeAlloc>
+ {
+ public:
+ constexpr _Node_handle() noexcept = default;
+ ~_Node_handle() = default;
+ _Node_handle(_Node_handle&&) noexcept = default;
+
+ _Node_handle&
+ operator=(_Node_handle&&) noexcept = default;
+
+ using value_type = _Value;
+
+ value_type&
+ value() const noexcept
+ {
+ __glibcxx_assert(!this->empty());
+ return *this->_M_ptr->_M_valptr();
+ }
+
+ void
+ swap(_Node_handle& __nh) noexcept
+ { this->_M_swap(__nh); }
+
+ friend void
+ swap(_Node_handle& __x, _Node_handle& __y)
+ noexcept(noexcept(__x.swap(__y)))
+ { __x.swap(__y); }
+
+ private:
+ using _AllocTraits = allocator_traits<_NodeAlloc>;
+
+ _Node_handle(typename _AllocTraits::pointer __ptr,
+ const _NodeAlloc& __alloc)
+ : _Node_handle_common<_Value, _NodeAlloc>(__ptr, __alloc) { }
+
+ const value_type&
+ _M_key() const noexcept { return value(); }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ friend class _Rb_tree;
+
+ template<typename _Key2, typename _Value2, typename _ValueAlloc,
+ typename _ExtractKey, typename _Equal,
+ typename _H1, typename _H2, typename _Hash,
+ typename _RehashPolicy, typename _Traits>
+ friend class _Hashtable;
+ };
+
+ /// Return type of insert(node_handle&&) on unique maps/sets.
+ template<typename _Iterator, typename _NodeHandle>
+ struct _Node_insert_return
+ {
+ bool inserted = false;
+ _Iterator position = _Iterator();
+ _NodeHandle node;
+
+ template<size_t _Idx>
+ decltype(auto) get() &
+ { return std::get<_Idx>(std::tie(inserted, position, node)); }
+
+ template<size_t _Idx>
+ decltype(auto) get() const &
+ { return std::get<_Idx>(std::tie(inserted, position, node)); }
+
+ template<size_t _Idx>
+ decltype(auto) get() &&
+ {
+ return std::move(std::get<_Idx>(std::tie(inserted, position, node)));
+ }
+
+ template<size_t _Idx>
+ decltype(auto) get() const &&
+ {
+ return std::move(std::get<_Idx>(std::tie(inserted, position, node)));
+ }
+ };
+
+ template<typename _Iterator, typename _NodeHandle>
+ struct tuple_size<_Node_insert_return<_Iterator, _NodeHandle>>
+ : integral_constant<size_t, 3> { };
+
+ template<typename _Iterator, typename _NodeHandle>
+ struct tuple_element<0, _Node_insert_return<_Iterator, _NodeHandle>>
+ { using type = bool; };
+
+ template<typename _Iterator, typename _NodeHandle>
+ struct tuple_element<1, _Node_insert_return<_Iterator, _NodeHandle>>
+ { using type = _Iterator; };
+
+ template<typename _Iterator, typename _NodeHandle>
+ struct tuple_element<2, _Node_insert_return<_Iterator, _NodeHandle>>
+ { using type = _NodeHandle; };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++17
+#endif
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index 27cc8ede458..95c3d52099a 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -38,10 +38,6 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
-#if __cplusplus >= 201402L
-# define __cpp_lib_array_constexpr 201603L
-#endif
-
/**
* @brief Return an iterator pointing to the first element of
* the container.
diff --git a/libstdc++-v3/include/bits/std_abs.h b/libstdc++-v3/include/bits/std_abs.h
new file mode 100644
index 00000000000..ab0f980a3a6
--- /dev/null
+++ b/libstdc++-v3/include/bits/std_abs.h
@@ -0,0 +1,107 @@
+// -*- C++ -*- C library enhancements header.
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/std_abs.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{cmath, cstdlib}
+ */
+
+#ifndef _GLIBCXX_BITS_STD_ABS_H
+#define _GLIBCXX_BITS_STD_ABS_H
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+
+#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include_next <stdlib.h>
+#ifdef __CORRECT_ISO_CPP_MATH_H_PROTO
+# include_next <math.h>
+#endif
+#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+
+#undef abs
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ using ::abs;
+
+#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
+ inline long
+ abs(long __i) { return __builtin_labs(__i); }
+#endif
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+ inline long long
+ abs(long long __x) { return __builtin_llabs (__x); }
+#endif
+
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 2192. Validity and return type of std::abs(0u) is unclear
+// 2294. <cstdlib> should declare abs(double)
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+ inline _GLIBCXX_CONSTEXPR double
+ abs(double __x)
+ { return __builtin_fabs(__x); }
+
+ inline _GLIBCXX_CONSTEXPR float
+ abs(float __x)
+ { return __builtin_fabsf(__x); }
+
+ inline _GLIBCXX_CONSTEXPR long double
+ abs(long double __x)
+ { return __builtin_fabsl(__x); }
+#endif
+
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_0
+ abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_1
+ abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_2
+ abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
+ inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_3
+ abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+
+#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
+ inline _GLIBCXX_CONSTEXPR
+ __float128
+ abs(__float128 __x)
+ { return __x < 0 ? -__x : __x; }
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif // _GLIBCXX_BITS_STD_ABS_H
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index 3d126288d85..4a771c4f0d1 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -84,6 +84,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif
+ template<typename _T1>
+ inline void
+ _Construct_novalue(_T1* __p)
+ { ::new(static_cast<void*>(__p)) _T1; }
+
/**
* Destroy the object pointed to by a pointer type.
*/
@@ -127,6 +132,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__destroy(__first, __last);
}
+ template<bool>
+ struct _Destroy_n_aux
+ {
+ template<typename _ForwardIterator, typename _Size>
+ static _ForwardIterator
+ __destroy_n(_ForwardIterator __first, _Size __count)
+ {
+ for (; __count > 0; (void)++__first, --__count)
+ std::_Destroy(std::__addressof(*__first));
+ return __first;
+ }
+ };
+
+ template<>
+ struct _Destroy_n_aux<true>
+ {
+ template<typename _ForwardIterator, typename _Size>
+ static _ForwardIterator
+ __destroy_n(_ForwardIterator __first, _Size __count)
+ {
+ std::advance(__first, __count);
+ return __first;
+ }
+ };
+
+ /**
+ * Destroy a range of objects. If the value_type of the object has
+ * a trivial destructor, the compiler should optimize all of this
+ * away, otherwise the objects' destructors must be invoked.
+ */
+ template<typename _ForwardIterator, typename _Size>
+ inline _ForwardIterator
+ _Destroy_n(_ForwardIterator __first, _Size __count)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::value_type
+ _Value_type;
+ return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
+ __destroy_n(__first, __count);
+ }
+
/**
* Destroy a range of objects using the supplied allocator. For
* nondefault allocators we do not optimize away invocation of
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index 29bade7298b..9a0454aa583 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -67,6 +67,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
+ template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ class multimap;
+
/**
* @brief A standard container made up of (key,value) pairs, which can be
* retrieved based on a key, in logarithmic time.
@@ -153,6 +156,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Rep_type::reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+#if __cplusplus > 201402L
+ using node_type = typename _Rep_type::node_type;
+ using insert_return_type = typename _Rep_type::insert_return_type;
+#endif
+
// [23.3.1.1] construct/copy/destroy
// (get_allocator() is also listed in this section)
@@ -594,6 +602,60 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_t.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __x)
+ { return _M_t.extract(__x); }
+
+ /// Re-insert an extracted node.
+ insert_return_type
+ insert(node_type&& __nh)
+ { return _M_t._M_reinsert_node_unique(std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ { return _M_t._M_reinsert_node_hint_unique(__hint, std::move(__nh)); }
+
+ template<typename, typename>
+ friend class _Rb_tree_merge_helper;
+
+ template<typename _C2>
+ void
+ merge(map<_Key, _Tp, _C2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<map, _C2>;
+ _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _C2>
+ void
+ merge(map<_Key, _Tp, _C2, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _C2>
+ void
+ merge(multimap<_Key, _Tp, _C2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<map, _C2>;
+ _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _C2>
+ void
+ merge(multimap<_Key, _Tp, _C2, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
+#if __cplusplus > 201402L
#define __cpp_lib_map_try_emplace 201411
/**
* @brief Attempts to build and insert a std::pair into the %map.
@@ -1365,6 +1427,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
+
+#if __cplusplus > 201402L
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // Allow std::map access to internals of compatible maps.
+ template<typename _Key, typename _Val, typename _Cmp1, typename _Alloc,
+ typename _Cmp2>
+ struct
+ _Rb_tree_merge_helper<_GLIBCXX_STD_C::map<_Key, _Val, _Cmp1, _Alloc>,
+ _Cmp2>
+ {
+ private:
+ friend class _GLIBCXX_STD_C::map<_Key, _Val, _Cmp1, _Alloc>;
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::map<_Key, _Val, _Cmp2, _Alloc>& __map)
+ { return __map._M_t; }
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp2, _Alloc>& __map)
+ { return __map._M_t; }
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+#endif // C++17
+
} // namespace std
#endif /* _STL_MAP_H */
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 0bb379fed5f..c794b9bec4e 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -65,6 +65,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
+ template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ class map;
+
/**
* @brief A standard container made up of (key,value) pairs, which can be
* retrieved based on a key, in logarithmic time.
@@ -151,6 +154,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Rep_type::reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+#if __cplusplus > 201402L
+ using node_type = typename _Rep_type::node_type;
+#endif
+
// [23.3.2] construct/copy/destroy
// (get_allocator() is also listed in this section)
@@ -595,6 +602,60 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ this->insert(__l.begin(), __l.end()); }
#endif
+#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_t.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __x)
+ { return _M_t.extract(__x); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(node_type&& __nh)
+ { return _M_t._M_reinsert_node_equal(std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ { return _M_t._M_reinsert_node_hint_equal(__hint, std::move(__nh)); }
+
+ template<typename, typename>
+ friend class _Rb_tree_merge_helper;
+
+ template<typename _C2>
+ void
+ merge(multimap<_Key, _Tp, _C2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<multimap, _C2>;
+ _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _C2>
+ void
+ merge(multimap<_Key, _Tp, _C2, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _C2>
+ void
+ merge(map<_Key, _Tp, _C2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<multimap, _C2>;
+ _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _C2>
+ void
+ merge(map<_Key, _Tp, _C2, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
@@ -1030,6 +1091,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
+
+#if __cplusplus > 201402L
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // Allow std::multimap access to internals of compatible maps.
+ template<typename _Key, typename _Val, typename _Cmp1, typename _Alloc,
+ typename _Cmp2>
+ struct
+ _Rb_tree_merge_helper<_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp1, _Alloc>,
+ _Cmp2>
+ {
+ private:
+ friend class _GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp1, _Alloc>;
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::map<_Key, _Val, _Cmp2, _Alloc>& __map)
+ { return __map._M_t; }
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp2, _Alloc>& __map)
+ { return __map._M_t; }
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+#endif // C++17
+
} // namespace std
#endif /* _STL_MULTIMAP_H */
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 13b253c64c5..d3219ebf083 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -65,6 +65,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
+ template<typename _Key, typename _Compare, typename _Alloc>
+ class set;
+
/**
* @brief A standard container made up of elements, which can be retrieved
* in logarithmic time.
@@ -133,6 +136,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Rep_type::size_type size_type;
typedef typename _Rep_type::difference_type difference_type;
+#if __cplusplus > 201402L
+ using node_type = typename _Rep_type::node_type;
+#endif
+
// allocation/deallocation
/**
* @brief Default constructor creates no elements.
@@ -538,6 +545,60 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ this->insert(__l.begin(), __l.end()); }
#endif
+#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_t.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __x)
+ { return _M_t.extract(__x); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(node_type&& __nh)
+ { return _M_t._M_reinsert_node_equal(std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ { return _M_t._M_reinsert_node_hint_equal(__hint, std::move(__nh)); }
+
+ template<typename, typename>
+ friend class _Rb_tree_merge_helper;
+
+ template<typename _Compare1>
+ void
+ merge(multiset<_Key, _Compare1, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<multiset, _Compare1>;
+ _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _Compare1>
+ void
+ merge(multiset<_Key, _Compare1, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _Compare1>
+ void
+ merge(set<_Key, _Compare1, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<multiset, _Compare1>;
+ _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _Compare1>
+ void
+ merge(set<_Key, _Compare1, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
@@ -881,6 +942,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
+
+#if __cplusplus > 201402L
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // Allow std::multiset access to internals of compatible sets.
+ template<typename _Val, typename _Cmp1, typename _Alloc, typename _Cmp2>
+ struct
+ _Rb_tree_merge_helper<_GLIBCXX_STD_C::multiset<_Val, _Cmp1, _Alloc>,
+ _Cmp2>
+ {
+ private:
+ friend class _GLIBCXX_STD_C::multiset<_Val, _Cmp1, _Alloc>;
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::set<_Val, _Cmp2, _Alloc>& __set)
+ { return __set._M_t; }
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set)
+ { return __set._M_t; }
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+#endif // C++17
+
} // namespace std
#endif /* _STL_MULTISET_H */
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index 5ff160ac6d1..ef5253823ef 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -88,52 +88,95 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Concept utility functions, reused in conditionally-explicit
// constructors.
// See PR 70437, don't look at is_constructible or
- // is_convertible if the decayed types are the same to
+ // is_convertible if the types are the same to
// avoid querying those properties for incomplete types.
- template <typename _T1, typename _T2, typename _U1, typename _U2>
- constexpr bool _ConstructiblePair()
- {
- return __and_<__or_<is_same<typename decay<_T1>::type,
- typename decay<_U1>::type>,
- is_constructible<_T1, const _U1&>>,
- __or_<is_same<typename decay<_T2>::type,
- typename decay<_U2>::type>,
- is_constructible<_T2, const _U2&>>>::value;
- }
-
- template <typename _T1, typename _T2, typename _U1, typename _U2>
- constexpr bool _ImplicitlyConvertiblePair()
- {
- return __and_<__or_<is_same<typename decay<_T1>::type,
- typename decay<_U1>::type>,
- is_convertible<const _U1&, _T1>>,
- __or_<is_same<typename decay<_T2>::type,
- typename decay<_U2>::type>,
- is_convertible<const _U2&, _T2>>>::value;
- }
-
- template <typename _T1, typename _T2, typename _U1, typename _U2>
- constexpr bool _MoveConstructiblePair()
- {
- return __and_<__or_<is_same<typename decay<_T1>::type,
- typename decay<_U1>::type>,
- is_constructible<_T1, _U1&&>>,
- __or_<is_same<typename decay<_T2>::type,
- typename decay<_U2>::type>,
- is_constructible<_T2, _U2&&>>>::value;
- }
-
- template <typename _T1, typename _T2, typename _U1, typename _U2>
- constexpr bool _ImplicitlyMoveConvertiblePair()
- {
- return __and_<__or_<is_same<typename decay<_T1>::type,
- typename decay<_U1>::type>,
- is_convertible<_U1&&, _T1>>,
- __or_<is_same<typename decay<_T2>::type,
- typename decay<_U2>::type>,
- is_convertible<_U2&&, _T2>>>::value;
- }
+ template <bool, typename _T1, typename _T2>
+ struct _PCC
+ {
+ template <typename _U1, typename _U2>
+ static constexpr bool _ConstructiblePair()
+ {
+ return __and_<is_constructible<_T1, const _U1&>,
+ is_constructible<_T2, const _U2&>>::value;
+ }
+
+ template <typename _U1, typename _U2>
+ static constexpr bool _ImplicitlyConvertiblePair()
+ {
+ return __and_<is_convertible<const _U1&, _T1>,
+ is_convertible<const _U2&, _T2>>::value;
+ }
+
+ template <typename _U1, typename _U2>
+ static constexpr bool _MoveConstructiblePair()
+ {
+ return __and_<is_constructible<_T1, _U1&&>,
+ is_constructible<_T2, _U2&&>>::value;
+ }
+ template <typename _U1, typename _U2>
+ static constexpr bool _ImplicitlyMoveConvertiblePair()
+ {
+ return __and_<is_convertible<_U1&&, _T1>,
+ is_convertible<_U2&&, _T2>>::value;
+ }
+
+ template <bool __implicit, typename _U1, typename _U2>
+ static constexpr bool _CopyMovePair()
+ {
+ using __do_converts = __and_<is_convertible<const _U1&, _T1>,
+ is_convertible<_U2&&, _T2>>;
+ using __converts = typename conditional<__implicit,
+ __do_converts,
+ __not_<__do_converts>>::type;
+ return __and_<is_constructible<_T1, const _U1&>,
+ is_constructible<_T2, _U2&&>,
+ __converts
+ >::value;
+ }
+
+ template <bool __implicit, typename _U1, typename _U2>
+ static constexpr bool _MoveCopyPair()
+ {
+ using __do_converts = __and_<is_convertible<_U1&&, _T1>,
+ is_convertible<const _U2&, _T2>>;
+ using __converts = typename conditional<__implicit,
+ __do_converts,
+ __not_<__do_converts>>::type;
+ return __and_<is_constructible<_T1, _U1&&>,
+ is_constructible<_T2, const _U2&&>,
+ __converts
+ >::value;
+ }
+ };
+
+ template <typename _T1, typename _T2>
+ struct _PCC<false, _T1, _T2>
+ {
+ template <typename _U1, typename _U2>
+ static constexpr bool _ConstructiblePair()
+ {
+ return false;
+ }
+
+ template <typename _U1, typename _U2>
+ static constexpr bool _ImplicitlyConvertiblePair()
+ {
+ return false;
+ }
+
+ template <typename _U1, typename _U2>
+ static constexpr bool _MoveConstructiblePair()
+ {
+ return false;
+ }
+
+ template <typename _U1, typename _U2>
+ static constexpr bool _ImplicitlyMoveConvertiblePair()
+ {
+ return false;
+ }
+ };
#endif
@@ -186,16 +229,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pair(const _T1& __a, const _T2& __b)
: first(__a), second(__b) { }
#else
+ // Shortcut for constraining the templates that don't take pairs.
+ using _PCCP = _PCC<true, _T1, _T2>;
+
template<typename _U1 = _T1, typename _U2=_T2, typename
- enable_if<_ConstructiblePair<_T1, _T2, _U1, _U2>()
- && _ImplicitlyConvertiblePair<_T1, _T2, _U1, _U2>(),
+ enable_if<_PCCP::template
+ _ConstructiblePair<_U1, _U2>()
+ && _PCCP::template
+ _ImplicitlyConvertiblePair<_U1, _U2>(),
bool>::type=true>
constexpr pair(const _T1& __a, const _T2& __b)
: first(__a), second(__b) { }
template<typename _U1 = _T1, typename _U2=_T2, typename
- enable_if<_ConstructiblePair<_T1, _T2, _U1, _U2>()
- && !_ImplicitlyConvertiblePair<_T1, _T2, _U1, _U2>(),
+ enable_if<_PCCP::template
+ _ConstructiblePair<_U1, _U2>()
+ && !_PCCP::template
+ _ImplicitlyConvertiblePair<_U1, _U2>(),
bool>::type=false>
explicit constexpr pair(const _T1& __a, const _T2& __b)
: first(__a), second(__b) { }
@@ -207,16 +257,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pair(const pair<_U1, _U2>& __p)
: first(__p.first), second(__p.second) { }
#else
+ // Shortcut for constraining the templates that take pairs.
+ template <typename _U1, typename _U2>
+ using _PCCFP = _PCC<!is_same<_T1, _U1>::value
+ || !is_same<_T2, _U2>::value,
+ _T1, _T2>;
+
template<typename _U1, typename _U2, typename
- enable_if<_ConstructiblePair<_T1, _T2, _U1, _U2>()
- && _ImplicitlyConvertiblePair<_T1, _T2, _U1, _U2>(),
- bool>::type=true>
+ enable_if<_PCCFP<_U1, _U2>::template
+ _ConstructiblePair<_U1, _U2>()
+ && _PCCFP<_U1, _U2>::template
+ _ImplicitlyConvertiblePair<_U1, _U2>(),
+ bool>::type=true>
constexpr pair(const pair<_U1, _U2>& __p)
: first(__p.first), second(__p.second) { }
template<typename _U1, typename _U2, typename
- enable_if<_ConstructiblePair<_T1, _T2, _U1, _U2>()
- && !_ImplicitlyConvertiblePair<_T1, _T2, _U1, _U2>(),
+ enable_if<_PCCFP<_U1, _U2>::template
+ _ConstructiblePair<_U1, _U2>()
+ && !_PCCFP<_U1, _U2>::template
+ _ImplicitlyConvertiblePair<_U1, _U2>(),
bool>::type=false>
explicit constexpr pair(const pair<_U1, _U2>& __p)
: first(__p.first), second(__p.second) { }
@@ -226,75 +286,67 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// DR 811.
template<typename _U1, typename
- enable_if<_ConstructiblePair<_T2, _T2, _T2, _T2>()
- && _MoveConstructiblePair<_T1, _T2, _U1, _T2>()
- && _ImplicitlyConvertiblePair<_T2, _T2, _T2, _T2>()
- && _ImplicitlyMoveConvertiblePair<_T1, _T2,
- _U1, _T2>(),
+ enable_if<_PCCP::template
+ _MoveCopyPair<true, _U1, _T2>(),
bool>::type=true>
constexpr pair(_U1&& __x, const _T2& __y)
: first(std::forward<_U1>(__x)), second(__y) { }
template<typename _U1, typename
- enable_if<_ConstructiblePair<_T2, _T2, _T2, _T2>()
- && _MoveConstructiblePair<_T1, _T2, _U1, _T2>()
- && (!_ImplicitlyConvertiblePair<_T2, _T2, _T2, _T2>()
- || !_ImplicitlyMoveConvertiblePair<_T1, _T2,
- _U1, _T2>()),
+ enable_if<_PCCP::template
+ _MoveCopyPair<false, _U1, _T2>(),
bool>::type=false>
explicit constexpr pair(_U1&& __x, const _T2& __y)
: first(std::forward<_U1>(__x)), second(__y) { }
template<typename _U2, typename
- enable_if<_ConstructiblePair<_T1, _T1, _T1, _T1>()
- && _MoveConstructiblePair<_T1, _T2, _T1, _U2>()
- && _ImplicitlyConvertiblePair<_T1, _T1, _T1, _T1>()
- && _ImplicitlyMoveConvertiblePair<_T1, _T2,
- _T1, _U2>(),
+ enable_if<_PCCP::template
+ _CopyMovePair<true, _T1, _U2>(),
bool>::type=true>
constexpr pair(const _T1& __x, _U2&& __y)
: first(__x), second(std::forward<_U2>(__y)) { }
template<typename _U2, typename
- enable_if<_ConstructiblePair<_T1, _T1, _T1, _T1>()
- && _MoveConstructiblePair<_T1, _T2, _T1, _U2>()
- && (!_ImplicitlyConvertiblePair<_T1, _T1, _T1, _T1>()
- || !_ImplicitlyMoveConvertiblePair<_T1, _T2,
- _T1, _U2>()),
+ enable_if<_PCCP::template
+ _CopyMovePair<false, _T1, _U2>(),
bool>::type=false>
explicit pair(const _T1& __x, _U2&& __y)
: first(__x), second(std::forward<_U2>(__y)) { }
template<typename _U1, typename _U2, typename
- enable_if<_MoveConstructiblePair<_T1, _T2, _U1, _U2>()
- && _ImplicitlyMoveConvertiblePair<_T1, _T2,
- _U1, _U2>(),
+ enable_if<_PCCP::template
+ _MoveConstructiblePair<_U1, _U2>()
+ && _PCCP::template
+ _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
bool>::type=true>
constexpr pair(_U1&& __x, _U2&& __y)
: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
template<typename _U1, typename _U2, typename
- enable_if<_MoveConstructiblePair<_T1, _T2, _U1, _U2>()
- && !_ImplicitlyMoveConvertiblePair<_T1, _T2,
- _U1, _U2>(),
+ enable_if<_PCCP::template
+ _MoveConstructiblePair<_U1, _U2>()
+ && !_PCCP::template
+ _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
bool>::type=false>
explicit constexpr pair(_U1&& __x, _U2&& __y)
: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
template<typename _U1, typename _U2, typename
- enable_if<_MoveConstructiblePair<_T1, _T2, _U1, _U2>()
- && _ImplicitlyMoveConvertiblePair<_T1, _T2,
- _U1, _U2>(),
+ enable_if<_PCCFP<_U1, _U2>::template
+ _MoveConstructiblePair<_U1, _U2>()
+ && _PCCFP<_U1, _U2>::template
+ _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
bool>::type=true>
constexpr pair(pair<_U1, _U2>&& __p)
: first(std::forward<_U1>(__p.first)),
second(std::forward<_U2>(__p.second)) { }
template<typename _U1, typename _U2, typename
- enable_if<_MoveConstructiblePair<_T1, _T2, _U1, _U2>()
- && !_ImplicitlyMoveConvertiblePair<_T1, _T2,
- _U1, _U2>(),
+ enable_if<_PCCFP<_U1, _U2>::template
+ _MoveConstructiblePair<_U1, _U2>()
+ && !_PCCFP<_U1, _U2>::template
+ _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
bool>::type=false>
explicit constexpr pair(pair<_U1, _U2>&& __p)
: first(std::forward<_U1>(__p.first)),
@@ -304,7 +356,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
pair&
- operator=(const pair& __p)
+ operator=(typename conditional<
+ __and_<is_copy_assignable<_T1>,
+ is_copy_assignable<_T2>>::value,
+ const pair&, const __nonesuch&>::type __p)
{
first = __p.first;
second = __p.second;
@@ -312,7 +367,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
pair&
- operator=(pair&& __p)
+ operator=(typename conditional<
+ __not_<__and_<is_copy_assignable<_T1>,
+ is_copy_assignable<_T2>>>::value,
+ const pair&, const __nonesuch&>::type __p) = delete;
+
+ pair&
+ operator=(typename conditional<
+ __and_<is_move_assignable<_T1>,
+ is_move_assignable<_T2>>::value,
+ pair&&, __nonesuch&&>::type __p)
noexcept(__and_<is_nothrow_move_assignable<_T1>,
is_nothrow_move_assignable<_T2>>::value)
{
@@ -322,7 +386,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- pair&
+ typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
+ is_assignable<_T2&, const _U2&>>::value,
+ pair&>::type
operator=(const pair<_U1, _U2>& __p)
{
first = __p.first;
@@ -331,7 +397,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- pair&
+ typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
+ is_assignable<_T2&, _U2&&>>::value,
+ pair&>::type
operator=(pair<_U1, _U2>&& __p)
{
first = std::forward<_U1>(__p.first);
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index c104310f121..140db39c9f6 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -65,6 +65,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
+ template<typename _Key, typename _Compare, typename _Alloc>
+ class multiset;
+
/**
* @brief A standard container made up of unique keys, which can be
* retrieved in logarithmic time.
@@ -135,6 +138,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Rep_type::difference_type difference_type;
//@}
+#if __cplusplus > 201402L
+ using node_type = typename _Rep_type::node_type;
+ using insert_return_type = typename _Rep_type::insert_return_type;
+#endif
+
// allocation/deallocation
/**
* @brief Default constructor creates no elements.
@@ -553,6 +561,60 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ this->insert(__l.begin(), __l.end()); }
#endif
+#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_t.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __x)
+ { return _M_t.extract(__x); }
+
+ /// Re-insert an extracted node.
+ insert_return_type
+ insert(node_type&& __nh)
+ { return _M_t._M_reinsert_node_unique(std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ { return _M_t._M_reinsert_node_hint_unique(__hint, std::move(__nh)); }
+
+ template<typename, typename>
+ friend class _Rb_tree_merge_helper;
+
+ template<typename _Compare1>
+ void
+ merge(set<_Key, _Compare1, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<set, _Compare1>;
+ _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _Compare1>
+ void
+ merge(set<_Key, _Compare1, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _Compare1>
+ void
+ merge(multiset<_Key, _Compare1, _Alloc>& __source)
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<set, _Compare1>;
+ _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source));
+ }
+
+ template<typename _Compare1>
+ void
+ merge(multiset<_Key, _Compare1, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
@@ -897,5 +959,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
+
+#if __cplusplus > 201402L
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // Allow std::set access to internals of compatible sets.
+ template<typename _Val, typename _Cmp1, typename _Alloc, typename _Cmp2>
+ struct
+ _Rb_tree_merge_helper<_GLIBCXX_STD_C::set<_Val, _Cmp1, _Alloc>, _Cmp2>
+ {
+ private:
+ friend class _GLIBCXX_STD_C::set<_Val, _Cmp1, _Alloc>;
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::set<_Val, _Cmp2, _Alloc>& __set)
+ { return __set._M_t; }
+
+ static auto&
+ _S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set)
+ { return __set._M_t; }
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+#endif // C++17
+
} //namespace std
#endif /* _STL_SET_H */
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 02b00b01c54..32da609e38d 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -66,7 +66,10 @@
#include <bits/cpp_type_traits.h>
#include <ext/alloc_traits.h>
#if __cplusplus >= 201103L
-#include <ext/aligned_buffer.h>
+# include <ext/aligned_buffer.h>
+#endif
+#if __cplusplus > 201402L
+# include <bits/node_handle.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
@@ -356,6 +359,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ typedef void type; };
#endif
+#if __cplusplus > 201402L
+ template<typename _Tree1, typename _Cmp2>
+ struct _Rb_tree_merge_helper { };
+#endif
+
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc = allocator<_Val> >
class _Rb_tree
@@ -735,6 +743,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+#if __cplusplus > 201402L
+ using node_type = _Node_handle<_Key, _Val, _Node_allocator>;
+ using insert_return_type = _Node_insert_return<iterator, node_type>;
+#endif
+
pair<_Base_ptr, _Base_ptr>
_M_get_insert_unique_pos(const key_type& __k);
@@ -1274,6 +1287,172 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_move_assign(_Rb_tree&, std::false_type);
#endif
+
+#if __cplusplus > 201402L
+ public:
+ /// Re-insert an extracted node.
+ insert_return_type
+ _M_reinsert_node_unique(node_type&& __nh)
+ {
+ insert_return_type __ret;
+ if (__nh.empty())
+ __ret.position = end();
+ else
+ {
+ __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
+
+ auto __res = _M_get_insert_unique_pos(__nh._M_key());
+ if (__res.second)
+ {
+ __ret.position
+ = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
+ __nh._M_ptr = nullptr;
+ __ret.inserted = true;
+ }
+ else
+ {
+ __ret.node = std::move(__nh);
+ __ret.position = iterator(__res.first);
+ __ret.inserted = false;
+ }
+ }
+ return __ret;
+ }
+
+ /// Re-insert an extracted node.
+ iterator
+ _M_reinsert_node_equal(node_type&& __nh)
+ {
+ iterator __ret;
+ if (__nh.empty())
+ __ret = end();
+ else
+ {
+ __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
+ auto __res = _M_get_insert_equal_pos(__nh._M_key());
+ if (__res.second)
+ __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
+ else
+ __ret = _M_insert_equal_lower_node(__nh._M_ptr);
+ __nh._M_ptr = nullptr;
+ }
+ return __ret;
+ }
+
+ /// Re-insert an extracted node.
+ iterator
+ _M_reinsert_node_hint_unique(const_iterator __hint, node_type&& __nh)
+ {
+ iterator __ret;
+ if (__nh.empty())
+ __ret = end();
+ else
+ {
+ __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
+ auto __res = _M_get_insert_hint_unique_pos(__hint, __nh._M_key());
+ if (__res.second)
+ {
+ __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
+ __nh._M_ptr = nullptr;
+ }
+ else
+ __ret = iterator(__res.first);
+ }
+ return __ret;
+ }
+
+ /// Re-insert an extracted node.
+ iterator
+ _M_reinsert_node_hint_equal(const_iterator __hint, node_type&& __nh)
+ {
+ iterator __ret;
+ if (__nh.empty())
+ __ret = end();
+ else
+ {
+ __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
+ auto __res = _M_get_insert_hint_equal_pos(__hint, __nh._M_key());
+ if (__res.second)
+ __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
+ else
+ __ret = _M_insert_equal_lower_node(__nh._M_ptr);
+ __nh._M_ptr = nullptr;
+ }
+ return __ret;
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ auto __ptr = _Rb_tree_rebalance_for_erase(
+ __pos._M_const_cast()._M_node, _M_impl._M_header);
+ --_M_impl._M_node_count;
+ return { static_cast<_Link_type>(__ptr), _M_get_Node_allocator() };
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __k)
+ {
+ node_type __nh;
+ auto __pos = find(__k);
+ if (__pos != end())
+ __nh = extract(const_iterator(__pos));
+ return __nh;
+ }
+
+ template<typename _Compare2>
+ using _Compatible_tree
+ = _Rb_tree<_Key, _Val, _KeyOfValue, _Compare2, _Alloc>;
+
+ template<typename, typename>
+ friend class _Rb_tree_merge_helper;
+
+ /// Merge from a compatible container into one with unique keys.
+ template<typename _Compare2>
+ void
+ _M_merge_unique(_Compatible_tree<_Compare2>& __src) noexcept
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
+ for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
+ {
+ auto __pos = __i++;
+ auto __res = _M_get_insert_unique_pos(_KeyOfValue()(*__pos));
+ if (__res.second)
+ {
+ auto& __src_impl = _Merge_helper::_S_get_impl(__src);
+ auto __ptr = _Rb_tree_rebalance_for_erase(
+ __pos._M_node, __src_impl._M_header);
+ --__src_impl._M_node_count;
+ _M_insert_node(__res.first, __res.second,
+ static_cast<_Link_type>(__ptr));
+ }
+ }
+ }
+
+ /// Merge from a compatible container into one with equivalent keys.
+ template<typename _Compare2>
+ void
+ _M_merge_equal(_Compatible_tree<_Compare2>& __src) noexcept
+ {
+ using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
+ for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
+ {
+ auto __pos = __i++;
+ auto __res = _M_get_insert_equal_pos(_KeyOfValue()(*__pos));
+ if (__res.second)
+ {
+ auto& __src_impl = _Merge_helper::_S_get_impl(__src);
+ auto __ptr = _Rb_tree_rebalance_for_erase(
+ __pos._M_node, __src_impl._M_header);
+ --__src_impl._M_node_count;
+ _M_insert_node(__res.first, __res.second,
+ static_cast<_Link_type>(__ptr));
+ }
+ }
+ }
+#endif // C++17
};
template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -2390,6 +2569,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return true;
}
+#if __cplusplus > 201402L
+ // Allow access to internals of compatible _Rb_tree specializations.
+ template<typename _Key, typename _Val, typename _Sel, typename _Cmp1,
+ typename _Alloc, typename _Cmp2>
+ struct _Rb_tree_merge_helper<_Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>,
+ _Cmp2>
+ {
+ private:
+ friend class _Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>;
+
+ static auto&
+ _S_get_impl(_Rb_tree<_Key, _Val, _Sel, _Cmp2, _Alloc>& __tree)
+ { return __tree._M_impl; }
+ };
+#endif // C++17
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index c5c81fb2c66..ef2e584c1b3 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -60,6 +60,10 @@
#include <utility>
#endif
+#if __cplusplus >= 201103L
+#include <type_traits>
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -640,6 +644,100 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
allocator<_Tp>&)
{ return std::__uninitialized_default_n(__first, __n); }
+ template<bool _TrivialValueType>
+ struct __uninitialized_default_novalue_1
+ {
+ template<typename _ForwardIterator>
+ static void
+ __uninit_default_novalue(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ _ForwardIterator __cur = __first;
+ __try
+ {
+ for (; __cur != __last; ++__cur)
+ std::_Construct_novalue(std::__addressof(*__cur));
+ }
+ __catch(...)
+ {
+ std::_Destroy(__first, __cur);
+ __throw_exception_again;
+ }
+ }
+ };
+
+ template<>
+ struct __uninitialized_default_novalue_1<true>
+ {
+ template<typename _ForwardIterator>
+ static void
+ __uninit_default_novalue(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ }
+ };
+
+ template<bool _TrivialValueType>
+ struct __uninitialized_default_novalue_n_1
+ {
+ template<typename _ForwardIterator, typename _Size>
+ static _ForwardIterator
+ __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
+ {
+ _ForwardIterator __cur = __first;
+ __try
+ {
+ for (; __n > 0; --__n, ++__cur)
+ std::_Construct_novalue(std::__addressof(*__cur));
+ return __cur;
+ }
+ __catch(...)
+ {
+ std::_Destroy(__first, __cur);
+ __throw_exception_again;
+ }
+ }
+ };
+
+ template<>
+ struct __uninitialized_default_novalue_n_1<true>
+ {
+ template<typename _ForwardIterator, typename _Size>
+ static _ForwardIterator
+ __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
+ {
+ }
+ };
+
+ // __uninitialized_default_novalue
+ // Fills [first, last) with std::distance(first, last) default-initialized
+ // value_types(s).
+ template<typename _ForwardIterator>
+ inline void
+ __uninitialized_default_novalue(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::value_type
+ _ValueType;
+
+ std::__uninitialized_default_novalue_1<
+ is_trivially_default_constructible<_ValueType>::value>::
+ __uninit_default_novalue(__first, __last);
+ }
+
+ // __uninitialized_default_n
+ // Fills [first, first + n) with n default-initialized value_type(s).
+ template<typename _ForwardIterator, typename _Size>
+ inline _ForwardIterator
+ __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::value_type
+ _ValueType;
+
+ return __uninitialized_default_novalue_n_1<
+ is_trivially_default_constructible<_ValueType>::value>::
+ __uninit_default_novalue_n(__first, __n);
+ }
template<typename _InputIterator, typename _Size,
typename _ForwardIterator>
@@ -669,6 +767,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
random_access_iterator_tag)
{ return std::uninitialized_copy(__first, __first + __n, __result); }
+ template<typename _InputIterator, typename _Size,
+ typename _ForwardIterator>
+ pair<_InputIterator, _ForwardIterator>
+ __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
+ _ForwardIterator __result, input_iterator_tag)
+ {
+ _ForwardIterator __cur = __result;
+ __try
+ {
+ for (; __n > 0; --__n, ++__first, ++__cur)
+ std::_Construct(std::__addressof(*__cur), *__first);
+ return {__first, __cur};
+ }
+ __catch(...)
+ {
+ std::_Destroy(__result, __cur);
+ __throw_exception_again;
+ }
+ }
+
+ template<typename _RandomAccessIterator, typename _Size,
+ typename _ForwardIterator>
+ inline pair<_RandomAccessIterator, _ForwardIterator>
+ __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
+ _ForwardIterator __result,
+ random_access_iterator_tag)
+ {
+ auto __second_res = uninitialized_copy(__first, __first + __n, __result);
+ auto __first_res = std::next(__first, __n);
+ return {__first_res, __second_res};
+ }
+
/**
* @brief Copies the range [first,first+n) into result.
* @param __first An input iterator.
@@ -684,6 +814,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ForwardIterator __result)
{ return std::__uninitialized_copy_n(__first, __n, __result,
std::__iterator_category(__first)); }
+
+ template<typename _InputIterator, typename _Size, typename _ForwardIterator>
+ inline pair<_InputIterator, _ForwardIterator>
+ __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
+ _ForwardIterator __result)
+ {
+ return
+ std::__uninitialized_copy_n_pair(__first, __n, __result,
+ std::__iterator_category(__first));
+ }
+
#endif
#if __cplusplus > 201402L
@@ -692,19 +833,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
uninitialized_default_construct(_ForwardIterator __first,
_ForwardIterator __last)
{
- for (; __first != __last; ++__first)
- ::new (static_cast<void*>(std::__addressof(*__first)))
- typename iterator_traits<_ForwardIterator>::value_type;
+ __uninitialized_default_novalue(__first, __last);
}
template <typename _ForwardIterator, typename _Size>
inline _ForwardIterator
uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
{
- for (; __count > 0; (void)++__first, --__count)
- ::new (static_cast<void*>(std::__addressof(*__first)))
- typename iterator_traits<_ForwardIterator>::value_type;
- return __first;
+ return __uninitialized_default_novalue_n(__first, __count);
}
template <typename _ForwardIterator>
@@ -712,19 +848,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
uninitialized_value_construct(_ForwardIterator __first,
_ForwardIterator __last)
{
- for (; __first != __last; ++__first)
- ::new (static_cast<void*>(std::__addressof(*__first)))
- typename iterator_traits<_ForwardIterator>::value_type();
+ return __uninitialized_default(__first, __last);
}
template <typename _ForwardIterator, typename _Size>
inline _ForwardIterator
uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
{
- for (; __count > 0; (void)++__first, --__count)
- ::new (static_cast<void*>(std::__addressof(*__first)))
- typename iterator_traits<_ForwardIterator>::value_type();
- return __first;
+ return __uninitialized_default_n(__first, __count);
}
template <typename _InputIterator, typename _ForwardIterator>
@@ -732,11 +863,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
uninitialized_move(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result)
{
- for (; __first != __last; (void)++__result, ++__first)
- ::new (static_cast<void*>(std::__addressof(*__result)))
- typename
- iterator_traits<_ForwardIterator>::value_type(std::move(*__first));
- return __result;
+ return std::uninitialized_copy
+ (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
+ _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
}
template <typename _InputIterator, typename _Size, typename _ForwardIterator>
@@ -744,35 +873,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
uninitialized_move_n(_InputIterator __first, _Size __count,
_ForwardIterator __result)
{
- for (; __count > 0; ++__result, (void) ++__first, --__count)
- ::new (static_cast<void*>(std::__addressof(*__result)))
- typename
- iterator_traits<_ForwardIterator>::value_type(std::move(*__first));
- return {__first, __result};
+ auto __res = std::__uninitialized_copy_n_pair
+ (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
+ __count, __result);
+ return {__res.first.base(), __res.second};
}
template <typename _Tp>
inline void
destroy_at(_Tp* __location)
{
- __location->~_Tp();
+ std::_Destroy(__location);
}
template <typename _ForwardIterator>
inline void
destroy(_ForwardIterator __first, _ForwardIterator __last)
{
- for (; __first != __last; ++__first)
- std::destroy_at(std::__addressof(*__first));
+ std::_Destroy(__first, __last);
}
template <typename _ForwardIterator, typename _Size>
inline _ForwardIterator
destroy_n(_ForwardIterator __first, _Size __count)
{
- for (; __count > 0; (void)++__first, --__count)
- std::destroy_at(std::__addressof(*__first));
- return __first;
+ return std::_Destroy_n(__first, __count);
}
#endif
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index a26ee1afa99..6776090e372 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -68,6 +68,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__detail::_Default_ranged_hash,
__detail::_Prime_rehash_policy, _Tr>;
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+ class unordered_multimap;
+
/**
* @brief A standard container composed of unique keys (containing
* at most one of each key value) that associates values of another type
@@ -126,6 +129,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Hashtable::difference_type difference_type;
//@}
+#if __cplusplus > 201402L
+ using node_type = typename _Hashtable::node_type;
+ using insert_return_type = typename _Hashtable::insert_return_type;
+#endif
+
//construct/destroy/copy
/// Default constructor.
@@ -409,8 +417,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
emplace_hint(const_iterator __pos, _Args&&... __args)
{ return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
-
#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_h.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __key)
+ { return _M_h.extract(__key); }
+
+ /// Re-insert an extracted node.
+ insert_return_type
+ insert(node_type&& __nh)
+ { return _M_h._M_reinsert_node(std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator, node_type&& __nh)
+ { return _M_h._M_reinsert_node(std::move(__nh)).position; }
+
#define __cpp_lib_unordered_map_try_emplace 201411
/**
* @brief Attempts to build and insert a std::pair into the
@@ -524,7 +554,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::forward<_Args>(__args)...));
return __i;
}
-#endif
+#endif // C++17
//@{
/**
@@ -817,6 +847,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
noexcept( noexcept(_M_h.swap(__x._M_h)) )
{ _M_h.swap(__x._M_h); }
+#if __cplusplus > 201402L
+ template<typename, typename, typename>
+ friend class _Hash_merge_helper;
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
+ _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
+ _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
// observers.
/// Returns the hash functor object with which the %unordered_map was
@@ -1052,8 +1113,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1,
typename _Alloc1>
friend bool
- operator==(const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&,
- const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&);
+ operator==(const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&,
+ const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&);
};
/**
@@ -1114,6 +1175,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Hashtable::difference_type difference_type;
//@}
+#if __cplusplus > 201402L
+ using node_type = typename _Hashtable::node_type;
+#endif
+
//construct/destroy/copy
/// Default constructor.
@@ -1468,6 +1533,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(initializer_list<value_type> __l)
{ _M_h.insert(__l); }
+#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_h.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __key)
+ { return _M_h.extract(__key); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(node_type&& __nh)
+ { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
+#endif // C++17
+
//@{
/**
* @brief Erases an element from an %unordered_multimap.
@@ -1551,6 +1641,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
noexcept( noexcept(_M_h.swap(__x._M_h)) )
{ _M_h.swap(__x._M_h); }
+#if __cplusplus > 201402L
+ template<typename, typename, typename>
+ friend class _Hash_merge_helper;
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper
+ = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
+ _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper
+ = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
+ _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
// observers.
/// Returns the hash functor object with which the %unordered_multimap
@@ -1786,6 +1909,59 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return !(__x == __y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
+
+#if __cplusplus > 201402L
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // Allow std::unordered_map access to internals of compatible maps.
+ template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
+ typename _Alloc, typename _Hash2, typename _Eq2>
+ struct _Hash_merge_helper<
+ _GLIBCXX_STD_C::unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>,
+ _Hash2, _Eq2>
+ {
+ private:
+ template<typename... _Tp>
+ using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
+ template<typename... _Tp>
+ using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
+
+ friend unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>;
+
+ static auto&
+ _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
+ { return __map._M_h; }
+
+ static auto&
+ _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
+ { return __map._M_h; }
+ };
+
+ // Allow std::unordered_multimap access to internals of compatible maps.
+ template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
+ typename _Alloc, typename _Hash2, typename _Eq2>
+ struct _Hash_merge_helper<
+ _GLIBCXX_STD_C::unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>,
+ _Hash2, _Eq2>
+ {
+ private:
+ template<typename... _Tp>
+ using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
+ template<typename... _Tp>
+ using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
+
+ friend unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>;
+
+ static auto&
+ _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
+ { return __map._M_h; }
+
+ static auto&
+ _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
+ { return __map._M_h; }
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+#endif // C++17
+
} // namespace std
#endif /* _UNORDERED_MAP_H */
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index 1e65b547522..99052575d99 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -65,6 +65,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__detail::_Default_ranged_hash,
__detail::_Prime_rehash_policy, _Tr>;
+ template<class _Value, class _Hash, class _Pred, class _Alloc>
+ class unordered_multiset;
+
/**
* @brief A standard container composed of unique keys (containing
* at most one of each key value) in which the elements' keys are
@@ -120,6 +123,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Hashtable::difference_type difference_type;
//@}
+#if __cplusplus > 201402L
+ using node_type = typename _Hashtable::node_type;
+ using insert_return_type = typename _Hashtable::insert_return_type;
+#endif
+
// construct/destroy/copy
/// Default constructor.
@@ -470,6 +478,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(initializer_list<value_type> __l)
{ _M_h.insert(__l); }
+#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_h.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __key)
+ { return _M_h.extract(__key); }
+
+ /// Re-insert an extracted node.
+ insert_return_type
+ insert(node_type&& __nh)
+ { return _M_h._M_reinsert_node(std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator, node_type&& __nh)
+ { return _M_h._M_reinsert_node(std::move(__nh)).position; }
+#endif // C++17
+
//@{
/**
* @brief Erases an element from an %unordered_set.
@@ -552,6 +585,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
noexcept( noexcept(_M_h.swap(__x._M_h)) )
{ _M_h.swap(__x._M_h); }
+#if __cplusplus > 201402L
+ template<typename, typename, typename>
+ friend class _Hash_merge_helper;
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
+ _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
+ _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
// observers.
/// Returns the hash functor object with which the %unordered_set was
@@ -793,6 +857,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Hashtable::difference_type difference_type;
//@}
+#if __cplusplus > 201402L
+ using node_type = typename _Hashtable::node_type;
+#endif
+
// construct/destroy/copy
/// Default constructor.
@@ -1121,6 +1189,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(initializer_list<value_type> __l)
{ _M_h.insert(__l); }
+#if __cplusplus > 201402L
+ /// Extract a node.
+ node_type
+ extract(const_iterator __pos)
+ {
+ __glibcxx_assert(__pos != end());
+ return _M_h.extract(__pos);
+ }
+
+ /// Extract a node.
+ node_type
+ extract(const key_type& __key)
+ { return _M_h.extract(__key); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(node_type&& __nh)
+ { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
+
+ /// Re-insert an extracted node.
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
+#endif // C++17
+
//@{
/**
* @brief Erases an element from an %unordered_multiset.
@@ -1208,6 +1301,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
noexcept( noexcept(_M_h.swap(__x._M_h)) )
{ _M_h.swap(__x._M_h); }
+#if __cplusplus > 201402L
+ template<typename, typename, typename>
+ friend class _Hash_merge_helper;
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper
+ = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
+ _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
+ {
+ using _Merge_helper
+ = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
+ _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
+ }
+
+ template<typename _H2, typename _P2>
+ void
+ merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
+ { merge(__source); }
+#endif // C++17
+
// observers.
/// Returns the hash functor object with which the %unordered_multiset
@@ -1429,6 +1555,58 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return !(__x == __y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
+
+#if __cplusplus > 201402L
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // Allow std::unordered_set access to internals of compatible sets.
+ template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
+ typename _Hash2, typename _Eq2>
+ struct _Hash_merge_helper<
+ _GLIBCXX_STD_C::unordered_set<_Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2>
+ {
+ private:
+ template<typename... _Tp>
+ using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
+ template<typename... _Tp>
+ using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
+
+ friend unordered_set<_Val, _Hash1, _Eq1, _Alloc>;
+
+ static auto&
+ _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
+ { return __set._M_h; }
+
+ static auto&
+ _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
+ { return __set._M_h; }
+ };
+
+ // Allow std::unordered_multiset access to internals of compatible sets.
+ template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
+ typename _Hash2, typename _Eq2>
+ struct _Hash_merge_helper<
+ _GLIBCXX_STD_C::unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>,
+ _Hash2, _Eq2>
+ {
+ private:
+ template<typename... _Tp>
+ using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
+ template<typename... _Tp>
+ using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
+
+ friend unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>;
+
+ static auto&
+ _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
+ { return __set._M_h; }
+
+ static auto&
+ _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
+ { return __set._M_h; }
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+#endif // C++17
+
} // namespace std
#endif /* _UNORDERED_SET_H */
diff --git a/libstdc++-v3/include/bits/uses_allocator.h b/libstdc++-v3/include/bits/uses_allocator.h
index 500bd901554..c7d14f33132 100644
--- a/libstdc++-v3/include/bits/uses_allocator.h
+++ b/libstdc++-v3/include/bits/uses_allocator.h
@@ -144,24 +144,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename... _Args>
void __uses_allocator_construct_impl(__uses_alloc0 __a, _Tp* __ptr,
_Args&&... __args)
- { new (__ptr) _Tp(forward<_Args>(__args)...); }
+ { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)...); }
template<typename _Tp, typename _Alloc, typename... _Args>
void __uses_allocator_construct_impl(__uses_alloc1<_Alloc> __a, _Tp* __ptr,
_Args&&... __args)
- { new (__ptr) _Tp(allocator_arg, *__a._M_a, forward<_Args>(__args)...); }
+ {
+ ::new ((void*)__ptr) _Tp(allocator_arg, *__a._M_a,
+ std::forward<_Args>(__args)...);
+ }
template<typename _Tp, typename _Alloc, typename... _Args>
void __uses_allocator_construct_impl(__uses_alloc2<_Alloc> __a, _Tp* __ptr,
_Args&&... __args)
- { new (__ptr) _Tp(forward<_Args>(__args)..., *__a._M_a); }
+ { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)..., *__a._M_a); }
template<typename _Tp, typename _Alloc, typename... _Args>
void __uses_allocator_construct(const _Alloc& __a, _Tp* __ptr,
_Args&&... __args)
{
__uses_allocator_construct_impl(__use_alloc<_Tp, _Alloc, _Args...>(__a),
- __ptr, forward<_Args>(__args)...);
+ __ptr, std::forward<_Args>(__args)...);
}
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath
index 6db9deeb996..24ce811adf2 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -44,12 +44,12 @@
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next <math.h>
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include <bits/std_abs.h>
#ifndef _GLIBCXX_CMATH
#define _GLIBCXX_CMATH 1
// Get rid of those macros defined in <math.h> in lieu of real functions.
-#undef abs
#undef div
#undef acos
#undef asin
@@ -80,29 +80,6 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
- inline _GLIBCXX_CONSTEXPR double
- abs(double __x)
- { return __builtin_fabs(__x); }
-#endif
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
- inline _GLIBCXX_CONSTEXPR float
- abs(float __x)
- { return __builtin_fabsf(__x); }
-
- inline _GLIBCXX_CONSTEXPR long double
- abs(long double __x)
- { return __builtin_fabsl(__x); }
-#endif
-
- template<typename _Tp>
- inline _GLIBCXX_CONSTEXPR
- typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
- double>::__type
- abs(_Tp __x)
- { return __builtin_fabs(__x); }
-
using ::acos;
#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
@@ -1790,6 +1767,53 @@ _GLIBCXX_END_NAMESPACE_VERSION
#endif // C++11
+#if __cplusplus > 201402L
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ // [c.math.hypot3], three-dimensional hypotenuse
+#define __cpp_lib_hypot 201603
+
+ template<typename _Tp>
+ inline _Tp
+ __hypot3(_Tp __x, _Tp __y, _Tp __z)
+ {
+ __x = std::abs(__x);
+ __y = std::abs(__y);
+ __z = std::abs(__z);
+ if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x)
+ return __a * std::sqrt((__x / __a) * (__x / __a)
+ + (__y / __a) * (__y / __a)
+ + (__z / __a) * (__z / __a));
+ else
+ return {};
+ }
+
+ inline float
+ hypot(float __x, float __y, float __z)
+ { return std::__hypot3<float>(__x, __y, __z); }
+
+ inline double
+ hypot(double __x, double __y, double __z)
+ { return std::__hypot3<double>(__x, __y, __z); }
+
+ inline long double
+ hypot(long double __x, long double __y, long double __z)
+ { return std::__hypot3<long double>(__x, __y, __z); }
+
+ template<typename _Tp, typename _Up, typename _Vp>
+ typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type
+ hypot(_Tp __x, _Up __y, _Vp __z)
+ {
+ using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type;
+ return std::__hypot3<__type>(__x, __y, __z);
+ }
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif // C++17
+
+
#if _GLIBCXX_USE_STD_SPEC_FUNCS
# include <bits/specfun.h>
#endif
diff --git a/libstdc++-v3/include/c_global/cstdio b/libstdc++-v3/include/c_global/cstdio
index 920d109bcb8..86d524f96a6 100644
--- a/libstdc++-v3/include/c_global/cstdio
+++ b/libstdc++-v3/include/c_global/cstdio
@@ -44,7 +44,7 @@
#ifndef _GLIBCXX_CSTDIO
#define _GLIBCXX_CSTDIO 1
-#ifndef _GLIBCXX_HAVE_GETS
+#if __cplusplus <= 201103L && !defined(_GLIBCXX_HAVE_GETS)
extern "C" char* gets (char* __s) __attribute__((__deprecated__));
#endif
diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib
index 1ba5fb7f03a..15733dfb75b 100644
--- a/libstdc++-v3/include/c_global/cstdlib
+++ b/libstdc++-v3/include/c_global/cstdlib
@@ -74,10 +74,10 @@ namespace std
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next <stdlib.h>
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include <bits/std_abs.h>
// Get rid of those macros defined in <stdlib.h> in lieu of real functions.
#undef abort
-#undef abs
#undef atexit
#if __cplusplus >= 201103L
# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
@@ -125,7 +125,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::ldiv_t;
using ::abort;
- using ::abs;
using ::atexit;
#if __cplusplus >= 201103L
# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
@@ -168,35 +167,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif // _GLIBCXX_USE_WCHAR_T
#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
- inline long
- abs(long __i) { return __builtin_labs(__i); }
-
inline ldiv_t
div(long __i, long __j) { return ldiv(__i, __j); }
#endif
-#ifdef _GLIBCXX_USE_LONG_LONG
- inline long long
- abs(long long __x) { return __builtin_llabs (__x); }
-#endif
-
-#if defined(__GLIBCXX_TYPE_INT_N_0)
- inline __GLIBCXX_TYPE_INT_N_0
- abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_1)
- inline __GLIBCXX_TYPE_INT_N_1
- abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_2)
- inline __GLIBCXX_TYPE_INT_N_2
- abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-#if defined(__GLIBCXX_TYPE_INT_N_3)
- inline __GLIBCXX_TYPE_INT_N_3
- abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
-#endif
-
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/c_std/cstdio b/libstdc++-v3/include/c_std/cstdio
index a4119ba6c64..549004c0a16 100644
--- a/libstdc++-v3/include/c_std/cstdio
+++ b/libstdc++-v3/include/c_std/cstdio
@@ -44,7 +44,7 @@
#include <bits/c++config.h>
#include <stdio.h>
-#ifndef _GLIBCXX_HAVE_GETS
+#if __cplusplus <= 201103L && !defined(_GLIBCXX_HAVE_GETS)
extern "C" char* gets (char* __s) __attribute__((__deprecated__));
#endif
diff --git a/libstdc++-v3/include/debug/bitset b/libstdc++-v3/include/debug/bitset
index 55d3281ee3d..b7bada30cf8 100644
--- a/libstdc++-v3/include/debug/bitset
+++ b/libstdc++-v3/include/debug/bitset
@@ -66,8 +66,7 @@ namespace __debug
friend class bitset;
reference();
- reference(const _Base_ref& __base,
- bitset* __seq __attribute__((__unused__))) _GLIBCXX_NOEXCEPT
+ reference(const _Base_ref& __base, bitset* __seq) _GLIBCXX_NOEXCEPT
: _Base_ref(__base)
, _Safe_iterator_base(__seq, false)
{ }
@@ -81,7 +80,7 @@ namespace __debug
reference&
operator=(bool __x) _GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
_M_message(__gnu_debug::__msg_bad_bitset_write)
._M_iterator(*this));
*static_cast<_Base_ref*>(this) = __x;
@@ -91,10 +90,10 @@ namespace __debug
reference&
operator=(const reference& __x) _GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
_M_message(__gnu_debug::__msg_bad_bitset_read)
._M_iterator(__x));
- _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
_M_message(__gnu_debug::__msg_bad_bitset_write)
._M_iterator(*this));
*static_cast<_Base_ref*>(this) = __x;
@@ -104,7 +103,7 @@ namespace __debug
bool
operator~() const _GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
_M_message(__gnu_debug::__msg_bad_bitset_read)
._M_iterator(*this));
return ~(*static_cast<const _Base_ref*>(this));
@@ -112,7 +111,7 @@ namespace __debug
operator bool() const _GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
_M_message(__gnu_debug::__msg_bad_bitset_read)
._M_iterator(*this));
return *static_cast<const _Base_ref*>(this);
@@ -121,7 +120,7 @@ namespace __debug
reference&
flip() _GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
_M_message(__gnu_debug::__msg_bad_bitset_flip)
._M_iterator(*this));
_Base_ref::flip();
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index 432bed39cfb..51cd140a122 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -397,8 +397,52 @@ namespace __debug
std::forward<_Obj>(__obj)),
this);
}
-#endif
+#endif // C++17
+
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ struct insert_return_type
+ {
+ bool inserted;
+ iterator position;
+ node_type node;
+ };
+
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ this->_M_invalidate_if(_Equal(__position.base()));
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ insert_return_type
+ insert(node_type&& __nh)
+ {
+ auto __ret = _Base::insert(std::move(__nh));
+ iterator __pos = iterator(__ret.position, this);
+ return { __ret.inserted, __pos, std::move(__ret.node) };
+ }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+ using _Base::merge;
+#endif // C++17
#if __cplusplus >= 201103L
iterator
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 30e7b196f2f..0cecedb5b38 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -296,6 +296,40 @@ namespace __debug
_Base::insert(__first, __last);
}
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ this->_M_invalidate_if(_Equal(__position.base()));
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ iterator
+ insert(node_type&& __nh)
+ { return iterator(_Base::insert(std::move(__nh)), this); }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+
+ using _Base::merge;
+#endif // C++17
+
#if __cplusplus >= 201103L
iterator
erase(const_iterator __position)
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index 67eb7e18fb7..2d68a3df92c 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -287,6 +287,40 @@ namespace __debug
{ _Base::insert(__l); }
#endif
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ this->_M_invalidate_if(_Equal(__position.base()));
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ iterator
+ insert(node_type&& __nh)
+ { return iterator(_Base::insert(std::move(__nh)), this); }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+
+ using _Base::merge;
+#endif // C++17
+
#if __cplusplus >= 201103L
iterator
erase(const_iterator __position)
diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h
index ede65fd88d3..733a8f04717 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -49,6 +49,8 @@ namespace __gnu_debug
*/
class _Safe_iterator_base
{
+ friend class _Safe_sequence_base;
+
public:
/** The sequence this iterator references; may be NULL to indicate
a singular iterator. */
@@ -101,7 +103,6 @@ namespace __gnu_debug
__gnu_cxx::__mutex&
_M_get_mutex() throw ();
- public:
/** Attaches this iterator to the given sequence, detaching it
* from whatever sequence it was attached to originally. If the
* new sequence is the NULL pointer, the iterator is left
@@ -120,6 +121,7 @@ namespace __gnu_debug
void
_M_detach();
+ public:
/** Likewise, but not thread-safe. */
void
_M_detach_single() throw ();
@@ -185,6 +187,8 @@ namespace __gnu_debug
*/
class _Safe_sequence_base
{
+ friend class _Safe_iterator_base;
+
public:
/// The list of mutable iterators that reference this container
_Safe_iterator_base* _M_iterators;
@@ -204,6 +208,11 @@ namespace __gnu_debug
#if __cplusplus >= 201103L
_Safe_sequence_base(const _Safe_sequence_base&) noexcept
: _Safe_sequence_base() { }
+
+ // Move constructor swap iterators.
+ _Safe_sequence_base(_Safe_sequence_base&& __seq) noexcept
+ : _Safe_sequence_base()
+ { _M_swap(__seq); }
#endif
/** Notify all iterators that reference this sequence that the
@@ -242,12 +251,12 @@ namespace __gnu_debug
__gnu_cxx::__mutex&
_M_get_mutex() throw ();
- public:
/** Invalidates all iterators. */
void
_M_invalidate_all() const
{ if (++_M_version == 0) _M_version = 1; }
+ private:
/** Attach an iterator to this sequence. */
void
_M_attach(_Safe_iterator_base* __it, bool __constant);
diff --git a/libstdc++-v3/include/debug/safe_container.h b/libstdc++-v3/include/debug/safe_container.h
index b73f68c62a5..d96cb17a2a3 100644
--- a/libstdc++-v3/include/debug/safe_container.h
+++ b/libstdc++-v3/include/debug/safe_container.h
@@ -55,12 +55,9 @@ namespace __gnu_debug
#if __cplusplus >= 201103L
_Safe_container() = default;
_Safe_container(const _Safe_container&) = default;
- _Safe_container(_Safe_container&& __x) noexcept
- : _Safe_container()
- { _Base::_M_swap(__x); }
+ _Safe_container(_Safe_container&&) = default;
- _Safe_container(_Safe_container&& __x,
- const _Alloc& __a)
+ _Safe_container(_Safe_container&& __x, const _Alloc& __a)
: _Safe_container()
{
if (__x._M_cont().get_allocator() == __a)
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index 03c02638a13..d550ac240e1 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -295,7 +295,7 @@ namespace __gnu_debug
_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
_M_message(__msg_bad_inc)
._M_iterator(*this, "this"));
- __gnu_cxx::__scoped_lock(this->_M_get_mutex());
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
++base();
return *this;
}
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc
index e8e1b00fe20..0ae7fd1571b 100644
--- a/libstdc++-v3/include/debug/safe_iterator.tcc
+++ b/libstdc++-v3/include/debug/safe_iterator.tcc
@@ -93,4 +93,3 @@ namespace __gnu_debug
} // namespace __gnu_debug
#endif
-
diff --git a/libstdc++-v3/include/debug/safe_unordered_base.h b/libstdc++-v3/include/debug/safe_unordered_base.h
index 82a42eb3c99..21292c33e34 100644
--- a/libstdc++-v3/include/debug/safe_unordered_base.h
+++ b/libstdc++-v3/include/debug/safe_unordered_base.h
@@ -76,24 +76,27 @@ namespace __gnu_debug
_Safe_unordered_container_base*
_M_get_container() const noexcept;
- public:
/** Attaches this iterator to the given container, detaching it
* from whatever container it was attached to originally. If the
* new container is the NULL pointer, the iterator is left
* unattached.
*/
- void _M_attach(_Safe_sequence_base* __seq, bool __constant);
+ void
+ _M_attach(_Safe_sequence_base* __seq, bool __constant);
/** Likewise, but not thread-safe. */
- void _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
+ void
+ _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
/** Detach the iterator for whatever container it is attached to,
* if any.
*/
- void _M_detach();
+ void
+ _M_detach();
/** Likewise, but not thread-safe. */
- void _M_detach_single() throw ();
+ void
+ _M_detach_single() throw ();
};
/**
@@ -116,7 +119,9 @@ namespace __gnu_debug
*/
class _Safe_unordered_container_base : public _Safe_sequence_base
{
+ friend class _Safe_local_iterator_base;
typedef _Safe_sequence_base _Base;
+
public:
/// The list of mutable local iterators that reference this container
_Safe_iterator_base* _M_local_iterators;
@@ -158,7 +163,7 @@ namespace __gnu_debug
void
_M_swap(_Safe_unordered_container_base& __x) noexcept;
- public:
+ private:
/** Attach an iterator to this container. */
void
_M_attach_local(_Safe_iterator_base* __it, bool __constant);
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index ede4103acd8..89376384458 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -296,6 +296,51 @@ namespace __debug
{ _Base::insert(__l); }
#endif
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ struct insert_return_type
+ {
+ bool inserted;
+ iterator position;
+ node_type node;
+ };
+
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ this->_M_invalidate_if(_Equal(__position.base()));
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ insert_return_type
+ insert(node_type&& __nh)
+ {
+ auto __ret = _Base::insert(std::move(__nh));
+ iterator __pos = iterator(__ret.position, this);
+ return { __ret.inserted, __pos, std::move(__ret.node) };
+ }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+
+ using _Base::merge;
+#endif // C++17
+
#if __cplusplus >= 201103L
iterator
erase(const_iterator __position)
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index 873f36a3499..4a834c67eba 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -458,8 +458,59 @@ namespace __debug
std::forward<_Obj>(__obj)),
this);
}
-#endif
+#endif // C++17
+
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ struct insert_return_type
+ {
+ bool inserted;
+ iterator position;
+ node_type node;
+ };
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ _Base_const_iterator __victim = __position.base();
+ this->_M_invalidate_if(
+ [__victim](_Base_const_iterator __it) { return __it == __victim; }
+ );
+ this->_M_invalidate_local_if(
+ [__victim](_Base_const_local_iterator __it) {
+ return __it._M_curr() == __victim._M_cur;
+ });
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ insert_return_type
+ insert(node_type&& __nh)
+ {
+ auto __ret = _Base::insert(std::move(__nh));
+ iterator __pos = iterator(__ret.position, this);
+ return { __ret.inserted, __pos, std::move(__ret.node) };
+ }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+
+ using _Base::merge;
+#endif // C++17
iterator
find(const key_type& __key)
@@ -913,6 +964,47 @@ namespace __debug
_M_check_rehashed(__bucket_count);
}
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ _Base_const_iterator __victim = __position.base();
+ this->_M_invalidate_if(
+ [__victim](_Base_const_iterator __it) { return __it == __victim; }
+ );
+ this->_M_invalidate_local_if(
+ [__victim](_Base_const_local_iterator __it) {
+ return __it._M_curr() == __victim._M_cur;
+ });
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ iterator
+ insert(node_type&& __nh)
+ { return iterator(_Base::insert(std::move(__nh)), this); }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+
+ using _Base::merge;
+#endif // C++17
+
iterator
find(const key_type& __key)
{ return iterator(_Base::find(__key), this); }
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index 6a4dba6475d..f8587c06bfc 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -370,6 +370,58 @@ namespace __debug
_M_check_rehashed(__bucket_count);
}
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ struct insert_return_type
+ {
+ bool inserted;
+ iterator position;
+ node_type node;
+ };
+
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ _Base_const_iterator __victim = __position.base();
+ this->_M_invalidate_if(
+ [__victim](_Base_const_iterator __it) { return __it == __victim; }
+ );
+ this->_M_invalidate_local_if(
+ [__victim](_Base_const_local_iterator __it) {
+ return __it._M_curr() == __victim._M_cur;
+ });
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ insert_return_type
+ insert(node_type&& __nh)
+ {
+ auto __ret = _Base::insert(std::move(__nh));
+ iterator __pos = iterator(__ret.position, this);
+ return { __ret.inserted, __pos, std::move(__ret.node) };
+ }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+
+ using _Base::merge;
+#endif // C++17
+
iterator
find(const key_type& __key)
{ return iterator(_Base::find(__key), this); }
@@ -821,6 +873,47 @@ namespace __debug
_M_check_rehashed(__bucket_count);
}
+#if __cplusplus > 201402L
+ using node_type = typename _Base::node_type;
+
+ node_type
+ extract(const_iterator __position)
+ {
+ __glibcxx_check_erase(__position);
+ _Base_const_iterator __victim = __position.base();
+ this->_M_invalidate_if(
+ [__victim](_Base_const_iterator __it) { return __it == __victim; }
+ );
+ this->_M_invalidate_local_if(
+ [__victim](_Base_const_local_iterator __it) {
+ return __it._M_curr() == __victim._M_cur;
+ });
+ return _Base::extract(__position.base());
+ }
+
+ node_type
+ extract(const key_type& __key)
+ {
+ const auto __position = find(__key);
+ if (__position != end())
+ return extract(__position);
+ return {};
+ }
+
+ iterator
+ insert(node_type&& __nh)
+ { return iterator(_Base::insert(std::move(__nh)), this); }
+
+ iterator
+ insert(const_iterator __hint, node_type&& __nh)
+ {
+ __glibcxx_check_insert(__hint);
+ return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
+ }
+
+ using _Base::merge;
+#endif // C++17
+
iterator
find(const key_type& __key)
{ return iterator(_Base::find(__key), this); }
diff --git a/libstdc++-v3/include/experimental/bits/fs_fwd.h b/libstdc++-v3/include/experimental/bits/fs_fwd.h
index 57aa4d3ee79..b9cc041c236 100644
--- a/libstdc++-v3/include/experimental/bits/fs_fwd.h
+++ b/libstdc++-v3/include/experimental/bits/fs_fwd.h
@@ -253,7 +253,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
operator^=(directory_options& __x, directory_options __y) noexcept
{ return __x = __x ^ __y; }
- typedef chrono::time_point<chrono::system_clock> file_time_type;
+ using file_time_type = std::chrono::system_clock::time_point;
// operational functions
diff --git a/libstdc++-v3/include/experimental/numeric b/libstdc++-v3/include/experimental/numeric
index 21878f3a910..50897722682 100644
--- a/libstdc++-v3/include/experimental/numeric
+++ b/libstdc++-v3/include/experimental/numeric
@@ -39,8 +39,8 @@
# include <bits/c++14_warning.h>
#else
+#include <numeric>
#include <experimental/type_traits>
-#include <cmath>
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -52,6 +52,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define __cpp_lib_experimental_gcd_lcm 201411
+ // std::abs is not constexpr and doesn't support unsigned integers.
+ template<typename _Tp>
+ constexpr
+ enable_if_t<__and_<is_integral<_Tp>, is_signed<_Tp>>::value, _Tp>
+ __abs(_Tp __val)
+ { return __val < 0 ? -__val : __val; }
+
+ template<typename _Tp>
+ constexpr
+ enable_if_t<__and_<is_integral<_Tp>, is_unsigned<_Tp>>::value, _Tp>
+ __abs(_Tp __val)
+ { return __val; }
+
// Greatest common divisor
template<typename _Mn, typename _Nn>
constexpr common_type_t<_Mn, _Nn>
@@ -60,8 +73,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_assert(is_integral<_Mn>::value, "arguments to gcd are integers");
static_assert(is_integral<_Nn>::value, "arguments to gcd are integers");
- return __m == 0 ? std::abs(__n)
- : __n == 0 ? std::abs(__m)
+ return __m == 0 ? fundamentals_v2::__abs(__n)
+ : __n == 0 ? fundamentals_v2::__abs(__m)
: fundamentals_v2::gcd(__n, __m % __n);
}
@@ -74,7 +87,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_assert(is_integral<_Nn>::value, "arguments to lcm are integers");
return (__m != 0 && __n != 0)
- ? (std::abs(__m) / fundamentals_v2::gcd(__m, __n)) * std::abs(__n)
+ ? (fundamentals_v2::__abs(__m) / fundamentals_v2::gcd(__m, __n))
+ * fundamentals_v2::__abs(__n)
: 0;
}
diff --git a/libstdc++-v3/include/ext/rc_string_base.h b/libstdc++-v3/include/ext/rc_string_base.h
index 1c1ed87531f..eab34614946 100644
--- a/libstdc++-v3/include/ext/rc_string_base.h
+++ b/libstdc++-v3/include/ext/rc_string_base.h
@@ -354,7 +354,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_clear()
- { _M_erase(size_type(0), _M_length()); }
+ {
+ _M_dispose();
+ _M_data(_S_empty_rep._M_refcopy());
+ }
bool
_M_compare(const __rc_string_base&) const
diff --git a/libstdc++-v3/include/parallel/algo.h b/libstdc++-v3/include/parallel/algo.h
index 2137a58196e..0ff138c22f6 100644
--- a/libstdc++-v3/include/parallel/algo.h
+++ b/libstdc++-v3/include/parallel/algo.h
@@ -65,100 +65,96 @@ namespace __parallel
// Sequential fallback
template<typename _IIter, typename _Function>
inline _Function
- for_each(_IIter __begin, _IIter __end, _Function __f,
- __gnu_parallel::sequential_tag)
+ for_each(_IIter __begin, _IIter __end, _Function __f,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::for_each(__begin, __end, __f); }
-
// Sequential fallback for input iterator case
template<typename _IIter, typename _Function, typename _IteratorTag>
inline _Function
- __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
- _IteratorTag)
+ __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
+ _IteratorTag)
{ return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
template<typename _RAIter, typename _Function>
_Function
- __for_each_switch(_RAIter __begin, _RAIter __end,
- _Function __f, random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __for_each_switch(_RAIter __begin, _RAIter __end,
+ _Function __f, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().for_each_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- bool __dummy;
- __gnu_parallel::__for_each_selector<_RAIter> __functionality;
-
- return __gnu_parallel::
- __for_each_template_random_access(
- __begin, __end, __f, __functionality,
- __gnu_parallel::_DummyReduct(), true, __dummy, -1,
- __parallelism_tag);
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().for_each_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ bool __dummy;
+ __gnu_parallel::__for_each_selector<_RAIter> __functionality;
+
+ return __gnu_parallel::
+ __for_each_template_random_access(
+ __begin, __end, __f, __functionality,
+ __gnu_parallel::_DummyReduct(), true, __dummy, -1,
+ __parallelism_tag);
+ }
else
- return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
+ return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
}
// Public interface
template<typename _Iterator, typename _Function>
inline _Function
- for_each(_Iterator __begin, _Iterator __end, _Function __f,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ for_each(_Iterator __begin, _Iterator __end, _Function __f,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<_Iterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return __for_each_switch(__begin, __end, __f, _IteratorCategory(),
- __parallelism_tag);
+ return __for_each_switch(__begin, __end, __f,
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _Iterator, typename _Function>
inline _Function
- for_each(_Iterator __begin, _Iterator __end, _Function __f)
+ for_each(_Iterator __begin, _Iterator __end, _Function __f)
{
- typedef std::iterator_traits<_Iterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return __for_each_switch(__begin, __end, __f, _IteratorCategory());
+ return __for_each_switch(__begin, __end, __f,
+ std::__iterator_category(__begin));
}
-
// Sequential fallback
template<typename _IIter, typename _Tp>
inline _IIter
- find(_IIter __begin, _IIter __end, const _Tp& __val,
- __gnu_parallel::sequential_tag)
+ find(_IIter __begin, _IIter __end, const _Tp& __val,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::find(__begin, __end, __val); }
// Sequential fallback for input iterator case
template<typename _IIter, typename _Tp, typename _IteratorTag>
inline _IIter
__find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
- _IteratorTag)
+ _IteratorTag)
{ return _GLIBCXX_STD_A::find(__begin, __end, __val); }
// Parallel find for random access iterators
template<typename _RAIter, typename _Tp>
_RAIter
__find_switch(_RAIter __begin, _RAIter __end,
- const _Tp& __val, random_access_iterator_tag)
+ const _Tp& __val, random_access_iterator_tag)
{
typedef iterator_traits<_RAIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType;
if (_GLIBCXX_PARALLEL_CONDITION(true))
- {
+ {
__gnu_parallel::__binder2nd<__gnu_parallel::_EqualTo<_ValueType,
const _Tp&>,
_ValueType, const _Tp&, bool>
- __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val);
- return __gnu_parallel::__find_template(
- __begin, __end, __begin, __comp,
- __gnu_parallel::__find_if_selector()).first;
- }
+ __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val);
+ return __gnu_parallel::__find_template(
+ __begin, __end, __begin, __comp,
+ __gnu_parallel::__find_if_selector()).first;
+ }
else
- return _GLIBCXX_STD_A::find(__begin, __end, __val);
+ return _GLIBCXX_STD_A::find(__begin, __end, __val);
}
// Public interface
@@ -166,37 +162,36 @@ namespace __parallel
inline _IIter
find(_IIter __begin, _IIter __end, const _Tp& __val)
{
- typedef std::iterator_traits<_IIter> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return __find_switch(__begin, __end, __val, _IteratorCategory());
+ return __find_switch(__begin, __end, __val,
+ std::__iterator_category(__begin));
}
// Sequential fallback
template<typename _IIter, typename _Predicate>
inline _IIter
- find_if(_IIter __begin, _IIter __end, _Predicate __pred,
- __gnu_parallel::sequential_tag)
+ find_if(_IIter __begin, _IIter __end, _Predicate __pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
// Sequential fallback for input iterator case
template<typename _IIter, typename _Predicate, typename _IteratorTag>
inline _IIter
- __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
- _IteratorTag)
+ __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
+ _IteratorTag)
{ return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
// Parallel find_if for random access iterators
template<typename _RAIter, typename _Predicate>
_RAIter
- __find_if_switch(_RAIter __begin, _RAIter __end,
- _Predicate __pred, random_access_iterator_tag)
+ __find_if_switch(_RAIter __begin, _RAIter __end,
+ _Predicate __pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
- __gnu_parallel::
- __find_if_selector()).first;
+ return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
+ __gnu_parallel::
+ __find_if_selector()).first;
else
- return _GLIBCXX_STD_A::find_if(__begin, __end, __pred);
+ return _GLIBCXX_STD_A::find_if(__begin, __end, __pred);
}
// Public interface
@@ -204,138 +199,132 @@ namespace __parallel
inline _IIter
find_if(_IIter __begin, _IIter __end, _Predicate __pred)
{
- typedef std::iterator_traits<_IIter> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return __find_if_switch(__begin, __end, __pred, _IteratorCategory());
+ return __find_if_switch(__begin, __end, __pred,
+ std::__iterator_category(__begin));
}
// Sequential fallback
template<typename _IIter, typename _FIterator>
inline _IIter
- find_first_of(_IIter __begin1, _IIter __end1,
- _FIterator __begin2, _FIterator __end2,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2);
- }
+ find_first_of(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2,
+ __gnu_parallel::sequential_tag)
+ {
+ return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2);
+ }
// Sequential fallback
template<typename _IIter, typename _FIterator,
- typename _BinaryPredicate>
+ typename _BinaryPredicate>
inline _IIter
find_first_of(_IIter __begin1, _IIter __end1,
- _FIterator __begin2, _FIterator __end2,
- _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::find_first_of(
- __begin1, __end1, __begin2, __end2, __comp); }
+ __begin1, __end1, __begin2, __end2, __comp); }
// Sequential fallback for input iterator type
template<typename _IIter, typename _FIterator,
- typename _IteratorTag1, typename _IteratorTag2>
+ typename _IteratorTag1, typename _IteratorTag2>
inline _IIter
__find_first_of_switch(_IIter __begin1, _IIter __end1,
- _FIterator __begin2, _FIterator __end2,
- _IteratorTag1, _IteratorTag2)
- { return find_first_of(__begin1, __end1, __begin2, __end2,
- __gnu_parallel::sequential_tag()); }
+ _FIterator __begin2, _FIterator __end2,
+ _IteratorTag1, _IteratorTag2)
+ { return find_first_of(__begin1, __end1, __begin2, __end2,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
template<typename _RAIter, typename _FIterator,
- typename _BinaryPredicate, typename _IteratorTag>
+ typename _BinaryPredicate, typename _IteratorTag>
inline _RAIter
__find_first_of_switch(_RAIter __begin1,
- _RAIter __end1,
- _FIterator __begin2, _FIterator __end2,
- _BinaryPredicate __comp, random_access_iterator_tag,
- _IteratorTag)
+ _RAIter __end1,
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp, random_access_iterator_tag,
+ _IteratorTag)
{
return __gnu_parallel::
- __find_template(__begin1, __end1, __begin1, __comp,
- __gnu_parallel::__find_first_of_selector
- <_FIterator>(__begin2, __end2)).first;
+ __find_template(__begin1, __end1, __begin1, __comp,
+ __gnu_parallel::__find_first_of_selector
+ <_FIterator>(__begin2, __end2)).first;
}
// Sequential fallback for input iterator type
template<typename _IIter, typename _FIterator,
- typename _BinaryPredicate, typename _IteratorTag1,
- typename _IteratorTag2>
+ typename _BinaryPredicate, typename _IteratorTag1,
+ typename _IteratorTag2>
inline _IIter
__find_first_of_switch(_IIter __begin1, _IIter __end1,
- _FIterator __begin2, _FIterator __end2,
- _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
- { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
- __gnu_parallel::sequential_tag()); }
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
+ { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
+ __gnu_parallel::sequential_tag()); }
// Public interface
template<typename _IIter, typename _FIterator,
- typename _BinaryPredicate>
+ typename _BinaryPredicate>
inline _IIter
find_first_of(_IIter __begin1, _IIter __end1,
- _FIterator __begin2, _FIterator __end2,
- _BinaryPredicate __comp)
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp)
{
- typedef std::iterator_traits<_IIter> _IIterTraits;
- typedef std::iterator_traits<_FIterator> _FIterTraits;
- typedef typename _IIterTraits::iterator_category _IIteratorCategory;
- typedef typename _FIterTraits::iterator_category _FIteratorCategory;
-
return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
- _IIteratorCategory(), _FIteratorCategory());
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2));
}
// Public interface, insert default comparator
template<typename _IIter, typename _FIterator>
inline _IIter
- find_first_of(_IIter __begin1, _IIter __end1,
- _FIterator __begin2, _FIterator __end2)
+ find_first_of(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2)
{
- typedef std::iterator_traits<_IIter> _IIterTraits;
- typedef std::iterator_traits<_FIterator> _FIterTraits;
- typedef typename _IIterTraits::value_type _IValueType;
- typedef typename _FIterTraits::value_type _FValueType;
+ typedef typename std::iterator_traits<_IIter>::value_type _IValueType;
+ typedef typename std::iterator_traits<_FIterator>::value_type _FValueType;
return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2,
- __gnu_parallel::_EqualTo<_IValueType, _FValueType>());
+ __gnu_parallel::_EqualTo<_IValueType, _FValueType>());
}
// Sequential fallback
template<typename _IIter, typename _OutputIterator>
inline _OutputIterator
unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
- __gnu_parallel::sequential_tag)
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); }
// Sequential fallback
template<typename _IIter, typename _OutputIterator,
- typename _Predicate>
+ typename _Predicate>
inline _OutputIterator
unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
- _Predicate __pred, __gnu_parallel::sequential_tag)
+ _Predicate __pred, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); }
// Sequential fallback for input iterator case
template<typename _IIter, typename _OutputIterator,
- typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
+ typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
inline _OutputIterator
- __unique_copy_switch(_IIter __begin, _IIter __last,
- _OutputIterator __out, _Predicate __pred,
- _IteratorTag1, _IteratorTag2)
+ __unique_copy_switch(_IIter __begin, _IIter __last,
+ _OutputIterator __out, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2)
{ return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); }
// Parallel unique_copy for random access iterators
template<typename _RAIter, typename RandomAccessOutputIterator,
- typename _Predicate>
+ typename _Predicate>
RandomAccessOutputIterator
- __unique_copy_switch(_RAIter __begin, _RAIter __last,
- RandomAccessOutputIterator __out, _Predicate __pred,
- random_access_iterator_tag, random_access_iterator_tag)
+ __unique_copy_switch(_RAIter __begin, _RAIter __last,
+ RandomAccessOutputIterator __out, _Predicate __pred,
+ random_access_iterator_tag, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
- > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
- return __gnu_parallel::__parallel_unique_copy(
- __begin, __last, __out, __pred);
+ static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
+ > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
+ return __gnu_parallel::__parallel_unique_copy(
+ __begin, __last, __out, __pred);
else
- return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred);
+ return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred);
}
// Public interface
@@ -343,288 +332,255 @@ namespace __parallel
inline _OutputIterator
unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
{
- typedef std::iterator_traits<_IIter> _IIterTraits;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits::iterator_category _IIteratorCategory;
- typedef typename _IIterTraits::value_type _ValueType;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
+ typedef typename std::iterator_traits<_IIter>::value_type _ValueType;
return __unique_copy_switch(
- __begin1, __end1, __out, equal_to<_ValueType>(),
- _IIteratorCategory(), _OIterCategory());
+ __begin1, __end1, __out, equal_to<_ValueType>(),
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__out));
}
// Public interface
template<typename _IIter, typename _OutputIterator, typename _Predicate>
inline _OutputIterator
unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
- _Predicate __pred)
+ _Predicate __pred)
{
- typedef std::iterator_traits<_IIter> _IIterTraits;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits::iterator_category _IIteratorCategory;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
return __unique_copy_switch(
- __begin1, __end1, __out, __pred,
- _IIteratorCategory(), _OIterCategory());
+ __begin1, __end1, __out, __pred,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__out));
}
// Sequential fallback
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
+ typename _OutputIterator>
inline _OutputIterator
set_union(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, __gnu_parallel::sequential_tag)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_union(
- __begin1, __end1, __begin2, __end2, __out); }
+ __begin1, __end1, __begin2, __end2, __out); }
// Sequential fallback
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
+ typename _OutputIterator, typename _Predicate>
inline _OutputIterator
set_union(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred,
- __gnu_parallel::sequential_tag)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_union(__begin1, __end1,
- __begin2, __end2, __out, __pred); }
+ __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case
template<typename _IIter1, typename _IIter2, typename _Predicate,
- typename _OutputIterator, typename _IteratorTag1,
- typename _IteratorTag2, typename _IteratorTag3>
+ typename _OutputIterator, typename _IteratorTag1,
+ typename _IteratorTag2, typename _IteratorTag3>
inline _OutputIterator
__set_union_switch(
_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __result, _Predicate __pred,
_IteratorTag1, _IteratorTag2, _IteratorTag3)
{ return _GLIBCXX_STD_A::set_union(__begin1, __end1,
- __begin2, __end2, __result, __pred); }
+ __begin2, __end2, __result, __pred); }
// Parallel set_union for random access iterators
template<typename _RAIter1, typename _RAIter2,
- typename _Output_RAIter, typename _Predicate>
+ typename _Output_RAIter, typename _Predicate>
_Output_RAIter
- __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
- _RAIter2 __begin2, _RAIter2 __end2,
- _Output_RAIter __result, _Predicate __pred,
- random_access_iterator_tag, random_access_iterator_tag,
- random_access_iterator_tag)
+ __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _RAIter2 __end2,
+ _Output_RAIter __result, _Predicate __pred,
+ random_access_iterator_tag, random_access_iterator_tag,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
- >= __gnu_parallel::_Settings::get().set_union_minimal_n
- || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
- >= __gnu_parallel::_Settings::get().set_union_minimal_n))
- return __gnu_parallel::__parallel_set_union(
- __begin1, __end1, __begin2, __end2, __result, __pred);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
+ >= __gnu_parallel::_Settings::get().set_union_minimal_n
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
+ >= __gnu_parallel::_Settings::get().set_union_minimal_n))
+ return __gnu_parallel::__parallel_set_union(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_A::set_union(__begin1, __end1,
- __begin2, __end2, __result, __pred);
+ return _GLIBCXX_STD_A::set_union(__begin1, __end1,
+ __begin2, __end2, __result, __pred);
}
// Public interface
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
- inline _OutputIterator
+ typename _OutputIterator>
+ inline _OutputIterator
set_union(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
- typedef typename _IIterTraits1::value_type _ValueType1;
- typedef typename _IIterTraits2::value_type _ValueType2;
+ _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
+ {
+ typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
+ typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
return __set_union_switch(
- __begin1, __end1, __begin2, __end2, __out,
- __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
// Public interface
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
- inline _OutputIterator
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
set_union(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
return __set_union_switch(
- __begin1, __end1, __begin2, __end2, __out, __pred,
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
// Sequential fallback.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
+ typename _OutputIterator>
inline _OutputIterator
set_intersection(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, __gnu_parallel::sequential_tag)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_intersection(__begin1, __end1,
- __begin2, __end2, __out); }
+ __begin2, __end2, __out); }
// Sequential fallback.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
+ typename _OutputIterator, typename _Predicate>
inline _OutputIterator
set_intersection(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred,
- __gnu_parallel::sequential_tag)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_intersection(
- __begin1, __end1, __begin2, __end2, __out, __pred); }
+ __begin1, __end1, __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case
template<typename _IIter1, typename _IIter2,
- typename _Predicate, typename _OutputIterator,
- typename _IteratorTag1, typename _IteratorTag2,
- typename _IteratorTag3>
- inline _OutputIterator
+ typename _Predicate, typename _OutputIterator,
+ typename _IteratorTag1, typename _IteratorTag2,
+ typename _IteratorTag3>
+ inline _OutputIterator
__set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __result, _Predicate __pred,
- _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
{ return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2,
- __end2, __result, __pred); }
+ __end2, __result, __pred); }
// Parallel set_intersection for random access iterators
template<typename _RAIter1, typename _RAIter2,
- typename _Output_RAIter, typename _Predicate>
+ typename _Output_RAIter, typename _Predicate>
_Output_RAIter
__set_intersection_switch(_RAIter1 __begin1,
- _RAIter1 __end1,
- _RAIter2 __begin2,
- _RAIter2 __end2,
- _Output_RAIter __result,
- _Predicate __pred,
- random_access_iterator_tag,
- random_access_iterator_tag,
- random_access_iterator_tag)
+ _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _RAIter2 __end2,
+ _Output_RAIter __result,
+ _Predicate __pred,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
- >= __gnu_parallel::_Settings::get().set_union_minimal_n
- || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
- >= __gnu_parallel::_Settings::get().set_union_minimal_n))
- return __gnu_parallel::__parallel_set_intersection(
- __begin1, __end1, __begin2, __end2, __result, __pred);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
+ >= __gnu_parallel::_Settings::get().set_union_minimal_n
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
+ >= __gnu_parallel::_Settings::get().set_union_minimal_n))
+ return __gnu_parallel::__parallel_set_intersection(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_A::set_intersection(
- __begin1, __end1, __begin2, __end2, __result, __pred);
+ return _GLIBCXX_STD_A::set_intersection(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
}
// Public interface
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
- inline _OutputIterator
- set_intersection(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
- typedef typename _IIterTraits1::value_type _ValueType1;
- typedef typename _IIterTraits2::value_type _ValueType2;
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_intersection(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out)
+ {
+ typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
+ typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
return __set_intersection_switch(
- __begin1, __end1, __begin2, __end2, __out,
- __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
- inline _OutputIterator
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
set_intersection(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
return __set_intersection_switch(
- __begin1, __end1, __begin2, __end2, __out, __pred,
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
// Sequential fallback
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
+ typename _OutputIterator>
inline _OutputIterator
set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out,
- __gnu_parallel::sequential_tag)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_symmetric_difference(
- __begin1, __end1, __begin2, __end2, __out); }
+ __begin1, __end1, __begin2, __end2, __out); }
// Sequential fallback
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
+ typename _OutputIterator, typename _Predicate>
inline _OutputIterator
set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred,
- __gnu_parallel::sequential_tag)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_symmetric_difference(
- __begin1, __end1, __begin2, __end2, __out, __pred); }
+ __begin1, __end1, __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case
template<typename _IIter1, typename _IIter2,
- typename _Predicate, typename _OutputIterator,
- typename _IteratorTag1, typename _IteratorTag2,
- typename _IteratorTag3>
- inline _OutputIterator
+ typename _Predicate, typename _OutputIterator,
+ typename _IteratorTag1, typename _IteratorTag2,
+ typename _IteratorTag3>
+ inline _OutputIterator
__set_symmetric_difference_switch(
- _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __result, _Predicate __pred,
- _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
{ return _GLIBCXX_STD_A::set_symmetric_difference(
- __begin1, __end1, __begin2, __end2, __result, __pred); }
+ __begin1, __end1, __begin2, __end2, __result, __pred); }
// Parallel set_symmetric_difference for random access iterators
template<typename _RAIter1, typename _RAIter2,
- typename _Output_RAIter, typename _Predicate>
+ typename _Output_RAIter, typename _Predicate>
_Output_RAIter
__set_symmetric_difference_switch(_RAIter1 __begin1,
- _RAIter1 __end1,
- _RAIter2 __begin2,
- _RAIter2 __end2,
- _Output_RAIter __result,
- _Predicate __pred,
- random_access_iterator_tag,
- random_access_iterator_tag,
- random_access_iterator_tag)
+ _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _RAIter2 __end2,
+ _Output_RAIter __result,
+ _Predicate __pred,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
@@ -632,209 +588,183 @@ namespace __parallel
|| static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
>= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
return __gnu_parallel::__parallel_set_symmetric_difference(
- __begin1, __end1, __begin2, __end2, __result, __pred);
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_A::set_symmetric_difference(
- __begin1, __end1, __begin2, __end2, __result, __pred);
+ return _GLIBCXX_STD_A::set_symmetric_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
}
// Public interface.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
- inline _OutputIterator
+ typename _OutputIterator>
+ inline _OutputIterator
set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
- typedef typename _IIterTraits1::value_type _ValueType1;
- typedef typename _IIterTraits2::value_type _ValueType2;
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out)
+ {
+ typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
+ typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
return __set_symmetric_difference_switch(
- __begin1, __end1, __begin2, __end2, __out,
- __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
// Public interface.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
- inline _OutputIterator
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
return __set_symmetric_difference_switch(
- __begin1, __end1, __begin2, __end2, __out, __pred,
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
// Sequential fallback.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
+ typename _OutputIterator>
inline _OutputIterator
- set_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, __gnu_parallel::sequential_tag)
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_difference(
- __begin1,__end1, __begin2, __end2, __out); }
+ __begin1,__end1, __begin2, __end2, __out); }
// Sequential fallback.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
+ typename _OutputIterator, typename _Predicate>
inline _OutputIterator
- set_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred,
- __gnu_parallel::sequential_tag)
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::set_difference(__begin1, __end1,
- __begin2, __end2, __out, __pred); }
+ __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case.
template<typename _IIter1, typename _IIter2, typename _Predicate,
- typename _OutputIterator, typename _IteratorTag1,
- typename _IteratorTag2, typename _IteratorTag3>
+ typename _OutputIterator, typename _IteratorTag1,
+ typename _IteratorTag2, typename _IteratorTag3>
inline _OutputIterator
- __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __result, _Predicate __pred,
- _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
{ return _GLIBCXX_STD_A::set_difference(
- __begin1, __end1, __begin2, __end2, __result, __pred); }
+ __begin1, __end1, __begin2, __end2, __result, __pred); }
// Parallel set_difference for random access iterators
template<typename _RAIter1, typename _RAIter2,
- typename _Output_RAIter, typename _Predicate>
+ typename _Output_RAIter, typename _Predicate>
_Output_RAIter
__set_difference_switch(_RAIter1 __begin1,
- _RAIter1 __end1,
- _RAIter2 __begin2,
- _RAIter2 __end2,
- _Output_RAIter __result, _Predicate __pred,
- random_access_iterator_tag,
- random_access_iterator_tag,
- random_access_iterator_tag)
+ _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _RAIter2 __end2,
+ _Output_RAIter __result, _Predicate __pred,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
- >= __gnu_parallel::_Settings::get().set_difference_minimal_n
- || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
- >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
- return __gnu_parallel::__parallel_set_difference(
- __begin1, __end1, __begin2, __end2, __result, __pred);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
+ >= __gnu_parallel::_Settings::get().set_difference_minimal_n
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
+ >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
+ return __gnu_parallel::__parallel_set_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_A::set_difference(
- __begin1, __end1, __begin2, __end2, __result, __pred);
+ return _GLIBCXX_STD_A::set_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
}
// Public interface
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
+ typename _OutputIterator>
inline _OutputIterator
- set_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
- typedef typename _IIterTraits1::value_type _ValueType1;
- typedef typename _IIterTraits2::value_type _ValueType2;
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out)
+ {
+ typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
+ typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
return __set_difference_switch(
- __begin1, __end1, __begin2, __end2, __out,
- __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
// Public interface
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Predicate>
+ typename _OutputIterator, typename _Predicate>
inline _OutputIterator
- set_difference(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __out, _Predicate __pred)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
return __set_difference_switch(
- __begin1, __end1, __begin2, __end2, __out, __pred,
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__out));
}
// Sequential fallback
template<typename _FIterator>
inline _FIterator
- adjacent_find(_FIterator __begin, _FIterator __end,
- __gnu_parallel::sequential_tag)
+ adjacent_find(_FIterator __begin, _FIterator __end,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::adjacent_find(__begin, __end); }
// Sequential fallback
template<typename _FIterator, typename _BinaryPredicate>
inline _FIterator
- adjacent_find(_FIterator __begin, _FIterator __end,
- _BinaryPredicate __binary_pred,
- __gnu_parallel::sequential_tag)
+ adjacent_find(_FIterator __begin, _FIterator __end,
+ _BinaryPredicate __binary_pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); }
// Parallel algorithm for random access iterators
template<typename _RAIter>
_RAIter
- __adjacent_find_switch(_RAIter __begin, _RAIter __end,
- random_access_iterator_tag)
+ __adjacent_find_switch(_RAIter __begin, _RAIter __end,
+ random_access_iterator_tag)
{
typedef iterator_traits<_RAIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType;
if (_GLIBCXX_PARALLEL_CONDITION(true))
- {
- _RAIter __spot = __gnu_parallel::
- __find_template(
- __begin, __end - 1, __begin, equal_to<_ValueType>(),
- __gnu_parallel::__adjacent_find_selector())
- .first;
- if (__spot == (__end - 1))
- return __end;
- else
- return __spot;
- }
+ {
+ _RAIter __spot = __gnu_parallel::
+ __find_template(
+ __begin, __end - 1, __begin, equal_to<_ValueType>(),
+ __gnu_parallel::__adjacent_find_selector())
+ .first;
+ if (__spot == (__end - 1))
+ return __end;
+ else
+ return __spot;
+ }
else
- return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
+ return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case
template<typename _FIterator, typename _IteratorTag>
inline _FIterator
__adjacent_find_switch(_FIterator __begin, _FIterator __end,
- _IteratorTag)
+ _IteratorTag)
{ return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }
// Public interface
@@ -842,60 +772,57 @@ namespace __parallel
inline _FIterator
adjacent_find(_FIterator __begin, _FIterator __end)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __adjacent_find_switch(__begin, __end, _IteratorCategory());
+ return __adjacent_find_switch(__begin, __end,
+ std::__iterator_category(__begin));
}
// Sequential fallback for input iterator case
template<typename _FIterator, typename _BinaryPredicate,
- typename _IteratorTag>
+ typename _IteratorTag>
inline _FIterator
- __adjacent_find_switch(_FIterator __begin, _FIterator __end,
- _BinaryPredicate __pred, _IteratorTag)
+ __adjacent_find_switch(_FIterator __begin, _FIterator __end,
+ _BinaryPredicate __pred, _IteratorTag)
{ return adjacent_find(__begin, __end, __pred,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
template<typename _RAIter, typename _BinaryPredicate>
_RAIter
- __adjacent_find_switch(_RAIter __begin, _RAIter __end,
- _BinaryPredicate __pred, random_access_iterator_tag)
+ __adjacent_find_switch(_RAIter __begin, _RAIter __end,
+ _BinaryPredicate __pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
- __gnu_parallel::
- __adjacent_find_selector()).first;
+ return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
+ __gnu_parallel::
+ __adjacent_find_selector()).first;
else
- return adjacent_find(__begin, __end, __pred,
- __gnu_parallel::sequential_tag());
+ return adjacent_find(__begin, __end, __pred,
+ __gnu_parallel::sequential_tag());
}
// Public interface
template<typename _FIterator, typename _BinaryPredicate>
inline _FIterator
- adjacent_find(_FIterator __begin, _FIterator __end,
- _BinaryPredicate __pred)
+ adjacent_find(_FIterator __begin, _FIterator __end,
+ _BinaryPredicate __pred)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
return __adjacent_find_switch(__begin, __end, __pred,
- _IteratorCategory());
+ std::__iterator_category(__begin));
}
// Sequential fallback
template<typename _IIter, typename _Tp>
inline typename iterator_traits<_IIter>::difference_type
- count(_IIter __begin, _IIter __end, const _Tp& __value,
- __gnu_parallel::sequential_tag)
+ count(_IIter __begin, _IIter __end, const _Tp& __value,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::count(__begin, __end, __value); }
// Parallel code for random access iterators
template<typename _RAIter, typename _Tp>
typename iterator_traits<_RAIter>::difference_type
- __count_switch(_RAIter __begin, _RAIter __end,
- const _Tp& __value, random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __count_switch(_RAIter __begin, _RAIter __end,
+ const _Tp& __value, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
typedef iterator_traits<_RAIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType;
@@ -903,68 +830,66 @@ namespace __parallel
typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().count_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
- __functionality;
- _DifferenceType __res = 0;
- __gnu_parallel::
- __for_each_template_random_access(
- __begin, __end, __value, __functionality,
- std::plus<_SequenceIndex>(), __res, __res, -1,
- __parallelism_tag);
- return __res;
- }
+ static_cast<_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().count_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
+ __functionality;
+ _DifferenceType __res = 0;
+ __gnu_parallel::
+ __for_each_template_random_access(
+ __begin, __end, __value, __functionality,
+ std::plus<_SequenceIndex>(), __res, __res, -1,
+ __parallelism_tag);
+ return __res;
+ }
else
- return count(__begin, __end, __value,
- __gnu_parallel::sequential_tag());
+ return count(__begin, __end, __value,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
template<typename _IIter, typename _Tp, typename _IteratorTag>
inline typename iterator_traits<_IIter>::difference_type
- __count_switch(_IIter __begin, _IIter __end, const _Tp& __value,
- _IteratorTag)
+ __count_switch(_IIter __begin, _IIter __end, const _Tp& __value,
+ _IteratorTag)
{ return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
}
// Public interface.
template<typename _IIter, typename _Tp>
inline typename iterator_traits<_IIter>::difference_type
- count(_IIter __begin, _IIter __end, const _Tp& __value,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ count(_IIter __begin, _IIter __end, const _Tp& __value,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<_IIter> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __count_switch(__begin, __end, __value, _IteratorCategory(),
- __parallelism_tag);
+ return __count_switch(__begin, __end, __value,
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _IIter, typename _Tp>
inline typename iterator_traits<_IIter>::difference_type
count(_IIter __begin, _IIter __end, const _Tp& __value)
{
- typedef iterator_traits<_IIter> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __count_switch(__begin, __end, __value, _IteratorCategory());
+ return __count_switch(__begin, __end, __value,
+ std::__iterator_category(__begin));
}
// Sequential fallback.
template<typename _IIter, typename _Predicate>
inline typename iterator_traits<_IIter>::difference_type
- count_if(_IIter __begin, _IIter __end, _Predicate __pred,
- __gnu_parallel::sequential_tag)
+ count_if(_IIter __begin, _IIter __end, _Predicate __pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); }
// Parallel count_if for random access iterators
template<typename _RAIter, typename _Predicate>
typename iterator_traits<_RAIter>::difference_type
- __count_if_switch(_RAIter __begin, _RAIter __end,
- _Predicate __pred, random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __count_if_switch(_RAIter __begin, _RAIter __end,
+ _Predicate __pred, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
typedef iterator_traits<_RAIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType;
@@ -972,53 +897,51 @@ namespace __parallel
typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().count_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- _DifferenceType __res = 0;
- __gnu_parallel::
- __count_if_selector<_RAIter, _DifferenceType>
- __functionality;
- __gnu_parallel::
- __for_each_template_random_access(
- __begin, __end, __pred, __functionality,
- std::plus<_SequenceIndex>(), __res, __res, -1,
- __parallelism_tag);
- return __res;
- }
+ static_cast<_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().count_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ _DifferenceType __res = 0;
+ __gnu_parallel::
+ __count_if_selector<_RAIter, _DifferenceType>
+ __functionality;
+ __gnu_parallel::
+ __for_each_template_random_access(
+ __begin, __end, __pred, __functionality,
+ std::plus<_SequenceIndex>(), __res, __res, -1,
+ __parallelism_tag);
+ return __res;
+ }
else
- return count_if(__begin, __end, __pred,
- __gnu_parallel::sequential_tag());
+ return count_if(__begin, __end, __pred,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
template<typename _IIter, typename _Predicate, typename _IteratorTag>
inline typename iterator_traits<_IIter>::difference_type
- __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
- _IteratorTag)
+ __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
+ _IteratorTag)
{ return count_if(__begin, __end, __pred,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Public interface.
template<typename _IIter, typename _Predicate>
inline typename iterator_traits<_IIter>::difference_type
- count_if(_IIter __begin, _IIter __end, _Predicate __pred,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ count_if(_IIter __begin, _IIter __end, _Predicate __pred,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<_IIter> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __count_if_switch(__begin, __end, __pred, _IteratorCategory(),
- __parallelism_tag);
+ return __count_if_switch(__begin, __end, __pred,
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _IIter, typename _Predicate>
inline typename iterator_traits<_IIter>::difference_type
count_if(_IIter __begin, _IIter __end, _Predicate __pred)
{
- typedef iterator_traits<_IIter> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __count_if_switch(__begin, __end, __pred, _IteratorCategory());
+ return __count_if_switch(__begin, __end, __pred,
+ std::__iterator_category(__begin));
}
@@ -1026,581 +949,540 @@ namespace __parallel
template<typename _FIterator1, typename _FIterator2>
inline _FIterator1
search(_FIterator1 __begin1, _FIterator1 __end1,
- _FIterator2 __begin2, _FIterator2 __end2,
- __gnu_parallel::sequential_tag)
+ _FIterator2 __begin2, _FIterator2 __end2,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); }
// Parallel algorithm for random access iterator
template<typename _RAIter1, typename _RAIter2>
_RAIter1
__search_switch(_RAIter1 __begin1, _RAIter1 __end1,
- _RAIter2 __begin2, _RAIter2 __end2,
- random_access_iterator_tag, random_access_iterator_tag)
+ _RAIter2 __begin2, _RAIter2 __end2,
+ random_access_iterator_tag, random_access_iterator_tag)
{
- typedef std::iterator_traits<_RAIter1> _Iterator1Traits;
- typedef typename _Iterator1Traits::value_type _ValueType1;
- typedef std::iterator_traits<_RAIter2> _Iterator2Traits;
- typedef typename _Iterator2Traits::value_type _ValueType2;
+ typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1;
+ typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2;
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
- >= __gnu_parallel::_Settings::get().search_minimal_n))
- return __gnu_parallel::
- __search_template(
- __begin1, __end1, __begin2, __end2,
- __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>());
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
+ >= __gnu_parallel::_Settings::get().search_minimal_n))
+ return __gnu_parallel::
+ __search_template(
+ __begin1, __end1, __begin2, __end2,
+ __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>());
else
- return search(__begin1, __end1, __begin2, __end2,
- __gnu_parallel::sequential_tag());
+ return search(__begin1, __end1, __begin2, __end2,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case
template<typename _FIterator1, typename _FIterator2,
- typename _IteratorTag1, typename _IteratorTag2>
+ typename _IteratorTag1, typename _IteratorTag2>
inline _FIterator1
__search_switch(_FIterator1 __begin1, _FIterator1 __end1,
- _FIterator2 __begin2, _FIterator2 __end2,
- _IteratorTag1, _IteratorTag2)
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _IteratorTag1, _IteratorTag2)
{ return search(__begin1, __end1, __begin2, __end2,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Public interface.
template<typename _FIterator1, typename _FIterator2>
inline _FIterator1
search(_FIterator1 __begin1, _FIterator1 __end1,
- _FIterator2 __begin2, _FIterator2 __end2)
+ _FIterator2 __begin2, _FIterator2 __end2)
{
- typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
- typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
- typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
- typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
-
return __search_switch(__begin1, __end1, __begin2, __end2,
- _IteratorCategory1(), _IteratorCategory2());
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2));
}
// Public interface.
template<typename _FIterator1, typename _FIterator2,
- typename _BinaryPredicate>
+ typename _BinaryPredicate>
inline _FIterator1
search(_FIterator1 __begin1, _FIterator1 __end1,
- _FIterator2 __begin2, _FIterator2 __end2,
- _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::search(
- __begin1, __end1, __begin2, __end2, __pred); }
+ __begin1, __end1, __begin2, __end2, __pred); }
// Parallel algorithm for random access iterator.
template<typename _RAIter1, typename _RAIter2,
- typename _BinaryPredicate>
+ typename _BinaryPredicate>
_RAIter1
__search_switch(_RAIter1 __begin1, _RAIter1 __end1,
- _RAIter2 __begin2, _RAIter2 __end2,
- _BinaryPredicate __pred,
- random_access_iterator_tag, random_access_iterator_tag)
+ _RAIter2 __begin2, _RAIter2 __end2,
+ _BinaryPredicate __pred,
+ random_access_iterator_tag, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
- >= __gnu_parallel::_Settings::get().search_minimal_n))
- return __gnu_parallel::__search_template(__begin1, __end1,
- __begin2, __end2, __pred);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
+ >= __gnu_parallel::_Settings::get().search_minimal_n))
+ return __gnu_parallel::__search_template(__begin1, __end1,
+ __begin2, __end2, __pred);
else
- return search(__begin1, __end1, __begin2, __end2, __pred,
- __gnu_parallel::sequential_tag());
+ return search(__begin1, __end1, __begin2, __end2, __pred,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case
template<typename _FIterator1, typename _FIterator2,
- typename _BinaryPredicate, typename _IteratorTag1,
- typename _IteratorTag2>
+ typename _BinaryPredicate, typename _IteratorTag1,
+ typename _IteratorTag2>
inline _FIterator1
__search_switch(_FIterator1 __begin1, _FIterator1 __end1,
- _FIterator2 __begin2, _FIterator2 __end2,
- _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
{ return search(__begin1, __end1, __begin2, __end2, __pred,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Public interface
template<typename _FIterator1, typename _FIterator2,
- typename _BinaryPredicate>
+ typename _BinaryPredicate>
inline _FIterator1
search(_FIterator1 __begin1, _FIterator1 __end1,
- _FIterator2 __begin2, _FIterator2 __end2,
- _BinaryPredicate __pred)
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _BinaryPredicate __pred)
{
- typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
- typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
- typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
- typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
- _IteratorCategory1(), _IteratorCategory2());
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2));
}
// Sequential fallback
template<typename _FIterator, typename _Integer, typename _Tp>
inline _FIterator
search_n(_FIterator __begin, _FIterator __end, _Integer __count,
- const _Tp& __val, __gnu_parallel::sequential_tag)
+ const _Tp& __val, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); }
// Sequential fallback
template<typename _FIterator, typename _Integer, typename _Tp,
- typename _BinaryPredicate>
+ typename _BinaryPredicate>
inline _FIterator
search_n(_FIterator __begin, _FIterator __end, _Integer __count,
- const _Tp& __val, _BinaryPredicate __binary_pred,
- __gnu_parallel::sequential_tag)
+ const _Tp& __val, _BinaryPredicate __binary_pred,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::search_n(
- __begin, __end, __count, __val, __binary_pred); }
+ __begin, __end, __count, __val, __binary_pred); }
// Public interface.
template<typename _FIterator, typename _Integer, typename _Tp>
inline _FIterator
search_n(_FIterator __begin, _FIterator __end, _Integer __count,
- const _Tp& __val)
+ const _Tp& __val)
{
typedef typename iterator_traits<_FIterator>::value_type _ValueType;
return __gnu_parallel::search_n(__begin, __end, __count, __val,
- __gnu_parallel::_EqualTo<_ValueType, _Tp>());
+ __gnu_parallel::_EqualTo<_ValueType, _Tp>());
}
// Parallel algorithm for random access iterators.
template<typename _RAIter, typename _Integer,
- typename _Tp, typename _BinaryPredicate>
+ typename _Tp, typename _BinaryPredicate>
_RAIter
__search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count,
- const _Tp& __val, _BinaryPredicate __binary_pred,
- random_access_iterator_tag)
+ const _Tp& __val, _BinaryPredicate __binary_pred,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().search_minimal_n))
- {
- __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count);
- return __gnu_parallel::__search_template(
- __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().search_minimal_n))
+ {
+ __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count);
+ return __gnu_parallel::__search_template(
+ __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
+ }
else
- return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
- __binary_pred);
+ return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
+ __binary_pred);
}
// Sequential fallback for input iterator case.
template<typename _FIterator, typename _Integer, typename _Tp,
- typename _BinaryPredicate, typename _IteratorTag>
+ typename _BinaryPredicate, typename _IteratorTag>
inline _FIterator
__search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count,
- const _Tp& __val, _BinaryPredicate __binary_pred,
- _IteratorTag)
+ const _Tp& __val, _BinaryPredicate __binary_pred,
+ _IteratorTag)
{ return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
- __binary_pred); }
+ __binary_pred); }
// Public interface.
template<typename _FIterator, typename _Integer, typename _Tp,
- typename _BinaryPredicate>
+ typename _BinaryPredicate>
inline _FIterator
search_n(_FIterator __begin, _FIterator __end, _Integer __count,
- const _Tp& __val, _BinaryPredicate __binary_pred)
+ const _Tp& __val, _BinaryPredicate __binary_pred)
{
return __search_n_switch(__begin, __end, __count, __val, __binary_pred,
- typename std::iterator_traits<_FIterator>::
- iterator_category());
+ std::__iterator_category(__begin));
}
// Sequential fallback.
template<typename _IIter, typename _OutputIterator,
- typename _UnaryOperation>
+ typename _UnaryOperation>
inline _OutputIterator
- transform(_IIter __begin, _IIter __end, _OutputIterator __result,
- _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
+ transform(_IIter __begin, _IIter __end, _OutputIterator __result,
+ _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); }
// Parallel unary transform for random access iterators.
template<typename _RAIter1, typename _RAIter2,
- typename _UnaryOperation>
+ typename _UnaryOperation>
_RAIter2
__transform1_switch(_RAIter1 __begin, _RAIter1 __end,
- _RAIter2 __result, _UnaryOperation __unary_op,
- random_access_iterator_tag, random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ _RAIter2 __result, _UnaryOperation __unary_op,
+ random_access_iterator_tag, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().transform_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- bool __dummy = true;
- typedef __gnu_parallel::_IteratorPair<_RAIter1,
- _RAIter2, random_access_iterator_tag> _ItTrip;
- _ItTrip __begin_pair(__begin, __result),
- __end_pair(__end, __result + (__end - __begin));
- __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
- __gnu_parallel::
- __for_each_template_random_access(
- __begin_pair, __end_pair, __unary_op, __functionality,
- __gnu_parallel::_DummyReduct(),
- __dummy, __dummy, -1, __parallelism_tag);
- return __functionality._M_finish_iterator;
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().transform_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ bool __dummy = true;
+ typedef __gnu_parallel::_IteratorPair<_RAIter1,
+ _RAIter2, random_access_iterator_tag> _ItTrip;
+ _ItTrip __begin_pair(__begin, __result),
+ __end_pair(__end, __result + (__end - __begin));
+ __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
+ __gnu_parallel::
+ __for_each_template_random_access(
+ __begin_pair, __end_pair, __unary_op, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ __dummy, __dummy, -1, __parallelism_tag);
+ return __functionality._M_finish_iterator;
+ }
else
- return transform(__begin, __end, __result, __unary_op,
- __gnu_parallel::sequential_tag());
+ return transform(__begin, __end, __result, __unary_op,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
template<typename _RAIter1, typename _RAIter2,
- typename _UnaryOperation, typename _IteratorTag1,
- typename _IteratorTag2>
+ typename _UnaryOperation, typename _IteratorTag1,
+ typename _IteratorTag2>
inline _RAIter2
__transform1_switch(_RAIter1 __begin, _RAIter1 __end,
- _RAIter2 __result, _UnaryOperation __unary_op,
- _IteratorTag1, _IteratorTag2)
- { return transform(__begin, __end, __result, __unary_op,
- __gnu_parallel::sequential_tag()); }
+ _RAIter2 __result, _UnaryOperation __unary_op,
+ _IteratorTag1, _IteratorTag2)
+ { return transform(__begin, __end, __result, __unary_op,
+ __gnu_parallel::sequential_tag()); }
// Public interface.
template<typename _IIter, typename _OutputIterator,
- typename _UnaryOperation>
+ typename _UnaryOperation>
inline _OutputIterator
transform(_IIter __begin, _IIter __end, _OutputIterator __result,
- _UnaryOperation __unary_op,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ _UnaryOperation __unary_op,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<_IIter> _IIterTraits;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits::iterator_category _IIteratorCategory;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
return __transform1_switch(__begin, __end, __result, __unary_op,
- _IIteratorCategory(), _OIterCategory(),
- __parallelism_tag);
+ std::__iterator_category(__begin),
+ std::__iterator_category(__result),
+ __parallelism_tag);
}
template<typename _IIter, typename _OutputIterator,
- typename _UnaryOperation>
+ typename _UnaryOperation>
inline _OutputIterator
transform(_IIter __begin, _IIter __end, _OutputIterator __result,
- _UnaryOperation __unary_op)
+ _UnaryOperation __unary_op)
{
- typedef std::iterator_traits<_IIter> _IIterTraits;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits::iterator_category _IIteratorCategory;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
return __transform1_switch(__begin, __end, __result, __unary_op,
- _IIteratorCategory(), _OIterCategory());
+ std::__iterator_category(__begin),
+ std::__iterator_category(__result));
}
// Sequential fallback
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _BinaryOperation>
+ typename _OutputIterator, typename _BinaryOperation>
inline _OutputIterator
transform(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _OutputIterator __result,
- _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::transform(__begin1, __end1,
- __begin2, __result, __binary_op); }
+ __begin2, __result, __binary_op); }
// Parallel binary transform for random access iterators.
template<typename _RAIter1, typename _RAIter2,
- typename _RAIter3, typename _BinaryOperation>
+ typename _RAIter3, typename _BinaryOperation>
_RAIter3
__transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
- _RAIter2 __begin2,
- _RAIter3 __result, _BinaryOperation __binary_op,
- random_access_iterator_tag, random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ _RAIter2 __begin2,
+ _RAIter3 __result, _BinaryOperation __binary_op,
+ random_access_iterator_tag, random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- (__end1 - __begin1) >=
- __gnu_parallel::_Settings::get().transform_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- bool __dummy = true;
- typedef __gnu_parallel::_IteratorTriple<_RAIter1,
- _RAIter2, _RAIter3,
- random_access_iterator_tag> _ItTrip;
- _ItTrip __begin_triple(__begin1, __begin2, __result),
- __end_triple(__end1, __begin2 + (__end1 - __begin1),
- __result + (__end1 - __begin1));
- __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
- __gnu_parallel::
- __for_each_template_random_access(__begin_triple, __end_triple,
- __binary_op, __functionality,
- __gnu_parallel::_DummyReduct(),
- __dummy, __dummy, -1,
- __parallelism_tag);
- return __functionality._M_finish_iterator;
- }
+ (__end1 - __begin1) >=
+ __gnu_parallel::_Settings::get().transform_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ bool __dummy = true;
+ typedef __gnu_parallel::_IteratorTriple<_RAIter1,
+ _RAIter2, _RAIter3,
+ random_access_iterator_tag> _ItTrip;
+ _ItTrip __begin_triple(__begin1, __begin2, __result),
+ __end_triple(__end1, __begin2 + (__end1 - __begin1),
+ __result + (__end1 - __begin1));
+ __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
+ __gnu_parallel::
+ __for_each_template_random_access(__begin_triple, __end_triple,
+ __binary_op, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ __dummy, __dummy, -1,
+ __parallelism_tag);
+ return __functionality._M_finish_iterator;
+ }
else
- return transform(__begin1, __end1, __begin2, __result, __binary_op,
- __gnu_parallel::sequential_tag());
+ return transform(__begin1, __end1, __begin2, __result, __binary_op,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _BinaryOperation,
- typename _Tag1, typename _Tag2, typename _Tag3>
+ typename _OutputIterator, typename _BinaryOperation,
+ typename _Tag1, typename _Tag2, typename _Tag3>
inline _OutputIterator
- __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _OutputIterator __result,
- _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
+ __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
{ return transform(__begin1, __end1, __begin2, __result, __binary_op,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Public interface.
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _BinaryOperation>
+ typename _OutputIterator, typename _BinaryOperation>
inline _OutputIterator
transform(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _OutputIterator __result,
- _BinaryOperation __binary_op,
- __gnu_parallel::_Parallelism __parallelism_tag)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op,
+ __gnu_parallel::_Parallelism __parallelism_tag)
+ {
return __transform2_switch(
- __begin1, __end1, __begin2, __result, __binary_op,
- _IIterCategory1(), _IIterCategory2(), _OIterCategory(),
- __parallelism_tag);
+ __begin1, __end1, __begin2, __result, __binary_op,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__result),
+ __parallelism_tag);
}
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _BinaryOperation>
+ typename _OutputIterator, typename _BinaryOperation>
inline _OutputIterator
transform(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _OutputIterator __result,
- _BinaryOperation __binary_op)
- {
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op)
+ {
return __transform2_switch(
- __begin1, __end1, __begin2, __result, __binary_op,
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __result, __binary_op,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__result));
}
// Sequential fallback
template<typename _FIterator, typename _Tp>
inline void
- replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
- const _Tp& __new_value, __gnu_parallel::sequential_tag)
+ replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
+ const _Tp& __new_value, __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); }
// Sequential fallback for input iterator case
template<typename _FIterator, typename _Tp, typename _IteratorTag>
inline void
- __replace_switch(_FIterator __begin, _FIterator __end,
- const _Tp& __old_value, const _Tp& __new_value,
- _IteratorTag)
- { replace(__begin, __end, __old_value, __new_value,
- __gnu_parallel::sequential_tag()); }
+ __replace_switch(_FIterator __begin, _FIterator __end,
+ const _Tp& __old_value, const _Tp& __new_value,
+ _IteratorTag)
+ { replace(__begin, __end, __old_value, __new_value,
+ __gnu_parallel::sequential_tag()); }
// Parallel replace for random access iterators
template<typename _RAIter, typename _Tp>
inline void
- __replace_switch(_RAIter __begin, _RAIter __end,
- const _Tp& __old_value, const _Tp& __new_value,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __replace_switch(_RAIter __begin, _RAIter __end,
+ const _Tp& __old_value, const _Tp& __new_value,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
// XXX parallel version is where?
- replace(__begin, __end, __old_value, __new_value,
- __gnu_parallel::sequential_tag());
+ replace(__begin, __end, __old_value, __new_value,
+ __gnu_parallel::sequential_tag());
}
// Public interface
template<typename _FIterator, typename _Tp>
inline void
- replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
- const _Tp& __new_value,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
+ const _Tp& __new_value,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
__replace_switch(__begin, __end, __old_value, __new_value,
- _IteratorCategory(),
- __parallelism_tag);
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _FIterator, typename _Tp>
inline void
- replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
- const _Tp& __new_value)
+ replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
+ const _Tp& __new_value)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
__replace_switch(__begin, __end, __old_value, __new_value,
- _IteratorCategory());
+ std::__iterator_category(__begin));
}
// Sequential fallback
template<typename _FIterator, typename _Predicate, typename _Tp>
inline void
- replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
- const _Tp& __new_value, __gnu_parallel::sequential_tag)
+ replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
+ const _Tp& __new_value, __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); }
// Sequential fallback for input iterator case
template<typename _FIterator, typename _Predicate, typename _Tp,
- typename _IteratorTag>
+ typename _IteratorTag>
inline void
__replace_if_switch(_FIterator __begin, _FIterator __end,
- _Predicate __pred, const _Tp& __new_value, _IteratorTag)
+ _Predicate __pred, const _Tp& __new_value, _IteratorTag)
{ replace_if(__begin, __end, __pred, __new_value,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
template<typename _RAIter, typename _Predicate, typename _Tp>
void
__replace_if_switch(_RAIter __begin, _RAIter __end,
- _Predicate __pred, const _Tp& __new_value,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ _Predicate __pred, const _Tp& __new_value,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().replace_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- bool __dummy;
- __gnu_parallel::
- __replace_if_selector<_RAIter, _Predicate, _Tp>
- __functionality(__new_value);
- __gnu_parallel::
- __for_each_template_random_access(
- __begin, __end, __pred, __functionality,
- __gnu_parallel::_DummyReduct(),
- true, __dummy, -1, __parallelism_tag);
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().replace_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ bool __dummy;
+ __gnu_parallel::
+ __replace_if_selector<_RAIter, _Predicate, _Tp>
+ __functionality(__new_value);
+ __gnu_parallel::
+ __for_each_template_random_access(
+ __begin, __end, __pred, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ true, __dummy, -1, __parallelism_tag);
+ }
else
- replace_if(__begin, __end, __pred, __new_value,
- __gnu_parallel::sequential_tag());
+ replace_if(__begin, __end, __pred, __new_value,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
template<typename _FIterator, typename _Predicate, typename _Tp>
inline void
replace_if(_FIterator __begin, _FIterator __end,
- _Predicate __pred, const _Tp& __new_value,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ _Predicate __pred, const _Tp& __new_value,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<_FIterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
__replace_if_switch(__begin, __end, __pred, __new_value,
- _IteratorCategory(), __parallelism_tag);
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _FIterator, typename _Predicate, typename _Tp>
inline void
replace_if(_FIterator __begin, _FIterator __end,
- _Predicate __pred, const _Tp& __new_value)
+ _Predicate __pred, const _Tp& __new_value)
{
- typedef std::iterator_traits<_FIterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
__replace_if_switch(__begin, __end, __pred, __new_value,
- _IteratorCategory());
+ std::__iterator_category(__begin));
}
// Sequential fallback
template<typename _FIterator, typename _Generator>
inline void
- generate(_FIterator __begin, _FIterator __end, _Generator __gen,
- __gnu_parallel::sequential_tag)
+ generate(_FIterator __begin, _FIterator __end, _Generator __gen,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::generate(__begin, __end, __gen); }
// Sequential fallback for input iterator case.
template<typename _FIterator, typename _Generator, typename _IteratorTag>
inline void
__generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen,
- _IteratorTag)
+ _IteratorTag)
{ generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
template<typename _RAIter, typename _Generator>
void
__generate_switch(_RAIter __begin, _RAIter __end,
- _Generator __gen, random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ _Generator __gen, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().generate_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- bool __dummy;
- __gnu_parallel::__generate_selector<_RAIter>
- __functionality;
- __gnu_parallel::
- __for_each_template_random_access(
- __begin, __end, __gen, __functionality,
- __gnu_parallel::_DummyReduct(),
- true, __dummy, -1, __parallelism_tag);
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().generate_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ bool __dummy;
+ __gnu_parallel::__generate_selector<_RAIter>
+ __functionality;
+ __gnu_parallel::
+ __for_each_template_random_access(
+ __begin, __end, __gen, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ true, __dummy, -1, __parallelism_tag);
+ }
else
- generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
+ generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
}
// Public interface.
template<typename _FIterator, typename _Generator>
inline void
generate(_FIterator __begin, _FIterator __end,
- _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
+ _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<_FIterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- __generate_switch(__begin, __end, __gen, _IteratorCategory(),
- __parallelism_tag);
+ __generate_switch(__begin, __end, __gen,
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _FIterator, typename _Generator>
inline void
generate(_FIterator __begin, _FIterator __end, _Generator __gen)
{
- typedef std::iterator_traits<_FIterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- __generate_switch(__begin, __end, __gen, _IteratorCategory());
+ __generate_switch(__begin, __end, __gen,
+ std::__iterator_category(__begin));
}
// Sequential fallback.
template<typename _OutputIterator, typename _Size, typename _Generator>
inline _OutputIterator
- generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
- __gnu_parallel::sequential_tag)
+ generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); }
// Sequential fallback for input iterator case.
template<typename _OutputIterator, typename _Size, typename _Generator,
- typename _IteratorTag>
+ typename _IteratorTag>
inline _OutputIterator
__generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen,
- _IteratorTag)
+ _IteratorTag)
{ return generate_n(__begin, __n, __gen,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
template<typename _RAIter, typename _Size, typename _Generator>
inline _RAIter
- __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
// XXX parallel version is where?
return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
@@ -1609,38 +1491,36 @@ namespace __parallel
// Public interface.
template<typename _OutputIterator, typename _Size, typename _Generator>
inline _OutputIterator
- generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return __generate_n_switch(__begin, __n, __gen, _IteratorCategory(),
- __parallelism_tag);
+ return __generate_n_switch(__begin, __n, __gen,
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _OutputIterator, typename _Size, typename _Generator>
inline _OutputIterator
generate_n(_OutputIterator __begin, _Size __n, _Generator __gen)
{
- typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
- typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return __generate_n_switch(__begin, __n, __gen, _IteratorCategory());
+ return __generate_n_switch(__begin, __n, __gen,
+ std::__iterator_category(__begin));
}
// Sequential fallback.
template<typename _RAIter>
inline void
- random_shuffle(_RAIter __begin, _RAIter __end,
- __gnu_parallel::sequential_tag)
+ random_shuffle(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::random_shuffle(__begin, __end); }
// Sequential fallback.
template<typename _RAIter, typename _RandomNumberGenerator>
inline void
random_shuffle(_RAIter __begin, _RAIter __end,
- _RandomNumberGenerator& __rand,
- __gnu_parallel::sequential_tag)
+ _RandomNumberGenerator& __rand,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); }
@@ -1668,56 +1548,56 @@ namespace __parallel
void
random_shuffle(_RAIter __begin, _RAIter __end,
#if __cplusplus >= 201103L
- _RandomNumberGenerator&& __rand)
+ _RandomNumberGenerator&& __rand)
#else
- _RandomNumberGenerator& __rand)
+ _RandomNumberGenerator& __rand)
#endif
{
if (__begin == __end)
- return;
+ return;
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
- __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
+ __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
else
- __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
+ __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
}
// Sequential fallback.
template<typename _FIterator, typename _Predicate>
inline _FIterator
partition(_FIterator __begin, _FIterator __end,
- _Predicate __pred, __gnu_parallel::sequential_tag)
+ _Predicate __pred, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::partition(__begin, __end, __pred); }
// Sequential fallback for input iterator case.
template<typename _FIterator, typename _Predicate, typename _IteratorTag>
inline _FIterator
__partition_switch(_FIterator __begin, _FIterator __end,
- _Predicate __pred, _IteratorTag)
+ _Predicate __pred, _IteratorTag)
{ return partition(__begin, __end, __pred,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
template<typename _RAIter, typename _Predicate>
_RAIter
__partition_switch(_RAIter __begin, _RAIter __end,
- _Predicate __pred, random_access_iterator_tag)
+ _Predicate __pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().partition_minimal_n))
- {
- typedef typename std::iterator_traits<_RAIter>::
- difference_type _DifferenceType;
- _DifferenceType __middle = __gnu_parallel::
- __parallel_partition(__begin, __end, __pred,
- __gnu_parallel::__get_max_threads());
- return __begin + __middle;
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().partition_minimal_n))
+ {
+ typedef typename std::iterator_traits<_RAIter>::
+ difference_type _DifferenceType;
+ _DifferenceType __middle = __gnu_parallel::
+ __parallel_partition(__begin, __end, __pred,
+ __gnu_parallel::__get_max_threads());
+ return __begin + __middle;
+ }
else
- return partition(__begin, __end, __pred,
- __gnu_parallel::sequential_tag());
+ return partition(__begin, __end, __pred,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
@@ -1725,9 +1605,8 @@ namespace __parallel
inline _FIterator
partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __partition_switch(__begin, __end, __pred, _IteratorCategory());
+ return __partition_switch(__begin, __end, __pred,
+ std::__iterator_category(__begin));
}
// sort interface
@@ -1735,37 +1614,36 @@ namespace __parallel
// Sequential fallback
template<typename _RAIter>
inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::sequential_tag)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::sort(__begin, __end); }
// Sequential fallback
template<typename _RAIter, typename _Compare>
inline void
sort(_RAIter __begin, _RAIter __end, _Compare __comp,
- __gnu_parallel::sequential_tag)
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end,
- __comp); }
+ __comp); }
// Public interface
template<typename _RAIter, typename _Compare,
- typename _Parallelism>
- void
- sort(_RAIter __begin, _RAIter __end, _Compare __comp,
- _Parallelism __parallelism)
+ typename _Parallelism>
+ void
+ sort(_RAIter __begin, _RAIter __end, _Compare __comp,
+ _Parallelism __parallelism)
{
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
if (__begin != __end)
{
- if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
- __gnu_parallel::_Settings::get().sort_minimal_n))
- __gnu_parallel::__parallel_sort<false>(
- __begin, __end, __comp, __parallelism);
- else
- sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
+ __gnu_parallel::_Settings::get().sort_minimal_n))
+ __gnu_parallel::__parallel_sort<false>(
+ __begin, __end, __comp, __parallelism);
+ else
+ sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
}
}
@@ -1774,458 +1652,425 @@ namespace __parallel
inline void
sort(_RAIter __begin, _RAIter __end)
{
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
sort(__begin, __end, std::less<_ValueType>(),
- __gnu_parallel::default_parallel_tag());
+ __gnu_parallel::default_parallel_tag());
}
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::default_parallel_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::default_parallel_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::parallel_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::parallel_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::multiway_mergesort_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::quicksort_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::quicksort_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::balanced_quicksort_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::balanced_quicksort_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface
template<typename _RAIter, typename _Compare>
void
sort(_RAIter __begin, _RAIter __end, _Compare __comp)
{
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
- }
-
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
+ }
// stable_sort interface
// Sequential fallback
template<typename _RAIter>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_A::stable_sort(__begin, __end); }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_A::stable_sort(__begin, __end); }
// Sequential fallback
template<typename _RAIter, typename _Compare>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end,
- _Compare __comp, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(
- __begin, __end, __comp); }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(__begin, __end, __comp); }
// Public interface
template<typename _RAIter, typename _Compare,
- typename _Parallelism>
- void
- stable_sort(_RAIter __begin, _RAIter __end,
- _Compare __comp, _Parallelism __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
+ typename _Parallelism>
+ void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, _Parallelism __parallelism)
+ {
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
- if (__begin != __end)
- {
- if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
- __gnu_parallel::_Settings::get().sort_minimal_n))
- __gnu_parallel::__parallel_sort<true>(
- __begin, __end, __comp, __parallelism);
- else
- stable_sort(__begin, __end, __comp,
- __gnu_parallel::sequential_tag());
- }
- }
+ if (__begin != __end)
+ {
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
+ __gnu_parallel::_Settings::get().sort_minimal_n))
+ __gnu_parallel::__parallel_sort<true>(__begin, __end,
+ __comp, __parallelism);
+ else
+ stable_sort(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag());
+ }
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- stable_sort(__begin, __end, std::less<_ValueType>(),
- __gnu_parallel::default_parallel_tag());
- }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(),
+ __gnu_parallel::default_parallel_tag());
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::default_parallel_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::default_parallel_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::parallel_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::parallel_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::multiway_mergesort_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::quicksort_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::quicksort_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface, insert default comparator
template<typename _RAIter>
- inline void
- stable_sort(_RAIter __begin, _RAIter __end,
- __gnu_parallel::balanced_quicksort_tag __parallelism)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
- }
+ inline void
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::balanced_quicksort_tag __parallelism)
+ {
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
+ }
// Public interface
template<typename _RAIter, typename _Compare>
- void
- stable_sort(_RAIter __begin, _RAIter __end,
- _Compare __comp)
- {
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
- stable_sort(
- __begin, __end, __comp, __gnu_parallel::default_parallel_tag());
- }
+ void
+ stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp)
+ {
+ stable_sort(
+ __begin, __end, __comp, __gnu_parallel::default_parallel_tag());
+ }
// Sequential fallback
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
+ typename _OutputIterator>
inline _OutputIterator
- merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
- _IIter2 __end2, _OutputIterator __result,
- __gnu_parallel::sequential_tag)
+ merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _IIter2 __end2, _OutputIterator __result,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::merge(
- __begin1, __end1, __begin2, __end2, __result); }
+ __begin1, __end1, __begin2, __end2, __result); }
// Sequential fallback
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Compare>
+ typename _OutputIterator, typename _Compare>
inline _OutputIterator
merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
- _IIter2 __end2, _OutputIterator __result, _Compare __comp,
- __gnu_parallel::sequential_tag)
+ _IIter2 __end2, _OutputIterator __result, _Compare __comp,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::merge(
- __begin1, __end1, __begin2, __end2, __result, __comp); }
+ __begin1, __end1, __begin2, __end2, __result, __comp); }
// Sequential fallback for input iterator case
template<typename _IIter1, typename _IIter2, typename _OutputIterator,
- typename _Compare, typename _IteratorTag1,
- typename _IteratorTag2, typename _IteratorTag3>
+ typename _Compare, typename _IteratorTag1,
+ typename _IteratorTag2, typename _IteratorTag3>
inline _OutputIterator
__merge_switch(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __result, _Compare __comp,
- _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Compare __comp,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
{ return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2,
- __result, __comp); }
+ __result, __comp); }
// Parallel algorithm for random access iterators
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Compare>
+ typename _OutputIterator, typename _Compare>
_OutputIterator
- __merge_switch(_IIter1 __begin1, _IIter1 __end1,
- _IIter2 __begin2, _IIter2 __end2,
- _OutputIterator __result, _Compare __comp,
- random_access_iterator_tag, random_access_iterator_tag,
- random_access_iterator_tag)
+ __merge_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Compare __comp,
+ random_access_iterator_tag, random_access_iterator_tag,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
- >= __gnu_parallel::_Settings::get().merge_minimal_n
- || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
- >= __gnu_parallel::_Settings::get().merge_minimal_n)))
- return __gnu_parallel::__parallel_merge_advance(
- __begin1, __end1, __begin2, __end2, __result,
- (__end1 - __begin1) + (__end2 - __begin2), __comp);
+ (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
+ >= __gnu_parallel::_Settings::get().merge_minimal_n
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
+ >= __gnu_parallel::_Settings::get().merge_minimal_n)))
+ return __gnu_parallel::__parallel_merge_advance(
+ __begin1, __end1, __begin2, __end2, __result,
+ (__end1 - __begin1) + (__end2 - __begin2), __comp);
else
- return __gnu_parallel::__merge_advance(
- __begin1, __end1, __begin2, __end2, __result,
- (__end1 - __begin1) + (__end2 - __begin2), __comp);
+ return __gnu_parallel::__merge_advance(
+ __begin1, __end1, __begin2, __end2, __result,
+ (__end1 - __begin1) + (__end2 - __begin2), __comp);
}
// Public interface
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator, typename _Compare>
+ typename _OutputIterator, typename _Compare>
inline _OutputIterator
- merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
- _IIter2 __end2, _OutputIterator __result, _Compare __comp)
+ merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _IIter2 __end2, _OutputIterator __result, _Compare __comp)
{
- typedef typename iterator_traits<_IIter1>::value_type _ValueType;
-
- typedef std::iterator_traits<_IIter1> _IIterTraits1;
- typedef std::iterator_traits<_IIter2> _IIterTraits2;
- typedef std::iterator_traits<_OutputIterator> _OIterTraits;
- typedef typename _IIterTraits1::iterator_category
- _IIterCategory1;
- typedef typename _IIterTraits2::iterator_category
- _IIterCategory2;
- typedef typename _OIterTraits::iterator_category _OIterCategory;
-
return __merge_switch(
- __begin1, __end1, __begin2, __end2, __result, __comp,
- _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ __begin1, __end1, __begin2, __end2, __result, __comp,
+ std::__iterator_category(__begin1),
+ std::__iterator_category(__begin2),
+ std::__iterator_category(__result));
}
-
// Public interface, insert default comparator
template<typename _IIter1, typename _IIter2,
- typename _OutputIterator>
+ typename _OutputIterator>
inline _OutputIterator
- merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
- _IIter2 __end2, _OutputIterator __result)
+ merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _IIter2 __end2, _OutputIterator __result)
{
- typedef std::iterator_traits<_IIter1> _Iterator1Traits;
- typedef std::iterator_traits<_IIter2> _Iterator2Traits;
- typedef typename _Iterator1Traits::value_type _ValueType1;
- typedef typename _Iterator2Traits::value_type _ValueType2;
+ typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
+ typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2,
- __result, __gnu_parallel::_Less<_ValueType1, _ValueType2>());
+ __result, __gnu_parallel::_Less<_ValueType1, _ValueType2>());
}
// Sequential fallback
template<typename _RAIter>
inline void
- nth_element(_RAIter __begin, _RAIter __nth,
- _RAIter __end, __gnu_parallel::sequential_tag)
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); }
// Sequential fallback
template<typename _RAIter, typename _Compare>
inline void
- nth_element(_RAIter __begin, _RAIter __nth,
- _RAIter __end, _Compare __comp,
- __gnu_parallel::sequential_tag)
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end, _Compare __comp,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); }
// Public interface
template<typename _RAIter, typename _Compare>
inline void
- nth_element(_RAIter __begin, _RAIter __nth,
- _RAIter __end, _Compare __comp)
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end, _Compare __comp)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
- __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
+ __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
else
- nth_element(__begin, __nth, __end, __comp,
- __gnu_parallel::sequential_tag());
+ nth_element(__begin, __nth, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
template<typename _RAIter>
inline void
- nth_element(_RAIter __begin, _RAIter __nth,
- _RAIter __end)
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end)
{
- typedef iterator_traits<_RAIter> _TraitsType;
- typedef typename _TraitsType::value_type _ValueType;
+ typedef typename iterator_traits<_RAIter>::value_type _ValueType;
__gnu_parallel::nth_element(__begin, __nth, __end,
- std::less<_ValueType>());
+ std::less<_ValueType>());
}
// Sequential fallback
template<typename _RAIter, typename _Compare>
inline void
- partial_sort(_RAIter __begin, _RAIter __middle,
- _RAIter __end, _Compare __comp,
- __gnu_parallel::sequential_tag)
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end, _Compare __comp,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); }
// Sequential fallback
template<typename _RAIter>
inline void
- partial_sort(_RAIter __begin, _RAIter __middle,
- _RAIter __end, __gnu_parallel::sequential_tag)
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end, __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); }
// Public interface, parallel algorithm for random access iterators
template<typename _RAIter, typename _Compare>
void
- partial_sort(_RAIter __begin, _RAIter __middle,
- _RAIter __end, _Compare __comp)
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end, _Compare __comp)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
- __gnu_parallel::
- __parallel_partial_sort(__begin, __middle, __end, __comp);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
+ __gnu_parallel::
+ __parallel_partial_sort(__begin, __middle, __end, __comp);
else
- partial_sort(__begin, __middle, __end, __comp,
- __gnu_parallel::sequential_tag());
+ partial_sort(__begin, __middle, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
template<typename _RAIter>
inline void
- partial_sort(_RAIter __begin, _RAIter __middle,
- _RAIter __end)
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end)
{
typedef iterator_traits<_RAIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType;
__gnu_parallel::partial_sort(__begin, __middle, __end,
- std::less<_ValueType>());
+ std::less<_ValueType>());
}
// Sequential fallback
template<typename _FIterator>
inline _FIterator
- max_element(_FIterator __begin, _FIterator __end,
- __gnu_parallel::sequential_tag)
+ max_element(_FIterator __begin, _FIterator __end,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::max_element(__begin, __end); }
// Sequential fallback
template<typename _FIterator, typename _Compare>
inline _FIterator
- max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
- __gnu_parallel::sequential_tag)
+ max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); }
// Sequential fallback for input iterator case
template<typename _FIterator, typename _Compare, typename _IteratorTag>
inline _FIterator
- __max_element_switch(_FIterator __begin, _FIterator __end,
- _Compare __comp, _IteratorTag)
+ __max_element_switch(_FIterator __begin, _FIterator __end,
+ _Compare __comp, _IteratorTag)
{ return max_element(__begin, __end, __comp,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
template<typename _RAIter, typename _Compare>
_RAIter
- __max_element_switch(_RAIter __begin, _RAIter __end,
- _Compare __comp, random_access_iterator_tag,
+ __max_element_switch(_RAIter __begin, _RAIter __end,
+ _Compare __comp, random_access_iterator_tag,
__gnu_parallel::_Parallelism __parallelism_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().max_element_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- _RAIter __res(__begin);
- __gnu_parallel::__identity_selector<_RAIter>
- __functionality;
- __gnu_parallel::
- __for_each_template_random_access(
- __begin, __end, __gnu_parallel::_Nothing(), __functionality,
- __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
- __res, __res, -1, __parallelism_tag);
- return __res;
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().max_element_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ _RAIter __res(__begin);
+ __gnu_parallel::__identity_selector<_RAIter>
+ __functionality;
+ __gnu_parallel::
+ __for_each_template_random_access(
+ __begin, __end, __gnu_parallel::_Nothing(), __functionality,
+ __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
+ __res, __res, -1, __parallelism_tag);
+ return __res;
+ }
else
- return max_element(__begin, __end, __comp,
- __gnu_parallel::sequential_tag());
+ return max_element(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
template<typename _FIterator>
inline _FIterator
- max_element(_FIterator __begin, _FIterator __end,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ max_element(_FIterator __begin, _FIterator __end,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
typedef typename iterator_traits<_FIterator>::value_type _ValueType;
return max_element(__begin, __end, std::less<_ValueType>(),
- __parallelism_tag);
+ __parallelism_tag);
}
template<typename _FIterator>
@@ -2234,89 +2079,87 @@ namespace __parallel
{
typedef typename iterator_traits<_FIterator>::value_type _ValueType;
return __gnu_parallel::max_element(__begin, __end,
- std::less<_ValueType>());
+ std::less<_ValueType>());
}
// Public interface
template<typename _FIterator, typename _Compare>
inline _FIterator
max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __max_element_switch(__begin, __end, __comp, _IteratorCategory(),
- __parallelism_tag);
+ return __max_element_switch(__begin, __end, __comp,
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _FIterator, typename _Compare>
inline _FIterator
max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __max_element_switch(__begin, __end, __comp, _IteratorCategory());
+ return __max_element_switch(__begin, __end, __comp,
+ std::__iterator_category(__begin));
}
// Sequential fallback
template<typename _FIterator>
inline _FIterator
- min_element(_FIterator __begin, _FIterator __end,
- __gnu_parallel::sequential_tag)
+ min_element(_FIterator __begin, _FIterator __end,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::min_element(__begin, __end); }
// Sequential fallback
template<typename _FIterator, typename _Compare>
inline _FIterator
- min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
- __gnu_parallel::sequential_tag)
+ min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); }
// Sequential fallback for input iterator case
template<typename _FIterator, typename _Compare, typename _IteratorTag>
inline _FIterator
- __min_element_switch(_FIterator __begin, _FIterator __end,
- _Compare __comp, _IteratorTag)
+ __min_element_switch(_FIterator __begin, _FIterator __end,
+ _Compare __comp, _IteratorTag)
{ return min_element(__begin, __end, __comp,
- __gnu_parallel::sequential_tag()); }
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
template<typename _RAIter, typename _Compare>
_RAIter
- __min_element_switch(_RAIter __begin, _RAIter __end,
- _Compare __comp, random_access_iterator_tag,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __min_element_switch(_RAIter __begin, _RAIter __end,
+ _Compare __comp, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
- >= __gnu_parallel::_Settings::get().min_element_minimal_n
- && __gnu_parallel::__is_parallel(__parallelism_tag)))
- {
- _RAIter __res(__begin);
- __gnu_parallel::__identity_selector<_RAIter>
- __functionality;
- __gnu_parallel::
- __for_each_template_random_access(
- __begin, __end, __gnu_parallel::_Nothing(), __functionality,
- __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
- __res, __res, -1, __parallelism_tag);
- return __res;
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().min_element_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ _RAIter __res(__begin);
+ __gnu_parallel::__identity_selector<_RAIter>
+ __functionality;
+ __gnu_parallel::
+ __for_each_template_random_access(
+ __begin, __end, __gnu_parallel::_Nothing(), __functionality,
+ __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
+ __res, __res, -1, __parallelism_tag);
+ return __res;
+ }
else
- return min_element(__begin, __end, __comp,
- __gnu_parallel::sequential_tag());
+ return min_element(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
template<typename _FIterator>
inline _FIterator
- min_element(_FIterator __begin, _FIterator __end,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ min_element(_FIterator __begin, _FIterator __end,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
typedef typename iterator_traits<_FIterator>::value_type _ValueType;
return min_element(__begin, __end, std::less<_ValueType>(),
- __parallelism_tag);
+ __parallelism_tag);
}
template<typename _FIterator>
@@ -2325,28 +2168,26 @@ namespace __parallel
{
typedef typename iterator_traits<_FIterator>::value_type _ValueType;
return __gnu_parallel::min_element(__begin, __end,
- std::less<_ValueType>());
+ std::less<_ValueType>());
}
// Public interface
template<typename _FIterator, typename _Compare>
inline _FIterator
min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
- __gnu_parallel::_Parallelism __parallelism_tag)
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __min_element_switch(__begin, __end, __comp, _IteratorCategory(),
- __parallelism_tag);
+ return __min_element_switch(__begin, __end, __comp,
+ std::__iterator_category(__begin),
+ __parallelism_tag);
}
template<typename _FIterator, typename _Compare>
inline _FIterator
min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
{
- typedef iterator_traits<_FIterator> _TraitsType;
- typedef typename _TraitsType::iterator_category _IteratorCategory;
- return __min_element_switch(__begin, __end, __comp, _IteratorCategory());
+ return __min_element_switch(__begin, __end, __comp,
+ std::__iterator_category(__begin));
}
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index f29d8e1adbc..11e7fa298c4 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -784,7 +784,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
// Clocks.
// Why nanosecond resolution as the default?
- // Why have std::system_clock always count in the higest
+ // Why have std::system_clock always count in the highest
// resolution (ie nanoseconds), even if on some OSes the low 3
// or 9 decimal digits will be always zero? This allows later
// implementations to change the system_clock::now()
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index c750a8374bc..74e65c7b96f 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -1401,7 +1401,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
void (_Undefined_class::*_M_member_pointer)();
};
- union _Any_data
+ union [[gnu::may_alias]] _Any_data
{
void* _M_access() { return &_M_pod_data[0]; }
const void* _M_access() const { return &_M_pod_data[0]; }
@@ -2206,6 +2206,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
}
// Searchers
+#define __cpp_lib_boyer_moore_searcher 201603
template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>>
class default_searcher
diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional
index 2ff75eae638..21210ab6532 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -378,7 +378,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr bool _M_is_engaged() const noexcept
{ return this->_M_engaged; }
- _Tp&
+ constexpr _Tp&
_M_get() noexcept
{ return _M_payload; }
@@ -423,19 +423,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
class optional;
- template<typename>
- struct __is_optional_impl : false_type
- { };
-
- template<typename _Tp>
- struct __is_optional_impl<optional<_Tp>> : true_type
- { };
-
- template<typename _Tp>
- struct __is_optional
- : public __is_optional_impl<std::remove_cv_t<std::remove_reference_t<_Tp>>>
- { };
-
+ template<typename _Tp, typename _Up>
+ using __converts_from_optional =
+ __or_<is_constructible<_Tp, const optional<_Up>&>,
+ is_constructible<_Tp, optional<_Up>&>,
+ is_constructible<_Tp, const optional<_Up>&&>,
+ is_constructible<_Tp, optional<_Up>&&>,
+ is_convertible<const optional<_Up>&, _Tp>,
+ is_convertible<optional<_Up>&, _Tp>,
+ is_convertible<const optional<_Up>&&, _Tp>,
+ is_convertible<optional<_Up>&&, _Tp>>;
+
+ template<typename _Tp, typename _Up>
+ using __assigns_from_optional =
+ __or_<is_assignable<_Tp&, const optional<_Up>&>,
+ is_assignable<_Tp&, optional<_Up>&>,
+ is_assignable<_Tp&, const optional<_Up>&&>,
+ is_assignable<_Tp&, optional<_Up>&&>>;
/**
* @brief Class template for optional values.
@@ -474,7 +478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Converting constructors for engaged optionals.
template <typename _Up = _Tp,
enable_if_t<__and_<
- __not_<__is_optional<decay_t<_Up>>>,
+ __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
is_constructible<_Tp, _Up&&>,
is_convertible<_Up&&, _Tp>
>::value, bool> = true>
@@ -483,7 +487,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _Up = _Tp,
enable_if_t<__and_<
- __not_<__is_optional<decay_t<_Up>>>,
+ __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
is_constructible<_Tp, _Up&&>,
__not_<is_convertible<_Up&&, _Tp>>
>::value, bool> = false>
@@ -494,37 +498,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
enable_if_t<__and_<
__not_<is_same<_Tp, _Up>>,
is_constructible<_Tp, const _Up&>,
- is_convertible<const _Up&, _Tp>
+ is_convertible<const _Up&, _Tp>,
+ __not_<__converts_from_optional<_Tp, _Up>>
>::value, bool> = true>
constexpr optional(const optional<_Up>& __t)
- : _Base(__t ? _Base(std::in_place, *__t) : _Base()) { }
+ {
+ if (__t)
+ emplace(*__t);
+ }
template <typename _Up,
enable_if_t<__and_<
__not_<is_same<_Tp, _Up>>,
is_constructible<_Tp, const _Up&>,
- __not_<is_convertible<const _Up&, _Tp>>
+ __not_<is_convertible<const _Up&, _Tp>>,
+ __not_<__converts_from_optional<_Tp, _Up>>
>::value, bool> = false>
explicit constexpr optional(const optional<_Up>& __t)
- : _Base(__t ? _Base(std::in_place, *__t) : _Base()) { }
+ {
+ if (__t)
+ emplace(*__t);
+ }
template <typename _Up,
enable_if_t<__and_<
__not_<is_same<_Tp, _Up>>,
is_constructible<_Tp, _Up&&>,
- is_convertible<_Up&&, _Tp>
+ is_convertible<_Up&&, _Tp>,
+ __not_<__converts_from_optional<_Tp, _Up>>
>::value, bool> = true>
constexpr optional(optional<_Up>&& __t)
- : _Base(__t ? _Base(std::in_place, std::move(*__t)) : _Base()) { }
+ {
+ if (__t)
+ emplace(std::move(*__t));
+ }
template <typename _Up,
enable_if_t<__and_<
__not_<is_same<_Tp, _Up>>,
is_constructible<_Tp, _Up&&>,
- __not_<is_convertible<_Up&&, _Tp>>
+ __not_<is_convertible<_Up&&, _Tp>>,
+ __not_<__converts_from_optional<_Tp, _Up>>
>::value, bool> = false>
explicit constexpr optional(optional<_Up>&& __t)
- : _Base(__t ? _Base(std::in_place, std::move(*__t)) : _Base()) { }
+ {
+ if (__t)
+ emplace(std::move(*__t));
+ }
template<typename... _Args>
explicit constexpr optional(in_place_t, _Args&&... __args)
@@ -550,8 +570,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up = _Tp,
enable_if_t<__and_<
- __not_<__is_optional<decay_t<_Up>>>,
+ __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
is_constructible<_Tp, _Up>,
+ __not_<__and_<is_scalar<_Tp>,
+ is_same<_Tp, decay_t<_Up>>>>,
is_assignable<_Tp&, _Up>>::value,
bool> = true>
optional&
@@ -568,8 +590,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up,
enable_if_t<__and_<
__not_<is_same<_Tp, _Up>>,
- is_constructible<_Tp, _Up>,
- is_assignable<_Tp&, _Up>>::value,
+ is_constructible<_Tp, const _Up&>,
+ is_assignable<_Tp&, _Up>,
+ __not_<__converts_from_optional<_Tp, _Up>>,
+ __not_<__assigns_from_optional<_Tp, _Up>>
+ >::value,
bool> = true>
optional&
operator=(const optional<_Up>& __u)
@@ -592,7 +617,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
enable_if_t<__and_<
__not_<is_same<_Tp, _Up>>,
is_constructible<_Tp, _Up>,
- is_assignable<_Tp&, _Up>>::value,
+ is_assignable<_Tp&, _Up>,
+ __not_<__converts_from_optional<_Tp, _Up>>,
+ __not_<__assigns_from_optional<_Tp, _Up>>
+ >::value,
bool> = true>
optional&
operator=(optional<_Up>&& __u)
@@ -749,7 +777,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
? std::move(this->_M_get())
: static_cast<_Tp>(std::forward<_Up>(__u));
}
- void reset() { this->_M_reset(); }
+ void reset() noexcept { this->_M_reset(); }
};
template<typename _Tp>
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index c06a040a960..32b932f79fd 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -220,8 +220,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr _Tuple_impl(const _Tuple_impl&) = default;
constexpr
- _Tuple_impl(_Tuple_impl&& __in)
- noexcept(__and_<is_nothrow_move_constructible<_Head>,
+ _Tuple_impl(typename conditional<
+ __and_<is_move_constructible<_Head>,
+ is_move_constructible<_Inherited>>::value,
+ _Tuple_impl&&, __nonesuch&&>::type __in)
+ noexcept(__and_<is_nothrow_move_constructible<_Head>,
is_nothrow_move_constructible<_Inherited>>::value)
: _Inherited(std::move(_M_tail(__in))),
_Base(std::forward<_Head>(_M_head(__in))) { }
@@ -232,7 +235,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
template<typename _UHead, typename... _UTails>
- constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+ constexpr _Tuple_impl(typename conditional<
+ __and_<is_move_constructible<_Head>,
+ is_move_constructible<_Inherited>>::value,
+ _Tuple_impl<_Idx, _UHead, _UTails...>&&,
+ __nonesuch&&>::type __in)
: _Inherited(std::move
(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
_Base(std::forward<_UHead>
@@ -338,6 +345,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
+ template<typename...>
+ struct __is_tuple_impl_trait_impl : false_type
+ { };
+
+ template<std::size_t _Idx, typename... _Tp>
+ struct __is_tuple_impl_trait_impl<_Tuple_impl<_Idx, _Tp...>> : true_type
+ { };
+
+ template<typename _Tp>
+ struct __is_tuple_impl_trait : public __is_tuple_impl_trait_impl<_Tp>
+ { };
+
// Basis case of inheritance recursion.
template<std::size_t _Idx, typename _Head>
struct _Tuple_impl<_Idx, _Head>
@@ -356,11 +375,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr _Tuple_impl()
: _Base() { }
+ template<typename _Dummy=void,
+ typename enable_if<is_constructible<_Base, const _Head&>::value,
+ bool>::type=true>
explicit
constexpr _Tuple_impl(const _Head& __head)
: _Base(__head) { }
- template<typename _UHead>
+ template<typename _UHead,
+ typename enable_if<__and_<is_constructible<_Base, _UHead&&>,
+ __not_<__is_tuple_impl_trait<
+ typename
+ remove_reference<_UHead>::type>>
+ >::value,
+ bool>::type = true>
explicit
constexpr _Tuple_impl(_UHead&& __head)
: _Base(std::forward<_UHead>(__head)) { }
@@ -368,15 +396,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr _Tuple_impl(const _Tuple_impl&) = default;
constexpr
- _Tuple_impl(_Tuple_impl&& __in)
+ _Tuple_impl(typename conditional<
+ is_move_constructible<_Head>::value,
+ _Tuple_impl&&, __nonesuch&&>::type __in)
noexcept(is_nothrow_move_constructible<_Head>::value)
: _Base(std::forward<_Head>(_M_head(__in))) { }
- template<typename _UHead>
+ template<typename _UHead,
+ typename enable_if<!is_same<_Head, _UHead>::value,
+ bool>::type = true>
constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
: _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
- template<typename _UHead>
+ template<typename _UHead,
+ typename enable_if<!is_same<_Head, _UHead>::value,
+ bool>::type = true>
constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
: _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
{ }
@@ -832,14 +866,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
tuple&
- operator=(const tuple& __in)
+ operator=(typename
+ conditional<__and_<is_copy_assignable<_Elements>...>::value,
+ const tuple&, const __nonesuch&>::type __in)
{
static_cast<_Inherited&>(*this) = __in;
return *this;
}
tuple&
- operator=(tuple&& __in)
+ operator=(typename
+ conditional<__and_<is_move_assignable<_Elements>...>::value,
+ tuple&&, __nonesuch&&>::type __in)
noexcept(is_nothrow_move_assignable<_Inherited>::value)
{
static_cast<_Inherited&>(*this) = std::move(__in);
@@ -848,7 +886,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename... _UElements, typename = typename
enable_if<sizeof...(_UElements)
- == sizeof...(_Elements)>::type>
+ == sizeof...(_Elements)
+ &&
+ __and_<is_assignable<_Elements&,
+ const _UElements&>...>::value>::type>
tuple&
operator=(const tuple<_UElements...>& __in)
{
@@ -858,7 +899,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename... _UElements, typename = typename
enable_if<sizeof...(_UElements)
- == sizeof...(_Elements)>::type>
+ == sizeof...(_Elements)
+ &&
+ __and_<is_assignable<_Elements&,
+ _UElements&&>...>::value>::type>
tuple&
operator=(tuple<_UElements...>&& __in)
{
@@ -1189,14 +1233,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::forward<_U2>(__in.second)) { }
tuple&
- operator=(const tuple& __in)
+ operator=(typename
+ conditional<__and_<is_copy_assignable<_T1>,
+ is_copy_assignable<_T2>>::value,
+ const tuple&, const __nonesuch&>::type __in)
{
static_cast<_Inherited&>(*this) = __in;
return *this;
}
tuple&
- operator=(tuple&& __in)
+ operator=(typename
+ conditional<__and_<is_move_assignable<_T1>,
+ is_move_assignable<_T2>>::value,
+ tuple&&, __nonesuch&&>::type __in)
noexcept(is_nothrow_move_assignable<_Inherited>::value)
{
static_cast<_Inherited&>(*this) = std::move(__in);
@@ -1204,7 +1254,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, const _U1&>,
+ is_assignable<_T2&, const _U2&>>::value,
+ tuple&>::type
operator=(const tuple<_U1, _U2>& __in)
{
static_cast<_Inherited&>(*this) = __in;
@@ -1212,7 +1265,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, _U1&&>,
+ is_assignable<_T2&, _U2&&>>::value,
+ tuple&>::type
operator=(tuple<_U1, _U2>&& __in)
{
static_cast<_Inherited&>(*this) = std::move(__in);
@@ -1220,7 +1276,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, const _U1&>,
+ is_assignable<_T2&, const _U2&>>::value,
+ tuple&>::type
operator=(const pair<_U1, _U2>& __in)
{
this->_M_head(*this) = __in.first;
@@ -1229,7 +1288,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _U1, typename _U2>
- tuple&
+ typename
+ enable_if<__and_<is_assignable<_T1&, _U1&&>,
+ is_assignable<_T2&, _U2&&>>::value,
+ tuple&>::type
operator=(pair<_U1, _U2>&& __in)
{
this->_M_head(*this) = std::forward<_U1>(__in.first);
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 5085196f654..cd0ba99dcb8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2850,6 +2850,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__call_is_nothrow<result_of<_Fn(_Args...)>, _Fn, _Args...>>::type
{ };
+ struct __nonesuch {
+ __nonesuch() = delete;
+ ~__nonesuch() = delete;
+ __nonesuch(__nonesuch const&) = delete;
+ void operator=(__nonesuch const&) = delete;
+ };
+
#if __cplusplus > 201402L
# define __cpp_lib_is_callable 201603
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 7dbb533dd83..ac483f3e6ab 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -296,15 +296,9 @@ namespace __variant
{
constexpr _Variant_storage() = default;
- template<typename... _Args>
- constexpr _Variant_storage(in_place_index_t<0>, _Args&&... __args)
- : _M_first(in_place<0>, forward<_Args>(__args)...)
- { }
-
- template<size_t _Np, typename... _Args,
- typename = enable_if_t<0 < _Np && _Np < sizeof...(_Rest) + 1>>
+ template<size_t _Np, typename... _Args>
constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
- : _M_rest(in_place<_Np - 1>, forward<_Args>(__args)...)
+ : _M_union(in_place<_Np>, std::forward<_Args>(__args)...)
{ }
~_Variant_storage() = default;
@@ -313,14 +307,27 @@ namespace __variant
_M_storage() const
{
return const_cast<void*>(
- static_cast<const void*>(std::addressof(_M_first._M_storage)));
+ static_cast<const void*>(std::addressof(_M_union._M_first._M_storage)));
}
- union
+ union _Union
{
+ constexpr _Union() {};
+
+ template<typename... _Args>
+ constexpr _Union(in_place_index_t<0>, _Args&&... __args)
+ : _M_first(in_place<0>, std::forward<_Args>(__args)...)
+ { }
+
+ template<size_t _Np, typename... _Args,
+ typename = enable_if_t<0 < _Np && _Np < sizeof...(_Rest) + 1>>
+ constexpr _Union(in_place_index_t<_Np>, _Args&&... __args)
+ : _M_rest(in_place<_Np - 1>, std::forward<_Args>(__args)...)
+ { }
+
_Uninitialized<__storage<_First>> _M_first;
_Variant_storage<_Rest...> _M_rest;
- };
+ } _M_union;
};
template<typename _Derived, bool __is_trivially_destructible>
@@ -379,7 +386,7 @@ namespace __variant
template<size_t _Np, typename... _Args>
constexpr explicit
_Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
- : _Storage(__i, forward<_Args>(__args)...), _M_index(_Np)
+ : _Storage(__i, std::forward<_Args>(__args)...), _M_index(_Np)
{ }
template<typename _Alloc>
@@ -419,7 +426,7 @@ namespace __variant
using _Storage =
__storage<variant_alternative_t<_Np, variant<_Types...>>>;
__uses_allocator_construct(__a, static_cast<_Storage*>(_M_storage()),
- forward<_Args>(__args)...);
+ std::forward<_Args>(__args)...);
__glibcxx_assert(_M_index == _Np);
}
@@ -574,7 +581,7 @@ namespace __variant
decltype(auto) __access(_Variant&& __v)
{
return __get_alternative<__reserved_type_map<_Variant&&, __storage<_Tp>>>(
- __get_storage(forward<_Variant>(__v)));
+ __get_storage(std::forward<_Variant>(__v)));
}
// A helper used to create variadic number of _To types.
@@ -584,10 +591,11 @@ namespace __variant
// Call the actual visitor.
// _Args are qualified storage types.
template<typename _Visitor, typename... _Args>
- decltype(auto) __visit_invoke(_Visitor&& __visitor,
- _To_type<_Args, void*>... __ptrs)
+ decltype(auto)
+ __visit_invoke(_Visitor&& __visitor, _To_type<_Args, void*>... __ptrs)
{
- return forward<_Visitor>(__visitor)(__get_alternative<_Args>(__ptrs)...);
+ return std::forward<_Visitor>(__visitor)(
+ __get_alternative<_Args>(__ptrs)...);
}
// Used for storing multi-dimensional vtable.
@@ -1003,7 +1011,7 @@ namespace __variant
constexpr
variant(_Tp&& __t)
noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
- : variant(in_place<__accepted_index<_Tp&&>>, forward<_Tp>(__t))
+ : variant(in_place<__accepted_index<_Tp&&>>, std::forward<_Tp>(__t))
{ __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
template<typename _Tp, typename... _Args,
@@ -1011,7 +1019,7 @@ namespace __variant
&& is_constructible_v<_Tp, _Args&&...>>>
constexpr explicit
variant(in_place_type_t<_Tp>, _Args&&... __args)
- : variant(in_place<__index_of<_Tp>>, forward<_Args>(__args)...)
+ : variant(in_place<__index_of<_Tp>>, std::forward<_Args>(__args)...)
{ __glibcxx_assert(holds_alternative<_Tp>(*this)); }
template<typename _Tp, typename _Up, typename... _Args,
@@ -1022,7 +1030,7 @@ namespace __variant
variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
_Args&&... __args)
: variant(in_place<__index_of<_Tp>>, __il,
- forward<_Args>(__args)...)
+ std::forward<_Args>(__args)...)
{ __glibcxx_assert(holds_alternative<_Tp>(*this)); }
template<size_t _Np, typename... _Args,
@@ -1030,7 +1038,7 @@ namespace __variant
is_constructible_v<__to_type<_Np>, _Args&&...>>>
constexpr explicit
variant(in_place_index_t<_Np>, _Args&&... __args)
- : _Base(in_place<_Np>, forward<_Args>(__args)...),
+ : _Base(in_place<_Np>, std::forward<_Args>(__args)...),
_Default_ctor_enabler(_Enable_default_constructor_tag{})
{ __glibcxx_assert(index() == _Np); }
@@ -1040,7 +1048,7 @@ namespace __variant
constexpr explicit
variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
_Args&&... __args)
- : _Base(in_place<_Np>, __il, forward<_Args>(__args)...),
+ : _Base(in_place<_Np>, __il, std::forward<_Args>(__args)...),
_Default_ctor_enabler(_Enable_default_constructor_tag{})
{ __glibcxx_assert(index() == _Np); }
@@ -1077,7 +1085,7 @@ namespace __variant
&& !is_same_v<decay_t<_Tp>, variant>, variant&>>
variant(allocator_arg_t, const _Alloc& __a, _Tp&& __t)
: variant(allocator_arg, __a, in_place<__accepted_index<_Tp&&>>,
- forward<_Tp>(__t))
+ std::forward<_Tp>(__t))
{ __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
template<typename _Alloc, typename _Tp, typename... _Args,
@@ -1088,7 +1096,7 @@ namespace __variant
variant(allocator_arg_t, const _Alloc& __a, in_place_type_t<_Tp>,
_Args&&... __args)
: variant(allocator_arg, __a, in_place<__index_of<_Tp>>,
- forward<_Args>(__args)...)
+ std::forward<_Args>(__args)...)
{ __glibcxx_assert(holds_alternative<_Tp>(*this)); }
template<typename _Alloc, typename _Tp, typename _Up, typename... _Args,
@@ -1099,7 +1107,7 @@ namespace __variant
variant(allocator_arg_t, const _Alloc& __a, in_place_type_t<_Tp>,
initializer_list<_Up> __il, _Args&&... __args)
: variant(allocator_arg, __a, in_place<__index_of<_Tp>>, __il,
- forward<_Args>(__args)...)
+ std::forward<_Args>(__args)...)
{ __glibcxx_assert(holds_alternative<_Tp>(*this)); }
template<typename _Alloc, size_t _Np, typename... _Args,
@@ -1108,7 +1116,7 @@ namespace __variant
__to_type<_Np>, _Alloc, _Args&&...>>>
variant(allocator_arg_t, const _Alloc& __a, in_place_index_t<_Np>,
_Args&&... __args)
- : _Base(__a, in_place<_Np>, forward<_Args>(__args)...),
+ : _Base(__a, in_place<_Np>, std::forward<_Args>(__args)...),
_Default_ctor_enabler(_Enable_default_constructor_tag{})
{ __glibcxx_assert(index() == _Np); }
@@ -1118,7 +1126,7 @@ namespace __variant
__to_type<_Np>, _Alloc, initializer_list<_Up>&, _Args&&...>>>
variant(allocator_arg_t, const _Alloc& __a, in_place_index_t<_Np>,
initializer_list<_Up> __il, _Args&&... __args)
- : _Base(__a, in_place<_Np>, __il, forward<_Args>(__args)...),
+ : _Base(__a, in_place<_Np>, __il, std::forward<_Args>(__args)...),
_Default_ctor_enabler(_Enable_default_constructor_tag{})
{ __glibcxx_assert(index() == _Np); }
@@ -1140,10 +1148,9 @@ namespace __variant
{
constexpr auto __index = __accepted_index<_Tp&&>;
if (index() == __index)
- *static_cast<__storage<__to_type<__index>>*>(this->_M_storage())
- = forward<_Tp>(__rhs);
+ std::get<__index>(*this) = std::forward<_Tp>(__rhs);
else
- this->emplace<__index>(forward<_Tp>(__rhs));
+ this->emplace<__index>(std::forward<_Tp>(__rhs));
__glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this));
return *this;
}
@@ -1153,7 +1160,7 @@ namespace __variant
{
static_assert(__exactly_once<_Tp>,
"T should occur for exactly once in alternatives");
- this->emplace<__index_of<_Tp>>(forward<_Args>(__args)...);
+ this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...);
__glibcxx_assert(holds_alternative<_Tp>(*this));
}
@@ -1162,7 +1169,7 @@ namespace __variant
{
static_assert(__exactly_once<_Tp>,
"T should occur for exactly once in alternatives");
- this->emplace<__index_of<_Tp>>(__il, forward<_Args>(__args)...);
+ this->emplace<__index_of<_Tp>>(__il, std::forward<_Args>(__args)...);
__glibcxx_assert(holds_alternative<_Tp>(*this));
}
@@ -1175,7 +1182,7 @@ namespace __variant
__try
{
::new (this) variant(in_place<_Np>,
- forward<_Args>(__args)...);
+ std::forward<_Args>(__args)...);
}
__catch (...)
{
@@ -1194,7 +1201,7 @@ namespace __variant
__try
{
::new (this) variant(in_place<_Np>, __il,
- forward<_Args>(__args)...);
+ std::forward<_Args>(__args)...);
}
__catch (...)
{
@@ -1304,12 +1311,12 @@ namespace __variant
visit(_Visitor&& __visitor, _Variants&&... __variants)
{
using _Result_type =
- decltype(forward<_Visitor>(__visitor)(get<0>(__variants)...));
+ decltype(std::forward<_Visitor>(__visitor)(get<0>(__variants)...));
static constexpr auto _S_vtable =
__detail::__variant::__gen_vtable<
_Result_type, _Visitor&&, _Variants&&...>::_S_apply();
auto __func_ptr = _S_vtable._M_access(__variants.index()...);
- return (*__func_ptr)(forward<_Visitor>(__visitor),
+ return (*__func_ptr)(std::forward<_Visitor>(__visitor),
__detail::__variant::__get_storage(__variants)...);
}
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index e828ed909ca..3e663e0026a 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -236,6 +236,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/libsupc++/hash_bytes.cc b/libstdc++-v3/libsupc++/hash_bytes.cc
index 2e5bbfaca19..1042de66388 100644
--- a/libstdc++-v3/libsupc++/hash_bytes.cc
+++ b/libstdc++-v3/libsupc++/hash_bytes.cc
@@ -95,8 +95,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
case 3:
hash ^= static_cast<unsigned char>(buf[2]) << 16;
+ [[gnu::fallthrough]];
case 2:
hash ^= static_cast<unsigned char>(buf[1]) << 8;
+ [[gnu::fallthrough]];
case 1:
hash ^= static_cast<unsigned char>(buf[0]);
hash *= m;
diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in
index 13993c85819..83f13d08a95 100644
--- a/libstdc++-v3/po/Makefile.in
+++ b/libstdc++-v3/po/Makefile.in
@@ -163,6 +163,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in
index 25b2ed487b2..dcc9e06be43 100644
--- a/libstdc++-v3/python/Makefile.in
+++ b/libstdc++-v3/python/Makefile.in
@@ -193,6 +193,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 8c29760e01c..b5fc2a02aa5 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -130,6 +130,10 @@ class UniquePointerPrinter:
return ('std::unique_ptr<%s> containing %s' % (str(v.type.target()),
str(v)))
+def get_value_from_aligned_membuf(buf, valtype):
+ """Returns the value held in a __gnu_cxx::__aligned_membuf."""
+ return buf['_M_storage'].address.cast(valtype.pointer()).dereference()
+
def get_value_from_list_node(node):
"""Returns the value held in an _List_node<_Val>"""
try:
@@ -139,9 +143,8 @@ def get_value_from_list_node(node):
return node['_M_data']
elif member == '_M_storage':
# C++11 implementation, node stores value in __aligned_membuf
- p = node['_M_storage']['_M_storage'].address
- p = p.cast(node.type.template_argument(0).pointer())
- return p.dereference()
+ valtype = node.type.template_argument(0)
+ return get_value_from_aligned_membuf(node['_M_storage'], valtype)
except:
pass
raise ValueError("Unsupported implementation for %s" % str(node.type))
@@ -461,9 +464,8 @@ def get_value_from_Rb_tree_node(node):
return node['_M_value_field']
elif member == '_M_storage':
# C++11 implementation, node stores value in __aligned_membuf
- p = node['_M_storage']['_M_storage'].address
- p = p.cast(node.type.template_argument(0).pointer())
- return p.dereference()
+ valtype = node.type.template_argument(0)
+ return get_value_from_aligned_membuf(node['_M_storage'], valtype)
except:
pass
raise ValueError("Unsupported implementation for %s" % str(node.type))
@@ -879,9 +881,10 @@ class StdForwardListPrinter:
class SingleObjContainerPrinter(object):
"Base class for printers of containers of single objects"
- def __init__ (self, val, viz):
+ def __init__ (self, val, viz, hint = None):
self.contained_value = val
self.visualizer = viz
+ self.hint = hint
def _recognize(self, type):
"""Return TYPE as a string after applying type printers"""
@@ -916,7 +919,7 @@ class SingleObjContainerPrinter(object):
# if contained value is a map we want to display in the same way
if hasattr (self.visualizer, 'children') and hasattr (self.visualizer, 'display_hint'):
return self.visualizer.display_hint ()
- return None
+ return self.hint
class StdExpAnyPrinter(SingleObjContainerPrinter):
@@ -985,7 +988,6 @@ class StdVariantPrinter(SingleObjContainerPrinter):
def __init__(self, typename, val):
alternatives = self._template_args(val)
- self.alts = alternatives
self.typename = "%s<%s>" % (typename, ', '.join([self._recognize(alt) for alt in alternatives]))
self.index = val['_M_index']
if self.index >= len(alternatives):
@@ -994,27 +996,70 @@ class StdVariantPrinter(SingleObjContainerPrinter):
visualizer = None
else:
self.contained_type = alternatives[int(self.index)]
- addr = val['_M_first']['_M_storage'].address
+ addr = val['_M_union']['_M_first']['_M_storage'].address
contained_value = addr.cast(self.contained_type.pointer()).dereference()
visualizer = gdb.default_visualizer(contained_value)
- super (StdVariantPrinter, self).__init__(contained_value, visualizer)
+ super (StdVariantPrinter, self).__init__(contained_value, visualizer, 'array')
- def _template_args(self, val):
+ @staticmethod
+ def _template_args(val):
n = 0
- args = ()
+ args = []
while True:
try:
- args += (val.type.template_argument(n),)
+ args.append(val.type.template_argument(n))
except:
return args
n += 1
def to_string(self):
if self.contained_value is None:
- return "%s [no value]" % self.typename
+ return "%s [no contained value]" % self.typename
if hasattr(self.visualizer, 'children'):
- return "%s [alternative %d] %s" % (self.typename, self.index, self.visualizer.to_string())
- return self.typename
+ return "%s [index %d] containing %s" % (self.typename, self.index, self.visualizer.to_string())
+ return "%s [index %d]" % (self.typename, self.index)
+
+class StdNodeHandlePrinter(SingleObjContainerPrinter):
+ "Print a container node handle"
+
+ def __init__(self, typename, val):
+ self.value_type = val.type.template_argument(1)
+ nodetype = val.type.template_argument(2).template_argument(0)
+ self.is_rb_tree_node = nodetype.name.startswith('std::_Rb_tree_node')
+ self.is_map_node = val.type.template_argument(0) != self.value_type
+ nodeptr = val['_M_ptr']
+ if nodeptr:
+ if self.is_rb_tree_node:
+ contained_value = get_value_from_Rb_tree_node(nodeptr.dereference())
+ else:
+ contained_value = get_value_from_aligned_membuf(nodeptr['_M_storage'],
+ self.value_type)
+ visualizer = gdb.default_visualizer(contained_value)
+ else:
+ contained_value = None
+ visualizer = None
+ optalloc = val['_M_alloc']
+ self.alloc = optalloc['_M_payload'] if optalloc['_M_engaged'] else None
+ super(StdNodeHandlePrinter, self).__init__(contained_value, visualizer,
+ 'array')
+
+ def to_string(self):
+
+ desc = 'node handle for '
+ if not self.is_rb_tree_node:
+ desc += 'unordered '
+ if self.is_map_node:
+ desc += 'map';
+ else:
+ desc += 'set';
+
+ if self.contained_value:
+ desc += ' with element'
+ if hasattr(self.visualizer, 'children'):
+ return "%s = %s" % (desc, self.visualizer.to_string())
+ return desc
+ else:
+ return 'empty %s' % desc
class StdExpStringViewPrinter:
"Print a std::basic_string_view or std::experimental::basic_string_view"
@@ -1262,6 +1307,7 @@ def register_type_printers(obj):
for pfx in ('', 'w'):
add_one_type_printer(obj, 'basic_string', pfx + 'string')
+ add_one_type_printer(obj, 'basic_string_view', pfx + 'string_view')
add_one_type_printer(obj, 'basic_ios', pfx + 'ios')
add_one_type_printer(obj, 'basic_streambuf', pfx + 'streambuf')
add_one_type_printer(obj, 'basic_istream', pfx + 'istream')
@@ -1296,6 +1342,9 @@ def register_type_printers(obj):
add_one_type_printer(obj, 'basic_string', 'u16string')
add_one_type_printer(obj, 'basic_string', 'u32string')
+ add_one_type_printer(obj, 'basic_string_view', 'u16string_view')
+ add_one_type_printer(obj, 'basic_string_view', 'u32string_view')
+
for dur in ('nanoseconds', 'microseconds', 'milliseconds',
'seconds', 'minutes', 'hours'):
add_one_type_printer(obj, 'duration', dur)
@@ -1353,11 +1402,14 @@ def register_type_printers(obj):
'unordered_multiset<{1}>')
# strip the "fundamentals_v1" inline namespace from these types
+ add_one_template_type_printer(obj, 'any<T>',
+ 'experimental::fundamentals_v\d::any<(.*)>',
+ 'experimental::any<\\1>')
add_one_template_type_printer(obj, 'optional<T>',
- 'experimental::fundamentals_v1::optional<(.*)>',
+ 'experimental::fundamentals_v\d::optional<(.*)>',
'experimental::optional<\\1>')
add_one_template_type_printer(obj, 'basic_string_view<C>',
- 'experimental::fundamentals_v1::basic_string_view<(.*), std::char_traits<\\1> >',
+ 'experimental::fundamentals_v\d::basic_string_view<(.*), std::char_traits<\\1> >',
'experimental::basic_string_view<\\1>')
def register_libstdcxx_printers (obj):
@@ -1483,6 +1535,8 @@ def build_libstdcxx_dictionary ():
'basic_string_view', StdExpStringViewPrinter)
libstdcxx_printer.add_version('std::',
'variant', StdVariantPrinter)
+ libstdcxx_printer.add_version('std::',
+ '_Node_handle', StdNodeHandlePrinter)
# Extensions.
libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index eccd57400f9..eb0dd79d74f 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -165,7 +165,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
class DequeWorkerBase(gdb.xmethod.XMethodWorker):
def __init__(self, val_type):
self._val_type = val_type
- self._bufsize = (512 / val_type.sizeof) or 1
+ self._bufsize = 512 // val_type.sizeof or 1
def size(self, obj):
first_node = obj['_M_impl']['_M_start']['_M_node']
@@ -174,10 +174,10 @@ class DequeWorkerBase(gdb.xmethod.XMethodWorker):
first = obj['_M_impl']['_M_finish']['_M_first']
return (last_node - first_node) * self._bufsize + (cur - first)
- def index(self, obj, index):
+ def index(self, obj, idx):
first_node = obj['_M_impl']['_M_start']['_M_node']
- index_node = first_node + index / self._bufsize
- return index_node[0][index % self._bufsize]
+ index_node = first_node + int(idx) // self._bufsize
+ return index_node[0][idx % self._bufsize]
class DequeEmptyWorker(DequeWorkerBase):
def get_arg_types(self):
@@ -328,6 +328,15 @@ class ListWorkerBase(gdb.xmethod.XMethodWorker):
def get_arg_types(self):
return None
+ def get_value_from_node(self, node):
+ node = node.dereference()
+ if node.type.fields()[1].name == '_M_data':
+ # C++03 implementation, node contains the value as a member
+ return node['_M_data']
+ # C++11 implementation, node stores value in __aligned_membuf
+ addr = node['_M_storage'].address
+ return addr.cast(self._val_type.pointer()).dereference()
+
class ListEmptyWorker(ListWorkerBase):
def get_result_type(self, obj):
return get_bool_type()
@@ -358,7 +367,7 @@ class ListFrontWorker(ListWorkerBase):
def __call__(self, obj):
node = obj['_M_impl']['_M_node']['_M_next'].cast(self._node_type)
- return node['_M_data']
+ return self.get_value_from_node(node)
class ListBackWorker(ListWorkerBase):
def get_result_type(self, obj):
@@ -366,7 +375,7 @@ class ListBackWorker(ListWorkerBase):
def __call__(self, obj):
prev_node = obj['_M_impl']['_M_node']['_M_prev'].cast(self._node_type)
- return prev_node['_M_data']
+ return self.get_value_from_node(prev_node)
class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
def __init__(self):
@@ -410,7 +419,7 @@ class VectorWorkerBase(gdb.xmethod.XMethodWorker):
if self._val_type.code == gdb.TYPE_CODE_BOOL:
start = obj['_M_impl']['_M_start']['_M_p']
bit_size = start.dereference().type.sizeof * 8
- valp = start + index / bit_size
+ valp = start + index // bit_size
offset = index % bit_size
return (valp.dereference() & (1 << offset)) > 0
else:
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 00a6168508d..d9830c2a8db 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -109,9 +109,9 @@ libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
# pass -mlong-double-64.
if GLIBCXX_LDBL_COMPAT
compatibility-ldbl.lo: compatibility-ldbl.cc
- $(LTCXXCOMPILE) -mlong-double-64 -c $<
+ $(LTCXXCOMPILE) $(LONG_DOUBLE_COMPAT_FLAGS) -c $<
compatibility-ldbl.o: compatibility-ldbl.cc
- $(CXXCOMPILE) -mlong-double-64 -c $<
+ $(CXXCOMPILE) $(LONG_DOUBLE_COMPAT_FLAGS) -c $<
endif
# Use special rules for C++11 files/objects.
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 09fe24eab67..ed532699fe7 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -226,6 +226,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
@@ -902,9 +903,9 @@ vpath % $(top_srcdir)/src/c++11
# Use special rules for compatibility-ldbl.cc compilation, as we need to
# pass -mlong-double-64.
@GLIBCXX_LDBL_COMPAT_TRUE@compatibility-ldbl.lo: compatibility-ldbl.cc
-@GLIBCXX_LDBL_COMPAT_TRUE@ $(LTCXXCOMPILE) -mlong-double-64 -c $<
+@GLIBCXX_LDBL_COMPAT_TRUE@ $(LTCXXCOMPILE) $(LONG_DOUBLE_COMPAT_FLAGS) -c $<
@GLIBCXX_LDBL_COMPAT_TRUE@compatibility-ldbl.o: compatibility-ldbl.cc
-@GLIBCXX_LDBL_COMPAT_TRUE@ $(CXXCOMPILE) -mlong-double-64 -c $<
+@GLIBCXX_LDBL_COMPAT_TRUE@ $(CXXCOMPILE) $(LONG_DOUBLE_COMPAT_FLAGS) -c $<
# Use special rules for C++11 files/objects.
compatibility-c++0x.lo: compatibility-c++0x.cc
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index 30c4a23b87a..465ec3a4fb8 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -196,6 +196,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index f25304c5310..f58e829c47a 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -30,12 +30,13 @@
#include <debug/safe_unordered_base.h>
#include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h>
+#include <debug/vector>
#include <cassert>
#include <cstdio>
+#include <cctype> // for std::isspace
#include <algorithm> // for std::min
-#include <functional> // for _Hash_impl
#include <cxxabi.h> // for __cxa_demangle
@@ -47,11 +48,16 @@ namespace
* in order to limit contention without breaking current library binary
* compatibility. */
__gnu_cxx::__mutex&
- get_safe_base_mutex(void* __address)
+ get_safe_base_mutex(void* address)
{
const size_t mask = 0xf;
static __gnu_cxx::__mutex safe_base_mutex[mask + 1];
- const size_t index = _Hash_impl::hash(__address) & mask;
+
+ // Use arbitrarily __gnu_debug::vector<int> as the container giving
+ // alignment of debug containers.
+ const auto alignbits = __builtin_ctz(alignof(__gnu_debug::vector<int>));
+ const size_t index
+ = (reinterpret_cast<std::size_t>(address) >> alignbits) & mask;
return safe_base_mutex[index];
}
@@ -70,8 +76,8 @@ namespace
}
void
- swap_seq(__gnu_debug::_Safe_sequence_base& __lhs,
- __gnu_debug::_Safe_sequence_base& __rhs)
+ swap_seq_single(__gnu_debug::_Safe_sequence_base& __lhs,
+ __gnu_debug::_Safe_sequence_base& __rhs)
{
swap(__lhs._M_version, __rhs._M_version);
swap_its(__lhs, __lhs._M_iterators,
@@ -80,11 +86,42 @@ namespace
__rhs, __rhs._M_const_iterators);
}
+ template<typename _Action>
+ void
+ lock_and_run(__gnu_cxx::__mutex& lhs_mutex, __gnu_cxx::__mutex& rhs_mutex,
+ _Action action)
+ {
+ // We need to lock both sequences to run action.
+ if (&lhs_mutex == &rhs_mutex)
+ {
+ __gnu_cxx::__scoped_lock sentry(lhs_mutex);
+ action();
+ }
+ else
+ {
+ __gnu_cxx::__scoped_lock sentry1(&lhs_mutex < &rhs_mutex
+ ? lhs_mutex : rhs_mutex);
+ __gnu_cxx::__scoped_lock sentry2(&lhs_mutex < &rhs_mutex
+ ? rhs_mutex : lhs_mutex);
+ action();
+ }
+ }
+
+ void
+ swap_seq(__gnu_cxx::__mutex& lhs_mutex,
+ __gnu_debug::_Safe_sequence_base& lhs,
+ __gnu_cxx::__mutex& rhs_mutex,
+ __gnu_debug::_Safe_sequence_base& rhs)
+ {
+ lock_and_run(lhs_mutex, rhs_mutex,
+ [&lhs, &rhs]() { swap_seq_single(lhs, rhs); });
+ }
+
void
- swap_ucont(__gnu_debug::_Safe_unordered_container_base& __lhs,
- __gnu_debug::_Safe_unordered_container_base& __rhs)
+ swap_ucont_single(__gnu_debug::_Safe_unordered_container_base& __lhs,
+ __gnu_debug::_Safe_unordered_container_base& __rhs)
{
- swap_seq(__lhs, __rhs);
+ swap_seq_single(__lhs, __rhs);
swap_its(__lhs, __lhs._M_local_iterators,
__rhs, __rhs._M_local_iterators);
swap_its(__lhs, __lhs._M_const_local_iterators,
@@ -92,6 +129,16 @@ namespace
}
void
+ swap_ucont(__gnu_cxx::__mutex& lhs_mutex,
+ __gnu_debug::_Safe_unordered_container_base& lhs,
+ __gnu_cxx::__mutex& rhs_mutex,
+ __gnu_debug::_Safe_unordered_container_base& rhs)
+ {
+ lock_and_run(lhs_mutex, rhs_mutex,
+ [&lhs, &rhs]() { swap_ucont_single(lhs, rhs); });
+ }
+
+ void
detach_all(__gnu_debug::_Safe_iterator_base* __iter)
{
for (; __iter;)
@@ -242,25 +289,7 @@ namespace __gnu_debug
void
_Safe_sequence_base::
_M_swap(_Safe_sequence_base& __x) noexcept
- {
- // We need to lock both sequences to swap
- using namespace __gnu_cxx;
- __mutex *__this_mutex = &_M_get_mutex();
- __mutex *__x_mutex = &__x._M_get_mutex();
- if (__this_mutex == __x_mutex)
- {
- __scoped_lock __lock(*__this_mutex);
- swap_seq(*this, __x);
- }
- else
- {
- __scoped_lock __l1(__this_mutex < __x_mutex
- ? *__this_mutex : *__x_mutex);
- __scoped_lock __l2(__this_mutex < __x_mutex
- ? *__x_mutex : *__this_mutex);
- swap_seq(*this, __x);
- }
- }
+ { swap_seq(_M_get_mutex(), *this, __x._M_get_mutex(), __x); }
__gnu_cxx::__mutex&
_Safe_sequence_base::
@@ -384,7 +413,7 @@ namespace __gnu_debug
__gnu_cxx::__mutex&
_Safe_iterator_base::
_M_get_mutex() throw ()
- { return get_safe_base_mutex(_M_sequence); }
+ { return _M_sequence->_M_get_mutex(); }
_Safe_unordered_container_base*
_Safe_local_iterator_base::
@@ -462,25 +491,7 @@ namespace __gnu_debug
void
_Safe_unordered_container_base::
_M_swap(_Safe_unordered_container_base& __x) noexcept
- {
- // We need to lock both containers to swap
- using namespace __gnu_cxx;
- __mutex *__this_mutex = &_M_get_mutex();
- __mutex *__x_mutex = &__x._M_get_mutex();
- if (__this_mutex == __x_mutex)
- {
- __scoped_lock __lock(*__this_mutex);
- swap_ucont(*this, __x);
- }
- else
- {
- __scoped_lock __l1(__this_mutex < __x_mutex
- ? *__this_mutex : *__x_mutex);
- __scoped_lock __l2(__this_mutex < __x_mutex
- ? *__x_mutex : *__this_mutex);
- swap_ucont(*this, __x);
- }
- }
+ { swap_ucont(_M_get_mutex(), *this, __x._M_get_mutex(), __x); }
void
_Safe_unordered_container_base::
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 931f8793216..591fe709476 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -197,6 +197,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/src/filesystem/Makefile.in b/libstdc++-v3/src/filesystem/Makefile.in
index 7e77aa55b8b..a620c68f017 100644
--- a/libstdc++-v3/src/filesystem/Makefile.in
+++ b/libstdc++-v3/src/filesystem/Makefile.in
@@ -205,6 +205,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 0ecb8b9f4d8..659cfbb6f81 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -288,16 +288,24 @@ namespace
}
inline fs::file_time_type
- file_time(const stat_type& st) noexcept
+ file_time(const stat_type& st, std::error_code& ec) noexcept
{
using namespace std::chrono;
- return fs::file_time_type{
#ifdef _GLIBCXX_USE_ST_MTIM
- seconds{st.st_mtim.tv_sec} + nanoseconds{st.st_mtim.tv_nsec}
+ time_t s = st.st_mtim.tv_sec;
+ nanoseconds ns{st.st_mtim.tv_nsec};
#else
- seconds{st.st_mtime}
+ time_t s = st.st_mtime;
+ nanoseconds ns{};
#endif
- };
+
+ if (s >= (nanoseconds::max().count() / 1e9))
+ {
+ ec = std::make_error_code(std::errc::value_too_large); // EOVERFLOW
+ return fs::file_time_type::min();
+ }
+ ec.clear();
+ return fs::file_time_type{seconds{s} + ns};
}
// Returns true if the file descriptor was successfully closed,
@@ -373,11 +381,11 @@ namespace
}
else if (is_set(option, opts::update_existing))
{
- if (file_time(*from_st) <= file_time(*to_st))
- {
- ec.clear();
- return false;
- }
+ const auto from_mtime = file_time(*from_st, ec);
+ if (ec)
+ return false;
+ if ((from_mtime <= file_time(*to_st, ec)) || ec)
+ return false;
}
else if (!is_set(option, opts::overwrite_existing))
{
@@ -1036,7 +1044,7 @@ fs::last_write_time(const path& p)
fs::file_time_type
fs::last_write_time(const path& p, error_code& ec) noexcept
{
- return do_stat(p, ec, [](const auto& st) { return file_time(st); },
+ return do_stat(p, ec, [&ec](const auto& st) { return file_time(st, ec); },
file_time_type::min());
}
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/searchers.cc b/libstdc++-v3/testsuite/20_util/function_objects/searchers.cc
index 1c7276207d9..53103598d09 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/searchers.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/searchers.cc
@@ -25,6 +25,12 @@
#include <algorithm>
#include <testsuite_hooks.h>
+#ifndef __cpp_lib_boyer_moore_searcher
+# error "Feature-test macro for searchers missing"
+#elif __cpp_lib_boyer_moore_searcher < 201603
+# error "Feature-test macro for searchers has wrong value"
+#endif
+
using std::make_default_searcher;
using std::make_boyer_moore_searcher;
using std::make_boyer_moore_horspool_searcher;
diff --git a/libstdc++-v3/testsuite/20_util/optional/77288.cc b/libstdc++-v3/testsuite/20_util/optional/77288.cc
new file mode 100644
index 00000000000..0df74a9963c
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/77288.cc
@@ -0,0 +1,405 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <optional>
+#include <any>
+
+using std::optional;
+
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ optional<optional<int>> nested_element;
+ optional<int> element = {};
+ nested_element = element;
+ VERIFY(nested_element);
+}
+
+template <class T>
+struct service_result
+{
+ static optional<T> get_result()
+ {
+ T sr;
+ return sr;
+ }
+
+ static optional<T> get_result_with_cond(bool cond)
+ {
+ if (cond)
+ return T{};
+ return {};
+ }
+};
+
+void test02()
+{
+ VERIFY(service_result<int>::get_result());
+ VERIFY(service_result<optional<int>>::get_result());
+ VERIFY(service_result<int>::get_result_with_cond(true));
+ VERIFY(service_result<optional<int>>::get_result_with_cond(true));
+ VERIFY(!service_result<int>::get_result_with_cond(false));
+ VERIFY(!service_result<optional<int>>::get_result_with_cond(false));
+}
+
+struct Widget
+{
+ Widget(int) {}
+ Widget(optional<int>) {}
+};
+
+
+void test03()
+{
+ optional<Widget> w;
+ w = optional<int>();
+ VERIFY(w);
+ static_assert(!std::is_assignable_v<optional<Widget>&,
+ optional<short>>);;
+ w = optional<optional<int>>();
+ VERIFY(!w);
+ static_assert(!std::is_assignable_v<optional<Widget>&,
+ optional<optional<short>>>);;
+
+ optional<Widget> w2{optional<int>()};
+ VERIFY(w2);
+ optional<Widget> w3 = optional<int>();
+ VERIFY(w3);
+ optional<Widget> w4{optional<short>()};
+ VERIFY(w4);
+ static_assert(!std::is_convertible_v<optional<short>&&, optional<Widget>>);
+
+ optional<Widget> w6{optional<optional<int>>()};
+ VERIFY(!w6);
+ optional<Widget> w7 = optional<optional<int>>();
+ VERIFY(!w7);
+ optional<Widget> w8{optional<optional<short>>()};
+ VERIFY(!w8);
+ static_assert(!std::is_convertible_v<optional<optional<short>>&&,
+ optional<Widget>>);
+ optional<Widget> w10{optional<optional<short>>(10)};
+ VERIFY(w10);
+ optional<Widget> w11 = std::nullopt;
+ VERIFY(!w11);
+ optional<Widget> w12 = {};
+ VERIFY(!w12);
+ optional<Widget> w13{std::nullopt};
+ VERIFY(!w13);
+ optional<Widget> w14;
+ w14 = {};
+ VERIFY(!w14);
+}
+
+struct Widget2
+{
+ Widget2(int) {}
+ Widget2(optional<int>) {}
+ Widget2& operator=(int) {return *this;}
+ Widget2& operator=(optional<int>) {return *this;}
+};
+
+void test04()
+{
+ optional<Widget2> w;
+ w = optional<int>();
+ VERIFY(w);
+ w = optional<short>();
+ VERIFY(w);
+ w = optional<optional<int>>();
+ VERIFY(!w);
+ w = optional<optional<short>>();
+ VERIFY(!w);
+ w = optional<optional<short>>(10);
+ optional<Widget2> w2 = std::nullopt;
+ VERIFY(!w2);
+ optional<Widget2> w3 = {};
+ VERIFY(!w3);
+ optional<Widget2> w4{std::nullopt};
+ VERIFY(!w4);
+ optional<Widget2> w5;
+ w5 = {};
+ VERIFY(!w5);
+}
+
+struct Thingy
+{
+ Thingy(int) {}
+ Thingy(Widget) {}
+};
+
+void test05()
+{
+ optional<Thingy> ot;
+
+ static_assert(!std::is_assignable_v<optional<Thingy>&,
+ optional<int>>);
+ static_assert(std::is_assignable_v<optional<Thingy>&,
+ optional<short>>);
+ static_assert(!std::is_assignable_v<optional<Thingy>&,
+ optional<optional<int>>>);
+ ot = optional<Widget>();
+ VERIFY(!ot);
+ optional<Thingy> ot2{optional<int>()};
+ VERIFY(ot2);
+ static_assert(!std::is_convertible_v<optional<int>&&,
+ optional<Thingy>>);
+ optional<Thingy> ot3{optional<short>()};
+ VERIFY(!ot3);
+ optional<Thingy> ot4 = optional<short>();
+ VERIFY(!ot4);
+
+ optional<Thingy> ot5{optional<optional<int>>()};
+ VERIFY(!ot5);
+ static_assert(!std::is_convertible_v<optional<optional<int>>&&,
+ optional<Thingy>>);
+
+ optional<Thingy> ot7{optional<Widget>()};
+ VERIFY(!ot7);
+ optional<Thingy> ot8 = optional<Widget>();
+ VERIFY(!ot8);
+ static_assert(!std::is_constructible_v<optional<Thingy>,
+ optional<optional<short>>>);
+ static_assert(!std::is_convertible_v<optional<optional<short>>,
+ optional<Thingy>>);
+ static_assert(!std::is_assignable_v<optional<Thingy>&,
+ optional<optional<short>>>);
+ optional<Thingy> ot9 = std::nullopt;
+ VERIFY(!ot9);
+ optional<Thingy> ot10 = {};
+ VERIFY(!ot10);
+ optional<Thingy> ot11{std::nullopt};
+ VERIFY(!ot11);
+ optional<Thingy> ot12;
+ ot12 = {};
+ VERIFY(!ot12);
+}
+
+struct RvalueConstructible
+{
+ RvalueConstructible(int) {}
+ RvalueConstructible(optional<int>&&) {}
+};
+
+void test06()
+{
+ optional<int> oi;
+ optional<RvalueConstructible> ori;
+ static_assert(!std::is_assignable_v<optional<RvalueConstructible>&,
+ optional<int>&>);
+ ori = std::move(oi);
+ VERIFY(ori);
+
+ optional<optional<int>> ooi;
+ static_assert(!std::is_assignable_v<optional<RvalueConstructible>&,
+ optional<optional<int>>&>);
+ ori = std::move(ooi);
+ VERIFY(!ori);
+
+ static_assert(!std::is_constructible_v<optional<RvalueConstructible>,
+ optional<int>&>);
+ static_assert(!std::is_convertible_v<optional<int>&,
+ optional<RvalueConstructible>>);
+
+ optional<RvalueConstructible> ori2(std::move(oi));
+ VERIFY(ori2);
+ optional<RvalueConstructible> ori3 = std::move(oi);
+ VERIFY(ori3);
+
+ static_assert(!std::is_constructible_v<optional<RvalueConstructible>,
+ optional<optional<int>>&>);
+ static_assert(!std::is_convertible_v<optional<optional<int>>&,
+ optional<RvalueConstructible>>);
+ optional<RvalueConstructible> ori6(std::move(ooi));
+ VERIFY(!ori6);
+ optional<RvalueConstructible> ori7 = std::move(ooi);
+ VERIFY(!ori7);
+ optional<RvalueConstructible> ori8 = std::nullopt;
+ VERIFY(!ori8);
+ optional<RvalueConstructible> ori9 = {};
+ VERIFY(!ori9);
+ optional<RvalueConstructible> ori10{std::nullopt};
+ VERIFY(!ori10);
+ optional<RvalueConstructible> ori11;
+ ori11 = {};
+ VERIFY(!ori11);
+}
+
+struct Thingy2
+{
+ Thingy2(int) {}
+ explicit Thingy2(optional<int>) {}
+ Thingy2(Widget) {}
+};
+
+void test07()
+{
+ optional<Thingy2> ot{optional<int>{}};
+ VERIFY(ot);
+ static_assert(!std::is_convertible_v<optional<int>,
+ optional<Thingy2>>);
+ optional<Thingy2> ot2{optional<short>{}};
+ VERIFY(ot2);
+ static_assert(!std::is_convertible_v<optional<short>,
+ optional<Thingy2>>);
+ optional<Thingy2> ot3{optional<optional<int>>{}};
+ VERIFY(!ot3);
+ static_assert(!std::is_convertible_v<optional<optional<int>>,
+ optional<Thingy2>>);
+ optional<Thingy2> ot4{optional<optional<short>>{}};
+ VERIFY(!ot4);
+ static_assert(!std::is_convertible_v<optional<optional<short>>,
+ optional<Thingy2>>);
+
+ optional<Thingy2> ot5{optional<Widget>{}};
+ VERIFY(!ot5);
+ optional<Thingy2> ot6 = optional<Widget>();
+ VERIFY(!ot6);
+
+ static_assert(!std::is_assignable_v<optional<Thingy2>&,
+ optional<int>>);
+ static_assert(!std::is_assignable_v<optional<Thingy2>&,
+ optional<short>>);
+ static_assert(!std::is_assignable_v<optional<Thingy2>&,
+ optional<optional<int>>>);
+ static_assert(!std::is_assignable_v<optional<Thingy2>&,
+ optional<optional<short>>>);
+ optional<Thingy2> ot7;
+ ot = optional<Widget>();
+ VERIFY(!ot7);
+ optional<Thingy2> ot8 = std::nullopt;
+ VERIFY(!ot8);
+ optional<Thingy2> ot9 = {};
+ VERIFY(!ot9);
+ optional<Thingy2> ot10{std::nullopt};
+ VERIFY(!ot10);
+ optional<Thingy2> ot11;
+ ot11 = {};
+ VERIFY(!ot11);
+}
+
+struct Thingy3
+{
+ Thingy3(int) {}
+ template<class... Args,
+ std::enable_if_t<std::is_constructible_v<Widget, Args&&...>,
+ bool> = true>
+ explicit Thingy3(Args&&... args) {}
+ Thingy3(Widget) {}
+};
+
+void test08()
+{
+ optional<Thingy3> ot{optional<int>{}};
+ VERIFY(ot);
+ static_assert(!std::is_convertible_v<optional<int>,
+ optional<Thingy3>>);
+ optional<Thingy3> ot2{optional<short>{}};
+ VERIFY(ot2);
+ static_assert(!std::is_convertible_v<optional<short>,
+ optional<Thingy3>>);
+ optional<Thingy3> ot3{optional<optional<int>>{}};
+ VERIFY(!ot3);
+ static_assert(!std::is_convertible_v<optional<optional<int>>,
+ optional<Thingy3>>);
+ optional<Thingy3> ot4{optional<optional<short>>{}};
+ VERIFY(!ot4);
+ static_assert(!std::is_convertible_v<optional<optional<short>>,
+ optional<Thingy3>>);
+
+ optional<Thingy3> ot5{optional<Widget>{}};
+ VERIFY(!ot5);
+ optional<Thingy3> ot6 = optional<Widget>();
+ VERIFY(!ot6);
+
+ static_assert(!std::is_assignable_v<optional<Thingy3>&,
+ optional<int>>);
+ static_assert(!std::is_assignable_v<optional<Thingy3>&,
+ optional<short>>);
+ static_assert(!std::is_assignable_v<optional<Thingy3>&,
+ optional<optional<int>>>);
+ static_assert(!std::is_assignable_v<optional<Thingy3>&,
+ optional<optional<short>>>);
+ optional<Thingy3> ot7;
+ ot = optional<Widget>();
+ VERIFY(!ot7);
+ optional<Thingy3> ot8 = std::nullopt;
+ VERIFY(!ot8);
+ optional<Thingy3> ot9 = {};
+ VERIFY(!ot9);
+ optional<Thingy3> ot10{std::nullopt};
+ VERIFY(!ot10);
+ optional<Thingy3> ot11;
+ ot11 = {};
+ VERIFY(!ot11);
+}
+
+void test09()
+{
+ std::any a = 42;
+ optional<std::any> oa2 = a;
+ VERIFY(oa2);
+ VERIFY(std::any_cast<int>(*oa2) == 42);
+ optional<std::any> oa3 = oa2;
+ VERIFY(oa3);
+ VERIFY(std::any_cast<int>(*oa3) == 42);
+ optional<std::any> oa4{oa2};
+ VERIFY(oa4);
+ VERIFY(std::any_cast<int>(*oa4) == 42);
+ optional<std::any> oa5(oa2);
+ VERIFY(oa5);
+ VERIFY(std::any_cast<int>(*oa5) == 42);
+ optional<std::any> oa6;
+ VERIFY(!oa6);
+ optional<std::any> oa7 = oa6;
+ VERIFY(!oa7);
+ optional<std::any> oa8{oa6};
+ VERIFY(!oa8);
+ optional<std::any> oa9(oa6);
+ VERIFY(!oa9);
+}
+
+void test10()
+{
+ struct X {};
+ optional<int> oi(std::in_place);
+ oi = {};
+ VERIFY(oi.has_value() == false);
+ optional<X> ot(std::in_place);
+ ot = {};
+ VERIFY(ot.has_value() == false);
+ optional<int> oi2(std::in_place);
+ short int si = 6;
+ oi2 = si;
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ test05();
+ test06();
+ test07();
+ test08();
+ test09();
+ test10();
+}
diff --git a/libstdc++-v3/testsuite/20_util/optional/assignment/7.cc b/libstdc++-v3/testsuite/20_util/optional/assignment/7.cc
new file mode 100644
index 00000000000..d392b40e49f
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/assignment/7.cc
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <optional>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ std::optional<int> o{666};
+ VERIFY(o && *o == 666);
+ o.reset();
+ VERIFY(!o);
+ static_assert(noexcept(std::declval<std::optional<int>>().reset()));
+}
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/77727.cc b/libstdc++-v3/testsuite/20_util/optional/cons/77727.cc
new file mode 100644
index 00000000000..7a3b101beca
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/cons/77727.cc
@@ -0,0 +1,51 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <optional>
+#include <testsuite_hooks.h>
+
+
+struct NonTransferable
+{
+ int x;
+ NonTransferable(int x) : x(x) {}
+ NonTransferable(NonTransferable&&) = delete;
+ NonTransferable& operator=(NonTransferable&&) = delete;
+ operator int() {return x;}
+};
+
+int main()
+{
+ std::optional<int> oi;
+ std::optional<NonTransferable> ot(std::move(oi));
+ VERIFY(!ot);
+
+ std::optional<int> oi2;
+ std::optional<NonTransferable> ot2(oi2);
+ VERIFY(!ot);
+
+ std::optional<int> oi3{42};
+ std::optional<NonTransferable> ot3(std::move(oi3));
+ VERIFY(ot3 && *ot3 == 42);
+
+ std::optional<int> oi4{666};
+ std::optional<NonTransferable> ot4(oi4);
+ VERIFY(ot4 && *ot4 == 666);
+}
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/value.cc b/libstdc++-v3/testsuite/20_util/optional/cons/value.cc
index 6a2d8716aee..141293c1bc2 100644
--- a/libstdc++-v3/testsuite/20_util/optional/cons/value.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/cons/value.cc
@@ -256,17 +256,21 @@ int main()
ox4 = oi;
}
{
+ std::optional<int> oi = std::optional<short>();
+ VERIFY(!bool(oi));
+ std::optional<std::string> os = std::optional<const char*>();
+ VERIFY(!bool(os));
std::optional<std::optional<int>> ooi = std::optional<int>();
- VERIFY(!bool(ooi));
+ VERIFY(bool(ooi));
ooi = std::optional<int>();
- VERIFY(!bool(ooi));
+ VERIFY(bool(ooi));
ooi = std::optional<int>(42);
VERIFY(bool(ooi));
VERIFY(bool(*ooi));
std::optional<std::optional<int>> ooi2 = std::optional<short>();
- VERIFY(!bool(ooi2));
+ VERIFY(bool(ooi2));
ooi2 = std::optional<short>();
- VERIFY(!bool(ooi2));
+ VERIFY(bool(ooi2));
ooi2 = std::optional<short>(6);
VERIFY(bool(ooi2));
VERIFY(bool(*ooi2));
diff --git a/libstdc++-v3/testsuite/20_util/optional/observers/6.cc b/libstdc++-v3/testsuite/20_util/optional/observers/6.cc
new file mode 100644
index 00000000000..562da2c171e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/observers/6.cc
@@ -0,0 +1,39 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a moved_to of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <optional>
+#include <testsuite_hooks.h>
+
+struct Y
+{
+ constexpr int test() & {return 7;}
+};
+
+constexpr int
+test()
+{
+ std::optional<Y> opt{Y{}};
+ return opt.value().test();
+}
+
+int main()
+{
+ static_assert(test());
+}
diff --git a/libstdc++-v3/testsuite/20_util/pair/traits.cc b/libstdc++-v3/testsuite/20_util/pair/traits.cc
new file mode 100644
index 00000000000..850f898a414
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/traits.cc
@@ -0,0 +1,76 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <utility>
+
+#include <type_traits>
+#include <memory>
+
+using namespace std;
+
+struct Poison
+{
+ Poison(Poison&&) = delete;
+};
+
+struct ThrowingCopy
+{
+ ThrowingCopy(const ThrowingCopy&) {}
+ ThrowingCopy& operator=(const ThrowingCopy&) {}
+};
+
+int main()
+{
+ static_assert(!is_copy_constructible<Poison>::value, "");
+ static_assert(!is_move_constructible<Poison>::value, "");
+ static_assert(!is_copy_assignable<Poison>::value, "");
+ static_assert(!is_move_assignable<Poison>::value, "");
+ static_assert(!is_copy_constructible<std::pair<int, Poison>>::value,
+ "");
+ static_assert(!is_move_constructible<std::pair<int, Poison>>::value,
+ "");
+ static_assert(!is_copy_assignable<std::pair<int, Poison>>::value, "");
+ static_assert(!is_move_assignable<std::pair<int, Poison>>::value, "");
+ static_assert(!is_constructible<std::pair<int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_assignable<std::pair<int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_constructible<std::pair<int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+ static_assert(!is_assignable<std::pair<int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+ static_assert(!is_copy_constructible<std::pair<ThrowingCopy,
+ std::unique_ptr<int>>>::value,
+ "");
+ static_assert(is_move_constructible<std::pair<ThrowingCopy,
+ std::unique_ptr<int>>>::value,
+ "");
+ static_assert(!is_nothrow_move_constructible<std::pair<ThrowingCopy,
+ std::unique_ptr<int>>>::value,
+ "");
+ static_assert(!is_copy_assignable<std::pair<ThrowingCopy,
+ std::unique_ptr<int>>>::value,
+ "");
+ static_assert(is_move_assignable<std::pair<ThrowingCopy,
+ std::unique_ptr<int>>>::value,
+ "");
+ static_assert(!is_nothrow_move_assignable<std::pair<ThrowingCopy,
+ std::unique_ptr<int>>>::value,
+ "");
+}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc
index ec72b826a53..84a68579344 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc
@@ -21,14 +21,40 @@
#include <testsuite_hooks.h>
#include <string>
#include <array>
+#include <sstream>
int del_count = 0;
+int ctor_count = 0;
+int throw_after = 0;
struct DelCount
{
~DelCount() { ++del_count; }
};
+struct ThrowAfterN
+{
+ ThrowAfterN()
+ {
+ if (++ctor_count == throw_after) {
+ std::ostringstream os;
+ os << "ThrowAfterN(), ctor_count: " << ctor_count
+ << " throw_after: " << throw_after << std::endl;
+ throw std::runtime_error(os.str());
+ }
+ }
+ ThrowAfterN(ThrowAfterN&&)
+ {
+ if (++ctor_count == throw_after) {
+ std::ostringstream os;
+ os << "ThrowAfterN(), ctor_count: " << ctor_count
+ << " throw_after: " << throw_after << std::endl;
+ throw std::runtime_error(os.str());
+ }
+ }
+ DelCount dc;
+};
+
void test01()
{
char test_data[] = "123456";
@@ -118,6 +144,153 @@ void test09()
free(target);
}
+void test10()
+{
+ char* x = (char*)malloc(sizeof(char)*10);
+ for (int i = 0; i < 10; ++i) new (x+i) char;
+ std::destroy(x, x+10);
+ free(x);
+}
+
+void test11()
+{
+ char* x = (char*)malloc(sizeof(char)*10);
+ for (int i = 0; i < 10; ++i) new (x+i) char;
+ std::destroy_n(x, 10);
+ free(x);
+}
+
+void test12()
+{
+ throw_after = 5;
+ del_count = 0;
+ ctor_count = 0;
+ ThrowAfterN* target =
+ (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
+ try {
+ std::uninitialized_default_construct(target, target+10);
+ } catch (...) {
+ }
+ VERIFY(ctor_count == 5);
+ VERIFY(del_count == 5);
+ throw_after = 0;
+ del_count = 0;
+ ctor_count = 0;
+}
+
+void test13()
+{
+ throw_after = 5;
+ del_count = 0;
+ ctor_count = 0;
+ ThrowAfterN* target =
+ (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
+ try {
+ std::uninitialized_value_construct(target, target+10);
+ } catch (...) {
+ }
+ VERIFY(ctor_count == 5);
+ VERIFY(del_count == 5);
+ throw_after = 0;
+ del_count = 0;
+ ctor_count = 0;
+}
+
+void test14()
+{
+ throw_after = 5;
+ del_count = 0;
+ ctor_count = 0;
+ ThrowAfterN* target =
+ (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
+ try {
+ std::uninitialized_default_construct_n(target, 10);
+ } catch (...) {
+ }
+ VERIFY(ctor_count == 5);
+ VERIFY(del_count == 5);
+ throw_after = 0;
+ del_count = 0;
+ ctor_count = 0;
+}
+
+void test15()
+{
+ throw_after = 5;
+ del_count = 0;
+ ctor_count = 0;
+ ThrowAfterN* target =
+ (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
+ try {
+ std::uninitialized_value_construct_n(target, 10);
+ } catch (...) {
+ }
+ VERIFY(ctor_count == 5);
+ VERIFY(del_count == 5);
+ throw_after = 0;
+ del_count = 0;
+ ctor_count = 0;
+}
+
+void test16()
+{
+ std::vector<ThrowAfterN> source(10);
+ del_count = 0;
+ ctor_count = 0;
+ throw_after = 5;
+ throw_after = 5;
+ ThrowAfterN* target =
+ (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
+ try {
+ std::uninitialized_move(source.begin(), source.end(), target);
+ } catch (...) {
+ }
+ VERIFY(ctor_count == 5);
+ VERIFY(del_count == 5);
+ throw_after = 0;
+ del_count = 0;
+ ctor_count = 0;
+}
+
+void test17()
+{
+ std::vector<ThrowAfterN> source(10);
+ del_count = 0;
+ ctor_count = 0;
+ throw_after = 5;
+ ThrowAfterN* target =
+ (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
+ try {
+ std::uninitialized_move_n(source.begin(), 10, target);
+ } catch (...) {
+ }
+ VERIFY(ctor_count == 5);
+ VERIFY(del_count == 5);
+ throw_after = 0;
+ del_count = 0;
+ ctor_count = 0;
+}
+
+void test18()
+{
+ char test_source[] = "123456";
+ char test_target[] = "000000";
+ std::uninitialized_move(std::begin(test_source),
+ std::end(test_source),
+ test_target);
+ VERIFY(std::string(test_target) == "123456");
+}
+
+void test19()
+{
+ char test_source[] = "123456";
+ char test_target[] = "000000";
+ std::uninitialized_move_n(std::begin(test_source),
+ 6,
+ test_target);
+ VERIFY(std::string(test_target) == "123456");
+}
+
int main()
{
test01();
@@ -129,4 +302,14 @@ int main()
test07();
test08();
test09();
+ test10();
+ test11();
+ test12();
+ test13();
+ test14();
+ test15();
+ test16();
+ test17();
+ test18();
+ test19();
}
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
index 5bcf5761c36..1c08d459648 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
@@ -17,7 +17,7 @@
// { dg-options "-fno-show-column" }
// { dg-do compile { target c++14 } }
-// { dg-error "in range" "" { target *-*-* } 1280 }
+// { dg-error "in range" "" { target *-*-* } 1342 }
#include <tuple>
diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc
new file mode 100644
index 00000000000..b72f535a6fc
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc
@@ -0,0 +1,244 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+#include <memory>
+
+using namespace std;
+
+struct Poison
+{
+ Poison(Poison&&) = delete;
+};
+
+
+int main()
+{
+ static_assert(!is_copy_constructible<Poison>::value, "");
+ static_assert(!is_move_constructible<Poison>::value, "");
+ static_assert(!is_copy_assignable<Poison>::value, "");
+ static_assert(!is_move_assignable<Poison>::value, "");
+
+ static_assert(!is_copy_constructible<std::tuple<Poison>>::value, "");
+ static_assert(!is_move_constructible<std::tuple<Poison>>::value, "");
+ static_assert(!is_copy_assignable<std::tuple<Poison>>::value, "");
+ static_assert(!is_move_assignable<std::tuple<Poison>>::value, "");
+
+ static_assert(!is_copy_constructible<std::tuple<int, Poison>>::value,
+ "");
+ static_assert(!is_move_constructible<std::tuple<int, Poison>>::value,
+ "");
+ static_assert(!is_copy_assignable<std::tuple<int, Poison>>::value, "");
+ static_assert(!is_move_assignable<std::tuple<int, Poison>>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>&>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>&>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::tuple<char, Poison>>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_constructible<std::tuple<int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+ static_assert(!is_assignable<std::tuple<int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+
+ static_assert(!is_copy_constructible<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_move_constructible<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_copy_assignable<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_move_assignable<
+ std::tuple<int, int, Poison>>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int,Poison>&,
+ std::tuple<int, char, Poison>&>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::tuple<int, char, Poison>&>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int, Poison>&,
+ std::tuple<int, char, Poison>>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::tuple<int, char, Poison>>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>&>::value, "");
+ static_assert(!is_constructible<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+ static_assert(!is_assignable<
+ std::tuple<int, int, Poison>&,
+ std::pair<char, Poison>>::value, "");
+
+ static_assert(is_trivially_copy_constructible<tuple<int>>::value, "");
+ static_assert(!is_trivially_move_constructible<tuple<int>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<tuple<int>>::value, "");
+ static_assert(!is_trivially_move_assignable<tuple<int>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<int>>::value, "");
+ static_assert(is_move_constructible<tuple<int>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int>>::value, "");
+ static_assert(is_move_assignable<tuple<int>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<vector<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<vector<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<vector<int>>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<vector<int>>>::value, "");
+ static_assert(is_move_constructible<tuple<vector<int>>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<vector<int>>>::value, "");
+ static_assert(is_move_assignable<tuple<vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<unique_ptr<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(!is_copy_constructible<
+ tuple<unique_ptr<int>>>::value, "");
+ static_assert(is_move_constructible<tuple<unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_assignable<tuple<unique_ptr<int>>>::value, "");
+ static_assert(is_move_assignable<tuple<unique_ptr<int>>>::value, "");
+
+ static_assert(is_trivially_copy_constructible<
+ tuple<int, int>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, int>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, int>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, int>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<int, int>>::value, "");
+ static_assert(is_move_constructible<tuple<int, int>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int, int>>::value, "");
+ static_assert(is_move_assignable<tuple<int, int>>::value, "");
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, vector<int>>>::value, "");
+
+ static_assert(is_copy_constructible<
+ tuple<int, vector<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, vector<int>>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int, vector<int>>>::value, "");
+ static_assert(is_move_assignable<tuple<int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_assignable<
+ tuple<int, unique_ptr<int>>>::value, "");
+
+ static_assert(is_copy_constructible<tuple<int, int, int>>::value, "");
+ static_assert(is_move_constructible<tuple<int, int, int>>::value, "");
+
+ static_assert(is_copy_assignable<tuple<int, int, int>>::value, "");
+ static_assert(is_move_assignable<tuple<int, int, int>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(is_copy_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(is_copy_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+ static_assert(is_move_assignable<
+ tuple<int, int, vector<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_trivially_copy_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(!is_trivially_move_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_constructible<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+
+ static_assert(!is_copy_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+ static_assert(is_move_assignable<
+ tuple<int, int, unique_ptr<int>>>::value, "");
+}
diff --git a/libstdc++-v3/testsuite/20_util/variant/compile.cc b/libstdc++-v3/testsuite/20_util/variant/compile.cc
index b57d356d301..85a697f5e29 100644
--- a/libstdc++-v3/testsuite/20_util/variant/compile.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/compile.cc
@@ -169,6 +169,12 @@ void copy_assign()
variant<DefaultNoexcept> a;
static_assert(!noexcept(a = a), "");
}
+
+ {
+ float f1 = 1.0f, f2 = 2.0f;
+ std::variant<float&> v1(f1);
+ v1 = f2;
+ }
}
void move_assign()
@@ -403,3 +409,59 @@ void test_void()
v = 3;
v = "asdf";
}
+
+void test_pr77641()
+{
+ struct X {
+ constexpr X() { }
+ };
+
+ constexpr std::variant<X> v1 = X{};
+}
+
+namespace adl_trap
+{
+ struct X {
+ X() = default;
+ X(int) { }
+ X(std::initializer_list<int>, const X&) { }
+ };
+ template<typename T> void move(T&) { }
+ template<typename T> void forward(T&) { }
+
+ struct Visitor {
+ template<typename T> void operator()(T&&) { }
+ };
+}
+
+void test_adl()
+{
+ using adl_trap::X;
+ using std::allocator_arg;
+ X x;
+ std::allocator<int> a;
+ std::initializer_list<int> il;
+ adl_trap::Visitor vis;
+
+ std::variant<X> v0(x);
+ v0 = x;
+ v0.emplace<0>(x);
+ v0.emplace<0>(il, x);
+ visit(vis, v0);
+ variant<X> v1{in_place<0>, x};
+ variant<X> v2{in_place<X>, x};
+ variant<X> v3{in_place<0>, il, x};
+ variant<X> v4{in_place<X>, il, x};
+ variant<X> v5{allocator_arg, a, in_place<0>, x};
+ variant<X> v6{allocator_arg, a, in_place<X>, x};
+ variant<X> v7{allocator_arg, a, in_place<0>, il, x};
+ variant<X> v8{allocator_arg, a, in_place<X>, il, x};
+ variant<X> v9{allocator_arg, a, in_place<X>, 1};
+
+ std::variant<X&> vr0(x);
+ vr0 = x;
+ variant<X&> vr1{in_place<0>, x};
+ variant<X&> vr2{in_place<X&>, x};
+ variant<X&> vr3{allocator_arg, a, in_place<0>, x};
+ variant<X&> vr4{allocator_arg, a, in_place<X&>, x};
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/56166.cc b/libstdc++-v3/testsuite/21_strings/basic_string/56166.cc
new file mode 100644
index 00000000000..3d4d876dbb1
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/56166.cc
@@ -0,0 +1,93 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+// libstdc++/56166
+
+#ifndef _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_USE_CXX11_ABI 0
+#endif
+#include <string>
+#include <new>
+
+static int fail_after = -1;
+
+template<typename T>
+ struct Allocator
+ {
+ using value_type = T;
+
+ // Need these typedefs because COW string doesn't use allocator_traits.
+ using pointer = T*;
+ using const_pointer = const T*;
+ using reference = T&;
+ using const_reference = const T&;
+ using difference_type = long;
+ using size_type = unsigned long;
+ template<typename U>
+ struct rebind {
+ using other = Allocator<U>;
+ };
+
+ Allocator() { }
+
+ template<typename U>
+ Allocator(const Allocator<U>&) { }
+
+ T* allocate(size_type n)
+ {
+ if (fail_after >= 0) {
+ if (fail_after-- == 0) {
+ throw std::bad_alloc();
+ }
+ }
+ return (T*)new char[n * sizeof(T)];
+ }
+
+ void deallocate(T* p, size_type)
+ {
+ delete[] (char*)p;
+ }
+ };
+
+template<typename T, typename U>
+ bool operator==(const Allocator<T>&, const Allocator<U>&) { return true; }
+template<typename T, typename U>
+ bool operator!=(const Allocator<T>&, const Allocator<U>&) { return false; }
+
+using string = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
+
+string f()
+{
+ string s1("xxxxxx");
+ string s2 = s1;
+ s1.clear();
+ return s2;
+}
+
+int main()
+{
+ for (int i = 0; i < 10; i++) {
+ try {
+ fail_after = i;
+ f();
+ break;
+ } catch (std::bad_alloc) {
+ }
+ }
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/compare/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/compare/char/1.cc
index 77188b3eba1..28e2514d016 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/compare/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/compare/char/1.cc
@@ -82,8 +82,8 @@ test01()
test_value(strncmp(str_1.data(), str_0.data(), 6), z);
test_value(strncmp(str_1.data(), str_0.data(), 14), lt);
test_value(memcmp(str_1.data(), str_0.data(), 6), z);
- test_value(memcmp(str_1.data(), str_0.data(), 14), lt);
- test_value(memcmp("costa marbella", "costa rica", 14), lt);
+ test_value(memcmp(str_1.data(), str_0.data(), 10), lt);
+ test_value(memcmp("costa marbella", "costa rica", 10), lt);
// int compare(const basic_string_view& str) const;
test_value(str_0.compare(str_1), gt); //because r>m
diff --git a/libstdc++-v3/testsuite/23_containers/map/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/map/modifiers/extract.cc
new file mode 100644
index 00000000000..dbbcc803ba7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/modifiers/extract.cc
@@ -0,0 +1,147 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <map>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::map<int, int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, {2, 20}, {3, 30} };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( c.count(1) == 0 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == 1 );
+ VERIFY( node.mapped() == 10 );
+
+ node.key() = 4;
+ node.mapped() = 40;
+ VERIFY( node.key() == 4 );
+ VERIFY( node.mapped() == 40 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( ins.position->first == 4 );
+ VERIFY( ins.position->second == 40 );
+ VERIFY( c.count(1) == 0 );
+ VERIFY( c.count(4) == 1 );
+ VERIFY( std::is_sorted(c.begin(), c.end()) );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(2);
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( c.size() == 3 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == 2 );
+ VERIFY( pos->second == 20 );
+
+ test_type c2 = c;
+ node = c2.extract(3);
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( ins.position != c.end() );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node.empty() );
+ VERIFY( ins.node.key() == 3 );
+ VERIFY( ins.node.mapped() == 30 );
+ VERIFY( ins.position->first == ins.node.key() );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, {2, 20}, {3, 30} };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+
+ node = c.extract(c.begin());
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == 1 );
+ VERIFY( node.mapped() == 10 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( ins.position->first == 1 );
+ VERIFY( ins.position->second == 10 );
+}
+
+void
+test03()
+{
+ struct less : std::less<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::map<int, int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::multimap<int, int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::multimap<int, int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/map/modifiers/merge.cc
new file mode 100644
index 00000000000..c978ed21e07
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/modifiers/merge.cc
@@ -0,0 +1,147 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <map>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::map<int, int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {2, 20}, {3, 30} };
+ test_type c1 = c0, c2 = c0;
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2 == c0 );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(std::move(c1));
+ VERIFY( c1.empty() );
+ VERIFY( c2 == c0 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {2, 20}, {3, 30} };
+ test_type c1 = c0;
+ std::map<int, int, std::less<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.begin(), c2.end(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(std::move(c1));
+ VERIFY( c1.empty() );
+ VERIFY( std::equal(c2.begin(), c2.end(), c0.begin(), c0.end()) );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {2, 20}, {3, 30} };
+ test_type c1 = c0;
+ std::map<int, int, std::greater<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {2, 20}, {3, 30} };
+ test_type c1 = c0;
+ std::multimap<int, int, std::greater<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1 = c0;
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( c2.size() == (2 * c0.size()) );
+ VERIFY( std::is_sorted(c2.begin(), c2.end(), c2.value_comp()) );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/extract.cc
new file mode 100644
index 00000000000..cad131ceadf
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/extract.cc
@@ -0,0 +1,141 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <map>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::multimap<int, int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, { 1, 11 }, {2, 20}, { 2, 21}, {3, 30}, { 3, 31 } };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( c.count(1) == 1 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == 1 );
+ int mapped = node.mapped();
+ VERIFY( mapped == 10 || mapped == 11 );
+
+ node.key() = 4;
+ node.mapped() = 40;
+ VERIFY( node.key() == 4 );
+ VERIFY( node.mapped() == 40 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == 4 );
+ VERIFY( pos->second == 40 );
+ VERIFY( c.count(1) == 1 );
+ VERIFY( c.count(4) == 1 );
+ VERIFY( std::is_sorted(c.begin(), c.end()) );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ mapped = node.mapped();
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == 1 );
+ VERIFY( pos->second == mapped );
+
+ test_type c2 = c;
+ node = c2.extract(1);
+ mapped = node.mapped();
+ pos = c.insert(std::move(node));
+ VERIFY( pos != c.end() );
+ VERIFY( node.empty() );
+ VERIFY( pos->first == 1 );
+ VERIFY( pos->second == mapped );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, { 1, 11 }, {2, 20}, { 2, 21}, {3, 30}, { 3, 31 } };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ node = c.extract(c.begin());
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == 1 );
+ VERIFY( node.mapped() == 10 );
+
+ pos = c.insert(std::next(c.begin()), std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == 1 );
+ VERIFY( pos->second == 10 );
+ VERIFY( pos == std::next(c.begin()) );
+}
+
+void
+test03()
+{
+ struct less : std::less<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::multimap<int, int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::map<int, int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::map<int, int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/merge.cc
new file mode 100644
index 00000000000..70541ff7fbe
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/merge.cc
@@ -0,0 +1,119 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <map>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::multimap<int, int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0, c2 = c0;
+
+ c1.merge(c2);
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (2 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2 = c0;
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0;
+ std::multimap<int, int, std::less<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (2 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0;
+ std::multimap<int, int, std::greater<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (2 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0;
+ std::map<int, int, std::greater<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (1.5 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (1.5 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1.size() == (0.5 * c0.size()) );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/extract.cc
new file mode 100644
index 00000000000..56c2a286f45
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/extract.cc
@@ -0,0 +1,129 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <set>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::multiset<int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 1, 2, 2, 3, 3 };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == 1 );
+
+ node.value() = 4;
+ VERIFY( node.value() == 4 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == 4 );
+ VERIFY( c.count(1) == 1 );
+ VERIFY( c.count(4) == 1 );
+ VERIFY( std::is_sorted(c.begin(), c.end()) );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == 1 );
+
+ test_type c2 = c;
+ node = c2.extract(1);
+ pos = c.insert(std::move(node));
+ VERIFY( pos != c.end() );
+ VERIFY( node.empty() );
+ VERIFY( *pos == 1 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 1, 2, 2, 3, 3 };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ node = c.extract(c.begin());
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == 1 );
+
+ pos = c.insert(std::next(c.begin()), std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == 1 );
+ VERIFY( pos == std::next(c.begin()) );
+}
+
+void
+test03()
+{
+ struct less : std::less<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::multiset<int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::set<int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::set<int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/merge.cc
new file mode 100644
index 00000000000..ba422b889c4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/merge.cc
@@ -0,0 +1,117 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <set>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::multiset<int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0, c2 = c0;
+
+ c1.merge(c2);
+ for (auto i : c1)
+ VERIFY( c1.count(i) == (2 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2 = c0;
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0;
+ std::multiset<int, std::less<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto i : c1)
+ VERIFY( c1.count(i) == (2 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test03()
+{
+ const test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0;
+ std::multiset<int, std::greater<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto i : c1)
+ VERIFY( c1.count(i) == (2 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0;
+ std::set<int, std::greater<>> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (1.5 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i) == (1.5 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1.size() == (0.5 * c0.size()) );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/set/modifiers/extract.cc
new file mode 100644
index 00000000000..db5872a499a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/modifiers/extract.cc
@@ -0,0 +1,138 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <set>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::set<int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 2, 3 };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == 1 );
+
+ node.value() = 4;
+ VERIFY( node.value() == 4 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( *ins.position == 4 );
+ VERIFY( c.count(1) == 0 );
+ VERIFY( c.count(4) == 1 );
+ VERIFY( std::is_sorted(c.begin(), c.end()) );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(2);
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( c.size() == 3 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == 2 );
+
+ test_type c2 = c;
+ node = c2.extract(3);
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( ins.position != c.end() );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node.empty() );
+ VERIFY( ins.node.value() == 3 );
+ VERIFY( *ins.position == ins.node.value() );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 2, 3 };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+
+ node = c.extract(c.begin());
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == 1 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( *ins.position == 1 );
+}
+
+void
+test03()
+{
+ struct less : std::less<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::set<int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::multiset<int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::multiset<int, less>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/set/modifiers/merge.cc
new file mode 100644
index 00000000000..b1e06937b64
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/modifiers/merge.cc
@@ -0,0 +1,143 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <set>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::set<int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 2, 3 };
+ test_type c1 = c0, c2 = c0;
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2 == c0 );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(std::move(c1));
+ VERIFY( c1.empty() );
+ VERIFY( c2 == c0 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 2, 3 };
+ test_type c1 = c0;
+ std::set<int, std::less<>> c2( c0.begin(), c0.end() );
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.begin(), c2.end(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(std::move(c1));
+ VERIFY( c1.empty() );
+ VERIFY( std::equal(c2.begin(), c2.end(), c0.begin(), c0.end()) );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 2, 3 };
+ test_type c1 = c0;
+ std::set<int, std::greater<>> c2( c0.begin(), c0.end() );
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 2, 3 };
+ test_type c1 = c0;
+ std::multiset<int, std::greater<>> c2( c0.begin(), c0.end() );
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1 = c0;
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( c2.size() == (2 * c0.size()) );
+ VERIFY( std::is_sorted(c2.begin(), c2.end(), c2.value_comp()) );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( std::equal(c2.rbegin(), c2.rend(), c0.begin(), c0.end()) );
+
+ c1.clear();
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/extract.cc
new file mode 100644
index 00000000000..9d9c43ef905
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/extract.cc
@@ -0,0 +1,148 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_map<int, int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, {2, 20}, {3, 30} };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == 1 );
+ VERIFY( node.mapped() == 10 );
+
+ node.key() = 4;
+ node.mapped() = 40;
+ VERIFY( node.key() == 4 );
+ VERIFY( node.mapped() == 40 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( ins.position->first == 4 );
+ VERIFY( ins.position->second == 40 );
+ VERIFY( c.count(1) == 0 );
+ VERIFY( c.count(4) == 1 );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( pos == c.end() );
+
+ pos = c.insert(c.begin(), c.extract(2));
+ VERIFY( c.size() == 3 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == 2 );
+ VERIFY( pos->second == 20 );
+
+ test_type c2 = c;
+ node = c2.extract(3);
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( ins.position != c.end() );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node.empty() );
+ VERIFY( ins.node.key() == 3 );
+ VERIFY( ins.node.mapped() == 30 );
+ auto hasher = c.hash_function();
+ VERIFY( hasher(ins.position->first) == hasher(ins.node.key()) );
+ auto eq = c.key_eq();
+ VERIFY( eq(ins.position->first, ins.node.key()) );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, {2, 20}, {3, 30} };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+
+ const int key = c.begin()->first;
+ node = c.extract(c.begin());
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == key );
+ VERIFY( node.mapped() == (key * 10) );
+
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( ins.position->first == key );
+ VERIFY( ins.position->second == (key * 10) );
+}
+
+void
+test03()
+{
+ struct hash : std::hash<int> { };
+ struct equal : std::equal_to<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::unordered_map<int, int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::unordered_multimap<int, int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::unordered_multimap<int, int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/merge.cc
new file mode 100644
index 00000000000..f0035d2eb84
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/merge.cc
@@ -0,0 +1,140 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_map>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_map<int, int>;
+
+struct hash {
+ auto operator()(int i) const noexcept { return ~std::hash<int>()(i); }
+};
+struct equal : std::equal_to<> { };
+
+template<typename C1, typename C2>
+bool equal_elements(const C1& c1, const C2& c2)
+{
+ if (c2.size() != c1.size())
+ return false;
+ for (auto& i : c1)
+ if (c2.count(i.first) != c1.count(i.first))
+ return false;
+ return true;
+}
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {2, 20}, {3, 30} };
+ test_type c1 = c0, c2 = c0;
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2 == c0 );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(std::move(c1));
+ VERIFY( c1.empty() );
+ VERIFY( c2 == c0 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {2, 20}, {3, 30} };
+ test_type c1 = c0;
+ std::unordered_map<int, int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c2.empty() );
+ VERIFY( c1 == c0 );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {2, 20}, {3, 30} };
+ test_type c1 = c0;
+ std::unordered_multimap<int, int, hash, equal> c2( c0.begin(), c0.end() );
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1 = c0;
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( c2.size() == (2 * c0.size()) );
+ VERIFY( c2.count(1) == 2 );
+ VERIFY( c2.count(2) == 2 );
+ VERIFY( c2.count(3) == 2 );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.clear();
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/extract.cc
new file mode 100644
index 00000000000..635e7d0acd3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/extract.cc
@@ -0,0 +1,138 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_multimap<int, int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, { 1, 11 }, {2, 20}, { 2, 21}, {3, 30}, { 3, 31 } };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == 1 );
+ int mapped = node.mapped();
+ VERIFY( mapped == 10 || mapped == 11 );
+
+ node.key() = 4;
+ node.mapped() = 40;
+ VERIFY( node.key() == 4 );
+ VERIFY( node.mapped() == 40 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == 4 );
+ VERIFY( pos->second == 40 );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ mapped = node.mapped();
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == 1 );
+ VERIFY( pos->second == mapped );
+
+ test_type c2 = c;
+ node = c2.extract(1);
+ mapped = node.mapped();
+ pos = c.insert(std::move(node));
+ VERIFY( pos != c.end() );
+ VERIFY( node.empty() );
+ VERIFY( pos->first == 1 );
+ VERIFY( pos->second == mapped );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ {1, 10}, { 1, 11 }, {2, 20}, { 2, 21}, {3, 30}, { 3, 31 } };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ const int key = c.begin()->first;
+ const int mapped = c.begin()->second;
+ node = c.extract(c.begin());
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.key() == key );
+ VERIFY( node.mapped() == mapped );
+
+ pos = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( pos->first == key );
+ VERIFY( pos->second == mapped );
+}
+
+void
+test03()
+{
+ struct hash : std::hash<int> { };
+ struct equal : std::equal_to<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::unordered_multimap<int, int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::unordered_map<int, int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::unordered_map<int, int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/merge.cc
new file mode 100644
index 00000000000..3c67e3c28da
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/modifiers/merge.cc
@@ -0,0 +1,123 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_map>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_multimap<int, int>;
+struct hash {
+ auto operator()(int i) const noexcept { return ~std::hash<int>()(i); }
+};
+struct equal : std::equal_to<> { };
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0, c2 = c0;
+
+ c1.merge(c2);
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (2 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2 = c0;
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0;
+ std::unordered_multimap<int, int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (2 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0;
+ std::unordered_multimap<int, int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (2 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ {1, 10}, {1, 11}, {2, 20}, {2, 21}, {3, 30}, {3, 31} };
+ test_type c1 = c0;
+ std::unordered_map<int, int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (1.5 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i.first) == (1.5 * c0.count(i.first)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1.size() == (0.5 * c0.size()) );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/extract.cc
new file mode 100644
index 00000000000..e703dc41ca0
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/extract.cc
@@ -0,0 +1,128 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_multiset<int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 1, 2, 2, 3, 3 };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == 1 );
+
+ node.value() = 4;
+ VERIFY( node.value() == 4 );
+
+ pos = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == 4 );
+ VERIFY( c.count(1) == 1 );
+ VERIFY( c.count(4) == 1 );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos == c.end() );
+
+ node = c.extract(1);
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == 1 );
+
+ test_type c2 = c;
+ node = c2.extract(1);
+ pos = c.insert(std::move(node));
+ VERIFY( pos != c.end() );
+ VERIFY( node.empty() );
+ VERIFY( *pos == 1 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 1, 2, 2, 3, 3 };
+ test_type::node_type node;
+ test_type::iterator pos;
+
+ const int val = *c.begin();
+ node = c.extract(c.begin());
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 5 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == val );
+
+ pos = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 6 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == val );
+}
+
+void
+test03()
+{
+ struct hash : std::hash<int> { };
+ struct equal : std::equal_to<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::unordered_multiset<int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::unordered_set<int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::unordered_set<int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/merge.cc
new file mode 100644
index 00000000000..4ce4b84d717
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/merge.cc
@@ -0,0 +1,121 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_set>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_multiset<int>;
+struct hash {
+ auto operator()(int i) const noexcept { return ~std::hash<int>()(i); }
+};
+struct equal : std::equal_to<> { };
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0, c2 = c0;
+
+ c1.merge(c2);
+ for (auto i : c1)
+ VERIFY( c1.count(i) == (2 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2 = c0;
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0;
+ std::unordered_multiset<int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto i : c1)
+ VERIFY( c1.count(i) == (2 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test03()
+{
+ const test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0;
+ std::unordered_multiset<int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (2 * c0.size()) );
+ for (auto i : c1)
+ VERIFY( c1.count(i) == (2 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 1, 2, 2, 3, 3 };
+ test_type c1 = c0;
+ std::unordered_set<int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1.size() == (1.5 * c0.size()) );
+ for (auto& i : c1)
+ VERIFY( c1.count(i) == (1.5 * c0.count(i)) );
+ VERIFY( c2.empty() );
+
+ c1.clear();
+ c2.insert( c0.begin(), c0.end() );
+ c1.merge(std::move(c2));
+ VERIFY( c1.size() == (0.5 * c0.size()) );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
index cc572fc90ca..5e8de37c440 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
@@ -18,7 +18,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "with noexcept" "" { target *-*-* } 265 }
+// { dg-error "with noexcept" "" { target *-*-* } 268 }
#include <unordered_set>
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/extract.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/extract.cc
new file mode 100644
index 00000000000..cb48cbcef4e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/extract.cc
@@ -0,0 +1,140 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_set<int>;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 2, 3 };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+ test_type::iterator pos;
+
+ node = c.extract(0);
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position == c.end() );
+
+ node = c.extract(1);
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == 1 );
+
+ node.value() = 4;
+ VERIFY( node.value() == 4 );
+
+ ins = c.insert(std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( *ins.position == 4 );
+ VERIFY( c.count(1) == 0 );
+ VERIFY( c.count(4) == 1 );
+
+ pos = c.insert(c.begin(), std::move(node));
+ VERIFY( !node );
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( pos == c.end() );
+
+ pos = c.insert(c.begin(), c.extract(2));
+ VERIFY( c.size() == 3 );
+ VERIFY( pos != c.end() );
+ VERIFY( *pos == 2 );
+
+ test_type c2 = c;
+ node = c2.extract(3);
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( ins.position != c.end() );
+ VERIFY( !ins.inserted );
+ VERIFY( !ins.node.empty() );
+ VERIFY( ins.node.value() == 3 );
+ auto hasher = c.hash_function();
+ VERIFY( hasher(*ins.position) == hasher(ins.node.value()) );
+ auto eq = c.key_eq();
+ VERIFY( eq(*ins.position, ins.node.value()) );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ test_type c{ 1, 2, 3 };
+ test_type::node_type node;
+ test_type::insert_return_type ins;
+
+ const int val = *c.begin();
+ node = c.extract(c.begin());
+ VERIFY( (bool)node );
+ VERIFY( !node.empty() );
+ VERIFY( c.size() == 2 );
+ VERIFY( node.get_allocator() == c.get_allocator() );
+ VERIFY( node.value() == val );
+
+ ins = c.insert(std::move(node));
+ VERIFY( node.empty() );
+ VERIFY( c.size() == 3 );
+ VERIFY( ins.inserted );
+ VERIFY( !ins.node );
+ VERIFY( ins.position != c.end() );
+ VERIFY( *ins.position == val );
+}
+
+void
+test03()
+{
+ struct hash : std::hash<int> { };
+ struct equal : std::equal_to<int> { };
+ using std::is_same_v;
+ using compat_type1 = std::unordered_set<int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type1::node_type> );
+ using compat_type2 = std::unordered_multiset<int>;
+ static_assert( is_same_v<test_type::node_type, compat_type2::node_type> );
+ using compat_type3 = std::unordered_multiset<int, hash, equal>;
+ static_assert( is_same_v<test_type::node_type, compat_type3::node_type> );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/merge.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/merge.cc
new file mode 100644
index 00000000000..29387dd21f6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/merge.cc
@@ -0,0 +1,140 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+
+#include <unordered_set>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+using test_type = std::unordered_set<int>;
+
+struct hash {
+ auto operator()(int i) const noexcept { return ~std::hash<int>()(i); }
+};
+struct equal : std::equal_to<> { };
+
+template<typename C1, typename C2>
+bool equal_elements(const C1& c1, const C2& c2)
+{
+ if (c2.size() != c1.size())
+ return false;
+ for (auto& i : c1)
+ if (c2.count(i) != c1.count(i))
+ return false;
+ return true;
+}
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 2, 3, };
+ test_type c1 = c0, c2 = c0;
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2 == c0 );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(std::move(c1));
+ VERIFY( c1.empty() );
+ VERIFY( c2 == c0 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 2, 3, };
+ test_type c1 = c0;
+ std::unordered_set<int, hash, equal> c2( c0.begin(), c0.end() );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c2.empty() );
+ VERIFY( c1 == c0 );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ const test_type c0{ 1, 2, 3, };
+ test_type c1 = c0;
+ std::unordered_multiset<int, hash, equal> c2( c0.begin(), c0.end() );
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.clear();
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1 = c0;
+ c2.merge(c1);
+ VERIFY( c1.empty() );
+ VERIFY( c2.size() == (2 * c0.size()) );
+ VERIFY( c2.count(1) == 2 );
+ VERIFY( c2.count(2) == 2 );
+ VERIFY( c2.count(3) == 2 );
+
+ c1.merge(c2);
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( equal_elements(c2, c0) );
+
+ c1.clear();
+ c1.merge(std::move(c2));
+ VERIFY( c1 == c0 );
+ VERIFY( c2.empty() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc
new file mode 100644
index 00000000000..a3c56e2ca5d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/mutex_association.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+
+#include <set>
+#include <debug/vector>
+
+#include <testsuite_hooks.h>
+
+class container : public __gnu_debug::_Safe_sequence<container>
+{
+public:
+ __gnu_cxx::__mutex&
+ get_mutex()
+ { return this->_M_get_mutex(); }
+};
+
+int
+main()
+{
+ std::set<__gnu_cxx::__mutex*> mutexes;
+ container conts[17];
+
+ for (int i = 0; i != 16; ++i)
+ VERIFY( mutexes.insert(&conts[i].get_mutex()).second );
+
+ VERIFY( !mutexes.insert(&conts[16].get_mutex()).second );
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc
new file mode 100644
index 00000000000..b8d13cdfd70
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires <cmath> to declare overloads for integral types.
+#include <cmath>
+
+template<typename, typename> struct is_same { enum { value = 0 }; };
+template<typename T> struct is_same<T, T> { enum { value = 1 }; };
+
+template<typename T, typename U = T>
+ constexpr bool check(T val) {
+ return is_same<decltype(std::abs(val)), U>::value;
+ }
+
+// Unsigned arguments that promote to int are valid:
+static_assert( check<short, int>(1), "abs((short)1) returns int" );
+static_assert( check<unsigned short, int>(1),
+ "abs((unsigned short)1) returns int" );
+
+static_assert( check(1), "abs(1) returns int" );
+static_assert( check(1l), "abs(1l) returns long" );
+static_assert( check(1ll), "abs(1ll) returns long long" );
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192_neg.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192_neg.cc
new file mode 100644
index 00000000000..bda980a0eda
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires abs to be ill-formed for unsigned arguments.
+#include <cmath>
+
+void test()
+{
+ std::abs(0u); // { dg-error "ambiguous" }
+ std::abs(0lu); // { dg-error "ambiguous" }
+ std::abs(0llu); // { dg-error "ambiguous" }
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/hypot.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/hypot.cc
new file mode 100644
index 00000000000..ec7429134ca
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/hypot.cc
@@ -0,0 +1,138 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <cmath>
+#include <type_traits>
+#if defined(__TEST_DEBUG)
+#include <iostream>
+#define VERIFY(A) \
+if (!(A)) \
+ { \
+ std::cout << "line " << __LINE__ \
+ << " max_abs_frac = " << max_abs_frac \
+ << " tolerance = " << toler \
+ << std::endl; \
+ }
+#else
+#include <testsuite_hooks.h>
+#endif
+
+using std::is_same_v;
+static_assert(is_same_v<double, decltype(std::hypot(0.0, 0.0, 0.0))>);
+static_assert(is_same_v<double, decltype(std::hypot(0.0f, 0.0, 0.0))>);
+static_assert(is_same_v<double, decltype(std::hypot(0.0, 0.0f, 0.0))>);
+static_assert(is_same_v<double, decltype(std::hypot(0.0, 0.0, 0.0f))>);
+static_assert(is_same_v<double, decltype(std::hypot(0.0f, 0.0f, 0.0))>);
+static_assert(is_same_v<double, decltype(std::hypot(0.0f, 0.0, 0))>);
+static_assert(is_same_v<long double, decltype(std::hypot(0.0f, 0.0, 0.0l))>);
+static_assert(is_same_v<long double, decltype(std::hypot(0, 0.0, 0.0l))>);
+
+template<typename T> struct testcase_hypot { T x, y, z, f0; };
+
+template<typename Tp, unsigned int Num>
+ void
+ test(const testcase_hypot<Tp> (&data)[Num], Tp toler)
+ {
+ bool test __attribute__((unused)) = true;
+ const Tp eps = std::numeric_limits<Tp>::epsilon();
+ Tp max_abs_diff = -Tp(1);
+ Tp max_abs_frac = -Tp(1);
+ unsigned int num_datum = Num;
+ for (unsigned int i = 0; i < num_datum; ++i)
+ {
+ const Tp f = std::hypot(data[i].x, data[i].y, data[i].z);
+ const Tp f0 = data[i].f0;
+ const Tp diff = f - f0;
+ if (std::abs(diff) > max_abs_diff)
+ max_abs_diff = std::abs(diff);
+ if (std::abs(f0) > Tp(10) * eps && std::abs(f) > Tp(10) * eps)
+ {
+ const Tp frac = diff / f0;
+ if (std::abs(frac) > max_abs_frac)
+ max_abs_frac = std::abs(frac);
+ }
+ }
+ VERIFY(max_abs_frac < toler);
+ }
+
+const testcase_hypot<double> data1[] = {
+ { 0.0, 0.0, 0.0, 0.0 },
+ { 0.0, 1.0, 1.0, std::sqrt(2.0) },
+ { 1.0, 1.0, 1.0, std::sqrt(3.0) },
+ { 1.0, 2.0, 2.0, 3.0 },
+ { 2.0, 3.0, 6.0, 7.0 },
+ { 1.0, 4.0, 8.0, 9.0 },
+ { 4.0, 4.0, 7.0, 9.0 },
+ { 12.0, 16.0, 21.0, 29.0 },
+ { 1e8, 1., 1e-8, 1e8 },
+ { 1., 1e8, 1e-8, 1e8 },
+ { 1e-8, 1., 1e8, 1e8 },
+ { 1e-2, 1e-4, 1e-4, 0.01000099995 },
+ { 214748364., 214748364., 214748364., 371955077.2902952 }
+};
+const double toler1 = 1e-12;
+
+const testcase_hypot<float> data2[] = {
+ { 0.0f, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 1.0f, 1.0f, std::sqrt(2.0f) },
+ { 1.0f, 1.0f, 1.0f, std::sqrt(3.0f) },
+ { 1.0f, 2.0f, 2.0f, 3.0f },
+ { 2.0f, 3.0f, 6.0f, 7.0f },
+ { 1.0f, 4.0f, 8.0f, 9.0f },
+ { 4.0f, 4.0f, 7.0f, 9.0f },
+ { 12.0f, 16.0f, 21.0f, 29.0f },
+ { 1e8f, 1.f, 1e-8f, 1e8f },
+ { 1.f, 1e8f, 1e-8f, 1e8f },
+ { 1e-8f, 1.f, 1e8f, 1e8f },
+ { 1e-2f, 1e-4f, 1e-4f, 0.010001f },
+ { 214748364.f, 214748364.f, 214748364.f, 371955072.f }
+};
+const float toler2 = 1e-7f;
+
+const testcase_hypot<long double> data3[] = {
+ { 0.0l, 0.0l, 0.0l, 0.0l },
+ { 0.0l, 1.0l, 1.0l, std::sqrt(2.0l) },
+ { 1.0l, 1.0l, 1.0l, std::sqrt(3.0l) },
+ { 1.0l, 2.0l, 2.0l, 3.0l },
+ { 2.0l, 3.0l, 6.0l, 7.0l },
+ { 1.0l, 4.0l, 8.0l, 9.0l },
+ { 4.0l, 4.0l, 7.0l, 9.0l },
+ { 12.0l, 16.0l, 21.0l, 29.0l },
+ { 1e8l, 1.l, 1e-8l, 1e8l },
+ { 1.l, 1e8l, 1e-8l, 1e8l },
+ { 1e-8l, 1.l, 1e8l, 1e8l },
+ { 1e-2l, 1e-4l, 1e-4l, 0.010000999950004999375l },
+ { 2147483647.l, 2147483647.l, 2147483647.l, 3719550785.027307813987l }
+};
+const long double toler3 = 1e-16l;
+
+void
+test01()
+{
+ test(data1, toler1);
+ test(data2, toler2);
+ test(data3, toler3);
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc
new file mode 100644
index 00000000000..312e907728c
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires <cstdlib> to declare overloads for floating point types.
+#include <cstdlib>
+
+template<typename, typename> struct is_same { enum { value = 0 }; };
+template<typename T> struct is_same<T, T> { enum { value = 1 }; };
+
+template<typename T>
+ constexpr bool check(T val) {
+ return is_same<decltype(std::abs(val)), T>::value;
+ }
+
+static_assert( check(1.f), "abs(1.f) returns float" );
+static_assert( check(1.), "abs(1.) returns double" );
+static_assert( check(1.l), "abs(1.l) returns long double" );
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc
new file mode 100644
index 00000000000..9f0046f93ca
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+// NB: Don't include any other headers in this file.
+// LWG 2192 requires abs to be ill-formed for unsigned arguments.
+#include <cstdlib>
+
+void test()
+{
+ std::abs(0u); // { dg-error "ambiguous" }
+ std::abs(0lu); // { dg-error "ambiguous" }
+ std::abs(0llu); // { dg-error "ambiguous" }
+}
diff --git a/libstdc++-v3/testsuite/27_io/headers/cstdio/functions_neg.cc b/libstdc++-v3/testsuite/27_io/headers/cstdio/functions_neg.cc
new file mode 100644
index 00000000000..f9e5f86ed37
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/headers/cstdio/functions_neg.cc
@@ -0,0 +1,25 @@
+// { dg-do compile { target c++14 } }
+
+// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <cstdio>
+
+namespace gnu
+{
+ using std::gets; // { dg-error "has not been declared" }
+}
diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in
index 31fa94c42cb..b37758b2ccb 100644
--- a/libstdc++-v3/testsuite/Makefile.in
+++ b/libstdc++-v3/testsuite/Makefile.in
@@ -163,6 +163,7 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc
new file mode 100644
index 00000000000..b1aea2012e9
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc
@@ -0,0 +1,111 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-lstdc++fs" }
+// { dg-do run { target c++11 } }
+// { dg-require-filesystem-ts "" }
+
+// 15.25 Permissions [fs.op.last_write_time]
+
+#include <experimental/filesystem>
+#include <testsuite_fs.h>
+#include <testsuite_hooks.h>
+
+#ifdef _GLIBCXX_HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#if _GLIBCXX_HAVE_UTIME_H
+# include <utime.h>
+#endif
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using time_type = std::experimental::filesystem::file_time_type;
+
+ auto p = __gnu_test::nonexistent_path();
+ std::error_code ec;
+ time_type mtime = last_write_time(p, ec);
+ VERIFY( ec );
+ VERIFY( ec == std::make_error_code(std::errc::no_such_file_or_directory) );
+#if __cpp_exceptions
+ bool caught = false;
+ try {
+ mtime = last_write_time(p);
+ } catch (std::system_error const& e) {
+ caught = true;
+ ec = e.code();
+ }
+ VERIFY( caught );
+ VERIFY( ec );
+ VERIFY( ec == std::make_error_code(std::errc::no_such_file_or_directory) );
+#endif
+
+ __gnu_test::scoped_file file(p);
+ VERIFY( exists(p) );
+ mtime = last_write_time(p, ec);
+ VERIFY( !ec );
+ VERIFY( mtime <= time_type::clock::now() );
+ VERIFY( mtime == last_write_time(p) );
+
+ auto end_of_time = time_type::duration::max();
+ auto last_second
+ = std::chrono::duration_cast<std::chrono::seconds>(end_of_time).count();
+ if (last_second > std::numeric_limits<std::time_t>::max())
+ return; // can't test overflow
+
+#if _GLIBCXX_USE_UTIMENSAT
+ struct ::timespec ts[2];
+ ts[0].tv_sec = 0;
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_sec = std::numeric_limits<std::time_t>::max() - 1;
+ ts[1].tv_nsec = 0;
+ VERIFY( !::utimensat(AT_FDCWD, p.c_str(), ts, 0) );
+#elif _GLIBCXX_HAVE_UTIME_H
+ ::utimbuf times;
+ times.modtime = std::numeric_limits<std::time_t>::max() - 1;
+ times.actime = std::numeric_limits<std::time_t>::max() - 1;
+ VERIFY( !::utime(p.c_str(), &times) );
+#else
+ return;
+#endif
+
+ mtime = last_write_time(p, ec);
+ VERIFY( ec );
+ VERIFY( ec == std::make_error_code(std::errc::value_too_large) );
+ VERIFY( mtime == time_type::min() );
+
+#if __cpp_exceptions
+ caught = false;
+ try {
+ mtime = last_write_time(p);
+ } catch (std::system_error const& e) {
+ caught = true;
+ ec = e.code();
+ }
+ VERIFY( caught );
+ VERIFY( ec );
+ VERIFY( ec == std::make_error_code(std::errc::value_too_large) );
+#endif
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/experimental/numeric/77801.cc b/libstdc++-v3/testsuite/experimental/numeric/77801.cc
new file mode 100644
index 00000000000..c4c8bfbfa44
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/numeric/77801.cc
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++14 } }
+
+#include <cstdlib>
+#include <experimental/numeric>
+constexpr int i = std::experimental::gcd(4L, 5L); // PR libstdc++/77801
diff --git a/libstdc++-v3/testsuite/experimental/numeric/gcd.cc b/libstdc++-v3/testsuite/experimental/numeric/gcd.cc
index 038f12d270c..b3345dc5e6d 100644
--- a/libstdc++-v3/testsuite/experimental/numeric/gcd.cc
+++ b/libstdc++-v3/testsuite/experimental/numeric/gcd.cc
@@ -25,3 +25,7 @@ static_assert(lcm(21, 6) == 42, "");
static_assert(lcm(41, 0) == 0, "LCD with zero is zero");
static_assert(lcm(0, 7) == 0, "LCD with zero is zero");
static_assert(lcm(0, 0) == 0, "no division by zero");
+
+static_assert(lcm(1u, 2) == 2, "unsigned and signed");
+static_assert(lcm(3, 4u) == 12, "signed and unsigned");
+static_assert(lcm(5u, 6u) == 30, "unsigned and unsigned");
diff --git a/libstdc++-v3/testsuite/experimental/numeric/lcm.cc b/libstdc++-v3/testsuite/experimental/numeric/lcm.cc
index 2c969b0afe5..d90c1527541 100644
--- a/libstdc++-v3/testsuite/experimental/numeric/lcm.cc
+++ b/libstdc++-v3/testsuite/experimental/numeric/lcm.cc
@@ -29,3 +29,6 @@ static_assert( gcd(0, 13) == 13, "GCD of any number and 0 is that number" );
static_assert( gcd(29, 0) == 29, "GCD of any number and 0 is that number" );
static_assert( gcd(0, 0) == 0, "" );
+static_assert(gcd(1u, 2) == 1, "unsigned and signed");
+static_assert(gcd(3, 4u) == 1, "signed and unsigned");
+static_assert(gcd(5u, 6u) == 1, "unsigned and unsigned");
diff --git a/libstdc++-v3/testsuite/ext/vstring/modifiers/clear/56166.cc b/libstdc++-v3/testsuite/ext/vstring/modifiers/clear/56166.cc
new file mode 100644
index 00000000000..109e6227372
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/vstring/modifiers/clear/56166.cc
@@ -0,0 +1,96 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+// libstdc++/56166
+
+#ifndef _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_USE_CXX11_ABI 0
+#endif
+#include <ext/vstring.h>
+#include <new>
+
+static int fail_after = -1;
+
+template<typename T>
+ struct Allocator
+ {
+ using value_type = T;
+
+ // Need these typedefs because COW string doesn't use allocator_traits.
+ using pointer = T*;
+ using const_pointer = const T*;
+ using reference = T&;
+ using const_reference = const T&;
+ using difference_type = long;
+ using size_type = unsigned long;
+ template<typename U>
+ struct rebind {
+ using other = Allocator<U>;
+ };
+
+ Allocator() { }
+
+ template<typename U>
+ Allocator(const Allocator<U>&) { }
+
+ T* allocate(size_type n)
+ {
+ if (fail_after >= 0) {
+ if (fail_after-- == 0) {
+ throw std::bad_alloc();
+ }
+ }
+ return (T*)new char[n * sizeof(T)];
+ }
+
+ void deallocate(T* p, size_type)
+ {
+ delete[] (char*)p;
+ }
+ };
+
+template<typename T, typename U>
+ bool operator==(const Allocator<T>&, const Allocator<U>&) { return true; }
+template<typename T, typename U>
+ bool operator!=(const Allocator<T>&, const Allocator<U>&) { return false; }
+
+
+using string = __gnu_cxx::__versa_string<char, std::char_traits<char>,
+ Allocator<char>,
+ __gnu_cxx::__rc_string_base>;
+
+string f()
+{
+ string s1("xxxxxx");
+ string s2 = s1;
+ s1.clear();
+ return s2;
+}
+
+int main()
+{
+ for (int i = 0; i < 10; i++) {
+ try {
+ fail_after = i;
+ f();
+ break;
+ } catch (std::bad_alloc) {
+ }
+ }
+}
diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp b/libstdc++-v3/testsuite/lib/gdb-test.exp
index a0298832be1..3ebbf6b4d2d 100644
--- a/libstdc++-v3/testsuite/lib/gdb-test.exp
+++ b/libstdc++-v3/testsuite/lib/gdb-test.exp
@@ -210,6 +210,12 @@ proc gdb-test { marker {selector {}} {load_xmethods 0} } {
return
}
+ -re {Error while executing Python code.[\n\r]} {
+ fail "$testname"
+ remote_close target
+ return
+ }
+
-re {^[^$][^\n\r]*[\n\r]+} {
send_log "skipping: $expect_out(buffer)"
exp_continue
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
new file mode 100644
index 00000000000..bc9b26a74f9
--- /dev/null
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
@@ -0,0 +1,108 @@
+// { dg-options "-g -O0 -std=gnu++1z" }
+// { dg-do run { target c++1z } }
+
+// Copyright (C) 2014-2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Type printers only recognize the old std::string for now.
+#define _GLIBCXX_USE_CXX11_ABI 0
+
+#include <any>
+#include <optional>
+#include <variant>
+#include <string_view>
+#include <string>
+#include <map>
+#include <unordered_set>
+#include <iostream>
+
+using std::any;
+using std::optional;
+using std::variant;
+using std::string_view;
+using std::map;
+using std::unordered_set;
+
+int
+main()
+{
+ string_view str = "string";
+// { dg-final { note-test str "\"string\"" } }
+
+ optional<int> o;
+// { dg-final { note-test o {std::optional<int> [no contained value]} } }
+ optional<bool> ob{false};
+// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
+ optional<int> oi{5};
+// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
+ optional<void*> op{nullptr};
+// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
+ optional<std::map<int, double>> om;
+ om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
+// { dg-final { note-test om {std::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+ optional<std::string> os{ "stringy" };
+// { dg-final { note-test os {std::optional<std::string> = {[contained value] = "stringy"}} } }
+
+ any a;
+// { dg-final { note-test a {std::any [no contained value]} } }
+ any ab(false);
+// { dg-final { note-test ab {std::any containing bool = {[contained value] = false}} } }
+ any ai(6);
+// { dg-final { note-test ai {std::any containing int = {[contained value] = 6}} } }
+ any ap = (void*)nullptr;
+// { dg-final { note-test ap {std::any containing void * = {[contained value] = 0x0}} } }
+ any as = *os;
+// { dg-final { note-test as {std::any containing std::string = {[contained value] = "stringy"}} } }
+ any as2("stringiest");
+// { dg-final { regexp-test as2 {std::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
+ any am = *om;
+// { dg-final { note-test am {std::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+
+ struct S { operator int() { throw 42; }};
+ variant<float, int, string_view> v0;
+// { dg-final { note-test v0 {std::variant<float, int, std::string_view> [index 0] = {0}} } }
+ variant<float, int, string_view> v1{ 0.5f };
+// { dg-final { note-test v1 {std::variant<float, int, std::string_view> [index 0] = {0.5}} } }
+ variant<float, int, string_view> v2;
+ try {
+ v2.emplace<1>(S());
+ } catch (int) { }
+// { dg-final { note-test v2 {std::variant<float, int, std::string_view> [no contained value]} } }
+ variant<float, int, string_view> v3{ 3 };
+// { dg-final { note-test v3 {std::variant<float, int, std::string_view> [index 1] = {3}} } }
+ variant<float, int, string_view> v4{ str };
+// { dg-final { note-test v4 {std::variant<float, int, std::string_view> [index 2] = {"string"}} } }
+ variant<string_view&> vref{str};
+// { dg-final { note-test vref {std::variant<std::basic_string_view<char, std::char_traits<char> > &> [index 0] = {"string"}} } }
+
+ map<int, string_view> m{ {1, "one"} };
+ map<int, string_view>::node_type n0;
+// { dg-final { note-test n0 {empty node handle for map}}}
+ map<int, string_view>::node_type n1 = m.extract(1);
+// { dg-final { note-test n1 {node handle for map with element = {{first = 1, second = "two"}}}}}
+
+ unordered_set<int> s{ 3, 4 };
+ unordered_set<int>::node_type n2;
+// { dg-final { note-test n2 {empty node handle for unordered set}}}
+ unordered_set<int>::node_type n3 = s.extract(3);
+// { dg-final { note-test n1 {node handle for unordered set with element = {3}}}}
+
+ std::cout << "\n";
+ return 0; // Mark SPOT
+}
+
+// { dg-final { gdb-test SPOT } }
diff --git a/libstdc++-v3/testsuite/util/testsuite_fs.h b/libstdc++-v3/testsuite/util/testsuite_fs.h
index f1e0bfcc252..5b36670ed52 100644
--- a/libstdc++-v3/testsuite/util/testsuite_fs.h
+++ b/libstdc++-v3/testsuite/util/testsuite_fs.h
@@ -23,7 +23,7 @@
#define _TESTSUITE_FS_H 1
#include <experimental/filesystem>
-#include <iostream>
+#include <fstream>
#include <string>
#include <cstdio>
#include <stdlib.h>
@@ -40,7 +40,6 @@ namespace __gnu_test
compare_paths(const std::experimental::filesystem::path& p1,
const std::experimental::filesystem::path& p2)
{
- // std::cout << "Comparing " << p1 << " and " << p2 << std::endl;
PATH_CHK( p1, p2, string );
PATH_CHK( p1, p2, empty );
PATH_CHK( p1, p2, has_root_path );
@@ -95,5 +94,23 @@ namespace __gnu_test
return p;
}
+ // RAII helper to remove a file on scope exit.
+ struct scoped_file
+ {
+ using path_type = std::experimental::filesystem::path;
+
+ enum adopt_file_t { adopt_file };
+
+ explicit
+ scoped_file(const path_type& p = nonexistent_path()) : path(p)
+ { std::ofstream{p.native()}; }
+
+ scoped_file(path_type p, adopt_file_t) : path(p) { }
+
+ ~scoped_file() { remove(path); }
+
+ path_type path;
+ };
+
} // namespace __gnu_test
#endif