diff options
author | Martin Jambor <mjambor@suse.cz> | 2016-10-04 14:05:48 +0000 |
---|---|---|
committer | Martin Jambor <mjambor@suse.cz> | 2016-10-04 14:05:48 +0000 |
commit | a5ad06150ad26c32138621126e4c365abe3e6332 (patch) | |
tree | ea68704f07efd32ea3189869ac807f682f7a7e98 /libstdc++-v3 | |
parent | 37ba4e6d655bfdb78f1c4cd481801d6769b74898 (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')
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<bool></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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 201411</code>, <code class="code"> __cpp_lib_unordered_map_try_emplace >= 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 >= 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 >= 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 >= 201606 </code>, <code class="code"> __cpp_lib_lcm >= 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 >= 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 >= 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(), ×) ); +#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 |