summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-05-02 14:43:35 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-05-02 14:43:35 +0000
commit34efdaf078b01a7387007c4e6bde6db86384c4b7 (patch)
treed503eaf41d085669d1481bb46ec038bc866fece6 /libstdc++-v3/include/bits
parentf733cf303bcdc952c92b81dd62199a40a1f555ec (diff)
downloadgcc-tarball-34efdaf078b01a7387007c4e6bde6db86384c4b7.tar.gz
gcc-7.1.0gcc-7.1.0
Diffstat (limited to 'libstdc++-v3/include/bits')
-rw-r--r--libstdc++-v3/include/bits/algorithmfwd.h253
-rw-r--r--libstdc++-v3/include/bits/alloc_traits.h74
-rw-r--r--libstdc++-v3/include/bits/allocated_ptr.h7
-rw-r--r--libstdc++-v3/include/bits/allocator.h27
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h40
-rw-r--r--libstdc++-v3/include/bits/atomic_futex.h2
-rw-r--r--libstdc++-v3/include/bits/basic_ios.h2
-rw-r--r--libstdc++-v3/include/bits/basic_ios.tcc8
-rw-r--r--libstdc++-v3/include/bits/basic_string.h870
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc50
-rw-r--r--libstdc++-v3/include/bits/boost_concept_check.h2
-rw-r--r--libstdc++-v3/include/bits/c++0x_warning.h2
-rw-r--r--libstdc++-v3/include/bits/c++14_warning.h8
-rw-r--r--libstdc++-v3/include/bits/c++17_warning.h37
-rw-r--r--libstdc++-v3/include/bits/c++config123
-rw-r--r--libstdc++-v3/include/bits/char_traits.h50
-rw-r--r--libstdc++-v3/include/bits/codecvt.h2
-rw-r--r--libstdc++-v3/include/bits/concept_check.h2
-rw-r--r--libstdc++-v3/include/bits/cpp_type_traits.h2
-rw-r--r--libstdc++-v3/include/bits/deque.tcc22
-rw-r--r--libstdc++-v3/include/bits/enable_special_members.h40
-rw-r--r--libstdc++-v3/include/bits/forward_list.h33
-rw-r--r--libstdc++-v3/include/bits/forward_list.tcc2
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc2
-rw-r--r--libstdc++-v3/include/bits/functexcept.h2
-rw-r--r--libstdc++-v3/include/bits/functional_hash.h19
-rw-r--r--libstdc++-v3/include/bits/gslice.h2
-rw-r--r--libstdc++-v3/include/bits/gslice_array.h2
-rw-r--r--libstdc++-v3/include/bits/hashtable.h153
-rw-r--r--libstdc++-v3/include/bits/hashtable_policy.h223
-rw-r--r--libstdc++-v3/include/bits/indirect_array.h2
-rw-r--r--libstdc++-v3/include/bits/invoke.h104
-rw-r--r--libstdc++-v3/include/bits/ios_base.h14
-rw-r--r--libstdc++-v3/include/bits/istream.tcc2
-rw-r--r--libstdc++-v3/include/bits/list.tcc161
-rw-r--r--libstdc++-v3/include/bits/locale_classes.h7
-rw-r--r--libstdc++-v3/include/bits/locale_classes.tcc2
-rw-r--r--libstdc++-v3/include/bits/locale_conv.h7
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h6
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc2
-rw-r--r--libstdc++-v3/include/bits/locale_facets_nonio.h2
-rw-r--r--libstdc++-v3/include/bits/locale_facets_nonio.tcc46
-rw-r--r--libstdc++-v3/include/bits/localefwd.h2
-rw-r--r--libstdc++-v3/include/bits/mask_array.h6
-rw-r--r--libstdc++-v3/include/bits/memoryfwd.h2
-rw-r--r--libstdc++-v3/include/bits/move.h26
-rw-r--r--libstdc++-v3/include/bits/node_handle.h328
-rw-r--r--libstdc++-v3/include/bits/ostream.tcc2
-rw-r--r--libstdc++-v3/include/bits/ostream_insert.h2
-rw-r--r--libstdc++-v3/include/bits/parse_numbers.h2
-rw-r--r--libstdc++-v3/include/bits/postypes.h4
-rw-r--r--libstdc++-v3/include/bits/predefined_ops.h111
-rw-r--r--libstdc++-v3/include/bits/ptr_traits.h17
-rw-r--r--libstdc++-v3/include/bits/quoted_string.h2
-rw-r--r--libstdc++-v3/include/bits/random.h158
-rw-r--r--libstdc++-v3/include/bits/random.tcc29
-rw-r--r--libstdc++-v3/include/bits/range_access.h30
-rw-r--r--libstdc++-v3/include/bits/refwrap.h383
-rw-r--r--libstdc++-v3/include/bits/regex.h34
-rw-r--r--libstdc++-v3/include/bits/regex.tcc19
-rw-r--r--libstdc++-v3/include/bits/regex_automaton.h5
-rw-r--r--libstdc++-v3/include/bits/regex_automaton.tcc2
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.h104
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.tcc163
-rw-r--r--libstdc++-v3/include/bits/regex_constants.h52
-rw-r--r--libstdc++-v3/include/bits/regex_error.h2
-rw-r--r--libstdc++-v3/include/bits/regex_executor.h35
-rw-r--r--libstdc++-v3/include/bits/regex_executor.tcc467
-rw-r--r--libstdc++-v3/include/bits/regex_scanner.h7
-rw-r--r--libstdc++-v3/include/bits/regex_scanner.tcc6
-rw-r--r--libstdc++-v3/include/bits/shared_ptr.h293
-rw-r--r--libstdc++-v3/include/bits/shared_ptr_atomic.h2
-rw-r--r--libstdc++-v3/include/bits/shared_ptr_base.h587
-rw-r--r--libstdc++-v3/include/bits/slice_array.h6
-rw-r--r--libstdc++-v3/include/bits/specfun.h6
-rw-r--r--libstdc++-v3/include/bits/sstream.tcc2
-rw-r--r--libstdc++-v3/include/bits/std_abs.h110
-rw-r--r--libstdc++-v3/include/bits/std_function.h811
-rw-r--r--libstdc++-v3/include/bits/std_mutex.h14
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h247
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h2
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h15
-rw-r--r--libstdc++-v3/include/bits/stl_construct.h47
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h312
-rw-r--r--libstdc++-v3/include/bits/stl_function.h4
-rw-r--r--libstdc++-v3/include/bits/stl_heap.h91
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h173
-rw-r--r--libstdc++-v3/include/bits/stl_iterator_base_funcs.h23
-rw-r--r--libstdc++-v3/include/bits/stl_iterator_base_types.h2
-rw-r--r--libstdc++-v3/include/bits/stl_list.h245
-rw-r--r--libstdc++-v3/include/bits/stl_map.h525
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h257
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h210
-rw-r--r--libstdc++-v3/include/bits/stl_numeric.h2
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h282
-rw-r--r--libstdc++-v3/include/bits/stl_queue.h152
-rw-r--r--libstdc++-v3/include/bits/stl_raw_storage_iter.h19
-rw-r--r--libstdc++-v3/include/bits/stl_relops.h2
-rw-r--r--libstdc++-v3/include/bits/stl_set.h187
-rw-r--r--libstdc++-v3/include/bits/stl_stack.h60
-rw-r--r--libstdc++-v3/include/bits/stl_tempbuf.h2
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h505
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h222
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h373
-rw-r--r--libstdc++-v3/include/bits/stream_iterator.h9
-rw-r--r--libstdc++-v3/include/bits/streambuf.tcc2
-rw-r--r--libstdc++-v3/include/bits/streambuf_iterator.h2
-rw-r--r--libstdc++-v3/include/bits/string_view.tcc227
-rw-r--r--libstdc++-v3/include/bits/stringfwd.h2
-rw-r--r--libstdc++-v3/include/bits/uniform_int_dist.h15
-rw-r--r--libstdc++-v3/include/bits/unique_ptr.h194
-rw-r--r--libstdc++-v3/include/bits/unordered_map.h200
-rw-r--r--libstdc++-v3/include/bits/unordered_set.h190
-rw-r--r--libstdc++-v3/include/bits/uses_allocator.h69
-rw-r--r--libstdc++-v3/include/bits/valarray_after.h2
-rw-r--r--libstdc++-v3/include/bits/valarray_array.h2
-rw-r--r--libstdc++-v3/include/bits/valarray_array.tcc2
-rw-r--r--libstdc++-v3/include/bits/valarray_before.h2
-rw-r--r--libstdc++-v3/include/bits/vector.tcc300
119 files changed, 8708 insertions, 2716 deletions
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h
index cd98fe0594..3ff4ff7123 100644
--- a/libstdc++-v3/include/bits/algorithmfwd.h
+++ b/libstdc++-v3/include/bits/algorithmfwd.h
@@ -1,6 +1,6 @@
// <algorithm> Forward declarations -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
@@ -45,13 +45,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/*
adjacent_find
- all_of (C++0x)
- any_of (C++0x)
+ all_of (C++11)
+ any_of (C++11)
binary_search
+ clamp (C++17)
copy
copy_backward
- copy_if (C++0x)
- copy_n (C++0x)
+ copy_if (C++11)
+ copy_n (C++11)
count
count_if
equal
@@ -62,17 +63,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
find_end
find_first_of
find_if
- find_if_not (C++0x)
+ find_if_not (C++11)
for_each
generate
generate_n
includes
inplace_merge
- is_heap (C++0x)
- is_heap_until (C++0x)
- is_partitioned (C++0x)
- is_sorted (C++0x)
- is_sorted_until (C++0x)
+ is_heap (C++11)
+ is_heap_until (C++11)
+ is_partitioned (C++11)
+ is_sorted (C++11)
+ is_sorted_until (C++11)
iter_swap
lexicographical_compare
lower_bound
@@ -82,17 +83,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
merge
min
min_element
- minmax (C++0x)
- minmax_element (C++0x)
+ minmax (C++11)
+ minmax_element (C++11)
mismatch
next_permutation
- none_of (C++0x)
+ none_of (C++11)
nth_element
partial_sort
partial_sort_copy
partition
- partition_copy (C++0x)
- partition_point (C++0x)
+ partition_copy (C++11)
+ partition_point (C++11)
pop_heap
prev_permutation
push_heap
@@ -115,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
set_intersection
set_symmetric_difference
set_union
- shuffle (C++0x)
+ shuffle (C++11)
sort
sort_heap
stable_partition
@@ -167,12 +168,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* These algorithms are variations of a classic binary search, and
* all assume that the sequence being searched is already sorted.
- *
+ *
* The number of comparisons will be logarithmic (and as few as
* possible). The number of steps through the sequence will be
* logarithmic for random-access iterators (e.g., pointers), and
* linear otherwise.
- *
+ *
* The LWG has passed Defect Report 270, which notes: <em>The
* proposed resolution reinterprets binary search. Instead of
* thinking about searching for a value in a sorted range, we view
@@ -201,15 +202,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _FIter, typename _Tp>
- bool
+ bool
binary_search(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
- bool
+ bool
binary_search(_FIter, _FIter, const _Tp&, _Compare);
+#if __cplusplus > 201402L
+ template<typename _Tp>
+ _GLIBCXX14_CONSTEXPR
+ const _Tp&
+ clamp(const _Tp&, const _Tp&, const _Tp&);
+
+ template<typename _Tp, typename _Compare>
+ _GLIBCXX14_CONSTEXPR
+ const _Tp&
+ clamp(const _Tp&, const _Tp&, const _Tp&, _Compare);
+#endif
+
template<typename _IIter, typename _OIter>
- _OIter
+ _OIter
copy(_IIter, _IIter, _OIter);
template<typename _BIter1, typename _BIter2>
@@ -238,7 +251,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
equal_range(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
- void
+ void
fill(_FIter, _FIter, const _Tp&);
template<typename _OIter, typename _Size, typename _Tp>
@@ -269,36 +282,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// generate_n
template<typename _IIter1, typename _IIter2>
- bool
+ bool
includes(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
- bool
+ bool
includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _BIter>
- void
+ void
inplace_merge(_BIter, _BIter, _BIter);
template<typename _BIter, typename _Compare>
- void
+ void
inplace_merge(_BIter, _BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _RAIter>
- bool
+ bool
is_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- bool
+ bool
is_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
- _RAIter
+ _RAIter
is_heap_until(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- _RAIter
+ _RAIter
is_heap_until(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _Predicate>
@@ -315,63 +328,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
is_permutation(_FIter1, _FIter1, _FIter2, _BinaryPredicate);
template<typename _FIter>
- bool
+ bool
is_sorted(_FIter, _FIter);
template<typename _FIter, typename _Compare>
- bool
+ bool
is_sorted(_FIter, _FIter, _Compare);
template<typename _FIter>
- _FIter
+ _FIter
is_sorted_until(_FIter, _FIter);
template<typename _FIter, typename _Compare>
- _FIter
+ _FIter
is_sorted_until(_FIter, _FIter, _Compare);
#endif
template<typename _FIter1, typename _FIter2>
- void
+ void
iter_swap(_FIter1, _FIter2);
template<typename _FIter, typename _Tp>
- _FIter
+ _FIter
lower_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
- _FIter
+ _FIter
lower_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _RAIter>
- void
+ void
make_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
make_heap(_RAIter, _RAIter, _Compare);
- template<typename _Tp>
+ template<typename _Tp>
_GLIBCXX14_CONSTEXPR
- const _Tp&
+ const _Tp&
max(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
- const _Tp&
+ const _Tp&
max(const _Tp&, const _Tp&, _Compare);
// max_element
// merge
- template<typename _Tp>
+ template<typename _Tp>
_GLIBCXX14_CONSTEXPR
- const _Tp&
+ const _Tp&
min(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
- const _Tp&
+ const _Tp&
min(const _Tp&, const _Tp&, _Compare);
// min_element
@@ -379,7 +392,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
- pair<const _Tp&, const _Tp&>
+ pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
@@ -431,11 +444,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// mismatch
template<typename _BIter>
- bool
+ bool
next_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
- bool
+ bool
next_permutation(_BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
@@ -469,65 +482,65 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _RAIter>
- void
+ void
pop_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
pop_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter>
- bool
+ bool
prev_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
- bool
+ bool
prev_permutation(_BIter, _BIter, _Compare);
template<typename _RAIter>
- void
+ void
push_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
push_heap(_RAIter, _RAIter, _Compare);
// random_shuffle
template<typename _FIter, typename _Tp>
- _FIter
+ _FIter
remove(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Predicate>
- _FIter
+ _FIter
remove_if(_FIter, _FIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Tp>
- _OIter
+ _OIter
remove_copy(_IIter, _IIter, _OIter, const _Tp&);
template<typename _IIter, typename _OIter, typename _Predicate>
- _OIter
+ _OIter
remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
// replace
template<typename _IIter, typename _OIter, typename _Tp>
- _OIter
+ _OIter
replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
- _OIter
+ _OIter
replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
// replace_if
template<typename _BIter>
- void
+ void
reverse(_BIter, _BIter);
template<typename _BIter, typename _OIter>
- _OIter
+ _OIter
reverse_copy(_BIter, _BIter, _OIter);
inline namespace _V2
@@ -538,7 +551,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _FIter, typename _OIter>
- _OIter
+ _OIter
rotate_copy(_FIter, _FIter, _FIter, _OIter);
// search
@@ -555,15 +568,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _RAIter>
- void
+ void
sort_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
sort_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
- _BIter
+ _BIter
stable_partition(_BIter, _BIter, _Predicate);
#if __cplusplus < 201103L
@@ -579,27 +592,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _FIter1, typename _FIter2>
- _FIter2
+ _FIter2
swap_ranges(_FIter1, _FIter1, _FIter2);
// transform
template<typename _FIter>
- _FIter
+ _FIter
unique(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
- _FIter
+ _FIter
unique(_FIter, _FIter, _BinaryPredicate);
// unique_copy
template<typename _FIter, typename _Tp>
- _FIter
+ _FIter
upper_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
- _FIter
+ _FIter
upper_bound(_FIter, _FIter, const _Tp&, _Compare);
_GLIBCXX_END_NAMESPACE_VERSION
@@ -607,11 +620,11 @@ _GLIBCXX_END_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _FIter>
- _FIter
+ _FIter
adjacent_find(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
- _FIter
+ _FIter
adjacent_find(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _Tp>
@@ -623,15 +636,15 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
count_if(_IIter, _IIter, _Predicate);
template<typename _IIter1, typename _IIter2>
- bool
+ bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
- bool
+ bool
equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _IIter, typename _Tp>
- _IIter
+ _IIter
find(_IIter, _IIter, const _Tp&);
template<typename _FIter1, typename _FIter2>
@@ -647,11 +660,11 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
find_if(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Funct>
- _Funct
+ _Funct
for_each(_IIter, _IIter, _Funct);
template<typename _FIter, typename _Generator>
- void
+ void
generate(_FIter, _FIter, _Generator);
template<typename _OIter, typename _Size, typename _Generator>
@@ -659,40 +672,40 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
generate_n(_OIter, _Size, _Generator);
template<typename _IIter1, typename _IIter2>
- bool
+ bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
- bool
+ bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
- _FIter
+ _FIter
max_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
- _FIter
+ _FIter
max_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
- _OIter
+ _OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
- template<typename _IIter1, typename _IIter2, typename _OIter,
+ template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
- _OIter
+ _OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
- _FIter
+ _FIter
min_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
- _FIter
+ _FIter
min_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2>
@@ -704,31 +717,31 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _RAIter>
- void
+ void
nth_element(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
- void
+ void
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
- _BIter
+ _BIter
partition(_BIter, _BIter, _Predicate);
template<typename _RAIter>
- void
+ void
random_shuffle(_RAIter, _RAIter);
template<typename _RAIter, typename _Generator>
- void
+ void
random_shuffle(_RAIter, _RAIter,
#if __cplusplus >= 201103L
_Generator&&);
@@ -737,98 +750,98 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
#endif
template<typename _FIter, typename _Tp>
- void
+ void
replace(_FIter, _FIter, const _Tp&, const _Tp&);
template<typename _FIter, typename _Predicate, typename _Tp>
- void
+ void
replace_if(_FIter, _FIter, _Predicate, const _Tp&);
template<typename _FIter1, typename _FIter2>
- _FIter1
+ _FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
- _FIter1
+ _FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter, typename _Size, typename _Tp>
- _FIter
+ _FIter
search_n(_FIter, _FIter, _Size, const _Tp&);
- template<typename _FIter, typename _Size, typename _Tp,
+ template<typename _FIter, typename _Size, typename _Tp,
typename _BinaryPredicate>
- _FIter
+ _FIter
search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
template<typename _IIter1, typename _IIter2, typename _OIter>
- _OIter
+ _OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
- template<typename _IIter1, typename _IIter2, typename _OIter,
+ template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
- _OIter
+ _OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
- _OIter
+ _OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
- _OIter
+ _OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
- template<typename _IIter1, typename _IIter2, typename _OIter,
+ template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_OIter
- set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
+ set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
- _OIter
+ _OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
- _OIter
+ _OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _RAIter>
- void
+ void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
sort(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
- void
+ void
stable_sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
- void
+ void
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _OIter, typename _UnaryOperation>
- _OIter
+ _OIter
transform(_IIter, _IIter, _OIter, _UnaryOperation);
- template<typename _IIter1, typename _IIter2, typename _OIter,
+ template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BinaryOperation>
- _OIter
+ _OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
template<typename _IIter, typename _OIter>
- _OIter
+ _OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryPredicate>
- _OIter
+ _OIter
unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
_GLIBCXX_END_NAMESPACE_ALGO
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index d2d13c692a..4d1e489b0c 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -1,6 +1,6 @@
// Allocator traits -*- C++ -*-
-// Copyright (C) 2011-2016 Free Software Foundation, Inc.
+// Copyright (C) 2011-2017 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
@@ -44,8 +44,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __allocator_traits_base
{
- template<typename _Alloc, typename _Up>
- using __rebind = typename _Alloc::template rebind<_Up>::other;
+ template<typename _Tp, typename _Up, typename = void>
+ struct __rebind : __replace_first_arg<_Tp, _Up> { };
+
+ template<typename _Tp, typename _Up>
+ struct __rebind<_Tp, _Up,
+ __void_t<typename _Tp::template rebind<_Up>::other>>
+ { using type = typename _Tp::template rebind<_Up>::other; };
protected:
template<typename _Tp>
@@ -57,10 +62,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
using __cv_pointer = typename _Tp::const_void_pointer;
template<typename _Tp>
- using __diff_type = typename _Tp::difference_type;
- template<typename _Tp>
- using __size_type = typename _Tp::size_type;
- template<typename _Tp>
using __pocca = typename _Tp::propagate_on_container_copy_assignment;
template<typename _Tp>
using __pocma = typename _Tp::propagate_on_container_move_assignment;
@@ -71,9 +72,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
template<typename _Alloc, typename _Up>
- using __alloc_rebind = __detected_or_t_<__replace_first_arg_t,
- __allocator_traits_base::__rebind,
- _Alloc, _Up>;
+ using __alloc_rebind
+ = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
/**
* @brief Uniform interface to all allocator types.
@@ -94,15 +94,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
+ private:
+ // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
+ template<template<typename> class _Func, typename _Tp, typename = void>
+ struct _Ptr
+ {
+ using type = typename pointer_traits<pointer>::template rebind<_Tp>;
+ };
+
+ template<template<typename> class _Func, typename _Tp>
+ struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
+ {
+ using type = _Func<_Alloc>;
+ };
+
+ // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
+ template<typename _A2, typename _PtrT, typename = void>
+ struct _Diff
+ { using type = typename pointer_traits<_PtrT>::difference_type; };
+
+ template<typename _A2, typename _PtrT>
+ struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
+ { using type = typename _A2::difference_type; };
+
+ // Select _A2::size_type or make_unsigned<_DiffT>::type
+ template<typename _A2, typename _DiffT, typename = void>
+ struct _Size : make_unsigned<_DiffT> { };
+
+ template<typename _A2, typename _DiffT>
+ struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
+ { using type = typename _A2::size_type; };
+
+ public:
/**
* @brief The allocator's const pointer type.
*
* @c Alloc::const_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
*/
- using const_pointer
- = __detected_or_t<__ptr_rebind<pointer, const value_type>,
- __c_pointer, _Alloc>;
+ using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
/**
* @brief The allocator's void pointer type.
@@ -110,8 +140,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @c Alloc::void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<void> </tt>
*/
- using void_pointer
- = __detected_or_t<__ptr_rebind<pointer, void>, __v_pointer, _Alloc>;
+ using void_pointer = typename _Ptr<__v_pointer, void>::type;
/**
* @brief The allocator's const void pointer type.
@@ -119,9 +148,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @c Alloc::const_void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const void> </tt>
*/
- using const_void_pointer
- = __detected_or_t<__ptr_rebind<pointer, const void>, __cv_pointer,
- _Alloc>;
+ using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
/**
* @brief The allocator's difference type
@@ -129,9 +156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @c Alloc::difference_type if that type exists, otherwise
* <tt> pointer_traits<pointer>::difference_type </tt>
*/
- using difference_type
- = __detected_or_t<typename pointer_traits<pointer>::difference_type,
- __diff_type, _Alloc>;
+ using difference_type = typename _Diff<_Alloc, pointer>::type;
/**
* @brief The allocator's size type
@@ -139,9 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @c Alloc::size_type if that type exists, otherwise
* <tt> make_unsigned<difference_type>::type </tt>
*/
- using size_type
- = __detected_or_t<typename make_unsigned<difference_type>::type,
- __size_type, _Alloc>;
+ using size_type = typename _Size<_Alloc, difference_type>::type;
/**
* @brief How the allocator is propagated on copy assignment
@@ -184,9 +207,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
- static_assert(!is_same<rebind_alloc<value_type>, __undefined>::value,
- "allocator defines rebind or is like Alloc<T, Args>");
-
private:
template<typename _Alloc2>
static auto
diff --git a/libstdc++-v3/include/bits/allocated_ptr.h b/libstdc++-v3/include/bits/allocated_ptr.h
index 2bd9d82fd0..773b3f500f 100644
--- a/libstdc++-v3/include/bits/allocated_ptr.h
+++ b/libstdc++-v3/include/bits/allocated_ptr.h
@@ -1,6 +1,6 @@
// Guarded Allocation -*- C++ -*-
-// Copyright (C) 2014-2016 Free Software Foundation, Inc.
+// Copyright (C) 2014-2017 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
@@ -85,10 +85,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
value_type* get() { return _S_raw_ptr(_M_ptr); }
private:
- value_type* _S_raw_ptr(value_type* __ptr) { return __ptr; }
+ static value_type* _S_raw_ptr(value_type* __ptr) { return __ptr; }
template<typename _Ptr>
- auto _S_raw_ptr(_Ptr __ptr) -> decltype(_S_raw_ptr(__ptr.operator->()))
+ static auto
+ _S_raw_ptr(_Ptr __ptr) -> decltype(_S_raw_ptr(__ptr.operator->()))
{ return _S_raw_ptr(__ptr.operator->()); }
_Alloc* _M_alloc;
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
index 984d80075b..20813864c6 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -1,6 +1,6 @@
// Allocators -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -50,6 +50,9 @@
#endif
#define __cpp_lib_incomplete_container_elements 201505
+#if __cplusplus >= 201103L
+# define __cpp_lib_allocator_is_always_equal 201411
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -72,16 +75,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef void value_type;
template<typename _Tp1>
- struct rebind
- { typedef allocator<_Tp1> other; };
+ struct rebind
+ { typedef allocator<_Tp1> other; };
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
typedef true_type propagate_on_container_move_assignment;
-#define __cpp_lib_allocator_is_always_equal 201411
typedef true_type is_always_equal;
+
+ template<typename _Up, typename... _Args>
+ void
+ construct(_Up* __p, _Args&&... __args)
+ { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
+
+ template<typename _Up>
+ void
+ destroy(_Up* __p) { __p->~_Up(); }
#endif
};
@@ -106,13 +117,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef _Tp value_type;
template<typename _Tp1>
- struct rebind
- { typedef allocator<_Tp1> other; };
+ struct rebind
+ { typedef allocator<_Tp1> other; };
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
typedef true_type propagate_on_container_move_assignment;
+
+ typedef true_type is_always_equal;
#endif
allocator() throw() { }
@@ -121,7 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __allocator_base<_Tp>(__a) { }
template<typename _Tp1>
- allocator(const allocator<_Tp1>&) throw() { }
+ allocator(const allocator<_Tp1>&) throw() { }
~allocator() throw() { }
diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index 6bb866bd08..e79ff67ea0 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1,6 +1,6 @@
// -*- C++ -*- header.
-// Copyright (C) 2008-2016 Free Software Foundation, Inc.
+// Copyright (C) 2008-2017 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
@@ -366,7 +366,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_ALWAYS_INLINE void
store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
{
- memory_order __b = __m & __memory_order_mask;
+ memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__glibcxx_assert(__b != memory_order_consume);
@@ -378,7 +378,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
store(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
- memory_order __b = __m & __memory_order_mask;
+ memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__glibcxx_assert(__b != memory_order_consume);
@@ -389,7 +389,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_ALWAYS_INLINE __int_type
load(memory_order __m = memory_order_seq_cst) const noexcept
{
- memory_order __b = __m & __memory_order_mask;
+ memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
@@ -399,7 +399,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_ALWAYS_INLINE __int_type
load(memory_order __m = memory_order_seq_cst) const volatile noexcept
{
- memory_order __b = __m & __memory_order_mask;
+ memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
@@ -425,8 +425,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_weak(__int_type& __i1, __int_type __i2,
memory_order __m1, memory_order __m2) noexcept
{
- memory_order __b2 = __m2 & __memory_order_mask;
- memory_order __b1 = __m1 & __memory_order_mask;
+ memory_order __b2 = __m2 & __memory_order_mask;
+ memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
@@ -439,8 +439,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) volatile noexcept
{
- memory_order __b2 = __m2 & __memory_order_mask;
- memory_order __b1 = __m1 & __memory_order_mask;
+ memory_order __b2 = __m2 & __memory_order_mask;
+ memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
@@ -468,8 +468,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_strong(__int_type& __i1, __int_type __i2,
memory_order __m1, memory_order __m2) noexcept
{
- memory_order __b2 = __m2 & __memory_order_mask;
- memory_order __b1 = __m1 & __memory_order_mask;
+ memory_order __b2 = __m2 & __memory_order_mask;
+ memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
@@ -482,8 +482,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) volatile noexcept
{
- memory_order __b2 = __m2 & __memory_order_mask;
- memory_order __b1 = __m1 & __memory_order_mask;
+ memory_order __b2 = __m2 & __memory_order_mask;
+ memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
@@ -695,7 +695,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
store(__pointer_type __p,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
- memory_order __b = __m & __memory_order_mask;
+ memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__glibcxx_assert(__b != memory_order_consume);
@@ -706,7 +706,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_ALWAYS_INLINE __pointer_type
load(memory_order __m = memory_order_seq_cst) const noexcept
{
- memory_order __b = __m & __memory_order_mask;
+ memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
@@ -716,7 +716,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_ALWAYS_INLINE __pointer_type
load(memory_order __m = memory_order_seq_cst) const volatile noexcept
{
- memory_order __b = __m & __memory_order_mask;
+ memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
@@ -743,8 +743,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) noexcept
{
- memory_order __b2 = __m2 & __memory_order_mask;
- memory_order __b1 = __m1 & __memory_order_mask;
+ memory_order __b2 = __m2 & __memory_order_mask;
+ memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
@@ -757,8 +757,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) volatile noexcept
{
- memory_order __b2 = __m2 & __memory_order_mask;
- memory_order __b1 = __m1 & __memory_order_mask;
+ memory_order __b2 = __m2 & __memory_order_mask;
+ memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h
index 2186f7e984..afcfeb7720 100644
--- a/libstdc++-v3/include/bits/atomic_futex.h
+++ b/libstdc++-v3/include/bits/atomic_futex.h
@@ -1,6 +1,6 @@
// -*- C++ -*- header.
-// Copyright (C) 2015-2016 Free Software Foundation, Inc.
+// Copyright (C) 2015-2017 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
diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h
index b4dc372182..318e41b7c5 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -1,6 +1,6 @@
// Iostreams base classes -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc
index 6c2ea11da1..8b3c829e4b 100644
--- a/libstdc++-v3/include/bits/basic_ios.tcc
+++ b/libstdc++-v3/include/bits/basic_ios.tcc
@@ -1,6 +1,6 @@
// basic_ios member functions -*- C++ -*-
-// Copyright (C) 1999-2016 Free Software Foundation, Inc.
+// Copyright (C) 1999-2017 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
@@ -157,17 +157,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc)
{
if (__builtin_expect(has_facet<__ctype_type>(__loc), true))
- _M_ctype = &use_facet<__ctype_type>(__loc);
+ _M_ctype = std::__addressof(use_facet<__ctype_type>(__loc));
else
_M_ctype = 0;
if (__builtin_expect(has_facet<__num_put_type>(__loc), true))
- _M_num_put = &use_facet<__num_put_type>(__loc);
+ _M_num_put = std::__addressof(use_facet<__num_put_type>(__loc));
else
_M_num_put = 0;
if (__builtin_expect(has_facet<__num_get_type>(__loc), true))
- _M_num_get = &use_facet<__num_get_type>(__loc);
+ _M_num_get = std::__addressof(use_facet<__num_get_type>(__loc));
else
_M_num_get = 0;
}
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 374c985153..b6693c440c 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -1,6 +1,6 @@
// Components for manipulating sequences of characters -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -44,6 +44,11 @@
#include <initializer_list>
#endif
+#if __cplusplus > 201402L
+# include <string_view>
+#endif
+
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -103,11 +108,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
typedef const_iterator __const_iterator;
#endif
+#if __cplusplus > 201402L
+ // A helper type for avoiding boiler-plate.
+ typedef basic_string_view<_CharT, _Traits> __sv_type;
+
+ template<typename _Tp, typename _Res>
+ using _If_sv = enable_if_t<
+ __and_<is_convertible<const _Tp&, __sv_type>,
+ __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
+ _Res>;
+#endif
+
// Use empty-base optimization: http://www.cantrip.org/emptyopt.html
struct _Alloc_hider : allocator_type // TODO check __is_final
{
+#if __cplusplus < 201103L
_Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
: allocator_type(__a), _M_p(__dat) { }
+#else
+ _Alloc_hider(pointer __dat, const _Alloc& __a)
+ : allocator_type(__a), _M_p(__dat) { }
+
+ _Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc())
+ : allocator_type(std::move(__a)), _M_p(__dat) { }
+#endif
pointer _M_p; // The actual data.
};
@@ -360,7 +384,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
}
void
- _M_assign(const basic_string& __rcs);
+ _M_assign(const basic_string&);
void
_M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
@@ -399,16 +423,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
{ _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2583. no way to supply an allocator for basic_string(str, pos)
/**
* @brief Construct string as copy of a substring.
* @param __str Source string.
* @param __pos Index of first character to copy from.
- * @param __n Number of characters to copy (default remainder).
+ * @param __a Allocator to use.
+ */
+ basic_string(const basic_string& __str, size_type __pos,
+ const _Alloc& __a = _Alloc())
+ : _M_dataplus(_M_local_data(), __a)
+ {
+ const _CharT* __start = __str._M_data()
+ + __str._M_check(__pos, "basic_string::basic_string");
+ _M_construct(__start, __start + __str._M_limit(__pos, npos));
+ }
+
+ /**
+ * @brief Construct string as copy of a substring.
+ * @param __str Source string.
+ * @param __pos Index of first character to copy from.
+ * @param __n Number of characters to copy.
*/
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 2402. [this constructor] shouldn't use Allocator()
basic_string(const basic_string& __str, size_type __pos,
- size_type __n = npos)
+ size_type __n)
: _M_dataplus(_M_local_data())
{
const _CharT* __start = __str._M_data()
@@ -420,7 +459,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @brief Construct string as copy of a substring.
* @param __str Source string.
* @param __pos Index of first character to copy from.
- * @param __n Number of characters to copy (default remainder).
+ * @param __n Number of characters to copy.
* @param __a Allocator to use.
*/
basic_string(const basic_string& __str, size_type __pos,
@@ -551,6 +590,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
: _M_dataplus(_M_local_data(), __a)
{ _M_construct(__beg, __end); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Construct string from a substring of a string_view.
+ * @param __t Source string view.
+ * @param __pos The index of the first character to copy from __t.
+ * @param __n The number of characters to copy from __t.
+ * @param __a Allocator to use.
+ */
+ template<typename _Tp, typename = _If_sv<_Tp, void>>
+ basic_string(const _Tp& __t, size_type __pos, size_type __n,
+ const _Alloc& __a = _Alloc())
+ : basic_string(__sv_type(__t).substr(__pos, __n), __a) { }
+
+ /**
+ * @brief Construct string from a string_view.
+ * @param __sv Source string view.
+ * @param __a Allocator to use (default is default allocator).
+ */
+ explicit
+ basic_string(__sv_type __sv, const _Alloc& __a = _Alloc())
+ : basic_string(__sv.data(), __sv.size(), __a) { }
+#endif // C++17
+
/**
* @brief Destroy the string instance.
*/
@@ -570,10 +632,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
&& _M_get_allocator() != __str._M_get_allocator())
{
- // replacement allocator cannot free existing storage
- _M_destroy(_M_allocated_capacity);
- _M_data(_M_local_data());
- _M_set_length(0);
+ // Propagating allocator cannot free existing storage so must
+ // deallocate it before replacing current allocator.
+ if (__str.size() <= _S_local_capacity)
+ {
+ _M_destroy(_M_allocated_capacity);
+ _M_data(_M_local_data());
+ _M_set_length(0);
+ }
+ else
+ {
+ const auto __len = __str.size();
+ auto __alloc = __str._M_get_allocator();
+ // If this allocation throws there are no effects:
+ auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1);
+ _M_destroy(_M_allocated_capacity);
+ _M_data(__ptr);
+ _M_capacity(__len);
+ _M_set_length(__len);
+ }
}
std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
}
@@ -676,6 +753,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
}
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Set value to string constructed from a string_view.
+ * @param __sv A string_view.
+ */
+ template<typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ operator=(_Tp __sv)
+ { return this->assign(__sv); }
+
+ /**
+ * @brief Convert to a string_view.
+ * @return A string_view.
+ */
+ operator __sv_type() const noexcept
+ { return __sv_type(data(), size()); }
+#endif // C++17
+
// Iterators:
/**
* Returns a read/write iterator that points to the first character in
@@ -1059,6 +1154,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ return this->append(__l.begin(), __l.size()); }
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Append a string_view.
+ * @param __sv The string_view to be appended.
+ * @return Reference to this string.
+ */
+ basic_string&
+ operator+=(__sv_type __sv)
+ { return this->append(__sv); }
+#endif // C++17
+
/**
* @brief Append a string to this string.
* @param __str The string to append.
@@ -1156,6 +1262,34 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
append(_InputIterator __first, _InputIterator __last)
{ return this->replace(end(), end(), __first, __last); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Append a string_view.
+ * @param __sv The string_view to be appended.
+ * @return Reference to this string.
+ */
+ basic_string&
+ append(__sv_type __sv)
+ { return this->append(__sv.data(), __sv.size()); }
+
+ /**
+ * @brief Append a range of characters from a string_view.
+ * @param __sv The string_view to be appended from.
+ * @param __pos The position in the string_view to append from.
+ * @param __n The number of characters to append from the string_view.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ append(const _Tp& __svt, size_type __pos, size_type __n = npos)
+ {
+ __sv_type __sv = __svt;
+ return _M_append(__sv.data()
+ + __sv._M_check(__pos, "basic_string::append"),
+ __sv._M_limit(__pos, __n));
+ }
+#endif // C++17
+
/**
* @brief Append a single character.
* @param __c Character to append.
@@ -1296,6 +1430,34 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ return this->assign(__l.begin(), __l.size()); }
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Set value from a string_view.
+ * @param __sv The source string_view.
+ * @return Reference to this string.
+ */
+ basic_string&
+ assign(__sv_type __sv)
+ { return this->assign(__sv.data(), __sv.size()); }
+
+ /**
+ * @brief Set value from a range of characters in a string_view.
+ * @param __sv The source string_view.
+ * @param __pos The position in the string_view to assign from.
+ * @param __n The number of characters to assign.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
+ {
+ __sv_type __sv = __svt;
+ return _M_replace(size_type(0), this->size(), __sv.data()
+ + __sv._M_check(__pos, "basic_string::assign"),
+ __sv._M_limit(__pos, __n));
+ }
+#endif // C++17
+
#if __cplusplus >= 201103L
/**
* @brief Insert multiple characters.
@@ -1526,6 +1688,38 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return iterator(_M_data() + __pos);
}
+#if __cplusplus > 201402L
+ /**
+ * @brief Insert a string_view.
+ * @param __pos Iterator referencing position in string to insert at.
+ * @param __sv The string_view to insert.
+ * @return Reference to this string.
+ */
+ basic_string&
+ insert(size_type __pos, __sv_type __sv)
+ { return this->insert(__pos, __sv.data(), __sv.size()); }
+
+ /**
+ * @brief Insert a string_view.
+ * @param __pos Iterator referencing position in string to insert at.
+ * @param __sv The string_view to insert from.
+ * @param __pos Iterator referencing position in string_view to insert
+ * from.
+ * @param __n The number of characters to insert.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ insert(size_type __pos1, const _Tp& __svt,
+ size_type __pos2, size_type __n = npos)
+ {
+ __sv_type __sv = __svt;
+ return this->replace(__pos1, size_type(0), __sv.data()
+ + __sv._M_check(__pos2, "basic_string::insert"),
+ __sv._M_limit(__pos2, __n));
+ }
+#endif // C++17
+
/**
* @brief Remove characters.
* @param __pos Index of first character to remove (default 0).
@@ -1544,8 +1738,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;
}
@@ -1582,7 +1779,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);
}
@@ -1912,9 +2112,55 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
basic_string& replace(const_iterator __i1, const_iterator __i2,
initializer_list<_CharT> __l)
- { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
+ { return this->replace(__i1, __i2, __l.begin(), __l.size()); }
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Replace range of characters with string_view.
+ * @param __pos The position to replace at.
+ * @param __n The number of characters to replace.
+ * @param __sv The string_view to insert.
+ * @return Reference to this string.
+ */
+ basic_string&
+ replace(size_type __pos, size_type __n, __sv_type __sv)
+ { return this->replace(__pos, __n, __sv.data(), __sv.size()); }
+
+ /**
+ * @brief Replace range of characters with string_view.
+ * @param __pos1 The position to replace at.
+ * @param __n1 The number of characters to replace.
+ * @param __sv The string_view to insert from.
+ * @param __pos2 The position in the string_view to insert from.
+ * @param __n2 The number of characters to insert.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ replace(size_type __pos1, size_type __n1, const _Tp& __svt,
+ size_type __pos2, size_type __n2 = npos)
+ {
+ __sv_type __sv = __svt;
+ return this->replace(__pos1, __n1, __sv.data()
+ + __sv._M_check(__pos2, "basic_string::replace"),
+ __sv._M_limit(__pos2, __n2));
+ }
+
+ /**
+ * @brief Replace range of characters with string_view.
+ * @param __i1 An iterator referencing the start position
+ to replace at.
+ * @param __i2 An iterator referencing the end position
+ for the replace.
+ * @param __sv The string_view to insert from.
+ * @return Reference to this string.
+ */
+ basic_string&
+ replace(const_iterator __i1, const_iterator __i2, __sv_type __sv)
+ { return this->replace(__i1 - begin(), __i2 - __i1, __sv); }
+#endif // C++17
+
private:
template<class _Integer>
basic_string&
@@ -1980,13 +2226,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
/**
* @brief Return const pointer to contents.
*
- * This is a handle to internal data. Do not modify or dire things may
- * happen.
+ * This is a pointer to internal data. It is undefined to modify
+ * the contents through the returned pointer. To get a pointer that
+ * allows modifying the contents use @c &str[0] instead,
+ * (or in C++17 the non-const @c str.data() overload).
*/
const _CharT*
data() const _GLIBCXX_NOEXCEPT
{ return _M_data(); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Return non-const pointer to contents.
+ *
+ * This is a pointer to the character sequence held by the string.
+ * Modifying the characters in the sequence is allowed.
+ */
+ _CharT*
+ data() noexcept
+ { return _M_data(); }
+#endif
+
/**
* @brief Return copy of allocator used to construct this string.
*/
@@ -2007,7 +2267,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* npos.
*/
size_type
- find(const _CharT* __s, size_type __pos, size_type __n) const;
+ find(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find position of a string.
@@ -2021,9 +2282,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find(const basic_string& __str, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find(__str.data(), __pos, __str.size()); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find position of a string_view.
+ * @param __sv The string_view to locate.
+ * @param __pos Index of character to search from (default 0).
+ * @return Index of start of first occurrence.
+ */
+ size_type
+ find(__sv_type __sv, size_type __pos = 0) const noexcept
+ { return this->find(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find position of a C string.
* @param __s C string to locate.
@@ -2035,7 +2308,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* it begins. If not found, returns npos.
*/
size_type
- find(const _CharT* __s, size_type __pos = 0) const
+ find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find(__s, __pos, traits_type::length(__s));
@@ -2066,9 +2339,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
rfind(const basic_string& __str, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->rfind(__str.data(), __pos, __str.size()); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find last position of a string_view.
+ * @param __sv The string_view to locate.
+ * @param __pos Index of character to search back from (default end).
+ * @return Index of start of last occurrence.
+ */
+ size_type
+ rfind(__sv_type __sv, size_type __pos = npos) const noexcept
+ { return this->rfind(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find last position of a C substring.
* @param __s C string to locate.
@@ -2082,7 +2367,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* npos.
*/
size_type
- rfind(const _CharT* __s, size_type __pos, size_type __n) const;
+ rfind(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find last position of a C string.
@@ -2127,9 +2413,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_first_of(const basic_string& __str, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_first_of(__str.data(), __pos, __str.size()); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find position of a character of a string_view.
+ * @param __sv A string_view containing characters to locate.
+ * @param __pos Index of character to search from (default 0).
+ * @return Index of first occurrence.
+ */
+ size_type
+ find_first_of(__sv_type __sv, size_type __pos = 0) const noexcept
+ { return this->find_first_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find position of a character of C substring.
* @param __s String containing characters to locate.
@@ -2143,7 +2441,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns npos.
*/
size_type
- find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
+ find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find position of a character of C string.
@@ -2157,6 +2456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_first_of(const _CharT* __s, size_type __pos = 0) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_first_of(__s, __pos, traits_type::length(__s));
@@ -2191,9 +2491,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_last_of(const basic_string& __str, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_last_of(__str.data(), __pos, __str.size()); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find last position of a character of string.
+ * @param __sv A string_view containing characters to locate.
+ * @param __pos Index of character to search back from (default end).
+ * @return Index of last occurrence.
+ */
+ size_type
+ find_last_of(__sv_type __sv, size_type __pos = npos) const noexcept
+ { return this->find_last_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find last position of a character of C substring.
* @param __s C string containing characters to locate.
@@ -2207,7 +2519,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns npos.
*/
size_type
- find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
+ find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find last position of a character of C string.
@@ -2221,6 +2534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_last_of(const _CharT* __s, size_type __pos = npos) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_last_of(__s, __pos, traits_type::length(__s));
@@ -2254,9 +2568,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_first_not_of(const basic_string& __str, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_first_not_of(__str.data(), __pos, __str.size()); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find position of a character not in a string_view.
+ * @param __sv A string_view containing characters to avoid.
+ * @param __pos Index of character to search from (default 0).
+ * @return Index of first occurrence.
+ */
+ size_type
+ find_first_not_of(__sv_type __sv, size_type __pos = 0) const noexcept
+ { return this->find_first_not_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find position of a character not in C substring.
* @param __s C string containing characters to avoid.
@@ -2271,7 +2597,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_first_not_of(const _CharT* __s, size_type __pos,
- size_type __n) const;
+ size_type __n) const _GLIBCXX_NOEXCEPT;
/**
* @brief Find position of a character not in C string.
@@ -2285,6 +2611,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_first_not_of(const _CharT* __s, size_type __pos = 0) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_first_not_of(__s, __pos, traits_type::length(__s));
@@ -2302,7 +2629,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_first_not_of(_CharT __c, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT;
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find last position of a character not in string.
@@ -2317,9 +2644,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_last_not_of(const basic_string& __str, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_last_not_of(__str.data(), __pos, __str.size()); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find last position of a character not in a string_view.
+ * @param __sv A string_view containing characters to avoid.
+ * @param __pos Index of character to search back from (default end).
+ * @return Index of last occurrence.
+ */
+ size_type
+ find_last_not_of(__sv_type __sv, size_type __pos = npos) const noexcept
+ { return this->find_last_not_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find last position of a character not in C substring.
* @param __s C string containing characters to avoid.
@@ -2334,7 +2673,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_last_not_of(const _CharT* __s, size_type __pos,
- size_type __n) const;
+ size_type __n) const _GLIBCXX_NOEXCEPT;
/**
* @brief Find last position of a character not in C string.
* @param __s C string containing characters to avoid.
@@ -2348,6 +2687,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_last_not_of(const _CharT* __s, size_type __pos = npos) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_last_not_of(__s, __pos, traits_type::length(__s));
@@ -2365,7 +2705,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
find_last_not_of(_CharT __c, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT;
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Get a substring.
@@ -2411,6 +2751,56 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return __r;
}
+#if __cplusplus > 201402L
+ /**
+ * @brief Compare to a string_view.
+ * @param __sv A string_view to compare against.
+ * @return Integer < 0, 0, or > 0.
+ */
+ int
+ compare(__sv_type __sv) const
+ {
+ const size_type __size = this->size();
+ const size_type __osize = __sv.size();
+ const size_type __len = std::min(__size, __osize);
+
+ int __r = traits_type::compare(_M_data(), __sv.data(), __len);
+ if (!__r)
+ __r = _S_compare(__size, __osize);
+ return __r;
+ }
+
+ /**
+ * @brief Compare to a string_view.
+ * @param __pos A position in the string to start comparing from.
+ * @param __n The number of characters to compare.
+ * @param __sv A string_view to compare against.
+ * @return Integer < 0, 0, or > 0.
+ */
+ int
+ compare(size_type __pos, size_type __n, __sv_type __sv) const
+ { return __sv_type(*this).substr(__pos, __n).compare(__sv); }
+
+ /**
+ * @brief Compare to a string_view.
+ * @param __pos1 A position in the string to start comparing from.
+ * @param __n1 The number of characters to compare.
+ * @param __sv A string_view to compare against.
+ * @param __pos2 A position in the string_view to start comparing from.
+ * @param __n2 The number of characters to compare.
+ * @return Integer < 0, 0, or > 0.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, int>
+ compare(size_type __pos1, size_type __n1, const _Tp& __svt,
+ size_type __pos2, size_type __n2 = npos) const
+ {
+ __sv_type __sv = __svt;
+ return __sv_type(*this)
+ .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
+ }
+#endif // C++17
+
/**
* @brief Compare substring to a string.
* @param __pos Index of first character of substring.
@@ -2475,7 +2865,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* ordered first.
*/
int
- compare(const _CharT* __s) const;
+ compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 5 String::compare specification questionable
@@ -2946,6 +3336,17 @@ _GLIBCXX_END_NAMESPACE_CXX11
_S_empty_rep() _GLIBCXX_NOEXCEPT
{ return _Rep::_S_empty_rep(); }
+#if __cplusplus > 201402L
+ // A helper type for avoiding boiler-plate.
+ typedef basic_string_view<_CharT, _Traits> __sv_type;
+
+ template<typename _Tp, typename _Res>
+ using _If_sv = enable_if_t<
+ __and_<is_convertible<const _Tp&, __sv_type>,
+ __not_<is_convertible<const _Tp&, const _CharT*>>>::value,
+ _Res>;
+#endif
+
public:
// Construct/copy/destroy:
// NB: We overload ctors in some cases instead of using default
@@ -2973,14 +3374,26 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @param __str Source string.
*/
basic_string(const basic_string& __str);
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2583. no way to supply an allocator for basic_string(str, pos)
/**
* @brief Construct string as copy of a substring.
* @param __str Source string.
* @param __pos Index of first character to copy from.
- * @param __n Number of characters to copy (default remainder).
+ * @param __a Allocator to use.
*/
basic_string(const basic_string& __str, size_type __pos,
- size_type __n = npos);
+ const _Alloc& __a = _Alloc());
+
+ /**
+ * @brief Construct string as copy of a substring.
+ * @param __str Source string.
+ * @param __pos Index of first character to copy from.
+ * @param __n Number of characters to copy.
+ */
+ basic_string(const basic_string& __str, size_type __pos,
+ size_type __n);
/**
* @brief Construct string as copy of a substring.
* @param __str Source string.
@@ -3055,6 +3468,29 @@ _GLIBCXX_END_NAMESPACE_CXX11
basic_string(_InputIterator __beg, _InputIterator __end,
const _Alloc& __a = _Alloc());
+#if __cplusplus > 201402L
+ /**
+ * @brief Construct string from a substring of a string_view.
+ * @param __t Source string view.
+ * @param __pos The index of the first character to copy from __t.
+ * @param __n The number of characters to copy from __t.
+ * @param __a Allocator to use.
+ */
+ template<typename _Tp, typename = _If_sv<_Tp, void>>
+ basic_string(const _Tp& __t, size_type __pos, size_type __n,
+ const _Alloc& __a = _Alloc())
+ : basic_string(__sv_type(__t).substr(__pos, __n), __a) { }
+
+ /**
+ * @brief Construct string from a string_view.
+ * @param __sv Source string view.
+ * @param __a Allocator to use (default is default allocator).
+ */
+ explicit
+ basic_string(__sv_type __sv, const _Alloc& __a = _Alloc())
+ : basic_string(__sv.data(), __sv.size(), __a) { }
+#endif // C++17
+
/**
* @brief Destroy the string instance.
*/
@@ -3120,6 +3556,24 @@ _GLIBCXX_END_NAMESPACE_CXX11
}
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Set value to string constructed from a string_view.
+ * @param __sv A string_view.
+ */
+ template<typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ operator=(_Tp __sv)
+ { return this->assign(__sv); }
+
+ /**
+ * @brief Convert to a string_view.
+ * @return A string_view.
+ */
+ operator __sv_type() const noexcept
+ { return __sv_type(data(), size()); }
+#endif // C++17
+
// Iterators:
/**
* Returns a read/write iterator that points to the first character in
@@ -3325,10 +3779,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
@@ -3510,6 +3978,17 @@ _GLIBCXX_END_NAMESPACE_CXX11
{ return this->append(__l.begin(), __l.size()); }
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Append a string_view.
+ * @param __sv The string_view to be appended.
+ * @return Reference to this string.
+ */
+ basic_string&
+ operator+=(__sv_type __sv)
+ { return this->append(__sv); }
+#endif // C++17
+
/**
* @brief Append a string to this string.
* @param __str The string to append.
@@ -3590,6 +4069,34 @@ _GLIBCXX_END_NAMESPACE_CXX11
append(_InputIterator __first, _InputIterator __last)
{ return this->replace(_M_iend(), _M_iend(), __first, __last); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Append a string_view.
+ * @param __sv The string_view to be appended.
+ * @return Reference to this string.
+ */
+ basic_string&
+ append(__sv_type __sv)
+ { return this->append(__sv.data(), __sv.size()); }
+
+ /**
+ * @brief Append a range of characters from a string_view.
+ * @param __sv The string_view to be appended from.
+ * @param __pos The position in the string_view to append from.
+ * @param __n The number of characters to append from the string_view.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ append(const _Tp& __svt, size_type __pos, size_type __n = npos)
+ {
+ __sv_type __sv = __svt;
+ return append(__sv.data()
+ + __sv._M_check(__pos, "basic_string::append"),
+ __sv._M_limit(__pos, __n));
+ }
+#endif // C++17
+
/**
* @brief Append a single character.
* @param __c Character to append.
@@ -3715,6 +4222,34 @@ _GLIBCXX_END_NAMESPACE_CXX11
{ return this->assign(__l.begin(), __l.size()); }
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Set value from a string_view.
+ * @param __sv The source string_view.
+ * @return Reference to this string.
+ */
+ basic_string&
+ assign(__sv_type __sv)
+ { return this->assign(__sv.data(), __sv.size()); }
+
+ /**
+ * @brief Set value from a range of characters in a string_view.
+ * @param __sv The source string_view.
+ * @param __pos The position in the string_view to assign from.
+ * @param __n The number of characters to assign.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ assign(const _Tp& __svt, size_type __pos, size_type __n = npos)
+ {
+ __sv_type __sv = __svt;
+ return assign(__sv.data()
+ + __sv._M_check(__pos, "basic_string::assign"),
+ __sv._M_limit(__pos, __n));
+ }
+#endif // C++17
+
/**
* @brief Insert multiple characters.
* @param __p Iterator referencing location in string to insert at.
@@ -3890,6 +4425,38 @@ _GLIBCXX_END_NAMESPACE_CXX11
return iterator(_M_data() + __pos);
}
+#if __cplusplus > 201402L
+ /**
+ * @brief Insert a string_view.
+ * @param __pos Iterator referencing position in string to insert at.
+ * @param __sv The string_view to insert.
+ * @return Reference to this string.
+ */
+ basic_string&
+ insert(size_type __pos, __sv_type __sv)
+ { return this->insert(__pos, __sv.data(), __sv.size()); }
+
+ /**
+ * @brief Insert a string_view.
+ * @param __pos Iterator referencing position in string to insert at.
+ * @param __sv The string_view to insert from.
+ * @param __pos Iterator referencing position in string_view to insert
+ * from.
+ * @param __n The number of characters to insert.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ insert(size_type __pos1, const _Tp& __svt,
+ size_type __pos2, size_type __n = npos)
+ {
+ __sv_type __sv = __svt;
+ return this->replace(__pos1, size_type(0), __sv.data()
+ + __sv._M_check(__pos2, "basic_string::insert"),
+ __sv._M_limit(__pos2, __n));
+ }
+#endif // C++17
+
/**
* @brief Remove characters.
* @param __pos Index of first character to remove (default 0).
@@ -4244,6 +4811,52 @@ _GLIBCXX_END_NAMESPACE_CXX11
{ return this->replace(__i1, __i2, __l.begin(), __l.end()); }
#endif // C++11
+#if __cplusplus > 201402L
+ /**
+ * @brief Replace range of characters with string_view.
+ * @param __pos The position to replace at.
+ * @param __n The number of characters to replace.
+ * @param __sv The string_view to insert.
+ * @return Reference to this string.
+ */
+ basic_string&
+ replace(size_type __pos, size_type __n, __sv_type __sv)
+ { return this->replace(__pos, __n, __sv.data(), __sv.size()); }
+
+ /**
+ * @brief Replace range of characters with string_view.
+ * @param __pos1 The position to replace at.
+ * @param __n1 The number of characters to replace.
+ * @param __sv The string_view to insert from.
+ * @param __pos2 The position in the string_view to insert from.
+ * @param __n2 The number of characters to insert.
+ * @return Reference to this string.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, basic_string&>
+ replace(size_type __pos1, size_type __n1, const _Tp& __svt,
+ size_type __pos2, size_type __n2 = npos)
+ {
+ __sv_type __sv = __svt;
+ return this->replace(__pos1, __n1, __sv.data()
+ + __sv._M_check(__pos2, "basic_string::replace"),
+ __sv._M_limit(__pos2, __n2));
+ }
+
+ /**
+ * @brief Replace range of characters with string_view.
+ * @param __i1 An iterator referencing the start position
+ to replace at.
+ * @param __i2 An iterator referencing the end position
+ for the replace.
+ * @param __sv The string_view to insert from.
+ * @return Reference to this string.
+ */
+ basic_string&
+ replace(const_iterator __i1, const_iterator __i2, __sv_type __sv)
+ { return this->replace(__i1 - begin(), __i2 - __i1, __sv); }
+#endif // C++17
+
private:
template<class _Integer>
basic_string&
@@ -4354,13 +4967,27 @@ _GLIBCXX_END_NAMESPACE_CXX11
/**
* @brief Return const pointer to contents.
*
- * This is a handle to internal data. Do not modify or dire things may
- * happen.
+ * This is a pointer to internal data. It is undefined to modify
+ * the contents through the returned pointer. To get a pointer that
+ * allows modifying the contents use @c &str[0] instead,
+ * (or in C++17 the non-const @c str.data() overload).
*/
const _CharT*
data() const _GLIBCXX_NOEXCEPT
{ return _M_data(); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Return non-const pointer to contents.
+ *
+ * This is a pointer to the character sequence held by the string.
+ * Modifying the characters in the sequence is allowed.
+ */
+ _CharT*
+ data() noexcept
+ { return _M_data(); }
+#endif
+
/**
* @brief Return copy of allocator used to construct this string.
*/
@@ -4381,7 +5008,8 @@ _GLIBCXX_END_NAMESPACE_CXX11
* npos.
*/
size_type
- find(const _CharT* __s, size_type __pos, size_type __n) const;
+ find(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find position of a string.
@@ -4395,7 +5023,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find(const basic_string& __str, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find(__str.data(), __pos, __str.size()); }
/**
@@ -4409,7 +5037,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* it begins. If not found, returns npos.
*/
size_type
- find(const _CharT* __s, size_type __pos = 0) const
+ find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find(__s, __pos, traits_type::length(__s));
@@ -4428,6 +5056,18 @@ _GLIBCXX_END_NAMESPACE_CXX11
size_type
find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;
+#if __cplusplus > 201402L
+ /**
+ * @brief Find position of a string_view.
+ * @param __sv The string_view to locate.
+ * @param __pos Index of character to search from (default 0).
+ * @return Index of start of first occurrence.
+ */
+ size_type
+ find(__sv_type __sv, size_type __pos = 0) const noexcept
+ { return this->find(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find last position of a string.
* @param __str String to locate.
@@ -4440,7 +5080,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
rfind(const basic_string& __str, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->rfind(__str.data(), __pos, __str.size()); }
/**
@@ -4456,7 +5096,8 @@ _GLIBCXX_END_NAMESPACE_CXX11
* npos.
*/
size_type
- rfind(const _CharT* __s, size_type __pos, size_type __n) const;
+ rfind(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find last position of a C string.
@@ -4469,7 +5110,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* where it begins. If not found, returns npos.
*/
size_type
- rfind(const _CharT* __s, size_type __pos = npos) const
+ rfind(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->rfind(__s, __pos, traits_type::length(__s));
@@ -4488,6 +5129,18 @@ _GLIBCXX_END_NAMESPACE_CXX11
size_type
rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
+#if __cplusplus > 201402L
+ /**
+ * @brief Find last position of a string_view.
+ * @param __sv The string_view to locate.
+ * @param __pos Index of character to search back from (default end).
+ * @return Index of start of last occurrence.
+ */
+ size_type
+ rfind(__sv_type __sv, size_type __pos = npos) const noexcept
+ { return this->rfind(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find position of a character of string.
* @param __str String containing characters to locate.
@@ -4501,7 +5154,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_first_of(const basic_string& __str, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_first_of(__str.data(), __pos, __str.size()); }
/**
@@ -4517,7 +5170,8 @@ _GLIBCXX_END_NAMESPACE_CXX11
* returns npos.
*/
size_type
- find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
+ find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find position of a character of C string.
@@ -4531,6 +5185,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_first_of(const _CharT* __s, size_type __pos = 0) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_first_of(__s, __pos, traits_type::length(__s));
@@ -4552,6 +5207,18 @@ _GLIBCXX_END_NAMESPACE_CXX11
find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
{ return this->find(__c, __pos); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find position of a character of a string_view.
+ * @param __sv A string_view containing characters to locate.
+ * @param __pos Index of character to search from (default 0).
+ * @return Index of first occurrence.
+ */
+ size_type
+ find_first_of(__sv_type __sv, size_type __pos = 0) const noexcept
+ { return this->find_first_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find last position of a character of string.
* @param __str String containing characters to locate.
@@ -4565,7 +5232,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_last_of(const basic_string& __str, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_last_of(__str.data(), __pos, __str.size()); }
/**
@@ -4581,7 +5248,8 @@ _GLIBCXX_END_NAMESPACE_CXX11
* returns npos.
*/
size_type
- find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
+ find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT;
/**
* @brief Find last position of a character of C string.
@@ -4595,6 +5263,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_last_of(const _CharT* __s, size_type __pos = npos) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_last_of(__s, __pos, traits_type::length(__s));
@@ -4616,6 +5285,18 @@ _GLIBCXX_END_NAMESPACE_CXX11
find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
{ return this->rfind(__c, __pos); }
+#if __cplusplus > 201402L
+ /**
+ * @brief Find last position of a character of string.
+ * @param __sv A string_view containing characters to locate.
+ * @param __pos Index of character to search back from (default end).
+ * @return Index of last occurrence.
+ */
+ size_type
+ find_last_of(__sv_type __sv, size_type __pos = npos) const noexcept
+ { return this->find_last_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
+
/**
* @brief Find position of a character not in string.
* @param __str String containing characters to avoid.
@@ -4628,7 +5309,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_first_not_of(const basic_string& __str, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_first_not_of(__str.data(), __pos, __str.size()); }
/**
@@ -4645,7 +5326,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_first_not_of(const _CharT* __s, size_type __pos,
- size_type __n) const;
+ size_type __n) const _GLIBCXX_NOEXCEPT;
/**
* @brief Find position of a character not in C string.
@@ -4659,6 +5340,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_first_not_of(const _CharT* __s, size_type __pos = 0) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_first_not_of(__s, __pos, traits_type::length(__s));
@@ -4676,7 +5358,19 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_first_not_of(_CharT __c, size_type __pos = 0) const
- _GLIBCXX_NOEXCEPT;
+ _GLIBCXX_NOEXCEPT;
+
+#if __cplusplus > 201402L
+ /**
+ * @brief Find position of a character not in a string_view.
+ * @param __sv A string_view containing characters to avoid.
+ * @param __pos Index of character to search from (default 0).
+ * @return Index of first occurrence.
+ */
+ size_type
+ find_first_not_of(__sv_type __sv, size_type __pos = 0) const noexcept
+ { return this->find_first_not_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
/**
* @brief Find last position of a character not in string.
@@ -4691,7 +5385,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_last_not_of(const basic_string& __str, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT
+ _GLIBCXX_NOEXCEPT
{ return this->find_last_not_of(__str.data(), __pos, __str.size()); }
/**
@@ -4708,7 +5402,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_last_not_of(const _CharT* __s, size_type __pos,
- size_type __n) const;
+ size_type __n) const _GLIBCXX_NOEXCEPT;
/**
* @brief Find last position of a character not in C string.
* @param __s C string containing characters to avoid.
@@ -4722,6 +5416,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_last_not_of(const _CharT* __s, size_type __pos = npos) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
return this->find_last_not_of(__s, __pos, traits_type::length(__s));
@@ -4739,7 +5434,19 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
size_type
find_last_not_of(_CharT __c, size_type __pos = npos) const
- _GLIBCXX_NOEXCEPT;
+ _GLIBCXX_NOEXCEPT;
+
+#if __cplusplus > 201402L
+ /**
+ * @brief Find last position of a character not in a string_view.
+ * @param __sv A string_view containing characters to avoid.
+ * @param __pos Index of character to search back from (default end).
+ * @return Index of last occurrence.
+ */
+ size_type
+ find_last_not_of(__sv_type __sv, size_type __pos = npos) const noexcept
+ { return this->find_last_not_of(__sv.data(), __pos, __sv.size()); }
+#endif // C++17
/**
* @brief Get a substring.
@@ -4785,6 +5492,56 @@ _GLIBCXX_END_NAMESPACE_CXX11
return __r;
}
+#if __cplusplus > 201402L
+ /**
+ * @brief Compare to a string_view.
+ * @param __sv A string_view to compare against.
+ * @return Integer < 0, 0, or > 0.
+ */
+ int
+ compare(__sv_type __sv) const
+ {
+ const size_type __size = this->size();
+ const size_type __osize = __sv.size();
+ const size_type __len = std::min(__size, __osize);
+
+ int __r = traits_type::compare(_M_data(), __sv.data(), __len);
+ if (!__r)
+ __r = _S_compare(__size, __osize);
+ return __r;
+ }
+
+ /**
+ * @brief Compare to a string_view.
+ * @param __pos A position in the string to start comparing from.
+ * @param __n The number of characters to compare.
+ * @param __sv A string_view to compare against.
+ * @return Integer < 0, 0, or > 0.
+ */
+ int
+ compare(size_type __pos, size_type __n, __sv_type __sv) const
+ { return __sv_type(*this).substr(__pos, __n).compare(__sv); }
+
+ /**
+ * @brief Compare to a string_view.
+ * @param __pos1 A position in the string to start comparing from.
+ * @param __n1 The number of characters to compare.
+ * @param __sv A string_view to compare against.
+ * @param __pos2 A position in the string_view to start comparing from.
+ * @param __n2 The number of characters to compare.
+ * @return Integer < 0, 0, or > 0.
+ */
+ template <typename _Tp>
+ _If_sv<_Tp, int>
+ compare(size_type __pos1, size_type __n1, const _Tp& __svt,
+ size_type __pos2, size_type __n2 = npos) const
+ {
+ __sv_type __sv = __svt;
+ return __sv_type(*this)
+ .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
+ }
+#endif // C++17
+
/**
* @brief Compare substring to a string.
* @param __pos Index of first character of substring.
@@ -4849,7 +5606,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* ordered first.
*/
int
- compare(const _CharT* __s) const;
+ compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 5 String::compare specification questionable
@@ -5698,6 +6455,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+
#if __cplusplus > 201103L
#define __cpp_lib_string_udls 201304
@@ -5706,6 +6465,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
inline namespace string_literals
{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_DEFAULT_ABI_TAG
inline basic_string<char>
@@ -5731,12 +6491,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return basic_string<char32_t>{__str, __len}; }
#endif
+_GLIBCXX_END_NAMESPACE_VERSION
} // inline namespace string_literals
} // inline namespace literals
#endif // __cplusplus > 201103L
-_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++11
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 2b6644d1c4..41b7fa196b 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -1,6 +1,6 @@
// Components for manipulating sequences of characters -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -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>
@@ -621,6 +621,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a)
+ : _M_dataplus(_S_construct(__str._M_data()
+ + __str._M_check(__pos,
+ "basic_string::basic_string"),
+ __str._M_data() + __str._M_limit(__pos, npos)
+ + __pos, __a), __a)
+ { }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string& __str, size_type __pos, size_type __n)
: _M_dataplus(_S_construct(__str._M_data()
+ __str._M_check(__pos,
@@ -1176,21 +1186,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::
find(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string_len(__s, __n);
const size_type __size = this->size();
- const _CharT* __data = _M_data();
if (__n == 0)
return __pos <= __size ? __pos : npos;
+ if (__pos >= __size)
+ return npos;
- if (__n <= __size)
+ const _CharT __elem0 = __s[0];
+ const _CharT* const __data = data();
+ const _CharT* __first = __data + __pos;
+ const _CharT* const __last = __data + __size;
+ size_type __len = __size - __pos;
+
+ while (__len >= __n)
{
- for (; __pos <= __size - __n; ++__pos)
- if (traits_type::eq(__data[__pos], __s[0])
- && traits_type::compare(__data + __pos + 1,
- __s + 1, __n - 1) == 0)
- return __pos;
+ // Find the first occurrence of __elem0:
+ __first = traits_type::find(__first, __len - __n + 1, __elem0);
+ if (!__first)
+ return npos;
+ // Compare the full strings from the first occurrence of __elem0.
+ // We already know that __first[0] == __s[0] but compare them again
+ // anyway because __s is probably aligned, which helps memcmp.
+ if (traits_type::compare(__first, __s, __n) == 0)
+ return __first - __data;
+ __len = __last - ++__first;
}
return npos;
}
@@ -1217,6 +1240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::
rfind(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string_len(__s, __n);
const size_type __size = this->size();
@@ -1255,6 +1279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::
find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string_len(__s, __n);
for (; __n && __pos < this->size(); ++__pos)
@@ -1270,6 +1295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::
find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string_len(__s, __n);
size_type __size = this->size();
@@ -1291,6 +1317,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string_len(__s, __n);
for (; __pos < this->size(); ++__pos)
@@ -1314,6 +1341,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+ _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string_len(__s, __n);
size_type __size = this->size();
@@ -1387,7 +1415,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits, typename _Alloc>
int
basic_string<_CharT, _Traits, _Alloc>::
- compare(const _CharT* __s) const
+ compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_string(__s);
const size_type __size = this->size();
@@ -1569,7 +1597,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
-#if _GLIBCXX_EXTERN_TEMPLATE > 0
+#if _GLIBCXX_EXTERN_TEMPLATE > 0 && __cplusplus <= 201402L
extern template class basic_string<char>;
extern template
basic_istream<char>&
diff --git a/libstdc++-v3/include/bits/boost_concept_check.h b/libstdc++-v3/include/bits/boost_concept_check.h
index 8429c0f523..fb9a643c86 100644
--- a/libstdc++-v3/include/bits/boost_concept_check.h
+++ b/libstdc++-v3/include/bits/boost_concept_check.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2004-2016 Free Software Foundation, Inc.
+// Copyright (C) 2004-2017 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
diff --git a/libstdc++-v3/include/bits/c++0x_warning.h b/libstdc++-v3/include/bits/c++0x_warning.h
index cec4968861..d2bc7148cc 100644
--- a/libstdc++-v3/include/bits/c++0x_warning.h
+++ b/libstdc++-v3/include/bits/c++0x_warning.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
diff --git a/libstdc++-v3/include/bits/c++14_warning.h b/libstdc++-v3/include/bits/c++14_warning.h
index f3cb99c593..5ead9c6b12 100644
--- a/libstdc++-v3/include/bits/c++14_warning.h
+++ b/libstdc++-v3/include/bits/c++14_warning.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -29,9 +29,9 @@
#define _CXX14_WARNING_H 1
#if __cplusplus <= 201103L
-#error This file requires compiler and library support for the forthcoming \
-ISO C++ 2014 standard. This support is currently experimental, and must be \
-enabled with the -std=c++1y or -std=gnu++1y compiler options.
+#error This file requires compiler and library support \
+for the ISO C++ 2014 standard. This support must be enabled \
+with the -std=c++14 or -std=gnu++14 compiler options.
#endif
#endif
diff --git a/libstdc++-v3/include/bits/c++17_warning.h b/libstdc++-v3/include/bits/c++17_warning.h
new file mode 100644
index 0000000000..759fdc9225
--- /dev/null
+++ b/libstdc++-v3/include/bits/c++17_warning.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2016-2017 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/c++17_warning.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{iosfwd}
+ */
+
+#ifndef _CXX17_WARNING_H
+#define _CXX17_WARNING_H 1
+
+#if __cplusplus <= 201402L
+#error This file requires compiler and library support \
+for the ISO C++ 2017 standard. This support must be enabled \
+with the -std=c++17 or -std=gnu++17 compiler options.
+#endif
+
+#endif
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 4625607425..8ca6b0345b 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -1,6 +1,6 @@
// Predefined symbols and macros -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -30,7 +30,10 @@
#ifndef _GLIBCXX_CXX_CONFIG_H
#define _GLIBCXX_CXX_CONFIG_H 1
-// The current version of the C++ library in compressed ISO date format.
+// The major release number for the GCC release the C++ library belongs to.
+#define _GLIBCXX_RELEASE
+
+// The datestamp of the C++ library in compressed ISO date format.
#define __GLIBCXX__
// Macros for various attributes.
@@ -111,6 +114,22 @@
# endif
#endif
+#ifndef _GLIBCXX17_CONSTEXPR
+# if __cplusplus > 201402L
+# define _GLIBCXX17_CONSTEXPR constexpr
+# else
+# define _GLIBCXX17_CONSTEXPR
+# endif
+#endif
+
+#ifndef _GLIBCXX17_INLINE
+# if __cplusplus > 201402L
+# define _GLIBCXX17_INLINE inline
+# else
+# define _GLIBCXX17_INLINE
+# endif
+#endif
+
// Macro for noexcept, to support in mixed 03/0x mode.
#ifndef _GLIBCXX_NOEXCEPT
# if __cplusplus >= 201103L
@@ -138,6 +157,14 @@
# endif
#endif
+#if __cpp_noexcept_function_type
+#define _GLIBCXX_NOEXCEPT_PARM , bool _NE
+#define _GLIBCXX_NOEXCEPT_QUAL noexcept (_NE)
+#else
+#define _GLIBCXX_NOEXCEPT_PARM
+#define _GLIBCXX_NOEXCEPT_QUAL
+#endif
+
// Macro for extern template, ie controlling template linkage via use
// of extern keyword on template declaration. As documented in the g++
// manual, it inhibits all implicit instantiations and is used
@@ -160,7 +187,9 @@
namespace __profile { }
namespace __cxx1998 { }
- namespace __detail { }
+ namespace __detail {
+ namespace __variant { } // C++17
+ }
namespace rel_ops { }
@@ -175,12 +204,16 @@
namespace decimal { }
- namespace chrono { }
- namespace placeholders { }
- namespace regex_constants { }
- namespace this_thread { }
-
- namespace experimental { }
+ namespace chrono { } // C++11
+ namespace placeholders { } // C++11
+ namespace regex_constants { } // C++11
+ namespace this_thread { } // C++11
+ inline namespace literals { // C++14
+ inline namespace chrono_literals { } // C++14
+ inline namespace complex_literals { } // C++14
+ inline namespace string_literals { } // C++14
+ inline namespace string_view_literals { } // C++17
+ }
}
namespace abi { }
@@ -260,14 +293,30 @@ namespace std
namespace decimal { inline namespace __7 { } }
+#if __cplusplus >= 201103L
namespace chrono { inline namespace __7 { } }
namespace placeholders { inline namespace __7 { } }
namespace regex_constants { inline namespace __7 { } }
namespace this_thread { inline namespace __7 { } }
- namespace experimental { inline namespace __7 { } }
+#if __cplusplus >= 201402L
+ inline namespace literals {
+ inline namespace chrono_literals { inline namespace __7 { } }
+ inline namespace complex_literals { inline namespace __7 { } }
+ inline namespace string_literals { inline namespace __7 { } }
+#if __cplusplus > 201402L
+ inline namespace string_view_literals { inline namespace __7 { } }
+#endif // C++17
+ }
+#endif // C++14
+#endif // C++11
- namespace __detail { inline namespace __7 { } }
+ namespace __detail {
+ inline namespace __7 { }
+#if __cplusplus > 201402L
+ namespace __variant { inline namespace __7 { } }
+#endif
+ }
}
namespace __gnu_cxx
@@ -350,6 +399,10 @@ namespace std
namespace _GLIBCXX_STD_C { _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_END_NAMESPACE_CONTAINER \
_GLIBCXX_END_NAMESPACE_VERSION }
+#else
+# define _GLIBCXX_STD_C std
+# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_BEGIN_NAMESPACE_VERSION
+# define _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION
#endif
#ifdef _GLIBCXX_PARALLEL
@@ -358,30 +411,10 @@ namespace std
namespace _GLIBCXX_STD_A { _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_END_NAMESPACE_ALGO \
_GLIBCXX_END_NAMESPACE_VERSION }
-#endif
-
-#ifndef _GLIBCXX_STD_A
+#else
# define _GLIBCXX_STD_A std
-#endif
-
-#ifndef _GLIBCXX_STD_C
-# define _GLIBCXX_STD_C std
-#endif
-
-#ifndef _GLIBCXX_BEGIN_NAMESPACE_ALGO
-# define _GLIBCXX_BEGIN_NAMESPACE_ALGO
-#endif
-
-#ifndef _GLIBCXX_END_NAMESPACE_ALGO
-# define _GLIBCXX_END_NAMESPACE_ALGO
-#endif
-
-#ifndef _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
-# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
-#endif
-
-#ifndef _GLIBCXX_END_NAMESPACE_CONTAINER
-# define _GLIBCXX_END_NAMESPACE_CONTAINER
+# define _GLIBCXX_BEGIN_NAMESPACE_ALGO _GLIBCXX_BEGIN_NAMESPACE_VERSION
+# define _GLIBCXX_END_NAMESPACE_ALGO _GLIBCXX_END_NAMESPACE_VERSION
#endif
// GLIBCXX_ABI Deprecated
@@ -413,7 +446,7 @@ namespace std
#endif
// Debug Mode implies checking assertions.
-#ifdef _GLIBCXX_DEBUG
+#if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS)
# define _GLIBCXX_ASSERTIONS 1
#endif
@@ -424,9 +457,8 @@ namespace std
#endif
// Assert.
-#if !defined(_GLIBCXX_ASSERTIONS) && !defined(_GLIBCXX_PARALLEL)
-# define __glibcxx_assert(_Condition)
-#else
+#if defined(_GLIBCXX_ASSERTIONS) \
+ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS)
namespace std
{
// Avoid the use of assert, because we're trying to keep the <cassert>
@@ -440,7 +472,7 @@ namespace std
__builtin_abort();
}
}
-#define __glibcxx_assert(_Condition) \
+#define __glibcxx_assert_impl(_Condition) \
do \
{ \
if (! (_Condition)) \
@@ -449,6 +481,12 @@ namespace std
} while (false)
#endif
+#if defined(_GLIBCXX_ASSERTIONS)
+# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition)
+#else
+# define __glibcxx_assert(_Condition)
+#endif
+
// Macros for race detectors.
// _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and
// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain
@@ -532,6 +570,13 @@ namespace std
#define _GLIBCXX_TXN_SAFE_DYN
#endif
+#if __cplusplus > 201402L
+// In C++17 mathematical special functions are in namespace std.
+# define _GLIBCXX_USE_STD_SPEC_FUNCS 1
+#elif __cplusplus >= 201103L && __STDCPP_WANT_MATH_SPEC_FUNCS__ != 0
+// For C++11 and C++14 they are in namespace std when requested.
+# define _GLIBCXX_USE_STD_SPEC_FUNCS 1
+#endif
// The remainder of the prewritten config is automatic; all the
// user hooks are listed above.
diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h
index fd2da76650..75db5b8932 100644
--- a/libstdc++-v3/include/bits/char_traits.h
+++ b/libstdc++-v3/include/bits/char_traits.h
@@ -1,6 +1,6 @@
// Character Traits for use by standard string and iostream -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename _Char_types<_CharT>::off_type off_type;
typedef typename _Char_types<_CharT>::state_type state_type;
- static void
+ static _GLIBCXX14_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2)
{ __c1 = __c2; }
@@ -100,13 +100,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2)
{ return __c1 < __c2; }
- static int
+ static _GLIBCXX14_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
- static std::size_t
+ static _GLIBCXX14_CONSTEXPR std::size_t
length(const char_type* __s);
- static const char_type*
+ static _GLIBCXX14_CONSTEXPR const char_type*
find(const char_type* __s, std::size_t __n, const char_type& __a);
static char_type*
@@ -139,8 +139,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
};
+// #define __cpp_lib_constexpr_char_traits 201611
+
template<typename _CharT>
- int
+ _GLIBCXX14_CONSTEXPR int
char_traits<_CharT>::
compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
{
@@ -153,7 +155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _CharT>
- std::size_t
+ _GLIBCXX14_CONSTEXPR std::size_t
char_traits<_CharT>::
length(const char_type* __p)
{
@@ -164,7 +166,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _CharT>
- const typename char_traits<_CharT>::char_type*
+ _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
find(const char_type* __s, std::size_t __n, const char_type& __a)
{
@@ -238,7 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef streamoff off_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
@@ -254,7 +256,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
< static_cast<unsigned char>(__c2));
}
- static int
+ static /* _GLIBCXX17_CONSTEXPR */ int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
@@ -262,11 +264,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __builtin_memcmp(__s1, __s2, __n);
}
- static size_t
+ static /* _GLIBCXX17_CONSTEXPR */ size_t
length(const char_type* __s)
{ return __builtin_strlen(__s); }
- static const char_type*
+ static /* _GLIBCXX17_CONSTEXPR */ const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
if (__n == 0)
@@ -333,7 +335,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef wstreampos pos_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
@@ -345,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
- static int
+ static /* _GLIBCXX17_CONSTEXPR */ int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
@@ -353,11 +355,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return wmemcmp(__s1, __s2, __n);
}
- static size_t
+ static /* _GLIBCXX17_CONSTEXPR */ size_t
length(const char_type* __s)
{ return wcslen(__s); }
- static const char_type*
+ static /* _GLIBCXX17_CONSTEXPR */ const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
if (__n == 0)
@@ -432,7 +434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef u16streampos pos_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
@@ -444,7 +446,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
- static int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
@@ -455,7 +457,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return 0;
}
- static size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
size_t __i = 0;
@@ -464,7 +466,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __i;
}
- static const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
@@ -529,7 +531,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef u32streampos pos_type;
typedef mbstate_t state_type;
- static void
+ static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
@@ -541,7 +543,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
- static int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
@@ -552,7 +554,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return 0;
}
- static size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
size_t __i = 0;
@@ -561,7 +563,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __i;
}
- static const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
diff --git a/libstdc++-v3/include/bits/codecvt.h b/libstdc++-v3/include/bits/codecvt.h
index 8a335af6cf..fc2da321ab 100644
--- a/libstdc++-v3/include/bits/codecvt.h
+++ b/libstdc++-v3/include/bits/codecvt.h
@@ -1,6 +1,6 @@
// Locale support (codecvt) -*- C++ -*-
-// Copyright (C) 2000-2016 Free Software Foundation, Inc.
+// Copyright (C) 2000-2017 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
diff --git a/libstdc++-v3/include/bits/concept_check.h b/libstdc++-v3/include/bits/concept_check.h
index 11092c0a78..83a96f4dc9 100644
--- a/libstdc++-v3/include/bits/concept_check.h
+++ b/libstdc++-v3/include/bits/concept_check.h
@@ -1,6 +1,6 @@
// Concept-checking control -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h
index fff1e9949d..932360cd2f 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -1,6 +1,6 @@
// The -*- C++ -*- type traits classes for internal use in libstdc++
-// Copyright (C) 2000-2016 Free Software Foundation, Inc.
+// Copyright (C) 2000-2017 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
diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc
index b1dab643f3..38a6e82aae 100644
--- a/libstdc++-v3/include/bits/deque.tcc
+++ b/libstdc++-v3/include/bits/deque.tcc
@@ -1,6 +1,6 @@
// Deque implementation (out of line) -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -119,7 +119,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
const_iterator __mid = __x.begin() + difference_type(__len);
std::copy(__x.begin(), __mid, this->_M_impl._M_start);
- insert(this->_M_impl._M_finish, __mid, __x.end());
+ _M_range_insert_aux(this->_M_impl._M_finish, __mid, __x.end(),
+ std::random_access_iterator_tag());
}
}
return *this;
@@ -128,7 +129,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
template<typename... _Args>
+#if __cplusplus > 201402L
+ typename deque<_Tp, _Alloc>::reference
+#else
void
+#endif
deque<_Tp, _Alloc>::
emplace_front(_Args&&... __args)
{
@@ -141,11 +146,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
else
_M_push_front_aux(std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return front();
+#endif
}
template<typename _Tp, typename _Alloc>
template<typename... _Args>
+#if __cplusplus > 201402L
+ typename deque<_Tp, _Alloc>::reference
+#else
void
+#endif
deque<_Tp, _Alloc>::
emplace_back(_Args&&... __args)
{
@@ -159,6 +171,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
else
_M_push_back_aux(std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return back();
+#endif
}
#endif
@@ -280,7 +295,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (__first == __last)
_M_erase_at_end(__cur);
else
- insert(end(), __first, __last);
+ _M_range_insert_aux(end(), __first, __last,
+ std::__iterator_category(__first));
}
template <typename _Tp, typename _Alloc>
diff --git a/libstdc++-v3/include/bits/enable_special_members.h b/libstdc++-v3/include/bits/enable_special_members.h
index 1ac8f38935..2c35eb50ad 100644
--- a/libstdc++-v3/include/bits/enable_special_members.h
+++ b/libstdc++-v3/include/bits/enable_special_members.h
@@ -1,6 +1,6 @@
// <bits/enable_special_members.h> -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -36,13 +36,33 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ struct _Enable_default_constructor_tag
+ {
+ explicit constexpr _Enable_default_constructor_tag() = default;
+ };
+
/**
* @brief A mixin helper to conditionally enable or disable the default
* constructor.
* @sa _Enable_special_members
*/
template<bool _Switch, typename _Tag = void>
- struct _Enable_default_constructor { };
+ struct _Enable_default_constructor
+ {
+ constexpr _Enable_default_constructor() noexcept = default;
+ constexpr _Enable_default_constructor(_Enable_default_constructor const&)
+ noexcept = default;
+ constexpr _Enable_default_constructor(_Enable_default_constructor&&)
+ noexcept = default;
+ _Enable_default_constructor&
+ operator=(_Enable_default_constructor const&) noexcept = default;
+ _Enable_default_constructor&
+ operator=(_Enable_default_constructor&&) noexcept = default;
+
+ // Can be used in other ctors.
+ constexpr explicit
+ _Enable_default_constructor(_Enable_default_constructor_tag) { }
+ };
/**
@@ -86,7 +106,21 @@ template<bool _Default, bool _Destructor,
template<typename _Tag>
struct _Enable_default_constructor<false, _Tag>
- { constexpr _Enable_default_constructor() noexcept = delete; };
+ {
+ constexpr _Enable_default_constructor() noexcept = delete;
+ constexpr _Enable_default_constructor(_Enable_default_constructor const&)
+ noexcept = default;
+ constexpr _Enable_default_constructor(_Enable_default_constructor&&)
+ noexcept = default;
+ _Enable_default_constructor&
+ operator=(_Enable_default_constructor const&) noexcept = default;
+ _Enable_default_constructor&
+ operator=(_Enable_default_constructor&&) noexcept = default;
+
+ // Can be used in other ctors.
+ constexpr explicit
+ _Enable_default_constructor(_Enable_default_constructor_tag) { }
+ };
template<typename _Tag>
struct _Enable_destructor<false, _Tag>
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 2e8d39f712..c37bf01345 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -1,6 +1,6 @@
// <forward_list.h> -*- C++ -*-
-// Copyright (C) 2008-2016 Free Software Foundation, Inc.
+// Copyright (C) 2008-2017 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
@@ -566,8 +566,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @param __list A %forward_list of identical element and allocator
* types.
*
- * All the elements of @a __list are copied, but unlike the copy
- * constructor, the allocator object is not copied.
+ * All the elements of @a __list are copied.
+ *
+ * Whether the allocator is copied depends on the allocator traits.
*/
forward_list&
operator=(const forward_list& __list);
@@ -579,7 +580,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* The contents of @a __list are moved into this %forward_list
* (without copying, if the allocators permit it).
- * @a __list is a valid, but unspecified %forward_list
+ *
+ * Afterwards @a __list is a valid, but unspecified %forward_list
+ *
+ * Whether the allocator is moved depends on the allocator traits.
*/
forward_list&
operator=(forward_list&& __list)
@@ -617,7 +621,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %forward_list and
* that the number of elements of the resulting %forward_list is the
- * same as the number of elements assigned. Old data is lost.
+ * same as the number of elements assigned.
*/
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
@@ -636,7 +640,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* This function fills a %forward_list with @a __n copies of the
* given value. Note that the assignment completely changes the
* %forward_list, and that the resulting %forward_list has __n
- * elements. Old data is lost.
+ * elements.
*/
void
assign(size_type __n, const _Tp& __val)
@@ -793,10 +797,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* and references.
*/
template<typename... _Args>
- void
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
emplace_front(_Args&&... __args)
- { this->_M_insert_after(cbefore_begin(),
- std::forward<_Args>(__args)...); }
+ {
+ this->_M_insert_after(cbefore_begin(),
+ std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return front();
+#endif
+ }
/**
* @brief Add data to the front of the %forward_list.
@@ -991,6 +1004,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* time. Note that the global std::swap() function is
* specialized such that std::swap(l1,l2) will feed to this
* function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(forward_list& __list) noexcept
diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc
index 7cc630f06d..b823b09e1a 100644
--- a/libstdc++-v3/include/bits/forward_list.tcc
+++ b/libstdc++-v3/include/bits/forward_list.tcc
@@ -1,6 +1,6 @@
// <forward_list.tcc> -*- C++ -*-
-// Copyright (C) 2008-2016 Free Software Foundation, Inc.
+// Copyright (C) 2008-2017 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
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index a6e83f7ed9..b1beff86ab 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -1,6 +1,6 @@
// File based streams -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/functexcept.h b/libstdc++-v3/include/bits/functexcept.h
index 86ca5caab5..148351f9fa 100644
--- a/libstdc++-v3/include/bits/functexcept.h
+++ b/libstdc++-v3/include/bits/functexcept.h
@@ -1,6 +1,6 @@
// Function-Based Exception Support -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/functional_hash.h b/libstdc++-v3/include/bits/functional_hash.h
index def35f589e..38be1724d3 100644
--- a/libstdc++-v3/include/bits/functional_hash.h
+++ b/libstdc++-v3/include/bits/functional_hash.h
@@ -1,6 +1,6 @@
// functional_hash.h header -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
@@ -57,6 +57,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct hash;
+ template<typename _Tp, typename = void>
+ struct __poison_hash
+ {
+ static constexpr bool __enable_hash_call = false;
+ private:
+ // Private rather than deleted to be non-trivially-copyable.
+ __poison_hash(__poison_hash&&);
+ ~__poison_hash();
+ };
+
+ template<typename _Tp>
+ struct __poison_hash<_Tp, __void_t<decltype(hash<_Tp>()(declval<_Tp>()))>>
+ {
+ static constexpr bool __enable_hash_call = true;
+ };
+
// Helper struct for SFINAE-poisoning non-enum types.
template<typename _Tp, bool = is_enum<_Tp>::value>
struct __hash_enum
@@ -186,6 +202,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return hash(&__val, sizeof(__val), __hash); }
};
+ // A hash function similar to FNV-1a (see PR59406 for how it differs).
struct _Fnv_hash_impl
{
static size_t
diff --git a/libstdc++-v3/include/bits/gslice.h b/libstdc++-v3/include/bits/gslice.h
index d49adfe0f1..8909dfde03 100644
--- a/libstdc++-v3/include/bits/gslice.h
+++ b/libstdc++-v3/include/bits/gslice.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- gslice class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/gslice_array.h b/libstdc++-v3/include/bits/gslice_array.h
index 4f4ded0b84..dd4545017d 100644
--- a/libstdc++-v3/include/bits/gslice_array.h
+++ b/libstdc++-v3/include/bits/gslice_array.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- gslice_array class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 5748920cc7..bc7448bcf1 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -1,6 +1,6 @@
// hashtable.h header -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
@@ -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)
{
@@ -294,7 +297,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _ExtractKeya, typename _Equala,
typename _H1a, typename _H2a, typename _Hasha,
typename _RehashPolicya, typename _Traitsa,
- bool _Constant_iteratorsa, bool _Unique_keysa>
+ bool _Constant_iteratorsa>
friend struct __detail::_Insert;
public:
@@ -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;
@@ -475,8 +483,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
swap(_Hashtable&)
- noexcept(__is_nothrow_swappable<_H1>::value
- && __is_nothrow_swappable<_Equal>::value);
+ noexcept(__and_<__is_nothrow_swappable<_H1>,
+ __is_nothrow_swappable<_Equal>>::value);
// Basic container operations
iterator
@@ -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);
@@ -1236,8 +1373,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
swap(_Hashtable& __x)
- noexcept(__is_nothrow_swappable<_H1>::value
- && __is_nothrow_swappable<_Equal>::value)
+ noexcept(__and_<__is_nothrow_swappable<_H1>,
+ __is_nothrow_swappable<_Equal>>::value)
{
// The only base class with member variables is hash_code_base.
// We define _Hash_code_base::_M_swap because different
@@ -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/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index 7a2ac92f83..8af8c498de 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -1,6 +1,6 @@
// Internal policy header for unordered_set and unordered_map -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -31,6 +31,8 @@
#ifndef _HASHTABLE_POLICY_H
#define _HASHTABLE_POLICY_H 1
+#include <bits/stl_algobase.h> // for std::min.
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -457,6 +459,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// smallest prime that keeps the load factor small enough.
struct _Prime_rehash_policy
{
+ using __has_load_factor = std::true_type;
+
_Prime_rehash_policy(float __z = 1.0) noexcept
: _M_max_load_factor(__z), _M_next_resize(0) { }
@@ -501,6 +505,132 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
mutable std::size_t _M_next_resize;
};
+ /// Range hashing function assuming that second arg is a power of 2.
+ struct _Mask_range_hashing
+ {
+ typedef std::size_t first_argument_type;
+ typedef std::size_t second_argument_type;
+ typedef std::size_t result_type;
+
+ result_type
+ operator()(first_argument_type __num,
+ second_argument_type __den) const noexcept
+ { return __num & (__den - 1); }
+ };
+
+ /// Compute closest power of 2.
+ _GLIBCXX14_CONSTEXPR
+ inline std::size_t
+ __clp2(std::size_t __n) noexcept
+ {
+#if __SIZEOF_SIZE_T__ >= 8
+ std::uint_fast64_t __x = __n;
+#else
+ std::uint_fast32_t __x = __n;
+#endif
+ // Algorithm from Hacker's Delight, Figure 3-3.
+ __x = __x - 1;
+ __x = __x | (__x >> 1);
+ __x = __x | (__x >> 2);
+ __x = __x | (__x >> 4);
+ __x = __x | (__x >> 8);
+ __x = __x | (__x >>16);
+#if __SIZEOF_SIZE_T__ >= 8
+ __x = __x | (__x >>32);
+#endif
+ return __x + 1;
+ }
+
+ /// Rehash policy providing power of 2 bucket numbers. Avoids modulo
+ /// operations.
+ struct _Power2_rehash_policy
+ {
+ using __has_load_factor = std::true_type;
+
+ _Power2_rehash_policy(float __z = 1.0) noexcept
+ : _M_max_load_factor(__z), _M_next_resize(0) { }
+
+ float
+ max_load_factor() const noexcept
+ { return _M_max_load_factor; }
+
+ // Return a bucket size no smaller than n (as long as n is not above the
+ // highest power of 2).
+ std::size_t
+ _M_next_bkt(std::size_t __n) noexcept
+ {
+ const auto __max_width = std::min<size_t>(sizeof(size_t), 8);
+ const auto __max_bkt = size_t(1) << (__max_width * __CHAR_BIT__ - 1);
+ std::size_t __res = __clp2(__n);
+
+ if (__res == __n)
+ __res <<= 1;
+
+ if (__res == 0)
+ __res = __max_bkt;
+
+ if (__res == __max_bkt)
+ // Set next resize to the max value so that we never try to rehash again
+ // as we already reach the biggest possible bucket number.
+ // Note that it might result in max_load_factor not being respected.
+ _M_next_resize = std::size_t(-1);
+ else
+ _M_next_resize
+ = __builtin_ceil(__res * (long double)_M_max_load_factor);
+
+ return __res;
+ }
+
+ // Return a bucket count appropriate for n elements
+ std::size_t
+ _M_bkt_for_elements(std::size_t __n) const noexcept
+ { return __builtin_ceil(__n / (long double)_M_max_load_factor); }
+
+ // __n_bkt is current bucket count, __n_elt is current element count,
+ // and __n_ins is number of elements to be inserted. Do we need to
+ // increase bucket count? If so, return make_pair(true, n), where n
+ // is the new bucket count. If not, return make_pair(false, 0).
+ std::pair<bool, std::size_t>
+ _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
+ std::size_t __n_ins) noexcept
+ {
+ if (__n_elt + __n_ins >= _M_next_resize)
+ {
+ long double __min_bkts = (__n_elt + __n_ins)
+ / (long double)_M_max_load_factor;
+ if (__min_bkts >= __n_bkt)
+ return std::make_pair(true,
+ _M_next_bkt(std::max<std::size_t>(__builtin_floor(__min_bkts) + 1,
+ __n_bkt * _S_growth_factor)));
+
+ _M_next_resize
+ = __builtin_floor(__n_bkt * (long double)_M_max_load_factor);
+ return std::make_pair(false, 0);
+ }
+ else
+ return std::make_pair(false, 0);
+ }
+
+ typedef std::size_t _State;
+
+ _State
+ _M_state() const noexcept
+ { return _M_next_resize; }
+
+ void
+ _M_reset() noexcept
+ { _M_next_resize = 0; }
+
+ void
+ _M_reset(_State __state) noexcept
+ { _M_next_resize = __state; }
+
+ static const std::size_t _S_growth_factor = 2;
+
+ float _M_max_load_factor;
+ std::size_t _M_next_resize;
+ };
+
// Base classes for std::_Hashtable. We define these base classes
// because in some cases we want to do different things depending on
// the value of a policy class. In some cases the policy class
@@ -667,7 +797,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* Primary class template _Insert_base.
*
- * insert member functions appropriate to all _Hashtables.
+ * Defines @c insert member functions appropriate to all _Hashtables.
*/
template<typename _Key, typename _Value, typename _Alloc,
typename _ExtractKey, typename _Equal,
@@ -769,14 +899,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* Primary class template _Insert.
*
- * Select insert member functions appropriate to _Hashtable policy choices.
+ * Defines @c insert member functions that depend on _Hashtable policies,
+ * via partial specializations.
*/
template<typename _Key, typename _Value, typename _Alloc,
typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash,
typename _RehashPolicy, typename _Traits,
- bool _Constant_iterators = _Traits::__constant_iterators::value,
- bool _Unique_keys = _Traits::__unique_keys::value>
+ bool _Constant_iterators = _Traits::__constant_iterators::value>
struct _Insert;
/// Specialization.
@@ -785,65 +915,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _H1, typename _H2, typename _Hash,
typename _RehashPolicy, typename _Traits>
struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits, true, true>
+ _RehashPolicy, _Traits, true>
: public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>
{
using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
_Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>;
- using value_type = typename __base_type::value_type;
- using iterator = typename __base_type::iterator;
- using const_iterator = typename __base_type::const_iterator;
-
- using __unique_keys = typename __base_type::__unique_keys;
- using __hashtable = typename __base_type::__hashtable;
- using __node_gen_type = typename __base_type::__node_gen_type;
-
- using __base_type::insert;
- std::pair<iterator, bool>
- insert(value_type&& __v)
- {
- __hashtable& __h = this->_M_conjure_hashtable();
- __node_gen_type __node_gen(__h);
- return __h._M_insert(std::move(__v), __node_gen, __unique_keys());
- }
-
- iterator
- insert(const_iterator __hint, value_type&& __v)
- {
- __hashtable& __h = this->_M_conjure_hashtable();
- __node_gen_type __node_gen(__h);
- return __h._M_insert(__hint, std::move(__v), __node_gen,
- __unique_keys());
- }
- };
+ using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey,
+ _Equal, _H1, _H2, _Hash,
+ _Traits>;
- /// Specialization.
- template<typename _Key, typename _Value, typename _Alloc,
- typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash,
- typename _RehashPolicy, typename _Traits>
- struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits, true, false>
- : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>
- {
- using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
- _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits>;
using value_type = typename __base_type::value_type;
using iterator = typename __base_type::iterator;
using const_iterator = typename __base_type::const_iterator;
using __unique_keys = typename __base_type::__unique_keys;
+ using __ireturn_type = typename __hashtable_base::__ireturn_type;
using __hashtable = typename __base_type::__hashtable;
using __node_gen_type = typename __base_type::__node_gen_type;
using __base_type::insert;
- iterator
+ __ireturn_type
insert(value_type&& __v)
{
__hashtable& __h = this->_M_conjure_hashtable();
@@ -865,9 +960,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Key, typename _Value, typename _Alloc,
typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash,
- typename _RehashPolicy, typename _Traits, bool _Unique_keys>
+ typename _RehashPolicy, typename _Traits>
struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits, false, _Unique_keys>
+ _RehashPolicy, _Traits, false>
: public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>
{
@@ -911,28 +1006,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
+ template<typename _Policy>
+ using __has_load_factor = typename _Policy::__has_load_factor;
+
/**
* Primary class template _Rehash_base.
*
* Give hashtable the max_load_factor functions and reserve iff the
- * rehash policy is _Prime_rehash_policy.
+ * rehash policy supports it.
*/
template<typename _Key, typename _Value, typename _Alloc,
typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash,
- typename _RehashPolicy, typename _Traits>
+ typename _RehashPolicy, typename _Traits,
+ typename =
+ __detected_or_t<std::false_type, __has_load_factor, _RehashPolicy>>
struct _Rehash_base;
- /// Specialization.
+ /// Specialization when rehash policy doesn't provide load factor management.
template<typename _Key, typename _Value, typename _Alloc,
typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash, typename _Traits>
+ typename _H1, typename _H2, typename _Hash,
+ typename _RehashPolicy, typename _Traits>
+ struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+ _H1, _H2, _Hash, _RehashPolicy, _Traits,
+ std::false_type>
+ {
+ };
+
+ /// Specialization when rehash policy provide load factor management.
+ template<typename _Key, typename _Value, typename _Alloc,
+ typename _ExtractKey, typename _Equal,
+ typename _H1, typename _H2, typename _Hash,
+ typename _RehashPolicy, typename _Traits>
struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _Prime_rehash_policy, _Traits>
+ _H1, _H2, _Hash, _RehashPolicy, _Traits,
+ std::true_type>
{
using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
_Equal, _H1, _H2, _Hash,
- _Prime_rehash_policy, _Traits>;
+ _RehashPolicy, _Traits>;
float
max_load_factor() const noexcept
@@ -945,7 +1058,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
max_load_factor(float __z)
{
__hashtable* __this = static_cast<__hashtable*>(this);
- __this->__rehash_policy(_Prime_rehash_policy(__z));
+ __this->__rehash_policy(_RehashPolicy(__z));
}
void
diff --git a/libstdc++-v3/include/bits/indirect_array.h b/libstdc++-v3/include/bits/indirect_array.h
index 4eae4dc445..ed799707e8 100644
--- a/libstdc++-v3/include/bits/indirect_array.h
+++ b/libstdc++-v3/include/bits/indirect_array.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- indirect_array class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/invoke.h b/libstdc++-v3/include/bits/invoke.h
new file mode 100644
index 0000000000..eba8707435
--- /dev/null
+++ b/libstdc++-v3/include/bits/invoke.h
@@ -0,0 +1,104 @@
+// Implementation of INVOKE -*- C++ -*-
+
+// Copyright (C) 2016-2017 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/invoke.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{functional}
+ */
+
+#ifndef _GLIBCXX_INVOKE_H
+#define _GLIBCXX_INVOKE_H 1
+
+#pragma GCC system_header
+
+#if __cplusplus < 201103L
+# include <bits/c++0x_warning.h>
+#else
+
+#include <type_traits>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @addtogroup utilities
+ * @{
+ */
+
+ // Used by __invoke_impl instead of std::forward<_Tp> so that a
+ // reference_wrapper is converted to an lvalue-reference.
+ template<typename _Tp, typename _Up = typename __inv_unwrap<_Tp>::type>
+ constexpr _Up&&
+ __invfwd(typename remove_reference<_Tp>::type& __t) noexcept
+ { return static_cast<_Up&&>(__t); }
+
+ template<typename _Res, typename _Fn, typename... _Args>
+ constexpr _Res
+ __invoke_impl(__invoke_other, _Fn&& __f, _Args&&... __args)
+ { return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); }
+
+ template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
+ constexpr _Res
+ __invoke_impl(__invoke_memfun_ref, _MemFun&& __f, _Tp&& __t,
+ _Args&&... __args)
+ { return (__invfwd<_Tp>(__t).*__f)(std::forward<_Args>(__args)...); }
+
+ template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
+ constexpr _Res
+ __invoke_impl(__invoke_memfun_deref, _MemFun&& __f, _Tp&& __t,
+ _Args&&... __args)
+ {
+ return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...);
+ }
+
+ template<typename _Res, typename _MemPtr, typename _Tp>
+ constexpr _Res
+ __invoke_impl(__invoke_memobj_ref, _MemPtr&& __f, _Tp&& __t)
+ { return __invfwd<_Tp>(__t).*__f; }
+
+ template<typename _Res, typename _MemPtr, typename _Tp>
+ constexpr _Res
+ __invoke_impl(__invoke_memobj_deref, _MemPtr&& __f, _Tp&& __t)
+ { return (*std::forward<_Tp>(__t)).*__f; }
+
+ /// Invoke a callable object.
+ template<typename _Callable, typename... _Args>
+ constexpr typename __invoke_result<_Callable, _Args...>::type
+ __invoke(_Callable&& __fn, _Args&&... __args)
+ noexcept(__is_nothrow_invocable<_Callable, _Args...>::value)
+ {
+ using __result = __invoke_result<_Callable, _Args...>;
+ using __type = typename __result::type;
+ using __tag = typename __result::__invoke_type;
+ return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
+ std::forward<_Args>(__args)...);
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++11
+
+#endif // _GLIBCXX_INVOKE_H
diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h
index 97210d28f9..e5a107db4b 100644
--- a/libstdc++-v3/include/bits/ios_base.h
+++ b/libstdc++-v3/include/bits/ios_base.h
@@ -1,6 +1,6 @@
// Iostreams base classes -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -52,8 +52,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// The following definitions of bitmask types are enums, not ints,
// as permitted (but not required) in the standard, in order to provide
- // better type safety in iostream calls. A side effect is that
- // expressions involving them are no longer compile-time constants.
+ // better type safety in iostream calls. A side effect is that in C++98
+ // expressions involving them are not compile-time constants.
enum _Ios_Fmtflags
{
_S_boolalpha = 1L << 0,
@@ -207,12 +207,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const error_category& iostream_category() noexcept;
inline error_code
- make_error_code(io_errc e) noexcept
- { return error_code(static_cast<int>(e), iostream_category()); }
+ make_error_code(io_errc __e) noexcept
+ { return error_code(static_cast<int>(__e), iostream_category()); }
inline error_condition
- make_error_condition(io_errc e) noexcept
- { return error_condition(static_cast<int>(e), iostream_category()); }
+ make_error_condition(io_errc __e) noexcept
+ { return error_condition(static_cast<int>(__e), iostream_category()); }
#endif
// 27.4.2 Class ios_base
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index bc962adc94..b390f743bb 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -1,6 +1,6 @@
// istream classes -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc
index 8b3fe00cfc..fcb8353e09 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -1,6 +1,6 @@
// List implementation (out of line) -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -380,26 +380,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// 300. list::merge() specification incomplete
if (this != std::__addressof(__x))
{
- _M_check_equal_allocators(__x);
+ _M_check_equal_allocators(__x);
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
- while (__first1 != __last1 && __first2 != __last2)
- if (*__first2 < *__first1)
- {
- iterator __next = __first2;
- _M_transfer(__first1, __first2, ++__next);
- __first2 = __next;
- }
- else
- ++__first1;
- if (__first2 != __last2)
- _M_transfer(__last1, __first2, __last2);
+ const size_t __orig_size = __x.size();
+ __try {
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first2 < *__first1)
+ {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2)
+ _M_transfer(__last1, __first2, __last2);
- this->_M_inc_size(__x._M_get_size());
- __x._M_set_size(0);
+ this->_M_inc_size(__x._M_get_size());
+ __x._M_set_size(0);
+ }
+ __catch(...)
+ {
+ const size_t __dist = std::distance(__first2, __last2);
+ this->_M_inc_size(__orig_size - __dist);
+ __x._M_set_size(__dist);
+ __throw_exception_again;
+ }
}
}
@@ -423,20 +433,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
- while (__first1 != __last1 && __first2 != __last2)
- if (__comp(*__first2, *__first1))
- {
- iterator __next = __first2;
- _M_transfer(__first1, __first2, ++__next);
- __first2 = __next;
- }
- else
- ++__first1;
- if (__first2 != __last2)
- _M_transfer(__last1, __first2, __last2);
-
- this->_M_inc_size(__x._M_get_size());
- __x._M_set_size(0);
+ const size_t __orig_size = __x.size();
+ __try
+ {
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first2, *__first1))
+ {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2)
+ _M_transfer(__last1, __first2, __last2);
+
+ this->_M_inc_size(__x._M_get_size());
+ __x._M_set_size(0);
+ }
+ __catch(...)
+ {
+ const size_t __dist = std::distance(__first2, __last2);
+ this->_M_inc_size(__orig_size - __dist);
+ __x._M_set_size(__dist);
+ __throw_exception_again;
+ }
}
}
@@ -453,27 +474,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
list __tmp[64];
list * __fill = __tmp;
list * __counter;
-
- do
+ __try
{
- __carry.splice(__carry.begin(), *this, begin());
-
- for(__counter = __tmp;
- __counter != __fill && !__counter->empty();
- ++__counter)
+ do
{
- __counter->merge(__carry);
+ __carry.splice(__carry.begin(), *this, begin());
+
+ for(__counter = __tmp;
+ __counter != __fill && !__counter->empty();
+ ++__counter)
+ {
+ __counter->merge(__carry);
+ __carry.swap(*__counter);
+ }
__carry.swap(*__counter);
+ if (__counter == __fill)
+ ++__fill;
}
- __carry.swap(*__counter);
- if (__counter == __fill)
- ++__fill;
- }
- while ( !empty() );
+ while ( !empty() );
- for (__counter = __tmp + 1; __counter != __fill; ++__counter)
- __counter->merge(*(__counter - 1));
- swap( *(__fill - 1) );
+ for (__counter = __tmp + 1; __counter != __fill; ++__counter)
+ __counter->merge(*(__counter - 1));
+ swap( *(__fill - 1) );
+ }
+ __catch(...)
+ {
+ this->splice(this->end(), __carry);
+ for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
+ this->splice(this->end(), __tmp[__i]);
+ __throw_exception_again;
+ }
}
}
@@ -530,27 +560,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
list __tmp[64];
list * __fill = __tmp;
list * __counter;
-
- do
+ __try
{
- __carry.splice(__carry.begin(), *this, begin());
-
- for(__counter = __tmp;
- __counter != __fill && !__counter->empty();
- ++__counter)
+ do
{
- __counter->merge(__carry, __comp);
+ __carry.splice(__carry.begin(), *this, begin());
+
+ for(__counter = __tmp;
+ __counter != __fill && !__counter->empty();
+ ++__counter)
+ {
+ __counter->merge(__carry, __comp);
+ __carry.swap(*__counter);
+ }
__carry.swap(*__counter);
+ if (__counter == __fill)
+ ++__fill;
}
- __carry.swap(*__counter);
- if (__counter == __fill)
- ++__fill;
- }
- while ( !empty() );
+ while ( !empty() );
- for (__counter = __tmp + 1; __counter != __fill; ++__counter)
- __counter->merge(*(__counter - 1), __comp);
- swap(*(__fill - 1));
+ for (__counter = __tmp + 1; __counter != __fill; ++__counter)
+ __counter->merge(*(__counter - 1), __comp);
+ swap(*(__fill - 1));
+ }
+ __catch(...)
+ {
+ this->splice(this->end(), __carry);
+ for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
+ this->splice(this->end(), __tmp[__i]);
+ __throw_exception_again;
+ }
}
}
diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h
index 04b4ab3b1d..b63e9c8a3e 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -461,10 +461,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
- class __shim;
-
const facet* _M_sso_shim(const id*) const;
const facet* _M_cow_shim(const id*) const;
+
+ protected:
+ class __shim; // For internal use only.
};
diff --git a/libstdc++-v3/include/bits/locale_classes.tcc b/libstdc++-v3/include/bits/locale_classes.tcc
index 8e9426a8b9..71378f68b2 100644
--- a/libstdc++-v3/include/bits/locale_classes.tcc
+++ b/libstdc++-v3/include/bits/locale_classes.tcc
@@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h
index d4bec2fa8b..9b952d4516 100644
--- a/libstdc++-v3/include/bits/locale_conv.h
+++ b/libstdc++-v3/include/bits/locale_conv.h
@@ -1,6 +1,6 @@
// wstring_convert implementation -*- C++ -*-
-// Copyright (C) 2015-2016 Free Software Foundation, Inc.
+// Copyright (C) 2015-2017 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
@@ -81,7 +81,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& (__outstr.size() - __outchars) < __maxlen);
if (__result == codecvt_base::error)
- return false;
+ {
+ __count = __next - __first;
+ return false;
+ }
if (__result == codecvt_base::noconv)
{
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index e3e206b7d4..1ad0eb5ab6 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -1128,7 +1128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @return The converted char.
*/
virtual char
- do_narrow(char_type __c, char __dfault) const
+ do_narrow(char_type __c, char __dfault __attribute__((__unused__))) const
{ return __c; }
/**
@@ -1155,7 +1155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
virtual const char_type*
do_narrow(const char_type* __lo, const char_type* __hi,
- char __dfault, char* __to) const
+ char __dfault __attribute__((__unused__)), char* __to) const
{
__builtin_memcpy(__to, __lo, __hi - __lo);
return __hi;
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index c9523ec315..351190ccb0 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h
index 5685d72aff..0cd307fb5e 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.h
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.h
@@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
index 1a4f9a0e66..a449c41e6b 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
@@ -1,6 +1,6 @@
// Locale support -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
@@ -659,30 +659,38 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
// Abbreviated weekday name [tm_wday]
const char_type* __days1[7];
__tp._M_days_abbreviated(__days1);
- __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
+ __beg = _M_extract_name(__beg, __end, __mem, __days1,
7, __io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_wday = __mem;
break;
case 'A':
// Weekday name [tm_wday].
const char_type* __days2[7];
__tp._M_days(__days2);
- __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
+ __beg = _M_extract_name(__beg, __end, __mem, __days2,
7, __io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_wday = __mem;
break;
case 'h':
case 'b':
// Abbreviated month name [tm_mon]
const char_type* __months1[12];
__tp._M_months_abbreviated(__months1);
- __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
+ __beg = _M_extract_name(__beg, __end, __mem,
__months1, 12, __io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_mon = __mem;
break;
case 'B':
// Month name [tm_mon].
const char_type* __months2[12];
__tp._M_months(__months2);
- __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
+ __beg = _M_extract_name(__beg, __end, __mem,
__months2, 12, __io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_mon = __mem;
break;
case 'c':
// Default time and date representation.
@@ -693,18 +701,22 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
break;
case 'd':
// Day [01, 31]. [tm_mday]
- __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
+ __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2,
__io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_mday = __mem;
break;
case 'e':
// Day [1, 31], with single digits preceded by
// space. [tm_mday]
if (__ctype.is(ctype_base::space, *__beg))
- __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
+ __beg = _M_extract_num(++__beg, __end, __mem, 1, 9,
1, __io, __tmperr);
else
- __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
+ __beg = _M_extract_num(__beg, __end, __mem, 10, 31,
2, __io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_mday = __mem;
break;
case 'D':
// Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
@@ -715,13 +727,17 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
break;
case 'H':
// Hour [00, 23]. [tm_hour]
- __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
+ __beg = _M_extract_num(__beg, __end, __mem, 0, 23, 2,
__io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_hour = __mem;
break;
case 'I':
// Hour [01, 12]. [tm_hour]
- __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
+ __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
__io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_hour = __mem;
break;
case 'm':
// Month [01, 12]. [tm_mon]
@@ -732,8 +748,10 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
break;
case 'M':
// Minute [00, 59]. [tm_min]
- __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
+ __beg = _M_extract_num(__beg, __end, __mem, 0, 59, 2,
__io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_min = __mem;
break;
case 'n':
if (__ctype.narrow(*__beg, 0) == '\n')
@@ -752,11 +770,13 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
// Seconds. [tm_sec]
// [00, 60] in C99 (one leap-second), [00, 61] in C89.
#if _GLIBCXX_USE_C99
- __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2,
+ __beg = _M_extract_num(__beg, __end, __mem, 0, 60, 2,
#else
- __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2,
+ __beg = _M_extract_num(__beg, __end, __mem, 0, 61, 2,
#endif
__io, __tmperr);
+ if (!__tmperr)
+ __tm->tm_sec = __mem;
break;
case 't':
if (__ctype.narrow(*__beg, 0) == '\t')
diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h
index 61579d45ff..ae302e26e1 100644
--- a/libstdc++-v3/include/bits/localefwd.h
+++ b/libstdc++-v3/include/bits/localefwd.h
@@ -1,6 +1,6 @@
// <locale> Forward declarations -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/mask_array.h b/libstdc++-v3/include/bits/mask_array.h
index ba7828266c..5c4fcc6763 100644
--- a/libstdc++-v3/include/bits/mask_array.h
+++ b/libstdc++-v3/include/bits/mask_array.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- mask_array class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -136,8 +136,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
template<typename _Tp>
- inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& a)
- : _M_sz(a._M_sz), _M_mask(a._M_mask), _M_array(a._M_array) {}
+ inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& __a)
+ : _M_sz(__a._M_sz), _M_mask(__a._M_mask), _M_array(__a._M_array) {}
template<typename _Tp>
inline
diff --git a/libstdc++-v3/include/bits/memoryfwd.h b/libstdc++-v3/include/bits/memoryfwd.h
index 8ef0076cbc..1429026c4c 100644
--- a/libstdc++-v3/include/bits/memoryfwd.h
+++ b/libstdc++-v3/include/bits/memoryfwd.h
@@ -1,6 +1,6 @@
// <memory> Forward declarations -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index afcea2d846..5f47b0e7ba 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -1,6 +1,6 @@
-// Move, forward and identity for C++0x + swap -*- C++ -*-
+// Move, forward and identity for C++11 + swap -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
@@ -43,12 +43,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @ingroup utilities
*/
template<typename _Tp>
- inline _Tp*
+ inline _GLIBCXX_CONSTEXPR _Tp*
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
- {
- return reinterpret_cast<_Tp*>
- (&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
- }
+ { return __builtin_addressof(__r); }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -123,6 +120,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// declval, from type_traits.
+#if __cplusplus > 201402L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2296. std::addressof should be constexpr
+# define __cpp_lib_addressof_constexpr 201603
+#endif
/**
* @brief Returns the actual address of the object or function
* referenced by r, even in the presence of an overloaded
@@ -131,10 +133,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @return The actual address.
*/
template<typename _Tp>
- inline _Tp*
+ inline _GLIBCXX17_CONSTEXPR _Tp*
addressof(_Tp& __r) noexcept
{ return std::__addressof(__r); }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2598. addressof works on temporaries
+ template<typename _Tp>
+ const _Tp* addressof(const _Tp&&) = delete;
+
// C++11 version of std::exchange for internal use.
template <typename _Tp, typename _Up = _Tp>
inline _Tp
@@ -174,7 +181,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
inline
#if __cplusplus >= 201103L
- typename enable_if<__and_<is_move_constructible<_Tp>,
+ typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
+ is_move_constructible<_Tp>,
is_move_assignable<_Tp>>::value>::type
swap(_Tp& __a, _Tp& __b)
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
diff --git a/libstdc++-v3/include/bits/node_handle.h b/libstdc++-v3/include/bits/node_handle.h
new file mode 100644
index 0000000000..44a92644cd
--- /dev/null
+++ b/libstdc++-v3/include/bits/node_handle.h
@@ -0,0 +1,328 @@
+// Node handles for containers -*- C++ -*-
+
+// Copyright (C) 2016-2017 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>;
+
+ _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/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc
index c3a4ec3a66..e96bad8121 100644
--- a/libstdc++-v3/include/bits/ostream.tcc
+++ b/libstdc++-v3/include/bits/ostream.tcc
@@ -1,6 +1,6 @@
// ostream classes -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/ostream_insert.h b/libstdc++-v3/include/bits/ostream_insert.h
index 8ff0a4519c..8c9b941a16 100644
--- a/libstdc++-v3/include/bits/ostream_insert.h
+++ b/libstdc++-v3/include/bits/ostream_insert.h
@@ -1,6 +1,6 @@
// Helpers for ostream inserters -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
diff --git a/libstdc++-v3/include/bits/parse_numbers.h b/libstdc++-v3/include/bits/parse_numbers.h
index 7aa43fc2ba..b82df75510 100644
--- a/libstdc++-v3/include/bits/parse_numbers.h
+++ b/libstdc++-v3/include/bits/parse_numbers.h
@@ -1,6 +1,6 @@
// Components for compile-time parsing of numbers -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
diff --git a/libstdc++-v3/include/bits/postypes.h b/libstdc++-v3/include/bits/postypes.h
index f63571eeb8..818086313f 100644
--- a/libstdc++-v3/include/bits/postypes.h
+++ b/libstdc++-v3/include/bits/postypes.h
@@ -1,6 +1,6 @@
// Position types -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -41,7 +41,7 @@
// XXX If <stdint.h> is really needed, make sure to define the macros
// before including it, in order not to break <tr1/cstdint> (and <cstdint>
-// in C++0x). Reconsider all this as soon as possible...
+// in C++11). Reconsider all this as soon as possible...
#if (defined(_GLIBCXX_HAVE_INT64_T) && !defined(_GLIBCXX_HAVE_INT64_T_LONG) \
&& !defined(_GLIBCXX_HAVE_INT64_T_LONG_LONG))
diff --git a/libstdc++-v3/include/bits/predefined_ops.h b/libstdc++-v3/include/bits/predefined_ops.h
index 3c4cb6d26a..0624a38a1b 100644
--- a/libstdc++-v3/include/bits/predefined_ops.h
+++ b/libstdc++-v3/include/bits/predefined_ops.h
@@ -1,6 +1,6 @@
// Default predicates for internal use -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -24,7 +24,7 @@
/** @file predefined_ops.h
* This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
+ * You should not attempt to use it directly. @headername{algorithm}
*/
#ifndef _GLIBCXX_PREDEFINED_OPS_H
@@ -42,6 +42,7 @@ namespace __ops
operator()(_Iterator1 __it1, _Iterator2 __it2) const
{ return *__it1 < *__it2; }
};
+
_GLIBCXX14_CONSTEXPR
inline _Iter_less_iter
__iter_less_iter()
@@ -49,11 +50,20 @@ namespace __ops
struct _Iter_less_val
{
+#if __cplusplus >= 201103L
+ constexpr _Iter_less_val() = default;
+#else
+ _Iter_less_val() { }
+#endif
+
+ explicit
+ _Iter_less_val(_Iter_less_iter) { }
+
template<typename _Iterator, typename _Value>
bool
operator()(_Iterator __it, _Value& __val) const
{ return *__it < __val; }
- };
+ };
inline _Iter_less_val
__iter_less_val()
@@ -65,11 +75,20 @@ namespace __ops
struct _Val_less_iter
{
+#if __cplusplus >= 201103L
+ constexpr _Val_less_iter() = default;
+#else
+ _Val_less_iter() { }
+#endif
+
+ explicit
+ _Val_less_iter(_Iter_less_iter) { }
+
template<typename _Value, typename _Iterator>
bool
operator()(_Value& __val, _Iterator __it) const
{ return __val < *__it; }
- };
+ };
inline _Val_less_iter
__val_less_iter()
@@ -85,7 +104,7 @@ namespace __ops
bool
operator()(_Iterator1 __it1, _Iterator2 __it2) const
{ return *__it1 == *__it2; }
- };
+ };
inline _Iter_equal_to_iter
__iter_equal_to_iter()
@@ -97,7 +116,7 @@ namespace __ops
bool
operator()(_Iterator __it, _Value& __val) const
{ return *__it == __val; }
- };
+ };
inline _Iter_equal_to_val
__iter_equal_to_val()
@@ -111,9 +130,10 @@ namespace __ops
struct _Iter_comp_iter
{
_Compare _M_comp;
- _GLIBCXX14_CONSTEXPR
+
+ explicit _GLIBCXX14_CONSTEXPR
_Iter_comp_iter(_Compare __comp)
- : _M_comp(__comp)
+ : _M_comp(_GLIBCXX_MOVE(__comp))
{ }
template<typename _Iterator1, typename _Iterator2>
@@ -127,17 +147,30 @@ namespace __ops
_GLIBCXX14_CONSTEXPR
inline _Iter_comp_iter<_Compare>
__iter_comp_iter(_Compare __comp)
- { return _Iter_comp_iter<_Compare>(__comp); }
+ { return _Iter_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
struct _Iter_comp_val
{
_Compare _M_comp;
+ explicit
_Iter_comp_val(_Compare __comp)
- : _M_comp(__comp)
+ : _M_comp(_GLIBCXX_MOVE(__comp))
+ { }
+
+ explicit
+ _Iter_comp_val(const _Iter_comp_iter<_Compare>& __comp)
+ : _M_comp(__comp._M_comp)
{ }
+#if __cplusplus >= 201103L
+ explicit
+ _Iter_comp_val(_Iter_comp_iter<_Compare>&& __comp)
+ : _M_comp(std::move(__comp._M_comp))
+ { }
+#endif
+
template<typename _Iterator, typename _Value>
bool
operator()(_Iterator __it, _Value& __val)
@@ -147,22 +180,35 @@ namespace __ops
template<typename _Compare>
inline _Iter_comp_val<_Compare>
__iter_comp_val(_Compare __comp)
- { return _Iter_comp_val<_Compare>(__comp); }
+ { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
inline _Iter_comp_val<_Compare>
__iter_comp_val(_Iter_comp_iter<_Compare> __comp)
- { return _Iter_comp_val<_Compare>(__comp._M_comp); }
+ { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
struct _Val_comp_iter
{
_Compare _M_comp;
+ explicit
_Val_comp_iter(_Compare __comp)
- : _M_comp(__comp)
+ : _M_comp(_GLIBCXX_MOVE(__comp))
{ }
+ explicit
+ _Val_comp_iter(const _Iter_comp_iter<_Compare>& __comp)
+ : _M_comp(__comp._M_comp)
+ { }
+
+#if __cplusplus >= 201103L
+ explicit
+ _Val_comp_iter(_Iter_comp_iter<_Compare>&& __comp)
+ : _M_comp(std::move(__comp._M_comp))
+ { }
+#endif
+
template<typename _Value, typename _Iterator>
bool
operator()(_Value& __val, _Iterator __it)
@@ -172,18 +218,19 @@ namespace __ops
template<typename _Compare>
inline _Val_comp_iter<_Compare>
__val_comp_iter(_Compare __comp)
- { return _Val_comp_iter<_Compare>(__comp); }
+ { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
inline _Val_comp_iter<_Compare>
__val_comp_iter(_Iter_comp_iter<_Compare> __comp)
- { return _Val_comp_iter<_Compare>(__comp._M_comp); }
+ { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Value>
struct _Iter_equals_val
{
_Value& _M_value;
+ explicit
_Iter_equals_val(_Value& __value)
: _M_value(__value)
{ }
@@ -202,16 +249,17 @@ namespace __ops
template<typename _Iterator1>
struct _Iter_equals_iter
{
- typename std::iterator_traits<_Iterator1>::reference _M_ref;
+ _Iterator1 _M_it1;
+ explicit
_Iter_equals_iter(_Iterator1 __it1)
- : _M_ref(*__it1)
+ : _M_it1(__it1)
{ }
template<typename _Iterator2>
bool
operator()(_Iterator2 __it2)
- { return *__it2 == _M_ref; }
+ { return *__it2 == *_M_it1; }
};
template<typename _Iterator>
@@ -224,8 +272,9 @@ namespace __ops
{
_Predicate _M_pred;
+ explicit
_Iter_pred(_Predicate __pred)
- : _M_pred(__pred)
+ : _M_pred(_GLIBCXX_MOVE(__pred))
{ }
template<typename _Iterator>
@@ -237,7 +286,7 @@ namespace __ops
template<typename _Predicate>
inline _Iter_pred<_Predicate>
__pred_iter(_Predicate __pred)
- { return _Iter_pred<_Predicate>(__pred); }
+ { return _Iter_pred<_Predicate>(_GLIBCXX_MOVE(__pred)); }
template<typename _Compare, typename _Value>
struct _Iter_comp_to_val
@@ -246,7 +295,7 @@ namespace __ops
_Value& _M_value;
_Iter_comp_to_val(_Compare __comp, _Value& __value)
- : _M_comp(__comp), _M_value(__value)
+ : _M_comp(_GLIBCXX_MOVE(__comp)), _M_value(__value)
{ }
template<typename _Iterator>
@@ -258,36 +307,42 @@ namespace __ops
template<typename _Compare, typename _Value>
_Iter_comp_to_val<_Compare, _Value>
__iter_comp_val(_Compare __comp, _Value &__val)
- { return _Iter_comp_to_val<_Compare, _Value>(__comp, __val); }
+ {
+ return _Iter_comp_to_val<_Compare, _Value>(_GLIBCXX_MOVE(__comp), __val);
+ }
template<typename _Compare, typename _Iterator1>
struct _Iter_comp_to_iter
{
_Compare _M_comp;
- typename std::iterator_traits<_Iterator1>::reference _M_ref;
+ _Iterator1 _M_it1;
_Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1)
- : _M_comp(__comp), _M_ref(*__it1)
+ : _M_comp(_GLIBCXX_MOVE(__comp)), _M_it1(__it1)
{ }
template<typename _Iterator2>
bool
operator()(_Iterator2 __it2)
- { return bool(_M_comp(*__it2, _M_ref)); }
+ { return bool(_M_comp(*__it2, *_M_it1)); }
};
template<typename _Compare, typename _Iterator>
inline _Iter_comp_to_iter<_Compare, _Iterator>
__iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it)
- { return _Iter_comp_to_iter<_Compare, _Iterator>(__comp._M_comp, __it); }
+ {
+ return _Iter_comp_to_iter<_Compare, _Iterator>(
+ _GLIBCXX_MOVE(__comp._M_comp), __it);
+ }
template<typename _Predicate>
struct _Iter_negate
{
_Predicate _M_pred;
+ explicit
_Iter_negate(_Predicate __pred)
- : _M_pred(__pred)
+ : _M_pred(_GLIBCXX_MOVE(__pred))
{ }
template<typename _Iterator>
@@ -299,7 +354,7 @@ namespace __ops
template<typename _Predicate>
inline _Iter_negate<_Predicate>
__negate(_Iter_pred<_Predicate> __pred)
- { return _Iter_negate<_Predicate>(__pred._M_pred); }
+ { return _Iter_negate<_Predicate>(_GLIBCXX_MOVE(__pred._M_pred)); }
} // namespace __ops
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h
index 023f21efc7..797e7fcec3 100644
--- a/libstdc++-v3/include/bits/ptr_traits.h
+++ b/libstdc++-v3/include/bits/ptr_traits.h
@@ -1,6 +1,6 @@
// Pointer Traits -*- C++ -*-
-// Copyright (C) 2011-2016 Free Software Foundation, Inc.
+// Copyright (C) 2011-2017 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
@@ -56,7 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Given Template<T, ...> and U return Template<U, ...>, otherwise invalid.
template<typename _Tp, typename _Up>
struct __replace_first_arg
- { using type = __undefined; };
+ { };
template<template<typename, typename...> class _Template, typename _Up,
typename _Tp, typename... _Types>
@@ -84,8 +84,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
using __difference_type = typename _Tp::difference_type;
+ template<typename _Tp, typename _Up, typename = void>
+ struct __rebind : __replace_first_arg<_Tp, _Up> { };
+
template<typename _Tp, typename _Up>
- using __rebind = typename _Tp::template rebind<_Up>;
+ struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>>>
+ { using type = typename _Tp::template rebind<_Up>; };
public:
/// The pointer type.
@@ -93,7 +97,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// The type pointed to.
using element_type
- = __detected_or_t_<__get_first_arg_t, __element_type, _Ptr>;
+ = __detected_or_t<__get_first_arg_t<_Ptr>, __element_type, _Ptr>;
/// The type used to represent the difference between two pointers.
using difference_type
@@ -101,8 +105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// A pointer to a different type.
template<typename _Up>
- using rebind
- = __detected_or_t_<__replace_first_arg_t, __rebind, _Ptr, _Up>;
+ using rebind = typename __rebind<_Ptr, _Up>::type;
static _Ptr
pointer_to(__make_not_void<element_type>& __e)
@@ -110,8 +113,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_assert(!is_same<element_type, __undefined>::value,
"pointer type defines element_type or is like SomePointer<T, Args>");
- static_assert(!is_same<rebind<element_type>, __undefined>::value,
- "pointer type defines rebind<U> or is like SomePointer<T, Args>");
};
/**
diff --git a/libstdc++-v3/include/bits/quoted_string.h b/libstdc++-v3/include/bits/quoted_string.h
index 1326d9fdf0..10cfec2118 100644
--- a/libstdc++-v3/include/bits/quoted_string.h
+++ b/libstdc++-v3/include/bits/quoted_string.h
@@ -1,6 +1,6 @@
// Helpers for quoted stream manipulators -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index 9de480c021..d39cc3e066 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -1,6 +1,6 @@
// random number generation -*- C++ -*-
-// Copyright (C) 2009-2016 Free Software Foundation, Inc.
+// Copyright (C) 2009-2017 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
@@ -158,7 +158,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
struct _Adaptor
{
static_assert(std::is_floating_point<_DInputType>::value,
- "template argument not a floating point type");
+ "template argument must be a floating point type");
public:
_Adaptor(_Engine& __g)
@@ -235,8 +235,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
class linear_congruential_engine
{
- static_assert(std::is_unsigned<_UIntType>::value, "template argument "
- "substituting _UIntType not an unsigned integral type");
+ static_assert(std::is_unsigned<_UIntType>::value,
+ "result_type must be an unsigned integral type");
static_assert(__m == 0u || (__a < __m && __c < __m),
"template argument substituting __m out of bounds");
@@ -443,8 +443,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_UIntType __c, size_t __l, _UIntType __f>
class mersenne_twister_engine
{
- static_assert(std::is_unsigned<_UIntType>::value, "template argument "
- "substituting _UIntType not an unsigned integral type");
+ static_assert(std::is_unsigned<_UIntType>::value,
+ "result_type must be an unsigned integral type");
static_assert(1u <= __m && __m <= __n,
"template argument substituting __m out of bounds");
static_assert(__r <= __w, "template argument substituting "
@@ -658,10 +658,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _UIntType, size_t __w, size_t __s, size_t __r>
class subtract_with_carry_engine
{
- static_assert(std::is_unsigned<_UIntType>::value, "template argument "
- "substituting _UIntType not an unsigned integral type");
+ static_assert(std::is_unsigned<_UIntType>::value,
+ "result_type must be an unsigned integral type");
static_assert(0u < __s && __s < __r,
- "template argument substituting __s out of bounds");
+ "0 < s < r");
static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
"template argument substituting __w out of bounds");
@@ -1065,8 +1065,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
class independent_bits_engine
{
- static_assert(std::is_unsigned<_UIntType>::value, "template argument "
- "substituting _UIntType not an unsigned integral type");
+ static_assert(std::is_unsigned<_UIntType>::value,
+ "result_type must be an unsigned integral type");
static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
"template argument substituting __w out of bounds");
@@ -1278,7 +1278,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Produces random numbers by combining random numbers from some
* base engine to produce random numbers with a specifies number of bits
- * @p __w.
+ * @p __k.
*/
template<typename _RandomNumberEngine, size_t __k>
class shuffle_order_engine
@@ -1702,11 +1702,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class uniform_real_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -1732,6 +1733,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_a;
_RealType _M_b;
@@ -1920,11 +1925,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class normal_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -1951,6 +1957,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return (__p1._M_mean == __p2._M_mean
&& __p1._M_stddev == __p2._M_stddev); }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_mean;
_RealType _M_stddev;
@@ -2133,11 +2143,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class lognormal_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -2161,6 +2172,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_m;
_RealType _M_s;
@@ -2337,11 +2352,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class gamma_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -2370,6 +2386,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return (__p1._M_alpha == __p2._M_alpha
&& __p1._M_beta == __p2._M_beta); }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
void
_M_initialize();
@@ -2554,11 +2574,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class chi_squared_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -2577,6 +2598,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_n == __p2._M_n; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_n;
};
@@ -2764,11 +2789,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class cauchy_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -2792,6 +2818,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_a;
_RealType _M_b;
@@ -2965,11 +2995,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class fisher_f_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -2993,6 +3024,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_m;
_RealType _M_n;
@@ -3189,11 +3224,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class student_t_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -3212,6 +3248,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_n == __p2._M_n; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_n;
};
@@ -3409,6 +3449,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public:
/** The type of the range of the distribution. */
typedef bool result_type;
+
/** Parameter type. */
struct param_type
{
@@ -3429,6 +3470,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_p == __p2._M_p; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
double _M_p;
};
@@ -3612,11 +3657,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class binomial_distribution
{
static_assert(std::is_integral<_IntType>::value,
- "template argument not an integral type");
+ "result_type must be an integral type");
public:
/** The type of the range of the distribution. */
typedef _IntType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -3645,6 +3691,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
void
_M_initialize();
@@ -3843,11 +3893,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class geometric_distribution
{
static_assert(std::is_integral<_IntType>::value,
- "template argument not an integral type");
+ "result_type must be an integral type");
public:
/** The type of the range of the distribution. */
typedef _IntType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -3870,6 +3921,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_p == __p2._M_p; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
void
_M_initialize()
@@ -4043,11 +4098,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class negative_binomial_distribution
{
static_assert(std::is_integral<_IntType>::value,
- "template argument not an integral type");
+ "result_type must be an integral type");
public:
/** The type of the range of the distribution. */
typedef _IntType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -4072,6 +4128,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_IntType _M_k;
double _M_p;
@@ -4265,11 +4325,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class poisson_distribution
{
static_assert(std::is_integral<_IntType>::value,
- "template argument not an integral type");
+ "result_type must be an integral type");
public:
/** The type of the range of the distribution. */
typedef _IntType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -4292,6 +4353,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_mean == __p2._M_mean; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
// Hosts either log(mean) or the threshold of the simple method.
void
@@ -4481,11 +4546,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class exponential_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -4506,6 +4572,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_lambda == __p2._M_lambda; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_lambda;
};
@@ -4683,11 +4753,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class weibull_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -4711,6 +4782,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_a;
_RealType _M_b;
@@ -4886,11 +4961,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class extreme_value_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -4914,6 +4990,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_RealType _M_a;
_RealType _M_b;
@@ -5086,11 +5166,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class discrete_distribution
{
static_assert(std::is_integral<_IntType>::value,
- "template argument not an integral type");
+ "result_type must be an integral type");
public:
/** The type of the range of the distribution. */
typedef _IntType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -5127,6 +5208,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_prob == __p2._M_prob; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
void
_M_initialize();
@@ -5316,11 +5401,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class piecewise_constant_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -5368,6 +5454,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
void
_M_initialize();
@@ -5583,11 +5673,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class piecewise_linear_distribution
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "result_type must be a floating point type");
public:
/** The type of the range of the distribution. */
typedef _RealType result_type;
+
/** Parameter type. */
struct param_type
{
@@ -5633,8 +5724,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend bool
operator==(const param_type& __p1, const param_type& __p2)
- { return (__p1._M_int == __p2._M_int
- && __p1._M_den == __p2._M_den); }
+ { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
+
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
private:
void
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index 7dfc721e55..df05ebea6e 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -1,6 +1,6 @@
// random number generation (out of line) -*- C++ -*-
-// Copyright (C) 2009-2016 Free Software Foundation, Inc.
+// Copyright (C) 2009-2017 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
@@ -3312,7 +3312,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
generate_canonical(_UniformRandomNumberGenerator& __urng)
{
static_assert(std::is_floating_point<_RealType>::value,
- "template argument not a floating point type");
+ "template argument must be a floating point type");
const size_t __b
= std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits),
@@ -3323,18 +3323,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const size_t __m = std::max<size_t>(1UL,
(__b + __log2r - 1UL) / __log2r);
_RealType __ret;
- do
+ _RealType __sum = _RealType(0);
+ _RealType __tmp = _RealType(1);
+ for (size_t __k = __m; __k != 0; --__k)
{
- _RealType __sum = _RealType(0);
- _RealType __tmp = _RealType(1);
- for (size_t __k = __m; __k != 0; --__k)
- {
- __sum += _RealType(__urng() - __urng.min()) * __tmp;
- __tmp *= __r;
- }
- __ret = __sum / __tmp;
+ __sum += _RealType(__urng() - __urng.min()) * __tmp;
+ __tmp *= __r;
+ }
+ __ret = __sum / __tmp;
+ if (__builtin_expect(__ret >= _RealType(1), 0))
+ {
+#if _GLIBCXX_USE_C99_MATH_TR1
+ __ret = std::nextafter(_RealType(1), _RealType(0));
+#else
+ __ret = _RealType(1)
+ - std::numeric_limits<_RealType>::epsilon() / _RealType(2);
+#endif
}
- while (__builtin_expect(__ret >= _RealType(1), 0));
return __ret;
}
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index e2ec072671..3987c2addf 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -1,6 +1,6 @@
// <range_access.h> -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -44,7 +44,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
begin(_Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
@@ -54,7 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
begin(const _Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
@@ -64,7 +64,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
end(_Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
@@ -74,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
end(const _Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
@@ -134,7 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rbegin(_Container& __cont) -> decltype(__cont.rbegin())
{ return __cont.rbegin(); }
@@ -144,7 +144,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
{ return __cont.rbegin(); }
@@ -154,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rend(_Container& __cont) -> decltype(__cont.rend())
{ return __cont.rend(); }
@@ -164,7 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rend(const _Container& __cont) -> decltype(__cont.rend())
{ return __cont.rend(); }
@@ -174,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
- inline reverse_iterator<_Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
rbegin(_Tp (&__arr)[_Nm])
{ return reverse_iterator<_Tp*>(__arr + _Nm); }
@@ -184,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
- inline reverse_iterator<_Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
rend(_Tp (&__arr)[_Nm])
{ return reverse_iterator<_Tp*>(__arr); }
@@ -194,7 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __il initializer_list.
*/
template<typename _Tp>
- inline reverse_iterator<const _Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
rbegin(initializer_list<_Tp> __il)
{ return reverse_iterator<const _Tp*>(__il.end()); }
@@ -204,7 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __il initializer_list.
*/
template<typename _Tp>
- inline reverse_iterator<const _Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
rend(initializer_list<_Tp> __il)
{ return reverse_iterator<const _Tp*>(__il.begin()); }
@@ -214,7 +214,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
{ return std::rbegin(__cont); }
@@ -224,7 +224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
crend(const _Container& __cont) -> decltype(std::rend(__cont))
{ return std::rend(__cont); }
diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h
new file mode 100644
index 0000000000..124ee97bd2
--- /dev/null
+++ b/libstdc++-v3/include/bits/refwrap.h
@@ -0,0 +1,383 @@
+// Implementation of std::reference_wrapper -*- C++ -*-
+
+// Copyright (C) 2004-2017 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/bind.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{functional}
+ */
+
+#ifndef _GLIBCXX_REFWRAP_H
+#define _GLIBCXX_REFWRAP_H 1
+
+#pragma GCC system_header
+
+#if __cplusplus < 201103L
+# include <bits/c++0x_warning.h>
+#else
+
+#include <bits/move.h>
+#include <bits/invoke.h>
+#include <bits/stl_function.h> // for unary_function and binary_function
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /// If we have found a result_type, extract it.
+ template<typename _Functor, typename = __void_t<>>
+ struct _Maybe_get_result_type
+ { };
+
+ template<typename _Functor>
+ struct _Maybe_get_result_type<_Functor,
+ __void_t<typename _Functor::result_type>>
+ { typedef typename _Functor::result_type result_type; };
+
+ /**
+ * Base class for any function object that has a weak result type, as
+ * defined in 20.8.2 [func.require] of C++11.
+ */
+ template<typename _Functor>
+ struct _Weak_result_type_impl
+ : _Maybe_get_result_type<_Functor>
+ { };
+
+ /// Retrieve the result type for a function type.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes...)>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes......)>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes...) volatile>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes......) volatile>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes...) const volatile>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes......) const volatile>
+ { typedef _Res result_type; };
+
+ /// Retrieve the result type for a function reference.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(&)(_ArgTypes......)>
+ { typedef _Res result_type; };
+
+ /// Retrieve the result type for a function pointer.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(*)(_ArgTypes......)>
+ { typedef _Res result_type; };
+
+ /// Retrieve result type for a member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)>
+ { typedef _Res result_type; };
+
+ /// Retrieve result type for a const member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) const>
+ { typedef _Res result_type; };
+
+ /// Retrieve result type for a volatile member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) volatile>
+ { typedef _Res result_type; };
+
+ /// Retrieve result type for a const volatile member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)
+ const volatile>
+ { typedef _Res result_type; };
+
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)
+ const volatile>
+ { typedef _Res result_type; };
+
+ /**
+ * Strip top-level cv-qualifiers from the function object and let
+ * _Weak_result_type_impl perform the real work.
+ */
+ template<typename _Functor>
+ struct _Weak_result_type
+ : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
+ { };
+
+ // Detect nested argument_type.
+ template<typename _Tp, typename = __void_t<>>
+ struct _Refwrap_base_arg1
+ { };
+
+ // Nested argument_type.
+ template<typename _Tp>
+ struct _Refwrap_base_arg1<_Tp,
+ __void_t<typename _Tp::argument_type>>
+ {
+ typedef typename _Tp::argument_type argument_type;
+ };
+
+ // Detect nested first_argument_type and second_argument_type.
+ template<typename _Tp, typename = __void_t<>>
+ struct _Refwrap_base_arg2
+ { };
+
+ // Nested first_argument_type and second_argument_type.
+ template<typename _Tp>
+ struct _Refwrap_base_arg2<_Tp,
+ __void_t<typename _Tp::first_argument_type,
+ typename _Tp::second_argument_type>>
+ {
+ typedef typename _Tp::first_argument_type first_argument_type;
+ typedef typename _Tp::second_argument_type second_argument_type;
+ };
+
+ /**
+ * Derives from unary_function or binary_function when it
+ * can. Specializations handle all of the easy cases. The primary
+ * template determines what to do with a class type, which may
+ * derive from both unary_function and binary_function.
+ */
+ template<typename _Tp>
+ struct _Reference_wrapper_base
+ : _Weak_result_type<_Tp>, _Refwrap_base_arg1<_Tp>, _Refwrap_base_arg2<_Tp>
+ { };
+
+ // - a function type (unary)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(_T1)>
+ : unary_function<_T1, _Res>
+ { };
+
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(_T1) const>
+ : unary_function<_T1, _Res>
+ { };
+
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(_T1) volatile>
+ : unary_function<_T1, _Res>
+ { };
+
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(_T1) const volatile>
+ : unary_function<_T1, _Res>
+ { };
+
+ // - a function type (binary)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(_T1, _T2)>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(_T1, _T2) const>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(_T1, _T2) volatile>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ // - a function pointer type (unary)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(*)(_T1)>
+ : unary_function<_T1, _Res>
+ { };
+
+ // - a function pointer type (binary)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, no qualifiers)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)()>
+ : unary_function<_T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, no qualifiers)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
+ : binary_function<_T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, const)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const>
+ : unary_function<const _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, const)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
+ : binary_function<const _T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, volatile)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
+ : unary_function<volatile _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, volatile)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
+ : binary_function<volatile _T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, const volatile)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
+ : unary_function<const volatile _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, const volatile)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
+ : binary_function<const volatile _T1*, _T2, _Res>
+ { };
+
+ /**
+ * @brief Primary class template for reference_wrapper.
+ * @ingroup functors
+ * @{
+ */
+ template<typename _Tp>
+ class reference_wrapper
+ : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
+ {
+ _Tp* _M_data;
+
+ public:
+ typedef _Tp type;
+
+ reference_wrapper(_Tp& __indata) noexcept
+ : _M_data(std::__addressof(__indata))
+ { }
+
+ reference_wrapper(_Tp&&) = delete;
+
+ reference_wrapper(const reference_wrapper&) = default;
+
+ reference_wrapper&
+ operator=(const reference_wrapper&) = default;
+
+ operator _Tp&() const noexcept
+ { return this->get(); }
+
+ _Tp&
+ get() const noexcept
+ { return *_M_data; }
+
+ template<typename... _Args>
+ typename result_of<_Tp&(_Args&&...)>::type
+ operator()(_Args&&... __args) const
+ {
+ return std::__invoke(get(), std::forward<_Args>(__args)...);
+ }
+ };
+
+
+ /// Denotes a reference should be taken to a variable.
+ template<typename _Tp>
+ inline reference_wrapper<_Tp>
+ ref(_Tp& __t) noexcept
+ { return reference_wrapper<_Tp>(__t); }
+
+ /// Denotes a const reference should be taken to a variable.
+ template<typename _Tp>
+ inline reference_wrapper<const _Tp>
+ cref(const _Tp& __t) noexcept
+ { return reference_wrapper<const _Tp>(__t); }
+
+ template<typename _Tp>
+ void ref(const _Tp&&) = delete;
+
+ template<typename _Tp>
+ void cref(const _Tp&&) = delete;
+
+ /// Partial specialization.
+ template<typename _Tp>
+ inline reference_wrapper<_Tp>
+ ref(reference_wrapper<_Tp> __t) noexcept
+ { return ref(__t.get()); }
+
+ /// Partial specialization.
+ template<typename _Tp>
+ inline reference_wrapper<const _Tp>
+ cref(reference_wrapper<_Tp> __t) noexcept
+ { return cref(__t.get()); }
+
+ // @} group functors
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++11
+
+#endif // _GLIBCXX_REFWRAP_H
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 4e87bc0088..60837ea6cf 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -762,17 +762,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
template<typename _FwdIter>
basic_regex(_FwdIter __first, _FwdIter __last, locale_type __loc,
flag_type __f)
- : _M_flags(__f), _M_loc(std::move(__loc)),
+ : _M_flags((__f & (ECMAScript | basic | extended | awk | grep | egrep))
+ ? __f : (__f | ECMAScript)),
+ _M_loc(std::move(__loc)),
_M_automaton(__detail::__compile_nfa<_FwdIter, _Rx_traits>(
std::move(__first), std::move(__last), _M_loc, _M_flags))
{ }
template<typename _Bp, typename _Ap, typename _Cp, typename _Rp,
__detail::_RegexExecutorPolicy, bool>
- friend bool
- __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&,
- const basic_regex<_Cp, _Rp>&,
- regex_constants::match_flag_type);
+ friend bool __detail::
+#if _GLIBCXX_INLINE_VERSION
+ __7:: // Required due to PR c++/59256
+#endif
+ __regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&,
+ const basic_regex<_Cp, _Rp>&,
+ regex_constants::match_flag_type);
template<typename, typename, typename, bool>
friend class __detail::_Executor;
@@ -1860,10 +1865,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
template<typename _Bp, typename _Ap, typename _Cp, typename _Rp,
__detail::_RegexExecutorPolicy, bool>
- friend bool
- __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&,
- const basic_regex<_Cp, _Rp>&,
- regex_constants::match_flag_type);
+ friend bool __detail::
+#if _GLIBCXX_INLINE_VERSION
+ __7:: // Required due to PR c++/59256
+#endif
+ __regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&,
+ const basic_regex<_Cp, _Rp>&,
+ regex_constants::match_flag_type);
void
_M_resize(unsigned int __size)
@@ -2448,7 +2456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* one-past-the-end of a range.
*/
regex_iterator()
- : _M_match()
+ : _M_pregex()
{ }
/**
@@ -2666,9 +2674,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
initializer_list<int>,
regex_constants::match_flag_type =
regex_constants::match_default) = delete;
- template <std::size_t N>
+ template <std::size_t _Nm>
regex_token_iterator(_Bi_iter, _Bi_iter, const regex_type&&,
- const int (&)[N],
+ const int (&)[_Nm],
regex_constants::match_flag_type =
regex_constants::match_default) = delete;
diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc
index 4a3d7c36cf..dc32a49dcd 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -496,12 +496,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator==(const regex_iterator& __rhs) const
{
- return (_M_match.empty() && __rhs._M_match.empty())
- || (_M_begin == __rhs._M_begin
- && _M_end == __rhs._M_end
- && _M_pregex == __rhs._M_pregex
- && _M_flags == __rhs._M_flags
- && _M_match[0] == __rhs._M_match[0]);
+ if (_M_pregex == nullptr && __rhs._M_pregex == nullptr)
+ return true;
+ return _M_pregex == __rhs._M_pregex
+ && _M_begin == __rhs._M_begin
+ && _M_end == __rhs._M_end
+ && _M_flags == __rhs._M_flags
+ && _M_match[0] == __rhs._M_match[0];
}
template<typename _Bi_iter,
@@ -525,7 +526,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
if (__start == _M_end)
{
- _M_match = value_type();
+ _M_pregex = nullptr;
return *this;
}
else
@@ -558,7 +559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_match._M_begin = _M_begin;
}
else
- _M_match = value_type();
+ _M_pregex = nullptr;
}
return *this;
}
diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h
index 07158c4926..a5fab6356c 100644
--- a/libstdc++-v3/include/bits/regex_automaton.h
+++ b/libstdc++-v3/include/bits/regex_automaton.h
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -241,7 +241,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
_StateIdT
- _M_insert_alt(_StateIdT __next, _StateIdT __alt, bool __neg)
+ _M_insert_alt(_StateIdT __next, _StateIdT __alt,
+ bool __neg __attribute__((__unused__)))
{
_StateT __tmp(_S_opcode_alternative);
// It labels every quantifier to make greedy comparison easier in BFS
diff --git a/libstdc++-v3/include/bits/regex_automaton.tcc b/libstdc++-v3/include/bits/regex_automaton.tcc
index 6955ab9203..727bde1f6c 100644
--- a/libstdc++-v3/include/bits/regex_automaton.tcc
+++ b/libstdc++-v3/include/bits/regex_automaton.tcc
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h
index 410d61b7da..49c01840c9 100644
--- a/libstdc++-v3/include/bits/regex_compiler.h
+++ b/libstdc++-v3/include/bits/regex_compiler.h
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -30,6 +30,15 @@
namespace std _GLIBCXX_VISIBILITY(default)
{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_CXX11
+
+ template<typename>
+ class regex_traits;
+
+_GLIBCXX_END_NAMESPACE_CXX11
+_GLIBCXX_END_NAMESPACE_VERSION
+
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -207,17 +216,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [28.13.14]
template<typename _TraitsT, bool __icase, bool __collate>
- class _RegexTranslator
+ class _RegexTranslatorBase
{
public:
typedef typename _TraitsT::char_type _CharT;
typedef typename _TraitsT::string_type _StringT;
- typedef typename std::conditional<__collate,
- _StringT,
- _CharT>::type _StrTransT;
+ typedef _StringT _StrTransT;
explicit
- _RegexTranslator(const _TraitsT& __traits)
+ _RegexTranslatorBase(const _TraitsT& __traits)
: _M_traits(__traits)
{ }
@@ -235,23 +242,86 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_StrTransT
_M_transform(_CharT __ch) const
{
- return _M_transform_impl(__ch, typename integral_constant<bool,
- __collate>::type());
+ _StrTransT __str(1, __ch);
+ return _M_traits.transform(__str.begin(), __str.end());
}
- private:
+ // See LWG 523. It's not efficiently implementable when _TraitsT is not
+ // std::regex_traits<>, and __collate is true. See specializations for
+ // implementations of other cases.
+ bool
+ _M_match_range(const _StrTransT& __first, const _StrTransT& __last,
+ const _StrTransT& __s) const
+ { return __first <= __s && __s <= __last; }
+
+ protected:
+ bool _M_in_range_icase(_CharT __first, _CharT __last, _CharT __ch) const
+ {
+ typedef std::ctype<_CharT> __ctype_type;
+ const auto& __fctyp = use_facet<__ctype_type>(this->_M_traits.getloc());
+ auto __lower = __fctyp.tolower(__ch);
+ auto __upper = __fctyp.toupper(__ch);
+ return (__first <= __lower && __lower <= __last)
+ || (__first <= __upper && __upper <= __last);
+ }
+
+ const _TraitsT& _M_traits;
+ };
+
+ template<typename _TraitsT, bool __icase, bool __collate>
+ class _RegexTranslator
+ : public _RegexTranslatorBase<_TraitsT, __icase, __collate>
+ {
+ public:
+ typedef _RegexTranslatorBase<_TraitsT, __icase, __collate> _Base;
+ using _Base::_Base;
+ };
+
+ template<typename _TraitsT, bool __icase>
+ class _RegexTranslator<_TraitsT, __icase, false>
+ : public _RegexTranslatorBase<_TraitsT, __icase, false>
+ {
+ public:
+ typedef _RegexTranslatorBase<_TraitsT, __icase, false> _Base;
+ typedef typename _Base::_CharT _CharT;
+ typedef _CharT _StrTransT;
+
+ using _Base::_Base;
+
_StrTransT
- _M_transform_impl(_CharT __ch, false_type) const
+ _M_transform(_CharT __ch) const
{ return __ch; }
- _StrTransT
- _M_transform_impl(_CharT __ch, true_type) const
+ bool
+ _M_match_range(_CharT __first, _CharT __last, _CharT __ch) const
{
- _StrTransT __str = _StrTransT(1, _M_translate(__ch));
- return _M_traits.transform(__str.begin(), __str.end());
+ if (!__icase)
+ return __first <= __ch && __ch <= __last;
+ return this->_M_in_range_icase(__first, __last, __ch);
}
+ };
- const _TraitsT& _M_traits;
+ template<typename _CharType>
+ class _RegexTranslator<std::regex_traits<_CharType>, true, true>
+ : public _RegexTranslatorBase<std::regex_traits<_CharType>, true, true>
+ {
+ public:
+ typedef _RegexTranslatorBase<std::regex_traits<_CharType>, true, true>
+ _Base;
+ typedef typename _Base::_CharT _CharT;
+ typedef typename _Base::_StrTransT _StrTransT;
+
+ using _Base::_Base;
+
+ bool
+ _M_match_range(const _StrTransT& __first, const _StrTransT& __last,
+ const _StrTransT& __str) const
+ {
+ __glibcxx_assert(__first.size() == 1);
+ __glibcxx_assert(__last.size() == 1);
+ __glibcxx_assert(__str.size() == 1);
+ return this->_M_in_range_icase(__first[0], __last[0], __str[0]);
+ }
};
template<typename _TraitsT>
@@ -272,6 +342,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_StrTransT
_M_transform(_CharT __ch) const
{ return __ch; }
+
+ bool
+ _M_match_range(_CharT __first, _CharT __last, _CharT __ch) const
+ { return __first <= __ch && __ch <= __last; }
};
template<typename _TraitsT, bool __is_ecma, bool __icase, bool __collate>
diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
index ff69e16551..a6d8016d87 100644
--- a/libstdc++-v3/include/bits/regex_compiler.tcc
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -426,13 +426,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pair<bool, _CharT> __last_char; // Optional<_CharT>
__last_char.first = false;
if (!(_M_flags & regex_constants::ECMAScript))
- if (_M_try_char())
- {
- __matcher._M_add_char(_M_value[0]);
- __last_char.first = true;
- __last_char.second = _M_value[0];
- }
+ {
+ if (_M_try_char())
+ {
+ __last_char.first = true;
+ __last_char.second = _M_value[0];
+ }
+ else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
+ {
+ __last_char.first = true;
+ __last_char.second = '-';
+ }
+ }
while (_M_expression_term(__last_char, __matcher));
+ if (__last_char.first)
+ __matcher._M_add_char(__last_char.second);
__matcher._M_ready();
_M_stack.push(_StateSeqT(
*_M_nfa,
@@ -449,19 +457,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (_M_match_token(_ScannerT::_S_token_bracket_end))
return false;
+ const auto __push_char = [&](_CharT __ch)
+ {
+ if (__last_char.first)
+ __matcher._M_add_char(__last_char.second);
+ else
+ __last_char.first = true;
+ __last_char.second = __ch;
+ };
+ const auto __flush = [&]
+ {
+ if (__last_char.first)
+ {
+ __matcher._M_add_char(__last_char.second);
+ __last_char.first = false;
+ }
+ };
+
if (_M_match_token(_ScannerT::_S_token_collsymbol))
{
auto __symbol = __matcher._M_add_collate_element(_M_value);
if (__symbol.size() == 1)
- {
- __last_char.first = true;
- __last_char.second = __symbol[0];
- }
+ __push_char(__symbol[0]);
+ else
+ __flush();
}
else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
- __matcher._M_add_equivalence_class(_M_value);
+ {
+ __flush();
+ __matcher._M_add_equivalence_class(_M_value);
+ }
else if (_M_match_token(_ScannerT::_S_token_char_class_name))
- __matcher._M_add_character_class(_M_value, false);
+ {
+ __flush();
+ __matcher._M_add_character_class(_M_value, false);
+ }
+ else if (_M_try_char())
+ __push_char(_M_value[0]);
// POSIX doesn't allow '-' as a start-range char (say [a-z--0]),
// except when the '-' is the first or last character in the bracket
// expression ([--0]). ECMAScript treats all '-' after a range as a
@@ -472,55 +504,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Clang (3.5) always uses ECMAScript style even in its POSIX syntax.
//
// It turns out that no one reads BNFs ;)
- else if (_M_try_char())
+ else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
{
if (!__last_char.first)
{
- __matcher._M_add_char(_M_value[0]);
- if (_M_value[0] == '-'
- && !(_M_flags & regex_constants::ECMAScript))
+ if (!(_M_flags & regex_constants::ECMAScript))
{
if (_M_match_token(_ScannerT::_S_token_bracket_end))
- return false;
+ {
+ __push_char('-');
+ return false;
+ }
__throw_regex_error(
regex_constants::error_range,
"Unexpected dash in bracket expression. For POSIX syntax, "
"a dash is not treated literally only when it is at "
"beginning or end.");
}
- __last_char.first = true;
- __last_char.second = _M_value[0];
+ __push_char('-');
}
else
{
- if (_M_value[0] == '-')
+ if (_M_try_char())
{
- if (_M_try_char())
- {
- __matcher._M_make_range(__last_char.second , _M_value[0]);
- __last_char.first = false;
- }
- else
- {
- if (_M_scanner._M_get_token()
- != _ScannerT::_S_token_bracket_end)
- __throw_regex_error(
- regex_constants::error_range,
- "Unexpected end of bracket expression.");
- __matcher._M_add_char(_M_value[0]);
- }
+ __matcher._M_make_range(__last_char.second, _M_value[0]);
+ __last_char.first = false;
+ }
+ else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
+ {
+ __matcher._M_make_range(__last_char.second, '-');
+ __last_char.first = false;
}
else
{
- __matcher._M_add_char(_M_value[0]);
- __last_char.second = _M_value[0];
+ if (_M_scanner._M_get_token()
+ != _ScannerT::_S_token_bracket_end)
+ __throw_regex_error(
+ regex_constants::error_range,
+ "Character is expected after a dash.");
+ __push_char('-');
}
}
}
else if (_M_match_token(_ScannerT::_S_token_quoted_class))
- __matcher._M_add_character_class(_M_value,
- _M_ctype.is(_CtypeT::upper,
- _M_value[0]));
+ {
+ __flush();
+ __matcher._M_add_character_class(_M_value,
+ _M_ctype.is(_CtypeT::upper,
+ _M_value[0]));
+ }
else
__throw_regex_error(regex_constants::error_brack,
"Unexpected character in bracket expression.");
@@ -580,37 +612,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_BracketMatcher<_TraitsT, __icase, __collate>::
_M_apply(_CharT __ch, false_type) const
{
- bool __ret = std::binary_search(_M_char_set.begin(), _M_char_set.end(),
- _M_translator._M_translate(__ch));
- if (!__ret)
- {
- auto __s = _M_translator._M_transform(__ch);
- for (auto& __it : _M_range_set)
- if (__it.first <= __s && __s <= __it.second)
- {
- __ret = true;
- break;
- }
- if (_M_traits.isctype(__ch, _M_class_set))
- __ret = true;
- else if (std::find(_M_equiv_set.begin(), _M_equiv_set.end(),
- _M_traits.transform_primary(&__ch, &__ch+1))
- != _M_equiv_set.end())
- __ret = true;
- else
- {
- for (auto& __it : _M_neg_class_set)
- if (!_M_traits.isctype(__ch, __it))
- {
- __ret = true;
- break;
- }
- }
- }
- if (_M_is_non_matching)
- return !__ret;
- else
- return __ret;
+ return [this, __ch]
+ {
+ if (std::binary_search(_M_char_set.begin(), _M_char_set.end(),
+ _M_translator._M_translate(__ch)))
+ return true;
+ auto __s = _M_translator._M_transform(__ch);
+ for (auto& __it : _M_range_set)
+ if (_M_translator._M_match_range(__it.first, __it.second, __s))
+ return true;
+ if (_M_traits.isctype(__ch, _M_class_set))
+ return true;
+ if (std::find(_M_equiv_set.begin(), _M_equiv_set.end(),
+ _M_traits.transform_primary(&__ch, &__ch+1))
+ != _M_equiv_set.end())
+ return true;
+ for (auto& __it : _M_neg_class_set)
+ if (!_M_traits.isctype(__ch, __it))
+ return true;
+ return false;
+ }() ^ _M_is_non_matching;
}
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/regex_constants.h b/libstdc++-v3/include/bits/regex_constants.h
index 4b063cc2a7..dad2d637aa 100644
--- a/libstdc++-v3/include/bits/regex_constants.h
+++ b/libstdc++-v3/include/bits/regex_constants.h
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Specifies that the matching of regular expressions against a character
* sequence shall be performed without regard to case.
*/
- constexpr syntax_option_type icase =
+ _GLIBCXX17_INLINE constexpr syntax_option_type icase =
static_cast<syntax_option_type>(1 << _S_icase);
/**
@@ -92,7 +92,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* container sequence, no sub-expression matches are to be stored in the
* supplied match_results structure.
*/
- constexpr syntax_option_type nosubs =
+ _GLIBCXX17_INLINE constexpr syntax_option_type nosubs =
static_cast<syntax_option_type>(1 << _S_nosubs);
/**
@@ -101,14 +101,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* speed with which regular expression objects are constructed. Otherwise
* it has no detectable effect on the program output.
*/
- constexpr syntax_option_type optimize =
+ _GLIBCXX17_INLINE constexpr syntax_option_type optimize =
static_cast<syntax_option_type>(1 << _S_optimize);
/**
* Specifies that character ranges of the form [a-b] should be locale
* sensitive.
*/
- constexpr syntax_option_type collate =
+ _GLIBCXX17_INLINE constexpr syntax_option_type collate =
static_cast<syntax_option_type>(1 << _S_collate);
/**
@@ -119,7 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* in the PERL scripting language but extended with elements found in the
* POSIX regular expression grammar.
*/
- constexpr syntax_option_type ECMAScript =
+ _GLIBCXX17_INLINE constexpr syntax_option_type ECMAScript =
static_cast<syntax_option_type>(1 << _S_ECMAScript);
/**
@@ -129,7 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Headers, Section 9, Regular Expressions [IEEE, Information Technology --
* Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
*/
- constexpr syntax_option_type basic =
+ _GLIBCXX17_INLINE constexpr syntax_option_type basic =
static_cast<syntax_option_type>(1 << _S_basic);
/**
@@ -138,7 +138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Portable Operating System Interface (POSIX), Base Definitions and
* Headers, Section 9, Regular Expressions.
*/
- constexpr syntax_option_type extended =
+ _GLIBCXX17_INLINE constexpr syntax_option_type extended =
static_cast<syntax_option_type>(1 << _S_extended);
/**
@@ -149,7 +149,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos,, &apos,,
* and \\ddd (where ddd is one, two, or three octal digits).
*/
- constexpr syntax_option_type awk =
+ _GLIBCXX17_INLINE constexpr syntax_option_type awk =
static_cast<syntax_option_type>(1 << _S_awk);
/**
@@ -158,7 +158,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* identical to syntax_option_type basic, except that newlines are treated
* as whitespace.
*/
- constexpr syntax_option_type grep =
+ _GLIBCXX17_INLINE constexpr syntax_option_type grep =
static_cast<syntax_option_type>(1 << _S_grep);
/**
@@ -167,7 +167,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* IEEE Std 1003.1-2001. This option is identical to syntax_option_type
* extended, except that newlines are treated as whitespace.
*/
- constexpr syntax_option_type egrep =
+ _GLIBCXX17_INLINE constexpr syntax_option_type egrep =
static_cast<syntax_option_type>(1 << _S_egrep);
/**
@@ -176,7 +176,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* If specified in a regex with back-references, the exception
* regex_constants::error_complexity will be thrown.
*/
- constexpr syntax_option_type __polynomial =
+ _GLIBCXX17_INLINE constexpr syntax_option_type __polynomial =
static_cast<syntax_option_type>(1 << _S_polynomial);
constexpr inline syntax_option_type
@@ -257,14 +257,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* The default matching rules.
*/
- constexpr match_flag_type match_default = static_cast<match_flag_type>(0);
+ _GLIBCXX17_INLINE constexpr match_flag_type match_default =
+ static_cast<match_flag_type>(0);
/**
* The first character in the sequence [first, last) is treated as though it
* is not at the beginning of a line, so the character (^) in the regular
* expression shall not match [first, first).
*/
- constexpr match_flag_type match_not_bol =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_not_bol =
static_cast<match_flag_type>(1 << _S_not_bol);
/**
@@ -272,40 +273,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* is not at the end of a line, so the character ($) in the regular
* expression shall not match [last, last).
*/
- constexpr match_flag_type match_not_eol =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_not_eol =
static_cast<match_flag_type>(1 << _S_not_eol);
/**
* The expression \\b is not matched against the sub-sequence
* [first,first).
*/
- constexpr match_flag_type match_not_bow =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_not_bow =
static_cast<match_flag_type>(1 << _S_not_bow);
/**
* The expression \\b should not be matched against the sub-sequence
* [last,last).
*/
- constexpr match_flag_type match_not_eow =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_not_eow =
static_cast<match_flag_type>(1 << _S_not_eow);
/**
* If more than one match is possible then any match is an acceptable
* result.
*/
- constexpr match_flag_type match_any =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_any =
static_cast<match_flag_type>(1 << _S_any);
/**
* The expression does not match an empty sequence.
*/
- constexpr match_flag_type match_not_null =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_not_null =
static_cast<match_flag_type>(1 << _S_not_null);
/**
* The expression only matches a sub-sequence that begins at first .
*/
- constexpr match_flag_type match_continuous =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_continuous =
static_cast<match_flag_type>(1 << _S_continuous);
/**
@@ -313,7 +314,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* flags match_not_bol and match_not_bow are ignored by the regular
* expression algorithms 28.11 and iterators 28.12.
*/
- constexpr match_flag_type match_prev_avail =
+ _GLIBCXX17_INLINE constexpr match_flag_type match_prev_avail =
static_cast<match_flag_type>(1 << _S_prev_avail);
/**
@@ -342,7 +343,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* undefined, use the empty string instead. If
* nn > match_results::size(), the result is implementation-defined.
*/
- constexpr match_flag_type format_default = static_cast<match_flag_type>(0);
+ _GLIBCXX17_INLINE constexpr match_flag_type format_default =
+ static_cast<match_flag_type>(0);
/**
* When a regular expression match is to be replaced by a new string, the
@@ -350,7 +352,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable
* Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
*/
- constexpr match_flag_type format_sed =
+ _GLIBCXX17_INLINE constexpr match_flag_type format_sed =
static_cast<match_flag_type>(1 << _S_sed);
/**
@@ -358,14 +360,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* container sequence being searched that do not match the regular
* expression shall not be copied to the output string.
*/
- constexpr match_flag_type format_no_copy =
+ _GLIBCXX17_INLINE constexpr match_flag_type format_no_copy =
static_cast<match_flag_type>(1 << _S_no_copy);
/**
* When specified during a search and replace operation, only the first
* occurrence of the regular expression shall be replaced.
*/
- constexpr match_flag_type format_first_only =
+ _GLIBCXX17_INLINE constexpr match_flag_type format_first_only =
static_cast<match_flag_type>(1 << _S_first_only);
constexpr inline match_flag_type
diff --git a/libstdc++-v3/include/bits/regex_error.h b/libstdc++-v3/include/bits/regex_error.h
index 16bf78c5e3..55f6db9cf7 100644
--- a/libstdc++-v3/include/bits/regex_error.h
+++ b/libstdc++-v3/include/bits/regex_error.h
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h
index ef8aa9167d..6105474287 100644
--- a/libstdc++-v3/include/bits/regex_executor.h
+++ b/libstdc++-v3/include/bits/regex_executor.h
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -109,6 +109,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_rep_once_more(_Match_mode __match_mode, _StateIdT);
void
+ _M_handle_repeat(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_subexpr_begin(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_subexpr_end(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_line_begin_assertion(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_line_end_assertion(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_word_boundary(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_subexpr_lookahead(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_match(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_backref(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_accept(_Match_mode, _StateIdT);
+
+ void
+ _M_handle_alternative(_Match_mode, _StateIdT);
+
+ void
_M_dfs(_Match_mode __match_mode, _StateIdT __start);
bool
diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc
index 2abd02099d..9d4ece7441 100644
--- a/libstdc++-v3/include/bits/regex_executor.tcc
+++ b/libstdc++-v3/include/bits/regex_executor.tcc
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -195,213 +195,295 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
+ // _M_alt branch is "match once more", while _M_next is "get me out
+ // of this quantifier". Executing _M_next first or _M_alt first don't
+ // mean the same thing, and we need to choose the correct order under
+ // given greedy mode.
template<typename _BiIter, typename _Alloc, typename _TraitsT,
bool __dfs_mode>
void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
- _M_dfs(_Match_mode __match_mode, _StateIdT __i)
+ _M_handle_repeat(_Match_mode __match_mode, _StateIdT __i)
{
- if (_M_states._M_visited(__i))
- return;
-
const auto& __state = _M_nfa[__i];
- // Every change on _M_cur_results and _M_current will be rolled back after
- // finishing the recursion step.
- switch (__state._M_opcode())
+
+ // Greedy.
+ if (!__state._M_neg)
{
- // _M_alt branch is "match once more", while _M_next is "get me out
- // of this quantifier". Executing _M_next first or _M_alt first don't
- // mean the same thing, and we need to choose the correct order under
- // given greedy mode.
- case _S_opcode_repeat:
- {
- // Greedy.
- if (!__state._M_neg)
- {
- _M_rep_once_more(__match_mode, __i);
- // If it's DFS executor and already accepted, we're done.
- if (!__dfs_mode || !_M_has_sol)
- _M_dfs(__match_mode, __state._M_next);
- }
- else // Non-greedy mode
- {
- if (__dfs_mode)
- {
- // vice-versa.
- _M_dfs(__match_mode, __state._M_next);
- if (!_M_has_sol)
- _M_rep_once_more(__match_mode, __i);
- }
- else
- {
- // DON'T attempt anything, because there's already another
- // state with higher priority accepted. This state cannot
- // be better by attempting its next node.
- if (!_M_has_sol)
- {
- _M_dfs(__match_mode, __state._M_next);
- // DON'T attempt anything if it's already accepted. An
- // accepted state *must* be better than a solution that
- // matches a non-greedy quantifier one more time.
- if (!_M_has_sol)
- _M_rep_once_more(__match_mode, __i);
- }
- }
- }
- }
- break;
- case _S_opcode_subexpr_begin:
- {
- auto& __res = _M_cur_results[__state._M_subexpr];
- auto __back = __res.first;
- __res.first = _M_current;
- _M_dfs(__match_mode, __state._M_next);
- __res.first = __back;
- }
- break;
- case _S_opcode_subexpr_end:
- {
- auto& __res = _M_cur_results[__state._M_subexpr];
- auto __back = __res;
- __res.second = _M_current;
- __res.matched = true;
- _M_dfs(__match_mode, __state._M_next);
- __res = __back;
- }
- break;
- case _S_opcode_line_begin_assertion:
- if (_M_at_begin())
- _M_dfs(__match_mode, __state._M_next);
- break;
- case _S_opcode_line_end_assertion:
- if (_M_at_end())
- _M_dfs(__match_mode, __state._M_next);
- break;
- case _S_opcode_word_boundary:
- if (_M_word_boundary() == !__state._M_neg)
- _M_dfs(__match_mode, __state._M_next);
- break;
- // Here __state._M_alt offers a single start node for a sub-NFA.
- // We recursively invoke our algorithm to match the sub-NFA.
- case _S_opcode_subexpr_lookahead:
- if (_M_lookahead(__state._M_alt) == !__state._M_neg)
+ _M_rep_once_more(__match_mode, __i);
+ // If it's DFS executor and already accepted, we're done.
+ if (!__dfs_mode || !_M_has_sol)
_M_dfs(__match_mode, __state._M_next);
- break;
- case _S_opcode_match:
- if (_M_current == _M_end)
- break;
+ }
+ else // Non-greedy mode
+ {
if (__dfs_mode)
{
- if (__state._M_matches(*_M_current))
- {
- ++_M_current;
- _M_dfs(__match_mode, __state._M_next);
- --_M_current;
- }
+ // vice-versa.
+ _M_dfs(__match_mode, __state._M_next);
+ if (!_M_has_sol)
+ _M_rep_once_more(__match_mode, __i);
}
else
- if (__state._M_matches(*_M_current))
- _M_states._M_queue(__state._M_next, _M_cur_results);
- break;
- // First fetch the matched result from _M_cur_results as __submatch;
- // then compare it with
- // (_M_current, _M_current + (__submatch.second - __submatch.first)).
- // If matched, keep going; else just return and try another state.
- case _S_opcode_backref:
- {
- __glibcxx_assert(__dfs_mode);
- auto& __submatch = _M_cur_results[__state._M_backref_index];
- if (!__submatch.matched)
- break;
- auto __last = _M_current;
- for (auto __tmp = __submatch.first;
- __last != _M_end && __tmp != __submatch.second;
- ++__tmp)
- ++__last;
- if (_M_re._M_automaton->_M_traits.transform(__submatch.first,
- __submatch.second)
- == _M_re._M_automaton->_M_traits.transform(_M_current, __last))
- {
- if (__last != _M_current)
- {
- auto __backup = _M_current;
- _M_current = __last;
- _M_dfs(__match_mode, __state._M_next);
- _M_current = __backup;
- }
- else
- _M_dfs(__match_mode, __state._M_next);
- }
- }
- break;
- case _S_opcode_accept:
- if (__dfs_mode)
{
- __glibcxx_assert(!_M_has_sol);
- if (__match_mode == _Match_mode::_Exact)
- _M_has_sol = _M_current == _M_end;
- else
- _M_has_sol = true;
- if (_M_current == _M_begin
- && (_M_flags & regex_constants::match_not_null))
- _M_has_sol = false;
- if (_M_has_sol)
+ // DON'T attempt anything, because there's already another
+ // state with higher priority accepted. This state cannot
+ // be better by attempting its next node.
+ if (!_M_has_sol)
{
- if (_M_nfa._M_flags & regex_constants::ECMAScript)
- _M_results = _M_cur_results;
- else // POSIX
- {
- __glibcxx_assert(_M_states._M_get_sol_pos());
- // Here's POSIX's logic: match the longest one. However
- // we never know which one (lhs or rhs of "|") is longer
- // unless we try both of them and compare the results.
- // The member variable _M_sol_pos records the end
- // position of the last successful match. It's better
- // to be larger, because POSIX regex is always greedy.
- // TODO: This could be slow.
- if (*_M_states._M_get_sol_pos() == _BiIter()
- || std::distance(_M_begin,
- *_M_states._M_get_sol_pos())
- < std::distance(_M_begin, _M_current))
- {
- *_M_states._M_get_sol_pos() = _M_current;
- _M_results = _M_cur_results;
- }
- }
+ _M_dfs(__match_mode, __state._M_next);
+ // DON'T attempt anything if it's already accepted. An
+ // accepted state *must* be better than a solution that
+ // matches a non-greedy quantifier one more time.
+ if (!_M_has_sol)
+ _M_rep_once_more(__match_mode, __i);
}
}
- else
+ }
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_subexpr_begin(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+
+ auto& __res = _M_cur_results[__state._M_subexpr];
+ auto __back = __res.first;
+ __res.first = _M_current;
+ _M_dfs(__match_mode, __state._M_next);
+ __res.first = __back;
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_subexpr_end(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+
+ auto& __res = _M_cur_results[__state._M_subexpr];
+ auto __back = __res;
+ __res.second = _M_current;
+ __res.matched = true;
+ _M_dfs(__match_mode, __state._M_next);
+ __res = __back;
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ inline void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_line_begin_assertion(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+ if (_M_at_begin())
+ _M_dfs(__match_mode, __state._M_next);
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ inline void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_line_end_assertion(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+ if (_M_at_end())
+ _M_dfs(__match_mode, __state._M_next);
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ inline void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_word_boundary(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+ if (_M_word_boundary() == !__state._M_neg)
+ _M_dfs(__match_mode, __state._M_next);
+ }
+
+ // Here __state._M_alt offers a single start node for a sub-NFA.
+ // We recursively invoke our algorithm to match the sub-NFA.
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_subexpr_lookahead(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+ if (_M_lookahead(__state._M_alt) == !__state._M_neg)
+ _M_dfs(__match_mode, __state._M_next);
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_match(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+
+ if (_M_current == _M_end)
+ return;
+ if (__dfs_mode)
+ {
+ if (__state._M_matches(*_M_current))
{
- if (_M_current == _M_begin
- && (_M_flags & regex_constants::match_not_null))
- break;
- if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end)
- if (!_M_has_sol)
- {
- _M_has_sol = true;
- _M_results = _M_cur_results;
- }
+ ++_M_current;
+ _M_dfs(__match_mode, __state._M_next);
+ --_M_current;
}
- break;
- case _S_opcode_alternative:
- if (_M_nfa._M_flags & regex_constants::ECMAScript)
+ }
+ else
+ if (__state._M_matches(*_M_current))
+ _M_states._M_queue(__state._M_next, _M_cur_results);
+ }
+
+ // First fetch the matched result from _M_cur_results as __submatch;
+ // then compare it with
+ // (_M_current, _M_current + (__submatch.second - __submatch.first)).
+ // If matched, keep going; else just return and try another state.
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_backref(_Match_mode __match_mode, _StateIdT __i)
+ {
+ __glibcxx_assert(__dfs_mode);
+
+ const auto& __state = _M_nfa[__i];
+ auto& __submatch = _M_cur_results[__state._M_backref_index];
+ if (!__submatch.matched)
+ return;
+ auto __last = _M_current;
+ for (auto __tmp = __submatch.first;
+ __last != _M_end && __tmp != __submatch.second;
+ ++__tmp)
+ ++__last;
+ if (_M_re._M_automaton->_M_traits.transform(__submatch.first,
+ __submatch.second)
+ == _M_re._M_automaton->_M_traits.transform(_M_current, __last))
+ {
+ if (__last != _M_current)
{
- // TODO: Fix BFS support. It is wrong.
- _M_dfs(__match_mode, __state._M_alt);
- // Pick lhs if it matches. Only try rhs if it doesn't.
- if (!_M_has_sol)
- _M_dfs(__match_mode, __state._M_next);
+ auto __backup = _M_current;
+ _M_current = __last;
+ _M_dfs(__match_mode, __state._M_next);
+ _M_current = __backup;
}
else
+ _M_dfs(__match_mode, __state._M_next);
+ }
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_accept(_Match_mode __match_mode, _StateIdT __i)
+ {
+ if (__dfs_mode)
+ {
+ __glibcxx_assert(!_M_has_sol);
+ if (__match_mode == _Match_mode::_Exact)
+ _M_has_sol = _M_current == _M_end;
+ else
+ _M_has_sol = true;
+ if (_M_current == _M_begin
+ && (_M_flags & regex_constants::match_not_null))
+ _M_has_sol = false;
+ if (_M_has_sol)
{
- // Try both and compare the result.
- // See "case _S_opcode_accept:" handling above.
- _M_dfs(__match_mode, __state._M_alt);
- auto __has_sol = _M_has_sol;
- _M_has_sol = false;
- _M_dfs(__match_mode, __state._M_next);
- _M_has_sol |= __has_sol;
+ if (_M_nfa._M_flags & regex_constants::ECMAScript)
+ _M_results = _M_cur_results;
+ else // POSIX
+ {
+ __glibcxx_assert(_M_states._M_get_sol_pos());
+ // Here's POSIX's logic: match the longest one. However
+ // we never know which one (lhs or rhs of "|") is longer
+ // unless we try both of them and compare the results.
+ // The member variable _M_sol_pos records the end
+ // position of the last successful match. It's better
+ // to be larger, because POSIX regex is always greedy.
+ // TODO: This could be slow.
+ if (*_M_states._M_get_sol_pos() == _BiIter()
+ || std::distance(_M_begin,
+ *_M_states._M_get_sol_pos())
+ < std::distance(_M_begin, _M_current))
+ {
+ *_M_states._M_get_sol_pos() = _M_current;
+ _M_results = _M_cur_results;
+ }
+ }
}
- break;
+ }
+ else
+ {
+ if (_M_current == _M_begin
+ && (_M_flags & regex_constants::match_not_null))
+ return;
+ if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end)
+ if (!_M_has_sol)
+ {
+ _M_has_sol = true;
+ _M_results = _M_cur_results;
+ }
+ }
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_handle_alternative(_Match_mode __match_mode, _StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+
+ if (_M_nfa._M_flags & regex_constants::ECMAScript)
+ {
+ // TODO: Fix BFS support. It is wrong.
+ _M_dfs(__match_mode, __state._M_alt);
+ // Pick lhs if it matches. Only try rhs if it doesn't.
+ if (!_M_has_sol)
+ _M_dfs(__match_mode, __state._M_next);
+ }
+ else
+ {
+ // Try both and compare the result.
+ // See "case _S_opcode_accept:" handling above.
+ _M_dfs(__match_mode, __state._M_alt);
+ auto __has_sol = _M_has_sol;
+ _M_has_sol = false;
+ _M_dfs(__match_mode, __state._M_next);
+ _M_has_sol |= __has_sol;
+ }
+ }
+
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_dfs(_Match_mode __match_mode, _StateIdT __i)
+ {
+ if (_M_states._M_visited(__i))
+ return;
+
+ switch (_M_nfa[__i]._M_opcode())
+ {
+ case _S_opcode_repeat:
+ _M_handle_repeat(__match_mode, __i); break;
+ case _S_opcode_subexpr_begin:
+ _M_handle_subexpr_begin(__match_mode, __i); break;
+ case _S_opcode_subexpr_end:
+ _M_handle_subexpr_end(__match_mode, __i); break;
+ case _S_opcode_line_begin_assertion:
+ _M_handle_line_begin_assertion(__match_mode, __i); break;
+ case _S_opcode_line_end_assertion:
+ _M_handle_line_end_assertion(__match_mode, __i); break;
+ case _S_opcode_word_boundary:
+ _M_handle_word_boundary(__match_mode, __i); break;
+ case _S_opcode_subexpr_lookahead:
+ _M_handle_subexpr_lookahead(__match_mode, __i); break;
+ case _S_opcode_match:
+ _M_handle_match(__match_mode, __i); break;
+ case _S_opcode_backref:
+ _M_handle_backref(__match_mode, __i); break;
+ case _S_opcode_accept:
+ _M_handle_accept(__match_mode, __i); break;
+ case _S_opcode_alternative:
+ _M_handle_alternative(__match_mode, __i); break;
default:
__glibcxx_assert(false);
}
@@ -413,6 +495,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
_M_word_boundary() const
{
+ if (_M_current == _M_begin && (_M_flags & regex_constants::match_not_bow))
+ return false;
+ if (_M_current == _M_end && (_M_flags & regex_constants::match_not_eow))
+ return false;
+
bool __left_is_word = false;
if (_M_current != _M_begin
|| (_M_flags & regex_constants::match_prev_avail))
@@ -424,13 +511,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool __right_is_word =
_M_current != _M_end && _M_is_word(*_M_current);
- if (__left_is_word == __right_is_word)
- return false;
- if (__left_is_word && !(_M_flags & regex_constants::match_not_eow))
- return true;
- if (__right_is_word && !(_M_flags & regex_constants::match_not_bow))
- return true;
- return false;
+ return __left_is_word != __right_is_word;
}
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/regex_scanner.h b/libstdc++-v3/include/bits/regex_scanner.h
index 37dea840d5..37ad862a66 100644
--- a/libstdc++-v3/include/bits/regex_scanner.h
+++ b/libstdc++-v3/include/bits/regex_scanner.h
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -43,7 +43,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
public:
/// Token types returned from the scanner.
- enum _TokenT
+ enum _TokenT : unsigned
{
_S_token_anychar,
_S_token_ord_char,
@@ -73,7 +73,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_S_token_comma,
_S_token_dup_count,
_S_token_eof,
- _S_token_unknown
+ _S_token_bracket_dash,
+ _S_token_unknown = -1u
};
protected:
diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc
index fedba09a71..ad0b0477f3 100644
--- a/libstdc++-v3/include/bits/regex_scanner.tcc
+++ b/libstdc++-v3/include/bits/regex_scanner.tcc
@@ -1,6 +1,6 @@
// class template regex -*- C++ -*-
-// Copyright (C) 2013-2016 Free Software Foundation, Inc.
+// Copyright (C) 2013-2017 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
@@ -210,7 +210,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto __c = *_M_current++;
- if (__c == '[')
+ if (__c == '-')
+ _M_token = _S_token_bracket_dash;
+ else if (__c == '[')
{
if (_M_current == _M_end)
__throw_regex_error(regex_constants::error_brack,
diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h
index b22477e96b..fe933ff2af 100644
--- a/libstdc++-v3/include/bits/shared_ptr.h
+++ b/libstdc++-v3/include/bits/shared_ptr.h
@@ -1,6 +1,6 @@
// shared_ptr and weak_ptr implementation -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
@@ -92,17 +92,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
class shared_ptr : public __shared_ptr<_Tp>
{
- template<typename _Ptr>
- using _Convertible
- = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
+ template<typename... _Args>
+ using _Constructible = typename enable_if<
+ is_constructible<__shared_ptr<_Tp>, _Args...>::value
+ >::type;
+
+ template<typename _Arg>
+ using _Assignable = typename enable_if<
+ is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
+ >::type;
public:
+
+ using element_type = typename __shared_ptr<_Tp>::element_type;
+
+#if __cplusplus > 201402L
+# define __cpp_lib_shared_ptr_weak_type 201606
+ using weak_type = weak_ptr<_Tp>;
+#endif
/**
* @brief Construct an empty %shared_ptr.
* @post use_count()==0 && get()==0
*/
- constexpr shared_ptr() noexcept
- : __shared_ptr<_Tp>() { }
+ constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
shared_ptr(const shared_ptr&) noexcept = default;
@@ -112,9 +124,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @post use_count() == 1 && get() == __p
* @throw std::bad_alloc, in which case @c delete @a __p is called.
*/
- template<typename _Tp1>
- explicit shared_ptr(_Tp1* __p)
- : __shared_ptr<_Tp>(__p) { }
+ template<typename _Yp, typename = _Constructible<_Yp*>>
+ explicit
+ shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
/**
* @brief Construct a %shared_ptr that owns the pointer @a __p
@@ -129,8 +141,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* __shared_ptr will release __p by calling __d(__p)
*/
- template<typename _Tp1, typename _Deleter>
- shared_ptr(_Tp1* __p, _Deleter __d)
+ template<typename _Yp, typename _Deleter,
+ typename = _Constructible<_Yp*, _Deleter>>
+ shared_ptr(_Yp* __p, _Deleter __d)
: __shared_ptr<_Tp>(__p, __d) { }
/**
@@ -165,8 +178,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* __shared_ptr will release __p by calling __d(__p)
*/
- template<typename _Tp1, typename _Deleter, typename _Alloc>
- shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
+ template<typename _Yp, typename _Deleter, typename _Alloc,
+ typename = _Constructible<_Yp*, _Deleter, _Alloc>>
+ shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
: __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
/**
@@ -206,8 +220,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* assert(pii.use_count() == 2);
* @endcode
*/
- template<typename _Tp1>
- shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) noexcept
+ template<typename _Yp>
+ shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
: __shared_ptr<_Tp>(__r, __p) { }
/**
@@ -217,8 +231,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __r A %shared_ptr.
* @post get() == __r.get() && use_count() == __r.use_count()
*/
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
+ template<typename _Yp,
+ typename = _Constructible<const shared_ptr<_Yp>&>>
+ shared_ptr(const shared_ptr<_Yp>& __r) noexcept
: __shared_ptr<_Tp>(__r) { }
/**
@@ -234,8 +249,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __r A %shared_ptr rvalue.
* @post *this contains the old value of @a __r, @a __r is empty.
*/
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
+ template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
+ shared_ptr(shared_ptr<_Yp>&& __r) noexcept
: __shared_ptr<_Tp>(std::move(__r)) { }
/**
@@ -246,22 +261,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @throw bad_weak_ptr when __r.expired(),
* in which case the constructor has no effect.
*/
- template<typename _Tp1>
- explicit shared_ptr(const weak_ptr<_Tp1>& __r)
+ template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
+ explicit shared_ptr(const weak_ptr<_Yp>& __r)
: __shared_ptr<_Tp>(__r) { }
#if _GLIBCXX_USE_DEPRECATED
- template<typename _Tp1>
- shared_ptr(std::auto_ptr<_Tp1>&& __r);
+ template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
+ shared_ptr(auto_ptr<_Yp>&& __r);
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2399. shared_ptr's constructor from unique_ptr should be constrained
- template<typename _Tp1, typename _Del, typename
- = _Convertible<typename unique_ptr<_Tp1, _Del>::pointer>>
- shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
+ template<typename _Yp, typename _Del,
+ typename = _Constructible<unique_ptr<_Yp, _Del>>>
+ shared_ptr(unique_ptr<_Yp, _Del>&& __r)
: __shared_ptr<_Tp>(std::move(__r)) { }
+#if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
+ // This non-standard constructor exists to support conversions that
+ // were possible in C++11 and C++14 but are ill-formed in C++17.
+ // If an exception is thrown this constructor has no effect.
+ template<typename _Yp, typename _Del,
+ _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
+ shared_ptr(unique_ptr<_Yp, _Del>&& __r)
+ : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
+#endif
+
/**
* @brief Construct an empty %shared_ptr.
* @post use_count() == 0 && get() == nullptr
@@ -270,18 +295,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
shared_ptr& operator=(const shared_ptr&) noexcept = default;
- template<typename _Tp1>
- shared_ptr&
- operator=(const shared_ptr<_Tp1>& __r) noexcept
+ template<typename _Yp>
+ _Assignable<const shared_ptr<_Yp>&>
+ operator=(const shared_ptr<_Yp>& __r) noexcept
{
this->__shared_ptr<_Tp>::operator=(__r);
return *this;
}
#if _GLIBCXX_USE_DEPRECATED
- template<typename _Tp1>
- shared_ptr&
- operator=(std::auto_ptr<_Tp1>&& __r)
+ template<typename _Yp>
+ _Assignable<auto_ptr<_Yp>>
+ operator=(auto_ptr<_Yp>&& __r)
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
@@ -295,17 +320,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
- template<class _Tp1>
- shared_ptr&
- operator=(shared_ptr<_Tp1>&& __r) noexcept
+ template<class _Yp>
+ _Assignable<shared_ptr<_Yp>>
+ operator=(shared_ptr<_Yp>&& __r) noexcept
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
- template<typename _Tp1, typename _Del>
- shared_ptr&
- operator=(std::unique_ptr<_Tp1, _Del>&& __r)
+ template<typename _Yp, typename _Del>
+ _Assignable<unique_ptr<_Yp, _Del>>
+ operator=(unique_ptr<_Yp, _Del>&& __r)
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
@@ -319,8 +344,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
{ }
- template<typename _Tp1, typename _Alloc, typename... _Args>
- friend shared_ptr<_Tp1>
+ template<typename _Yp, typename _Alloc, typename... _Args>
+ friend shared_ptr<_Yp>
allocate_shared(const _Alloc& __a, _Args&&... __args);
// This constructor is non-standard, it is used by weak_ptr::lock().
@@ -330,11 +355,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend class weak_ptr<_Tp>;
};
+#if __cpp_deduction_guides >= 201606
+ template<typename _Tp>
+ shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
+ template<typename _Tp, typename _Del>
+ shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;
+#endif
+
// 20.7.2.2.7 shared_ptr comparisons
- template<typename _Tp1, typename _Tp2>
+ template<typename _Tp, typename _Up>
inline bool
- operator==(const shared_ptr<_Tp1>& __a,
- const shared_ptr<_Tp2>& __b) noexcept
+ operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return __a.get() == __b.get(); }
template<typename _Tp>
@@ -347,10 +378,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !__a; }
- template<typename _Tp1, typename _Tp2>
+ template<typename _Tp, typename _Up>
inline bool
- operator!=(const shared_ptr<_Tp1>& __a,
- const shared_ptr<_Tp2>& __b) noexcept
+ operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return __a.get() != __b.get(); }
template<typename _Tp>
@@ -363,29 +393,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return (bool)__a; }
- template<typename _Tp1, typename _Tp2>
+ template<typename _Tp, typename _Up>
inline bool
- operator<(const shared_ptr<_Tp1>& __a,
- const shared_ptr<_Tp2>& __b) noexcept
+ operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{
- typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
- return std::less<_CT>()(__a.get(), __b.get());
+ using _Tp_elt = typename shared_ptr<_Tp>::element_type;
+ using _Up_elt = typename shared_ptr<_Up>::element_type;
+ using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
+ return less<_Vp>()(__a.get(), __b.get());
}
template<typename _Tp>
inline bool
operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
- { return std::less<_Tp*>()(__a.get(), nullptr); }
+ {
+ using _Tp_elt = typename shared_ptr<_Tp>::element_type;
+ return less<_Tp_elt*>()(__a.get(), nullptr);
+ }
template<typename _Tp>
inline bool
operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
- { return std::less<_Tp*>()(nullptr, __a.get()); }
+ {
+ using _Tp_elt = typename shared_ptr<_Tp>::element_type;
+ return less<_Tp_elt*>()(nullptr, __a.get());
+ }
- template<typename _Tp1, typename _Tp2>
+ template<typename _Tp, typename _Up>
inline bool
- operator<=(const shared_ptr<_Tp1>& __a,
- const shared_ptr<_Tp2>& __b) noexcept
+ operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return !(__b < __a); }
template<typename _Tp>
@@ -398,26 +434,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !(__a < nullptr); }
- template<typename _Tp1, typename _Tp2>
+ template<typename _Tp, typename _Up>
inline bool
- operator>(const shared_ptr<_Tp1>& __a,
- const shared_ptr<_Tp2>& __b) noexcept
+ operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return (__b < __a); }
template<typename _Tp>
inline bool
operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
- { return std::less<_Tp*>()(nullptr, __a.get()); }
+ { return nullptr < __a; }
template<typename _Tp>
inline bool
operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
- { return std::less<_Tp*>()(__a.get(), nullptr); }
+ { return __a < nullptr; }
- template<typename _Tp1, typename _Tp2>
+ template<typename _Tp, typename _Up>
inline bool
- operator>=(const shared_ptr<_Tp1>& __a,
- const shared_ptr<_Tp2>& __b) noexcept
+ operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
{ return !(__a < __b); }
template<typename _Tp>
@@ -441,25 +475,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ __a.swap(__b); }
// 20.7.2.2.9 shared_ptr casts.
- template<typename _Tp, typename _Tp1>
+ template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
- static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
- { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); }
+ static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
+ {
+ using _Sp = shared_ptr<_Tp>;
+ return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
+ }
- template<typename _Tp, typename _Tp1>
+ template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
- const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
- { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); }
+ const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
+ {
+ using _Sp = shared_ptr<_Tp>;
+ return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
+ }
- template<typename _Tp, typename _Tp1>
+ template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
- dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
+ dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
{
- if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
- return shared_ptr<_Tp>(__r, __p);
- return shared_ptr<_Tp>();
+ using _Sp = shared_ptr<_Tp>;
+ if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
+ return _Sp(__r, __p);
+ return _Sp();
}
+#if __cplusplus > 201402L
+ template<typename _Tp, typename _Up>
+ inline shared_ptr<_Tp>
+ reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
+ {
+ using _Sp = shared_ptr<_Tp>;
+ return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
+ }
+#endif
/**
* @brief A smart pointer with weak semantics.
@@ -469,43 +519,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
class weak_ptr : public __weak_ptr<_Tp>
{
- template<typename _Ptr>
- using _Convertible
- = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
+ template<typename _Arg>
+ using _Constructible = typename enable_if<
+ is_constructible<__weak_ptr<_Tp>, _Arg>::value
+ >::type;
+
+ template<typename _Arg>
+ using _Assignable = typename enable_if<
+ is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
+ >::type;
public:
constexpr weak_ptr() noexcept = default;
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
+ template<typename _Yp,
+ typename = _Constructible<const shared_ptr<_Yp>&>>
+ weak_ptr(const shared_ptr<_Yp>& __r) noexcept
: __weak_ptr<_Tp>(__r) { }
weak_ptr(const weak_ptr&) noexcept = default;
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
+ template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
+ weak_ptr(const weak_ptr<_Yp>& __r) noexcept
: __weak_ptr<_Tp>(__r) { }
weak_ptr(weak_ptr&&) noexcept = default;
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
+ template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
+ weak_ptr(weak_ptr<_Yp>&& __r) noexcept
: __weak_ptr<_Tp>(std::move(__r)) { }
weak_ptr&
operator=(const weak_ptr& __r) noexcept = default;
- template<typename _Tp1>
- weak_ptr&
- operator=(const weak_ptr<_Tp1>& __r) noexcept
+ template<typename _Yp>
+ _Assignable<const weak_ptr<_Yp>&>
+ operator=(const weak_ptr<_Yp>& __r) noexcept
{
this->__weak_ptr<_Tp>::operator=(__r);
return *this;
}
- template<typename _Tp1>
- weak_ptr&
- operator=(const shared_ptr<_Tp1>& __r) noexcept
+ template<typename _Yp>
+ _Assignable<const shared_ptr<_Yp>&>
+ operator=(const shared_ptr<_Yp>& __r) noexcept
{
this->__weak_ptr<_Tp>::operator=(__r);
return *this;
@@ -514,9 +571,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
weak_ptr&
operator=(weak_ptr&& __r) noexcept = default;
- template<typename _Tp1>
- weak_ptr&
- operator=(weak_ptr<_Tp1>&& __r) noexcept
+ template<typename _Yp>
+ _Assignable<weak_ptr<_Yp>>
+ operator=(weak_ptr<_Yp>&& __r) noexcept
{
this->__weak_ptr<_Tp>::operator=(std::move(__r));
return *this;
@@ -527,6 +584,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return shared_ptr<_Tp>(*this, std::nothrow); }
};
+#if __cpp_deduction_guides >= 201606
+ template<typename _Tp>
+ weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
+#endif
+
// 20.7.2.3.6 weak_ptr specialized algorithms.
template<typename _Tp>
inline void
@@ -535,9 +597,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Primary template owner_less
- template<typename _Tp>
+ template<typename _Tp = void>
struct owner_less;
+ /// Void specialization of owner_less
+ template<>
+ struct owner_less<void> : _Sp_owner_less<void, void>
+ { };
+
/// Partial specialization of owner_less for shared_ptr.
template<typename _Tp>
struct owner_less<shared_ptr<_Tp>>
@@ -576,31 +643,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
shared_from_this() const
{ return shared_ptr<const _Tp>(this->_M_weak_this); }
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+#define __cpp_lib_enable_shared_from_this 201603
+ weak_ptr<_Tp>
+ weak_from_this() noexcept
+ { return this->_M_weak_this; }
+
+ weak_ptr<const _Tp>
+ weak_from_this() const noexcept
+ { return this->_M_weak_this; }
+#endif
+
private:
template<typename _Tp1>
void
_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
{ _M_weak_this._M_assign(__p, __n); }
- template<typename _Tp1, typename _Tp2>
- friend void
- __enable_shared_from_this_helper(const __shared_count<>&,
- const enable_shared_from_this<_Tp1>*,
- const _Tp2*) noexcept;
+ // Found by ADL when this is an associated class.
+ friend const enable_shared_from_this*
+ __enable_shared_from_this_base(const __shared_count<>&,
+ const enable_shared_from_this* __p)
+ { return __p; }
+
+ template<typename, _Lock_policy>
+ friend class __shared_ptr;
mutable weak_ptr<_Tp> _M_weak_this;
};
- template<typename _Tp1, typename _Tp2>
- inline void
- __enable_shared_from_this_helper(const __shared_count<>& __pn,
- const enable_shared_from_this<_Tp1>*
- __pe, const _Tp2* __px) noexcept
- {
- if (__pe != nullptr)
- __pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn);
- }
-
/**
* @brief Create an object that is owned by a shared_ptr.
* @param __a An allocator.
@@ -643,7 +714,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
size_t
operator()(const shared_ptr<_Tp>& __s) const noexcept
- { return std::hash<_Tp*>()(__s.get()); }
+ {
+ return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
+ }
};
// @} group pointer_abstractions
diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h b/libstdc++-v3/include/bits/shared_ptr_atomic.h
index ad58ebb4fd..d05d686557 100644
--- a/libstdc++-v3/include/bits/shared_ptr_atomic.h
+++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h
@@ -1,6 +1,6 @@
// shared_ptr atomic access -*- C++ -*-
-// Copyright (C) 2014-2016 Free Software Foundation, Inc.
+// Copyright (C) 2014-2017 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
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
index e844c9c91f..c8d7f20d5d 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -1,6 +1,6 @@
// shared_ptr and weak_ptr implementation details -*- C++ -*-
-// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+// Copyright (C) 2007-2017 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
@@ -49,8 +49,12 @@
#ifndef _SHARED_PTR_BASE_H
#define _SHARED_PTR_BASE_H 1
-#include <typeinfo>
+#if __cpp_rtti
+# include <typeinfo>
+#endif
#include <bits/allocated_ptr.h>
+#include <bits/refwrap.h>
+#include <bits/stl_function.h>
#include <ext/aligned_buffer.h>
namespace std _GLIBCXX_VISIBILITY(default)
@@ -70,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public:
virtual char const* what() const noexcept;
- virtual ~bad_weak_ptr() noexcept;
+ virtual ~bad_weak_ptr() noexcept;
};
// Substitute for bad_weak_ptr object in the case of -fno-exceptions.
@@ -108,31 +112,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class _Sp_counted_base
: public _Mutex_base<_Lp>
{
- public:
+ public:
_Sp_counted_base() noexcept
: _M_use_count(1), _M_weak_count(1) { }
-
+
virtual
~_Sp_counted_base() noexcept
{ }
-
+
// Called when _M_use_count drops to zero, to release the resources
// managed by *this.
virtual void
_M_dispose() noexcept = 0;
-
+
// Called when _M_weak_count drops to zero.
virtual void
_M_destroy() noexcept
{ delete this; }
-
+
virtual void*
_M_get_deleter(const std::type_info&) noexcept = 0;
void
_M_add_ref_copy()
{ __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
-
+
void
_M_add_ref_lock();
@@ -167,7 +171,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
}
-
+
void
_M_weak_add_ref() noexcept
{ __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
@@ -189,7 +193,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_destroy();
}
}
-
+
long
_M_get_use_count() const noexcept
{
@@ -198,7 +202,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
}
- private:
+ private:
_Sp_counted_base(_Sp_counted_base const&) = delete;
_Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
@@ -229,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
- template<>
+ template<>
inline void
_Sp_counted_base<_S_atomic>::
_M_add_ref_lock()
@@ -241,10 +245,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__count == 0)
__throw_bad_weak_ptr();
// Replace the current counter value with the old value + 1, as
- // long as it's not changed meanwhile.
+ // long as it's not changed meanwhile.
}
while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
- true, __ATOMIC_ACQ_REL,
+ true, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED));
}
@@ -555,6 +559,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Impl _M_impl;
};
+ // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
+ struct __sp_array_delete
+ {
+ template<typename _Yp>
+ void operator()(_Yp* __p) const { delete[] __p; }
+ };
template<_Lock_policy _Lp>
class __shared_count
@@ -578,6 +588,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+ template<typename _Ptr>
+ __shared_count(_Ptr __p, /* is_array = */ false_type)
+ : __shared_count(__p)
+ { }
+
+ template<typename _Ptr>
+ __shared_count(_Ptr __p, /* is_array = */ true_type)
+ : __shared_count(__p, __sp_array_delete{}, allocator<void>())
+ { }
+
template<typename _Ptr, typename _Deleter>
__shared_count(_Ptr __p, _Deleter __d)
: __shared_count(__p, std::move(__d), allocator<void>())
@@ -844,68 +864,240 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_pi = nullptr;
}
- // Support for enable_shared_from_this.
+#define __cpp_lib_shared_ptr_arrays 201603
- // Friend of __enable_shared_from_this.
- template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
- void
- __enable_shared_from_this_helper(const __shared_count<_Lp>&,
- const __enable_shared_from_this<_Tp1,
- _Lp>*, const _Tp2*) noexcept;
+ // Helper traits for shared_ptr of array:
- // Friend of enable_shared_from_this.
- template<typename _Tp1, typename _Tp2>
- void
- __enable_shared_from_this_helper(const __shared_count<>&,
- const enable_shared_from_this<_Tp1>*,
- const _Tp2*) noexcept;
+ // A pointer type Y* is said to be compatible with a pointer type T* when
+ // either Y* is convertible to T* or Y is U[N] and T is U cv [].
+ template<typename _Yp_ptr, typename _Tp_ptr>
+ struct __sp_compatible_with
+ : false_type
+ { };
- template<_Lock_policy _Lp>
- inline void
- __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept
- { }
+ template<typename _Yp, typename _Tp>
+ struct __sp_compatible_with<_Yp*, _Tp*>
+ : is_convertible<_Yp*, _Tp*>::type
+ { };
+
+ template<typename _Up, size_t _Nm>
+ struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
+ : true_type
+ { };
+
+ template<typename _Up, size_t _Nm>
+ struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
+ : true_type
+ { };
+
+ template<typename _Up, size_t _Nm>
+ struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
+ : true_type
+ { };
+
+ template<typename _Up, size_t _Nm>
+ struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
+ : true_type
+ { };
+
+ // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
+ template<typename _Up, size_t _Nm, typename _Yp, typename = void>
+ struct __sp_is_constructible_arrN
+ : false_type
+ { };
+
+ template<typename _Up, size_t _Nm, typename _Yp>
+ struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
+ : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
+ { };
+
+ // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
+ template<typename _Up, typename _Yp, typename = void>
+ struct __sp_is_constructible_arr
+ : false_type
+ { };
+
+ template<typename _Up, typename _Yp>
+ struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
+ : is_convertible<_Yp(*)[], _Up(*)[]>::type
+ { };
+
+ // Trait to check if shared_ptr<T> can be constructed from Y*.
+ template<typename _Tp, typename _Yp>
+ struct __sp_is_constructible;
+
+ // When T is U[N], Y(*)[N] shall be convertible to T*;
+ template<typename _Up, size_t _Nm, typename _Yp>
+ struct __sp_is_constructible<_Up[_Nm], _Yp>
+ : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
+ { };
+
+ // when T is U[], Y(*)[] shall be convertible to T*;
+ template<typename _Up, typename _Yp>
+ struct __sp_is_constructible<_Up[], _Yp>
+ : __sp_is_constructible_arr<_Up, _Yp>::type
+ { };
+
+ // otherwise, Y* shall be convertible to T*.
+ template<typename _Tp, typename _Yp>
+ struct __sp_is_constructible
+ : is_convertible<_Yp*, _Tp*>::type
+ { };
+
+
+ // Define operator* and operator-> for shared_ptr<T>.
+ template<typename _Tp, _Lock_policy _Lp,
+ bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
+ class __shared_ptr_access
+ {
+ public:
+ using element_type = _Tp;
+
+ element_type&
+ operator*() const noexcept
+ {
+ __glibcxx_assert(_M_get() != nullptr);
+ return *_M_get();
+ }
+
+ element_type*
+ operator->() const noexcept
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
+ return _M_get();
+ }
+
+ private:
+ element_type*
+ _M_get() const noexcept
+ { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
+ };
+
+ // Define operator-> for shared_ptr<cv void>.
+ template<typename _Tp, _Lock_policy _Lp>
+ class __shared_ptr_access<_Tp, _Lp, false, true>
+ {
+ public:
+ using element_type = _Tp;
+
+ element_type*
+ operator->() const noexcept
+ {
+ auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
+ _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
+ return __ptr;
+ }
+ };
+
+ // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
+ template<typename _Tp, _Lock_policy _Lp>
+ class __shared_ptr_access<_Tp, _Lp, true, false>
+ {
+ public:
+ using element_type = typename remove_extent<_Tp>::type;
+
+#if __cplusplus <= 201402L
+ [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
+ element_type&
+ operator*() const noexcept
+ {
+ __glibcxx_assert(_M_get() != nullptr);
+ return *_M_get();
+ }
+
+ [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
+ element_type*
+ operator->() const noexcept
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
+ return _M_get();
+ }
+#endif
+
+ element_type&
+ operator[](ptrdiff_t __i) const
+ {
+ __glibcxx_assert(_M_get() != nullptr);
+ __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
+ return _M_get()[__i];
+ }
+ private:
+ element_type*
+ _M_get() const noexcept
+ { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
+ };
template<typename _Tp, _Lock_policy _Lp>
class __shared_ptr
+ : public __shared_ptr_access<_Tp, _Lp>
{
- template<typename _Ptr>
- using _Convertible
- = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
+ public:
+ using element_type = typename remove_extent<_Tp>::type;
+
+ private:
+ // Constraint for taking ownership of a pointer of type _Yp*:
+ template<typename _Yp>
+ using _SafeConv
+ = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
+
+ // Constraint for construction from shared_ptr and weak_ptr:
+ template<typename _Yp, typename _Res = void>
+ using _Compatible = typename
+ enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
+
+ // Constraint for assignment from shared_ptr and weak_ptr:
+ template<typename _Yp>
+ using _Assignable = _Compatible<_Yp, __shared_ptr&>;
+
+ // Constraint for construction from unique_ptr:
+ template<typename _Yp, typename _Del, typename _Res = void,
+ typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
+ using _UniqCompatible = typename enable_if<__and_<
+ __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*>
+ >::value, _Res>::type;
+
+ // Constraint for assignment from unique_ptr:
+ template<typename _Yp, typename _Del>
+ using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
public:
- typedef _Tp element_type;
+
+#if __cplusplus > 201402L
+ using weak_type = __weak_ptr<_Tp, _Lp>;
+#endif
constexpr __shared_ptr() noexcept
: _M_ptr(0), _M_refcount()
{ }
- template<typename _Tp1>
- explicit __shared_ptr(_Tp1* __p)
- : _M_ptr(__p), _M_refcount(__p)
+ template<typename _Yp, typename = _SafeConv<_Yp>>
+ explicit
+ __shared_ptr(_Yp* __p)
+ : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
{
- __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
- static_assert( !is_void<_Tp1>::value, "incomplete type" );
- static_assert( sizeof(_Tp1) > 0, "incomplete type" );
- __enable_shared_from_this_helper(_M_refcount, __p, __p);
+ static_assert( !is_void<_Yp>::value, "incomplete type" );
+ static_assert( sizeof(_Yp) > 0, "incomplete type" );
+ _M_enable_shared_from_this_with(__p);
}
- template<typename _Tp1, typename _Deleter>
- __shared_ptr(_Tp1* __p, _Deleter __d)
+ template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
+ __shared_ptr(_Yp* __p, _Deleter __d)
: _M_ptr(__p), _M_refcount(__p, __d)
{
- __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
- // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
- __enable_shared_from_this_helper(_M_refcount, __p, __p);
+ static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
+ "deleter expression d(p) is well-formed");
+ _M_enable_shared_from_this_with(__p);
}
- template<typename _Tp1, typename _Deleter, typename _Alloc>
- __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
+ template<typename _Yp, typename _Deleter, typename _Alloc,
+ typename = _SafeConv<_Yp>>
+ __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
: _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
{
- __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
- // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
- __enable_shared_from_this_helper(_M_refcount, __p, __p);
+ static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
+ "deleter expression d(p) is well-formed");
+ _M_enable_shared_from_this_with(__p);
}
template<typename _Deleter>
@@ -918,8 +1110,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
{ }
- template<typename _Tp1>
- __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
+ template<typename _Yp>
+ __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
+ element_type* __p) noexcept
: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
{ }
@@ -927,8 +1120,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__shared_ptr& operator=(const __shared_ptr&) noexcept = default;
~__shared_ptr() = default;
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
+ template<typename _Yp, typename = _Compatible<_Yp>>
+ __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
{ }
@@ -939,48 +1132,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__r._M_ptr = 0;
}
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
+ template<typename _Yp, typename = _Compatible<_Yp>>
+ __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
: _M_ptr(__r._M_ptr), _M_refcount()
{
_M_refcount._M_swap(__r._M_refcount);
__r._M_ptr = 0;
}
- template<typename _Tp1>
- explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
+ template<typename _Yp, typename = _Compatible<_Yp>>
+ explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
: _M_refcount(__r._M_refcount) // may throw
{
- __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
-
// It is now safe to copy __r._M_ptr, as
// _M_refcount(__r._M_refcount) did not throw.
_M_ptr = __r._M_ptr;
}
// If an exception is thrown this constructor has no effect.
- template<typename _Tp1, typename _Del, typename
- = _Convertible<typename unique_ptr<_Tp1, _Del>::pointer>>
- __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
+ template<typename _Yp, typename _Del,
+ typename = _UniqCompatible<_Yp, _Del>>
+ __shared_ptr(unique_ptr<_Yp, _Del>&& __r)
: _M_ptr(__r.get()), _M_refcount()
{
- __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
auto __raw = _S_raw_ptr(__r.get());
_M_refcount = __shared_count<_Lp>(std::move(__r));
- __enable_shared_from_this_helper(_M_refcount, __raw, __raw);
+ _M_enable_shared_from_this_with(__raw);
}
+#if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
+ protected:
+ // If an exception is thrown this constructor has no effect.
+ template<typename _Tp1, typename _Del,
+ typename enable_if<__and_<
+ __not_<is_array<_Tp>>, is_array<_Tp1>,
+ is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
+ >::value, bool>::type = true>
+ __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
+ : _M_ptr(__r.get()), _M_refcount()
+ {
+ auto __raw = _S_raw_ptr(__r.get());
+ _M_refcount = __shared_count<_Lp>(std::move(__r));
+ _M_enable_shared_from_this_with(__raw);
+ }
+ public:
+#endif
+
#if _GLIBCXX_USE_DEPRECATED
// Postcondition: use_count() == 1 and __r.get() == 0
- template<typename _Tp1>
- __shared_ptr(std::auto_ptr<_Tp1>&& __r);
+ template<typename _Yp, typename = _Compatible<_Yp>>
+ __shared_ptr(auto_ptr<_Yp>&& __r);
#endif
constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
- template<typename _Tp1>
- __shared_ptr&
- operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
+ template<typename _Yp>
+ _Assignable<_Yp>
+ operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
{
_M_ptr = __r._M_ptr;
_M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
@@ -988,9 +1196,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#if _GLIBCXX_USE_DEPRECATED
- template<typename _Tp1>
- __shared_ptr&
- operator=(std::auto_ptr<_Tp1>&& __r)
+ template<typename _Yp>
+ _Assignable<_Yp>
+ operator=(auto_ptr<_Yp>&& __r)
{
__shared_ptr(std::move(__r)).swap(*this);
return *this;
@@ -1004,17 +1212,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
- template<class _Tp1>
- __shared_ptr&
- operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
+ template<class _Yp>
+ _Assignable<_Yp>
+ operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
{
__shared_ptr(std::move(__r)).swap(*this);
return *this;
}
- template<typename _Tp1, typename _Del>
- __shared_ptr&
- operator=(std::unique_ptr<_Tp1, _Del>&& __r)
+ template<typename _Yp, typename _Del>
+ _UniqAssignable<_Yp, _Del>
+ operator=(unique_ptr<_Yp, _Del>&& __r)
{
__shared_ptr(std::move(__r)).swap(*this);
return *this;
@@ -1024,41 +1232,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reset() noexcept
{ __shared_ptr().swap(*this); }
- template<typename _Tp1>
- void
- reset(_Tp1* __p) // _Tp1 must be complete.
+ template<typename _Yp>
+ _SafeConv<_Yp>
+ reset(_Yp* __p) // _Yp must be complete.
{
// Catch self-reset errors.
__glibcxx_assert(__p == 0 || __p != _M_ptr);
__shared_ptr(__p).swap(*this);
}
- template<typename _Tp1, typename _Deleter>
- void
- reset(_Tp1* __p, _Deleter __d)
+ template<typename _Yp, typename _Deleter>
+ _SafeConv<_Yp>
+ reset(_Yp* __p, _Deleter __d)
{ __shared_ptr(__p, __d).swap(*this); }
- template<typename _Tp1, typename _Deleter, typename _Alloc>
- void
- reset(_Tp1* __p, _Deleter __d, _Alloc __a)
+ template<typename _Yp, typename _Deleter, typename _Alloc>
+ _SafeConv<_Yp>
+ reset(_Yp* __p, _Deleter __d, _Alloc __a)
{ __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
- // Allow class instantiation when _Tp is [cv-qual] void.
- typename std::add_lvalue_reference<_Tp>::type
- operator*() const noexcept
- {
- __glibcxx_assert(_M_ptr != 0);
- return *_M_ptr;
- }
-
- _Tp*
- operator->() const noexcept
- {
- _GLIBCXX_DEBUG_PEDASSERT(_M_ptr != 0);
- return _M_ptr;
- }
-
- _Tp*
+ element_type*
get() const noexcept
{ return _M_ptr; }
@@ -1103,7 +1296,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
void* __p = _M_refcount._M_get_deleter(typeid(__tag));
_M_ptr = static_cast<_Tp*>(__p);
- __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
+ _M_enable_shared_from_this_with(_M_ptr);
}
#else
template<typename _Alloc>
@@ -1135,7 +1328,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__shared_count<_Lp> __count(__ptr, __del, __del._M_alloc);
_M_refcount._M_swap(__count);
_M_ptr = __ptr;
- __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
+ _M_enable_shared_from_this_with(_M_ptr);
}
#endif
@@ -1155,6 +1348,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend class __weak_ptr<_Tp, _Lp>;
private:
+
+ template<typename _Yp>
+ using __esft_base_t = decltype(__enable_shared_from_this_base(
+ std::declval<const __shared_count<_Lp>&>(),
+ std::declval<_Yp*>()));
+
+ // Detect an accessible and unambiguous enable_shared_from_this base.
+ template<typename _Yp, typename = void>
+ struct __has_esft_base
+ : false_type { };
+
+ template<typename _Yp>
+ struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
+ : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
+
+ template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
+ typename enable_if<__has_esft_base<_Yp2>::value>::type
+ _M_enable_shared_from_this_with(_Yp* __p) noexcept
+ {
+ if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
+ __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
+ }
+
+ template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
+ typename enable_if<!__has_esft_base<_Yp2>::value>::type
+ _M_enable_shared_from_this_with(_Yp*) noexcept
+ { }
+
void*
_M_get_deleter(const std::type_info& __ti) const noexcept
{ return _M_refcount._M_get_deleter(__ti); }
@@ -1175,7 +1396,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
- _Tp* _M_ptr; // Contained pointer.
+ element_type* _M_ptr; // Contained pointer.
__shared_count<_Lp> _M_refcount; // Reference counter.
};
@@ -1213,24 +1434,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
{ return (bool)__a; }
- template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
+ template<typename _Tp, typename _Up, _Lock_policy _Lp>
inline bool
- operator<(const __shared_ptr<_Tp1, _Lp>& __a,
- const __shared_ptr<_Tp2, _Lp>& __b) noexcept
+ operator<(const __shared_ptr<_Tp, _Lp>& __a,
+ const __shared_ptr<_Up, _Lp>& __b) noexcept
{
- typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
- return std::less<_CT>()(__a.get(), __b.get());
+ using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
+ using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
+ using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
+ return less<_Vp>()(__a.get(), __b.get());
}
template<typename _Tp, _Lock_policy _Lp>
inline bool
operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
- { return std::less<_Tp*>()(__a.get(), nullptr); }
+ {
+ using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
+ return less<_Tp_elt*>()(__a.get(), nullptr);
+ }
template<typename _Tp, _Lock_policy _Lp>
inline bool
operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
- { return std::less<_Tp*>()(nullptr, __a.get()); }
+ {
+ using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
+ return less<_Tp_elt*>()(nullptr, __a.get());
+ }
template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
inline bool
@@ -1257,12 +1486,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, _Lock_policy _Lp>
inline bool
operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
- { return std::less<_Tp*>()(nullptr, __a.get()); }
+ { return nullptr < __a; }
template<typename _Tp, _Lock_policy _Lp>
inline bool
operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
- { return std::less<_Tp*>()(__a.get(), nullptr); }
+ { return __a < nullptr; }
template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
inline bool
@@ -1312,7 +1541,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
inline __shared_ptr<_Tp, _Lp>
static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
- { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
+ {
+ using _Sp = __shared_ptr<_Tp, _Lp>;
+ return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
+ }
// The seemingly equivalent code:
// shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
@@ -1322,7 +1554,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
inline __shared_ptr<_Tp, _Lp>
const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
- { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
+ {
+ using _Sp = __shared_ptr<_Tp, _Lp>;
+ return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
+ }
// The seemingly equivalent code:
// shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
@@ -1333,21 +1568,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline __shared_ptr<_Tp, _Lp>
dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
{
- if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
- return __shared_ptr<_Tp, _Lp>(__r, __p);
- return __shared_ptr<_Tp, _Lp>();
+ using _Sp = __shared_ptr<_Tp, _Lp>;
+ if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
+ return _Sp(__r, __p);
+ return _Sp();
}
+#if __cplusplus > 201402L
+ template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
+ inline __shared_ptr<_Tp, _Lp>
+ reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
+ {
+ using _Sp = __shared_ptr<_Tp, _Lp>;
+ return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
+ }
+#endif
template<typename _Tp, _Lock_policy _Lp>
class __weak_ptr
{
- template<typename _Ptr>
- using _Convertible
- = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
+ template<typename _Yp, typename _Res = void>
+ using _Compatible = typename
+ enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
+
+ // Constraint for assignment from shared_ptr and weak_ptr:
+ template<typename _Yp>
+ using _Assignable = _Compatible<_Yp, __weak_ptr&>;
public:
- typedef _Tp element_type;
+ using element_type = typename remove_extent<_Tp>::type;
constexpr __weak_ptr() noexcept
: _M_ptr(nullptr), _M_refcount()
@@ -1371,13 +1620,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
//
// It is not possible to avoid spurious access violations since
// in multithreaded programs __r._M_ptr may be invalidated at any point.
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
+ template<typename _Yp, typename = _Compatible<_Yp>>
+ __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
: _M_refcount(__r._M_refcount)
{ _M_ptr = __r.lock().get(); }
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
+ template<typename _Yp, typename = _Compatible<_Yp>>
+ __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
{ }
@@ -1385,26 +1634,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
{ __r._M_ptr = nullptr; }
- template<typename _Tp1, typename = _Convertible<_Tp1*>>
- __weak_ptr(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
+ template<typename _Yp, typename = _Compatible<_Yp>>
+ __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
: _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
{ __r._M_ptr = nullptr; }
__weak_ptr&
operator=(const __weak_ptr& __r) noexcept = default;
- template<typename _Tp1>
- __weak_ptr&
- operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
+ template<typename _Yp>
+ _Assignable<_Yp>
+ operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
{
_M_ptr = __r.lock().get();
_M_refcount = __r._M_refcount;
return *this;
}
- template<typename _Tp1>
- __weak_ptr&
- operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
+ template<typename _Yp>
+ _Assignable<_Yp>
+ operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
{
_M_ptr = __r._M_ptr;
_M_refcount = __r._M_refcount;
@@ -1420,9 +1669,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
- template<typename _Tp1>
- __weak_ptr&
- operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
+ template<typename _Yp>
+ _Assignable<_Yp>
+ operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
{
_M_ptr = __r.lock().get();
_M_refcount = std::move(__r._M_refcount);
@@ -1480,7 +1729,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend class __enable_shared_from_this<_Tp, _Lp>;
friend class enable_shared_from_this<_Tp>;
- _Tp* _M_ptr; // Contained pointer.
+ element_type* _M_ptr; // Contained pointer.
__weak_count<_Lp> _M_refcount; // Reference counter.
};
@@ -1506,6 +1755,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __lhs.owner_before(__rhs); }
};
+ template<>
+ struct _Sp_owner_less<void, void>
+ {
+ template<typename _Tp, typename _Up>
+ auto
+ operator()(const _Tp& __lhs, const _Up& __rhs) const
+ -> decltype(__lhs.owner_before(__rhs))
+ { return __lhs.owner_before(__rhs); }
+
+ using is_transparent = void;
+ };
+
template<typename _Tp, _Lock_policy _Lp>
struct owner_less<__shared_ptr<_Tp, _Lp>>
: public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
@@ -1540,32 +1801,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
shared_from_this() const
{ return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ __weak_ptr<_Tp, _Lp>
+ weak_from_this() noexcept
+ { return this->_M_weak_this; }
+
+ __weak_ptr<const _Tp, _Lp>
+ weak_from_this() const noexcept
+ { return this->_M_weak_this; }
+#endif
+
private:
template<typename _Tp1>
void
_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
{ _M_weak_this._M_assign(__p, __n); }
- template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
- friend void
- __enable_shared_from_this_helper(const __shared_count<_Lp1>&,
- const __enable_shared_from_this<_Tp1,
- _Lp1>*, const _Tp2*) noexcept;
+ friend const __enable_shared_from_this*
+ __enable_shared_from_this_base(const __shared_count<_Lp>&,
+ const __enable_shared_from_this* __p)
+ { return __p; }
+
+ template<typename, _Lock_policy>
+ friend class __shared_ptr;
mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
};
- template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
- inline void
- __enable_shared_from_this_helper(const __shared_count<_Lp1>& __pn,
- const __enable_shared_from_this<_Tp1,
- _Lp1>* __pe,
- const _Tp2* __px) noexcept
- {
- if (__pe != nullptr)
- __pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn);
- }
-
template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
inline __shared_ptr<_Tp, _Lp>
__allocate_shared(const _Alloc& __a, _Args&&... __args)
@@ -1590,7 +1852,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
size_t
operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
- { return std::hash<_Tp*>()(__s.get()); }
+ {
+ return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()(
+ __s.get());
+ }
};
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/slice_array.h b/libstdc++-v3/include/bits/slice_array.h
index 2efa199755..cd668fbc1d 100644
--- a/libstdc++-v3/include/bits/slice_array.h
+++ b/libstdc++-v3/include/bits/slice_array.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- slice_array class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
@@ -204,8 +204,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
inline
- slice_array<_Tp>::slice_array(const slice_array<_Tp>& a)
- : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {}
+ slice_array<_Tp>::slice_array(const slice_array<_Tp>& __a)
+ : _M_sz(__a._M_sz), _M_stride(__a._M_stride), _M_array(__a._M_array) {}
// template<typename _Tp>
// inline slice_array<_Tp>::~slice_array () {}
diff --git a/libstdc++-v3/include/bits/specfun.h b/libstdc++-v3/include/bits/specfun.h
index 77bbda36fd..6dd23d2c4c 100644
--- a/libstdc++-v3/include/bits/specfun.h
+++ b/libstdc++-v3/include/bits/specfun.h
@@ -1,6 +1,6 @@
// Mathematical Special Functions for -*- C++ -*-
-// Copyright (C) 2006-2016 Free Software Foundation, Inc.
+// Copyright (C) 2006-2017 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
@@ -38,7 +38,7 @@
#define __cpp_lib_math_special_functions 201603L
-#if __STDCPP_WANT_MATH_SPEC_FUNCS__ == 0
+#if __cplusplus <= 201403L && __STDCPP_WANT_MATH_SPEC_FUNCS__ == 0
# error include <cmath> and define __STDCPP_WANT_MATH_SPEC_FUNCS__
#endif
@@ -126,7 +126,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @subsection promotion Argument Promotion
* The arguments suppled to the non-suffixed functions will be promoted
* according to the following rules:
- * 1. If any argument intended to be floating opint is given an integral value
+ * 1. If any argument intended to be floating point is given an integral value
* That integral value is promoted to double.
* 2. All floating point arguments are promoted up to the largest floating
* point precision among them.
diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc
index 59366203ff..72e8742b4c 100644
--- a/libstdc++-v3/include/bits/sstream.tcc
+++ b/libstdc++-v3/include/bits/sstream.tcc
@@ -1,6 +1,6 @@
// String based streams -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/std_abs.h b/libstdc++-v3/include/bits/std_abs.h
new file mode 100644
index 0000000000..1f4a2cadd1
--- /dev/null
+++ b/libstdc++-v3/include/bits/std_abs.h
@@ -0,0 +1,110 @@
+// -*- C++ -*- C library enhancements header.
+
+// Copyright (C) 2016-2017 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
+
+extern "C++"
+{
+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/std_function.h b/libstdc++-v3/include/bits/std_function.h
new file mode 100644
index 0000000000..b393a94481
--- /dev/null
+++ b/libstdc++-v3/include/bits/std_function.h
@@ -0,0 +1,811 @@
+// Implementation of std::function -*- C++ -*-
+
+// Copyright (C) 2004-2017 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/function.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{functional}
+ */
+
+#ifndef _GLIBCXX_STD_FUNCTION_H
+#define _GLIBCXX_STD_FUNCTION_H 1
+
+#pragma GCC system_header
+
+#if __cplusplus < 201103L
+# include <bits/c++0x_warning.h>
+#else
+
+#if __cpp_rtti
+# include <typeinfo>
+#endif
+#include <bits/stl_function.h>
+#include <bits/invoke.h>
+#include <bits/refwrap.h>
+#include <bits/functexcept.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * Derives from @c unary_function or @c binary_function, or perhaps
+ * nothing, depending on the number of arguments provided. The
+ * primary template is the basis case, which derives nothing.
+ */
+ template<typename _Res, typename... _ArgTypes>
+ struct _Maybe_unary_or_binary_function { };
+
+ /// Derives from @c unary_function, as appropriate.
+ template<typename _Res, typename _T1>
+ struct _Maybe_unary_or_binary_function<_Res, _T1>
+ : std::unary_function<_T1, _Res> { };
+
+ /// Derives from @c binary_function, as appropriate.
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
+ : std::binary_function<_T1, _T2, _Res> { };
+
+
+ /**
+ * @brief Exception class thrown when class template function's
+ * operator() is called with an empty target.
+ * @ingroup exceptions
+ */
+ class bad_function_call : public std::exception
+ {
+ public:
+ virtual ~bad_function_call() noexcept;
+
+ const char* what() const noexcept;
+ };
+
+ /**
+ * Trait identifying "location-invariant" types, meaning that the
+ * address of the object (or any of its members) will not escape.
+ * Trivially copyable types are location-invariant and users can
+ * specialize this trait for other types.
+ */
+ template<typename _Tp>
+ struct __is_location_invariant
+ : is_trivially_copyable<_Tp>::type
+ { };
+
+ class _Undefined_class;
+
+ union _Nocopy_types
+ {
+ void* _M_object;
+ const void* _M_const_object;
+ void (*_M_function_pointer)();
+ void (_Undefined_class::*_M_member_pointer)();
+ };
+
+ union [[gnu::may_alias]] _Any_data
+ {
+ void* _M_access() { return &_M_pod_data[0]; }
+ const void* _M_access() const { return &_M_pod_data[0]; }
+
+ template<typename _Tp>
+ _Tp&
+ _M_access()
+ { return *static_cast<_Tp*>(_M_access()); }
+
+ template<typename _Tp>
+ const _Tp&
+ _M_access() const
+ { return *static_cast<const _Tp*>(_M_access()); }
+
+ _Nocopy_types _M_unused;
+ char _M_pod_data[sizeof(_Nocopy_types)];
+ };
+
+ enum _Manager_operation
+ {
+ __get_type_info,
+ __get_functor_ptr,
+ __clone_functor,
+ __destroy_functor
+ };
+
+ // Simple type wrapper that helps avoid annoying const problems
+ // when casting between void pointers and pointers-to-pointers.
+ template<typename _Tp>
+ struct _Simple_type_wrapper
+ {
+ _Simple_type_wrapper(_Tp __value) : __value(__value) { }
+
+ _Tp __value;
+ };
+
+ template<typename _Tp>
+ struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
+ : __is_location_invariant<_Tp>
+ { };
+
+ template<typename _Signature>
+ class function;
+
+ /// Base class of all polymorphic function object wrappers.
+ class _Function_base
+ {
+ public:
+ static const std::size_t _M_max_size = sizeof(_Nocopy_types);
+ static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
+
+ template<typename _Functor>
+ class _Base_manager
+ {
+ protected:
+ static const bool __stored_locally =
+ (__is_location_invariant<_Functor>::value
+ && sizeof(_Functor) <= _M_max_size
+ && __alignof__(_Functor) <= _M_max_align
+ && (_M_max_align % __alignof__(_Functor) == 0));
+
+ typedef integral_constant<bool, __stored_locally> _Local_storage;
+
+ // Retrieve a pointer to the function object
+ static _Functor*
+ _M_get_pointer(const _Any_data& __source)
+ {
+ const _Functor* __ptr =
+ __stored_locally? std::__addressof(__source._M_access<_Functor>())
+ /* have stored a pointer */ : __source._M_access<_Functor*>();
+ return const_cast<_Functor*>(__ptr);
+ }
+
+ // Clone a location-invariant function object that fits within
+ // an _Any_data structure.
+ static void
+ _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
+ {
+ ::new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
+ }
+
+ // Clone a function object that is not location-invariant or
+ // that cannot fit into an _Any_data structure.
+ static void
+ _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
+ {
+ __dest._M_access<_Functor*>() =
+ new _Functor(*__source._M_access<_Functor*>());
+ }
+
+ // Destroying a location-invariant object may still require
+ // destruction.
+ static void
+ _M_destroy(_Any_data& __victim, true_type)
+ {
+ __victim._M_access<_Functor>().~_Functor();
+ }
+
+ // Destroying an object located on the heap.
+ static void
+ _M_destroy(_Any_data& __victim, false_type)
+ {
+ delete __victim._M_access<_Functor*>();
+ }
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#if __cpp_rtti
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
+#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() = _M_get_pointer(__source);
+ break;
+
+ case __clone_functor:
+ _M_clone(__dest, __source, _Local_storage());
+ break;
+
+ case __destroy_functor:
+ _M_destroy(__dest, _Local_storage());
+ break;
+ }
+ return false;
+ }
+
+ static void
+ _M_init_functor(_Any_data& __functor, _Functor&& __f)
+ { _M_init_functor(__functor, std::move(__f), _Local_storage()); }
+
+ template<typename _Signature>
+ static bool
+ _M_not_empty_function(const function<_Signature>& __f)
+ { return static_cast<bool>(__f); }
+
+ template<typename _Tp>
+ static bool
+ _M_not_empty_function(_Tp* __fp)
+ { return __fp != nullptr; }
+
+ template<typename _Class, typename _Tp>
+ static bool
+ _M_not_empty_function(_Tp _Class::* __mp)
+ { return __mp != nullptr; }
+
+ template<typename _Tp>
+ static bool
+ _M_not_empty_function(const _Tp&)
+ { return true; }
+
+ private:
+ static void
+ _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type)
+ { ::new (__functor._M_access()) _Functor(std::move(__f)); }
+
+ static void
+ _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type)
+ { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); }
+ };
+
+ _Function_base() : _M_manager(nullptr) { }
+
+ ~_Function_base()
+ {
+ if (_M_manager)
+ _M_manager(_M_functor, _M_functor, __destroy_functor);
+ }
+
+ bool _M_empty() const { return !_M_manager; }
+
+ typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
+ _Manager_operation);
+
+ _Any_data _M_functor;
+ _Manager_type _M_manager;
+ };
+
+ template<typename _Signature, typename _Functor>
+ class _Function_handler;
+
+ template<typename _Res, typename _Functor, typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), _Functor>
+ : public _Function_base::_Base_manager<_Functor>
+ {
+ typedef _Function_base::_Base_manager<_Functor> _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
+ {
+ return (*_Base::_M_get_pointer(__functor))(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Functor, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), _Functor>
+ : public _Function_base::_Base_manager<_Functor>
+ {
+ typedef _Function_base::_Base_manager<_Functor> _Base;
+
+ public:
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
+ {
+ (*_Base::_M_get_pointer(__functor))(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Class, typename _Member, typename _Res,
+ typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), _Member _Class::*>
+ : public _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ {
+ typedef _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
+ {
+ return std::__invoke(_Base::_M_get_pointer(__functor)->__value,
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Class, typename _Member, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ : public _Function_base::_Base_manager<
+ _Simple_type_wrapper< _Member _Class::* > >
+ {
+ typedef _Member _Class::* _Functor;
+ typedef _Simple_type_wrapper<_Functor> _Wrapper;
+ typedef _Function_base::_Base_manager<_Wrapper> _Base;
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#if __cpp_rtti
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
+#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() =
+ &_Base::_M_get_pointer(__source)->__value;
+ break;
+
+ default:
+ _Base::_M_manager(__dest, __source, __op);
+ }
+ return false;
+ }
+
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
+ {
+ std::__invoke(_Base::_M_get_pointer(__functor)->__value,
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _From, typename _To>
+ using __check_func_return_type
+ = __or_<is_void<_To>, is_same<_From, _To>, is_convertible<_From, _To>>;
+
+ /**
+ * @brief Primary class template for std::function.
+ * @ingroup functors
+ *
+ * Polymorphic function wrapper.
+ */
+ template<typename _Res, typename... _ArgTypes>
+ class function<_Res(_ArgTypes...)>
+ : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
+ private _Function_base
+ {
+ template<typename _Func,
+ typename _Res2 = typename result_of<_Func&(_ArgTypes...)>::type>
+ struct _Callable : __check_func_return_type<_Res2, _Res> { };
+
+ // Used so the return type convertibility checks aren't done when
+ // performing overload resolution for copy construction/assignment.
+ template<typename _Tp>
+ struct _Callable<function, _Tp> : false_type { };
+
+ template<typename _Cond, typename _Tp>
+ using _Requires = typename enable_if<_Cond::value, _Tp>::type;
+
+ public:
+ typedef _Res result_type;
+
+ // [3.7.2.1] construct/copy/destroy
+
+ /**
+ * @brief Default construct creates an empty function call wrapper.
+ * @post @c !(bool)*this
+ */
+ function() noexcept
+ : _Function_base() { }
+
+ /**
+ * @brief Creates an empty function call wrapper.
+ * @post @c !(bool)*this
+ */
+ function(nullptr_t) noexcept
+ : _Function_base() { }
+
+ /**
+ * @brief %Function copy constructor.
+ * @param __x A %function object with identical call signature.
+ * @post @c bool(*this) == bool(__x)
+ *
+ * The newly-created %function contains a copy of the target of @a
+ * __x (if it has one).
+ */
+ function(const function& __x);
+
+ /**
+ * @brief %Function move constructor.
+ * @param __x A %function object rvalue with identical call signature.
+ *
+ * The newly-created %function contains the target of @a __x
+ * (if it has one).
+ */
+ function(function&& __x) : _Function_base()
+ {
+ __x.swap(*this);
+ }
+
+ /**
+ * @brief Builds a %function that targets a copy of the incoming
+ * function object.
+ * @param __f A %function object that is callable with parameters of
+ * type @c T1, @c T2, ..., @c TN and returns a value convertible
+ * to @c Res.
+ *
+ * The newly-created %function object will target a copy of
+ * @a __f. If @a __f is @c reference_wrapper<F>, then this function
+ * object will contain a reference to the function object @c
+ * __f.get(). If @a __f is a NULL function pointer or NULL
+ * pointer-to-member, the newly-created object will be empty.
+ *
+ * If @a __f is a non-NULL function pointer or an object of type @c
+ * reference_wrapper<F>, this function will not throw.
+ */
+ template<typename _Functor,
+ typename = _Requires<__not_<is_same<_Functor, function>>, void>,
+ typename = _Requires<_Callable<_Functor>, void>>
+ function(_Functor);
+
+ /**
+ * @brief %Function assignment operator.
+ * @param __x A %function with identical call signature.
+ * @post @c (bool)*this == (bool)x
+ * @returns @c *this
+ *
+ * The target of @a __x is copied to @c *this. If @a __x has no
+ * target, then @c *this will be empty.
+ *
+ * If @a __x targets a function pointer or a reference to a function
+ * object, then this operation will not throw an %exception.
+ */
+ function&
+ operator=(const function& __x)
+ {
+ function(__x).swap(*this);
+ return *this;
+ }
+
+ /**
+ * @brief %Function move-assignment operator.
+ * @param __x A %function rvalue with identical call signature.
+ * @returns @c *this
+ *
+ * The target of @a __x is moved to @c *this. If @a __x has no
+ * target, then @c *this will be empty.
+ *
+ * If @a __x targets a function pointer or a reference to a function
+ * object, then this operation will not throw an %exception.
+ */
+ function&
+ operator=(function&& __x)
+ {
+ function(std::move(__x)).swap(*this);
+ return *this;
+ }
+
+ /**
+ * @brief %Function assignment to zero.
+ * @post @c !(bool)*this
+ * @returns @c *this
+ *
+ * The target of @c *this is deallocated, leaving it empty.
+ */
+ function&
+ operator=(nullptr_t) noexcept
+ {
+ if (_M_manager)
+ {
+ _M_manager(_M_functor, _M_functor, __destroy_functor);
+ _M_manager = nullptr;
+ _M_invoker = nullptr;
+ }
+ return *this;
+ }
+
+ /**
+ * @brief %Function assignment to a new target.
+ * @param __f A %function object that is callable with parameters of
+ * type @c T1, @c T2, ..., @c TN and returns a value convertible
+ * to @c Res.
+ * @return @c *this
+ *
+ * This %function object wrapper will target a copy of @a
+ * __f. If @a __f is @c reference_wrapper<F>, then this function
+ * object will contain a reference to the function object @c
+ * __f.get(). If @a __f is a NULL function pointer or NULL
+ * pointer-to-member, @c this object will be empty.
+ *
+ * If @a __f is a non-NULL function pointer or an object of type @c
+ * reference_wrapper<F>, this function will not throw.
+ */
+ template<typename _Functor>
+ _Requires<_Callable<typename decay<_Functor>::type>, function&>
+ operator=(_Functor&& __f)
+ {
+ function(std::forward<_Functor>(__f)).swap(*this);
+ return *this;
+ }
+
+ /// @overload
+ template<typename _Functor>
+ function&
+ operator=(reference_wrapper<_Functor> __f) noexcept
+ {
+ function(__f).swap(*this);
+ return *this;
+ }
+
+ // [3.7.2.2] function modifiers
+
+ /**
+ * @brief Swap the targets of two %function objects.
+ * @param __x A %function with identical call signature.
+ *
+ * Swap the targets of @c this function object and @a __f. This
+ * function will not throw an %exception.
+ */
+ void swap(function& __x) noexcept
+ {
+ std::swap(_M_functor, __x._M_functor);
+ std::swap(_M_manager, __x._M_manager);
+ std::swap(_M_invoker, __x._M_invoker);
+ }
+
+ // [3.7.2.3] function capacity
+
+ /**
+ * @brief Determine if the %function wrapper has a target.
+ *
+ * @return @c true when this %function object contains a target,
+ * or @c false when it is empty.
+ *
+ * This function will not throw an %exception.
+ */
+ explicit operator bool() const noexcept
+ { return !_M_empty(); }
+
+ // [3.7.2.4] function invocation
+
+ /**
+ * @brief Invokes the function targeted by @c *this.
+ * @returns the result of the target.
+ * @throws bad_function_call when @c !(bool)*this
+ *
+ * The function call operator invokes the target function object
+ * stored by @c this.
+ */
+ _Res operator()(_ArgTypes... __args) const;
+
+#if __cpp_rtti
+ // [3.7.2.5] function target access
+ /**
+ * @brief Determine the type of the target of this function object
+ * wrapper.
+ *
+ * @returns the type identifier of the target function object, or
+ * @c typeid(void) if @c !(bool)*this.
+ *
+ * This function will not throw an %exception.
+ */
+ const type_info& target_type() const noexcept;
+
+ /**
+ * @brief Access the stored target function object.
+ *
+ * @return Returns a pointer to the stored target function object,
+ * if @c typeid(_Functor).equals(target_type()); otherwise, a NULL
+ * pointer.
+ *
+ * This function does not throw exceptions.
+ *
+ * @{
+ */
+ template<typename _Functor> _Functor* target() noexcept;
+
+ template<typename _Functor> const _Functor* target() const noexcept;
+ // @}
+#endif
+
+ private:
+ using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...);
+ _Invoker_type _M_invoker;
+ };
+
+#if __cpp_deduction_guides >= 201606
+ template<typename>
+ struct __function_guide_helper
+ { };
+
+ template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+ struct __function_guide_helper<
+ _Res (_Tp::*) (_Args...) noexcept(_Nx)
+ >
+ { using type = _Res(_Args...); };
+
+ template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+ struct __function_guide_helper<
+ _Res (_Tp::*) (_Args...) & noexcept(_Nx)
+ >
+ { using type = _Res(_Args...); };
+
+ template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+ struct __function_guide_helper<
+ _Res (_Tp::*) (_Args...) const noexcept(_Nx)
+ >
+ { using type = _Res(_Args...); };
+
+ template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+ struct __function_guide_helper<
+ _Res (_Tp::*) (_Args...) const & noexcept(_Nx)
+ >
+ { using type = _Res(_Args...); };
+
+ template<typename _Res, typename... _ArgTypes>
+ function(_Res(*)(_ArgTypes...)) -> function<_Res(_ArgTypes...)>;
+
+ template<typename _Functor, typename _Signature = typename
+ __function_guide_helper<decltype(&_Functor::operator())>::type>
+ function(_Functor) -> function<_Signature>;
+#endif
+
+ // Out-of-line member definitions.
+ template<typename _Res, typename... _ArgTypes>
+ function<_Res(_ArgTypes...)>::
+ function(const function& __x)
+ : _Function_base()
+ {
+ if (static_cast<bool>(__x))
+ {
+ __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
+ _M_invoker = __x._M_invoker;
+ _M_manager = __x._M_manager;
+ }
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor, typename, typename>
+ function<_Res(_ArgTypes...)>::
+ function(_Functor __f)
+ : _Function_base()
+ {
+ typedef _Function_handler<_Res(_ArgTypes...), _Functor> _My_handler;
+
+ if (_My_handler::_M_not_empty_function(__f))
+ {
+ _My_handler::_M_init_functor(_M_functor, std::move(__f));
+ _M_invoker = &_My_handler::_M_invoke;
+ _M_manager = &_My_handler::_M_manager;
+ }
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ _Res
+ function<_Res(_ArgTypes...)>::
+ operator()(_ArgTypes... __args) const
+ {
+ if (_M_empty())
+ __throw_bad_function_call();
+ return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
+ }
+
+#if __cpp_rtti
+ template<typename _Res, typename... _ArgTypes>
+ const type_info&
+ function<_Res(_ArgTypes...)>::
+ target_type() const noexcept
+ {
+ if (_M_manager)
+ {
+ _Any_data __typeinfo_result;
+ _M_manager(__typeinfo_result, _M_functor, __get_type_info);
+ return *__typeinfo_result._M_access<const type_info*>();
+ }
+ else
+ return typeid(void);
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ _Functor*
+ function<_Res(_ArgTypes...)>::
+ target() noexcept
+ {
+ const function* __const_this = this;
+ const _Functor* __func = __const_this->template target<_Functor>();
+ return const_cast<_Functor*>(__func);
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ const _Functor*
+ function<_Res(_ArgTypes...)>::
+ target() const noexcept
+ {
+ if (typeid(_Functor) == target_type() && _M_manager)
+ {
+ _Any_data __ptr;
+ _M_manager(__ptr, _M_functor, __get_functor_ptr);
+ return __ptr._M_access<const _Functor*>();
+ }
+ else
+ return nullptr;
+ }
+#endif
+
+ // [20.7.15.2.6] null pointer comparisons
+
+ /**
+ * @brief Compares a polymorphic function object wrapper against 0
+ * (the NULL pointer).
+ * @returns @c true if the wrapper has no target, @c false otherwise
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
+ { return !static_cast<bool>(__f); }
+
+ /// @overload
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
+ { return !static_cast<bool>(__f); }
+
+ /**
+ * @brief Compares a polymorphic function object wrapper against 0
+ * (the NULL pointer).
+ * @returns @c false if the wrapper has no target, @c true otherwise
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
+ { return static_cast<bool>(__f); }
+
+ /// @overload
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
+ { return static_cast<bool>(__f); }
+
+
+ // [20.7.15.2.7] specialized algorithms
+
+ /**
+ * @brief Swap the targets of two polymorphic function object wrappers.
+ *
+ * This function will not throw an %exception.
+ */
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2062. Effect contradictions w/o no-throw guarantee of std::function swaps
+ template<typename _Res, typename... _Args>
+ inline void
+ swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) noexcept
+ { __x.swap(__y); }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++11
+
+#endif // _GLIBCXX_STD_FUNCTION_H
diff --git a/libstdc++-v3/include/bits/std_mutex.h b/libstdc++-v3/include/bits/std_mutex.h
index 49ef752a4e..17d55f5576 100644
--- a/libstdc++-v3/include/bits/std_mutex.h
+++ b/libstdc++-v3/include/bits/std_mutex.h
@@ -1,6 +1,6 @@
// std::mutex implementation -*- C++ -*-
-// Copyright (C) 2003-2016 Free Software Foundation, Inc.
+// Copyright (C) 2003-2017 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
@@ -122,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
native_handle_type
- native_handle()
+ native_handle() noexcept
{ return &_M_mutex; }
};
@@ -139,13 +139,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct adopt_lock_t { explicit adopt_lock_t() = default; };
/// Tag used to prevent a scoped lock from acquiring ownership of a mutex.
- constexpr defer_lock_t defer_lock { };
+ _GLIBCXX17_INLINE constexpr defer_lock_t defer_lock { };
/// Tag used to prevent a scoped lock from blocking if a mutex is locked.
- constexpr try_to_lock_t try_to_lock { };
+ _GLIBCXX17_INLINE constexpr try_to_lock_t try_to_lock { };
/// Tag used to make a scoped lock take ownership of a locked mutex.
- constexpr adopt_lock_t adopt_lock { };
+ _GLIBCXX17_INLINE constexpr adopt_lock_t adopt_lock { };
/** @brief A simple scoped lock type.
*
@@ -161,7 +161,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit lock_guard(mutex_type& __m) : _M_device(__m)
{ _M_device.lock(); }
- lock_guard(mutex_type& __m, adopt_lock_t) : _M_device(__m)
+ lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m)
{ } // calling thread owns mutex
~lock_guard()
@@ -206,7 +206,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock())
{ }
- unique_lock(mutex_type& __m, adopt_lock_t)
+ unique_lock(mutex_type& __m, adopt_lock_t) noexcept
: _M_device(std::__addressof(__m)), _M_owns(true)
{
// XXX calling thread owns mutex
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index c2ac0317f1..2cd5303a10 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -1,6 +1,6 @@
// Algorithm implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -583,6 +583,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Predicate __pred)
{
__first = std::find_if_not(__first, __last, __pred);
+ if (__first == __last)
+ return true;
+ ++__first;
return std::none_of(__first, __last, __pred);
}
@@ -3698,10 +3701,80 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return std::__is_permutation(__first1, __last1, __first2, __last2,
__gnu_cxx::__ops::__iter_comp_iter(__pred));
}
-#endif
+
+#if __cplusplus > 201402L
+
+#define __cpp_lib_clamp 201603
+
+ /**
+ * @brief Returns the value clamped between lo and hi.
+ * @ingroup sorting_algorithms
+ * @param __val A value of arbitrary type.
+ * @param __lo A lower limit of arbitrary type.
+ * @param __hi An upper limit of arbitrary type.
+ * @return max(__val, __lo) if __val < __hi or min(__val, __hi) otherwise.
+ */
+ template<typename _Tp>
+ constexpr const _Tp&
+ clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi)
+ {
+ __glibcxx_assert(!(__hi < __lo));
+ return (__val < __lo) ? __lo : (__hi < __val) ? __hi : __val;
+ }
+
+ /**
+ * @brief Returns the value clamped between lo and hi.
+ * @ingroup sorting_algorithms
+ * @param __val A value of arbitrary type.
+ * @param __lo A lower limit of arbitrary type.
+ * @param __hi An upper limit of arbitrary type.
+ * @param __comp A comparison functor.
+ * @return max(__val, __lo, __comp) if __comp(__val, __hi)
+ * or min(__val, __hi, __comp) otherwise.
+ */
+ template<typename _Tp, typename _Compare>
+ constexpr const _Tp&
+ clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
+ {
+ __glibcxx_assert(!__comp(__hi, __lo));
+ return __comp(__val, __lo) ? __lo : __comp(__hi, __val) ? __hi : __val;
+ }
+#endif // C++17
+#endif // C++14
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
/**
+ * @brief Generate two uniformly distributed integers using a
+ * single distribution invocation.
+ * @param __b0 The upper bound for the first integer.
+ * @param __b1 The upper bound for the second integer.
+ * @param __g A UniformRandomBitGenerator.
+ * @return A pair (i, j) with i and j uniformly distributed
+ * over [0, __b0) and [0, __b1), respectively.
+ *
+ * Requires: __b0 * __b1 <= __g.max() - __g.min().
+ *
+ * Using uniform_int_distribution with a range that is very
+ * small relative to the range of the generator ends up wasting
+ * potentially expensively generated randomness, since
+ * uniform_int_distribution does not store leftover randomness
+ * between invocations.
+ *
+ * If we know we want two integers in ranges that are sufficiently
+ * small, we can compose the ranges, use a single distribution
+ * invocation, and significantly reduce the waste.
+ */
+ template<typename _IntType, typename _UniformRandomBitGenerator>
+ pair<_IntType, _IntType>
+ __gen_two_uniform_ints(_IntType __b0, _IntType __b1,
+ _UniformRandomBitGenerator&& __g)
+ {
+ _IntType __x
+ = uniform_int_distribution<_IntType>{0, (__b0 * __b1) - 1}(__g);
+ return std::make_pair(__x / __b1, __x % __b1);
+ }
+
+ /**
* @brief Shuffle the elements of a sequence using a uniform random
* number generator.
* @ingroup mutating_algorithms
@@ -3733,6 +3806,48 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename std::make_unsigned<_DistanceType>::type __ud_type;
typedef typename std::uniform_int_distribution<__ud_type> __distr_type;
typedef typename __distr_type::param_type __p_type;
+
+ typedef typename remove_reference<_UniformRandomNumberGenerator>::type
+ _Gen;
+ typedef typename common_type<typename _Gen::result_type, __ud_type>::type
+ __uc_type;
+
+ const __uc_type __urngrange = __g.max() - __g.min();
+ const __uc_type __urange = __uc_type(__last - __first);
+
+ if (__urngrange / __urange >= __urange)
+ // I.e. (__urngrange >= __urange * __urange) but without wrap issues.
+ {
+ _RandomAccessIterator __i = __first + 1;
+
+ // Since we know the range isn't empty, an even number of elements
+ // means an uneven number of elements /to swap/, in which case we
+ // do the first one up front:
+
+ if ((__urange % 2) == 0)
+ {
+ __distr_type __d{0, 1};
+ std::iter_swap(__i++, __first + __d(__g));
+ }
+
+ // Now we know that __last - __i is even, so we do the rest in pairs,
+ // using a single distribution invocation to produce swap positions
+ // for two successive elements at a time:
+
+ while (__i != __last)
+ {
+ const __uc_type __swap_range = __uc_type(__i - __first) + 1;
+
+ const pair<__uc_type, __uc_type> __pospos =
+ __gen_two_uniform_ints(__swap_range, __swap_range + 1, __g);
+
+ std::iter_swap(__i++, __first + __pospos.first);
+ std::iter_swap(__i++, __first + __pospos.second);
+ }
+
+ return;
+ }
+
__distr_type __d;
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
@@ -3752,7 +3867,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* @param __first An input iterator.
* @param __last An input iterator.
* @param __f A unary function object.
- * @return @p __f (std::move(@p __f) in C++0x).
+ * @return @p __f
*
* Applies the function object @p __f to each element in the range
* @p [first,last). @p __f must not modify the order of the sequence.
@@ -3767,7 +3882,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
- return _GLIBCXX_MOVE(__f);
+ return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant.
}
/**
@@ -5576,6 +5691,130 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__gnu_cxx::__ops::__iter_comp_iter(__comp));
}
+#if __cplusplus >= 201402L
+ /// Reservoir sampling algorithm.
+ template<typename _InputIterator, typename _RandomAccessIterator,
+ typename _Size, typename _UniformRandomBitGenerator>
+ _RandomAccessIterator
+ __sample(_InputIterator __first, _InputIterator __last, input_iterator_tag,
+ _RandomAccessIterator __out, random_access_iterator_tag,
+ _Size __n, _UniformRandomBitGenerator&& __g)
+ {
+ using __distrib_type = uniform_int_distribution<_Size>;
+ using __param_type = typename __distrib_type::param_type;
+ __distrib_type __d{};
+ _Size __sample_sz = 0;
+ while (__first != __last && __sample_sz != __n)
+ {
+ __out[__sample_sz++] = *__first;
+ ++__first;
+ }
+ for (auto __pop_sz = __sample_sz; __first != __last;
+ ++__first, (void) ++__pop_sz)
+ {
+ const auto __k = __d(__g, __param_type{0, __pop_sz});
+ if (__k < __n)
+ __out[__k] = *__first;
+ }
+ return __out + __sample_sz;
+ }
+
+ /// Selection sampling algorithm.
+ template<typename _ForwardIterator, typename _OutputIterator, typename _Cat,
+ typename _Size, typename _UniformRandomBitGenerator>
+ _OutputIterator
+ __sample(_ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag,
+ _OutputIterator __out, _Cat,
+ _Size __n, _UniformRandomBitGenerator&& __g)
+ {
+ using __distrib_type = uniform_int_distribution<_Size>;
+ using __param_type = typename __distrib_type::param_type;
+ using _USize = make_unsigned_t<_Size>;
+ using _Gen = remove_reference_t<_UniformRandomBitGenerator>;
+ using __uc_type = common_type_t<typename _Gen::result_type, _USize>;
+
+ __distrib_type __d{};
+ _Size __unsampled_sz = std::distance(__first, __last);
+ __n = std::min(__n, __unsampled_sz);
+
+ // If possible, we use __gen_two_uniform_ints to efficiently produce
+ // two random numbers using a single distribution invocation:
+
+ const __uc_type __urngrange = __g.max() - __g.min();
+ if (__urngrange / __uc_type(__unsampled_sz) >= __uc_type(__unsampled_sz))
+ // I.e. (__urngrange >= __unsampled_sz * __unsampled_sz) but without
+ // wrapping issues.
+ {
+ while (__n != 0 && __unsampled_sz >= 2)
+ {
+ const pair<_Size, _Size> __p =
+ __gen_two_uniform_ints(__unsampled_sz, __unsampled_sz - 1, __g);
+
+ --__unsampled_sz;
+ if (__p.first < __n)
+ {
+ *__out++ = *__first;
+ --__n;
+ }
+
+ ++__first;
+
+ if (__n == 0) break;
+
+ --__unsampled_sz;
+ if (__p.second < __n)
+ {
+ *__out++ = *__first;
+ --__n;
+ }
+
+ ++__first;
+ }
+ }
+
+ // The loop above is otherwise equivalent to this one-at-a-time version:
+
+ for (; __n != 0; ++__first)
+ if (__d(__g, __param_type{0, --__unsampled_sz}) < __n)
+ {
+ *__out++ = *__first;
+ --__n;
+ }
+ return __out;
+ }
+
+#if __cplusplus > 201402L
+#define __cpp_lib_sample 201603
+ /// Take a random sample from a population.
+ template<typename _PopulationIterator, typename _SampleIterator,
+ typename _Distance, typename _UniformRandomBitGenerator>
+ _SampleIterator
+ sample(_PopulationIterator __first, _PopulationIterator __last,
+ _SampleIterator __out, _Distance __n,
+ _UniformRandomBitGenerator&& __g)
+ {
+ using __pop_cat = typename
+ std::iterator_traits<_PopulationIterator>::iterator_category;
+ using __samp_cat = typename
+ std::iterator_traits<_SampleIterator>::iterator_category;
+
+ static_assert(
+ __or_<is_convertible<__pop_cat, forward_iterator_tag>,
+ is_convertible<__samp_cat, random_access_iterator_tag>>::value,
+ "output range must use a RandomAccessIterator when input range"
+ " does not meet the ForwardIterator requirements");
+
+ static_assert(is_integral<_Distance>::value,
+ "sample size must be an integer type");
+
+ typename iterator_traits<_PopulationIterator>::difference_type __d = __n;
+ return std::__sample(__first, __last, __pop_cat{}, __out, __samp_cat{},
+ __d, std::forward<_UniformRandomBitGenerator>(__g));
+ }
+#endif // C++17
+#endif // C++14
+
_GLIBCXX_END_NAMESPACE_ALGO
} // namespace std
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 210b173454..ea7cd21023 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1,6 +1,6 @@
// Core algorithmic facilities -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 629fe4dd90..37e000ad96 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1,6 +1,6 @@
// vector<bool> specialization -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -500,6 +500,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Bit_alloc_traits::deallocate(_M_impl,
_M_impl._M_end_of_storage - __n,
__n);
+ _M_impl._M_start = _M_impl._M_finish = _Bit_iterator();
+ _M_impl._M_end_of_storage = _Bit_pointer();
}
}
@@ -1054,9 +1056,18 @@ template<typename _Alloc>
#if __cplusplus >= 201103L
template<typename... _Args>
+#if __cplusplus > 201402L
+ reference
+#else
void
+#endif
emplace_back(_Args&&... __args)
- { push_back(bool(__args...)); }
+ {
+ push_back(bool(__args...));
+#if __cplusplus > 201402L
+ return back();
+#endif
+ }
template<typename... _Args>
iterator
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index 3d126288d8..c1504e9bcb 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -1,6 +1,6 @@
// nonstandard construct and destroy functions -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -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_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index d7a9d523e3..6090635b7d 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -1,6 +1,6 @@
// Deque implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -63,6 +63,8 @@
#include <initializer_list>
#endif
+#include <debug/assertions.h>
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
@@ -106,10 +108,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
struct _Deque_iterator
{
#if __cplusplus < 201103L
- typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
+ typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
- typedef _Tp* _Elt_pointer;
- typedef _Tp** _Map_pointer;
+ typedef _Tp* _Elt_pointer;
+ typedef _Tp** _Map_pointer;
#else
private:
template<typename _Up>
@@ -126,13 +128,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT
{ return __deque_buf_size(sizeof(_Tp)); }
- typedef std::random_access_iterator_tag iterator_category;
- typedef _Tp value_type;
- typedef _Ptr pointer;
- typedef _Ref reference;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Deque_iterator _Self;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef _Ptr pointer;
+ typedef _Ref reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Deque_iterator _Self;
_Elt_pointer _M_cur;
_Elt_pointer _M_first;
@@ -141,14 +143,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Deque_iterator(_Elt_pointer __x, _Map_pointer __y) _GLIBCXX_NOEXCEPT
: _M_cur(__x), _M_first(*__y),
- _M_last(*__y + _S_buffer_size()), _M_node(__y) { }
+ _M_last(*__y + _S_buffer_size()), _M_node(__y) { }
_Deque_iterator() _GLIBCXX_NOEXCEPT
: _M_cur(), _M_first(), _M_last(), _M_node() { }
_Deque_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT
: _M_cur(__x._M_cur), _M_first(__x._M_first),
- _M_last(__x._M_last), _M_node(__x._M_node) { }
+ _M_last(__x._M_last), _M_node(__x._M_node) { }
iterator
_M_const_cast() const _GLIBCXX_NOEXCEPT
@@ -212,7 +214,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
const difference_type __node_offset =
__offset > 0 ? __offset / difference_type(_S_buffer_size())
- : -difference_type((-__offset - 1)
+ : -difference_type((-__offset - 1)
/ _S_buffer_size()) - 1;
_M_set_node(_M_node + __node_offset);
_M_cur = _M_first + (__offset - __node_offset
@@ -243,7 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
{ return *(*this + __n); }
- /**
+ /**
* Prepares to traverse new_node. Sets everything except
* _M_cur, which should therefore be set by the caller
* immediately afterwards, based on _M_first and _M_last.
@@ -291,7 +293,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
{ return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
- : (__x._M_node < __y._M_node); }
+ : (__x._M_node < __y._M_node); }
template<typename _Tp, typename _RefL, typename _PtrL,
typename _RefR, typename _PtrR>
@@ -299,7 +301,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
{ return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
- : (__x._M_node < __y._M_node); }
+ : (__x._M_node < __y._M_node); }
template<typename _Tp, typename _Ref, typename _Ptr>
inline bool
@@ -475,14 +477,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef __gnu_cxx::__alloc_traits<_Map_alloc_type> _Map_alloc_traits;
public:
- typedef _Alloc allocator_type;
+ typedef _Alloc allocator_type;
typedef typename _Alloc_traits::size_type size_type;
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_get_Tp_allocator()); }
- typedef _Deque_iterator<_Tp, _Tp&, _Ptr> iterator;
+ typedef _Deque_iterator<_Tp, _Tp&, _Ptr> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, _Ptr_const> const_iterator;
_Deque_base()
@@ -595,7 +597,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Ptr
_M_allocate_node()
- {
+ {
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Traits;
return _Traits::allocate(_M_impl, __deque_buf_size(sizeof(_Tp)));
}
@@ -828,12 +830,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class deque : protected _Deque_base<_Tp, _Alloc>
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
- typedef typename _Alloc::value_type _Alloc_value_type;
-#if __cplusplus < 201103L
+ typedef typename _Alloc::value_type _Alloc_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
-#endif
+# endif
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
+#endif
typedef _Deque_base<_Tp, _Alloc> _Base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
@@ -841,18 +845,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef typename _Base::_Map_pointer _Map_pointer;
public:
- typedef _Tp value_type;
- typedef typename _Alloc_traits::pointer pointer;
- typedef typename _Alloc_traits::const_pointer const_pointer;
- typedef typename _Alloc_traits::reference reference;
- typedef typename _Alloc_traits::const_reference const_reference;
- typedef typename _Base::iterator iterator;
- typedef typename _Base::const_iterator const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Alloc allocator_type;
+ typedef _Tp value_type;
+ typedef typename _Alloc_traits::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Alloc allocator_type;
protected:
static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT
@@ -868,7 +872,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
using _Base::_M_deallocate_map;
using _Base::_M_get_Tp_allocator;
- /**
+ /**
* A total of four data members accumulated down the hierarchy.
* May be accessed via _M_impl.*
*/
@@ -937,13 +941,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Deque copy constructor.
* @param __x A %deque of identical element and allocator types.
*
- * The newly-created %deque uses a copy of the allocation object used
- * by @a __x.
+ * The newly-created %deque uses a copy of the allocator object used
+ * by @a __x (unless the allocator traits dictate a different object).
*/
deque(const deque& __x)
: _Base(_Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()),
__x.size())
- { std::__uninitialized_copy_a(__x.begin(), __x.end(),
+ { std::__uninitialized_copy_a(__x.begin(), __x.end(),
this->_M_impl._M_start,
_M_get_Tp_allocator()); }
@@ -1016,16 +1020,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- deque(_InputIterator __first, _InputIterator __last,
+ deque(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
- { _M_initialize_dispatch(__first, __last, __false_type()); }
+ { _M_initialize_dispatch(__first, __last, __false_type()); }
#else
template<typename _InputIterator>
- deque(_InputIterator __first, _InputIterator __last,
+ deque(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
- {
+ {
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
@@ -1044,8 +1048,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Deque assignment operator.
* @param __x A %deque of identical element and allocator types.
*
- * All the elements of @a x are copied, but unlike the copy constructor,
- * the allocator object is not copied.
+ * All the elements of @a x are copied.
+ *
+ * The newly-created %deque uses a copy of the allocator object used
+ * by @a __x (unless the allocator traits dictate a different object).
*/
deque&
operator=(const deque& __x);
@@ -1076,12 +1082,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %deque and that the
* resulting %deque's size is the same as the number of elements
- * assigned. Old data may be lost.
+ * assigned.
*/
deque&
operator=(initializer_list<value_type> __l)
{
- this->assign(__l.begin(), __l.end());
+ _M_assign_aux(__l.begin(), __l.end(),
+ random_access_iterator_tag());
return *this;
}
#endif
@@ -1094,7 +1101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* This function fills a %deque with @a n copies of the given
* value. Note that the assignment completely changes the
* %deque and that the resulting %deque's size is the same as
- * the number of elements assigned. Old data may be lost.
+ * the number of elements assigned.
*/
void
assign(size_type __n, const value_type& __val)
@@ -1110,19 +1117,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %deque and that the
* resulting %deque's size is the same as the number of elements
- * assigned. Old data may be lost.
+ * assigned.
*/
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- void
- assign(_InputIterator __first, _InputIterator __last)
- { _M_assign_dispatch(__first, __last, __false_type()); }
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ { _M_assign_dispatch(__first, __last, __false_type()); }
#else
template<typename _InputIterator>
- void
- assign(_InputIterator __first, _InputIterator __last)
- {
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_assign_dispatch(__first, __last, _Integral());
}
@@ -1138,11 +1145,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %deque and that the
* resulting %deque's size is the same as the number of elements
- * assigned. Old data may be lost.
+ * assigned.
*/
void
assign(initializer_list<value_type> __l)
- { this->assign(__l.begin(), __l.end()); }
+ { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); }
#endif
/// Get a copy of the memory allocation object.
@@ -1306,7 +1313,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
const size_type __len = size();
if (__new_size > __len)
- insert(this->_M_impl._M_finish, __new_size - __len, __x);
+ _M_fill_insert(this->_M_impl._M_finish, __new_size - __len, __x);
else if (__new_size < __len)
_M_erase_at_end(this->_M_impl._M_start
+ difference_type(__new_size));
@@ -1328,7 +1335,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
const size_type __len = size();
if (__new_size > __len)
- insert(this->_M_impl._M_finish, __new_size - __len, __x);
+ _M_fill_insert(this->_M_impl._M_finish, __new_size - __len, __x);
else if (__new_size < __len)
_M_erase_at_end(this->_M_impl._M_start
+ difference_type(__new_size));
@@ -1364,7 +1371,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
operator[](size_type __n) _GLIBCXX_NOEXCEPT
- { return this->_M_impl._M_start[difference_type(__n)]; }
+ {
+ __glibcxx_requires_subscript(__n);
+ return this->_M_impl._M_start[difference_type(__n)];
+ }
/**
* @brief Subscript access to the data contained in the %deque.
@@ -1379,7 +1389,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
const_reference
operator[](size_type __n) const _GLIBCXX_NOEXCEPT
- { return this->_M_impl._M_start[difference_type(__n)]; }
+ {
+ __glibcxx_requires_subscript(__n);
+ return this->_M_impl._M_start[difference_type(__n)];
+ }
protected:
/// Safety check used only from at().
@@ -1436,7 +1449,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
front() _GLIBCXX_NOEXCEPT
- { return *begin(); }
+ {
+ __glibcxx_requires_nonempty();
+ return *begin();
+ }
/**
* Returns a read-only (constant) reference to the data at the first
@@ -1444,7 +1460,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
const_reference
front() const _GLIBCXX_NOEXCEPT
- { return *begin(); }
+ {
+ __glibcxx_requires_nonempty();
+ return *begin();
+ }
/**
* Returns a read/write reference to the data at the last element of the
@@ -1453,6 +1472,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
reference
back() _GLIBCXX_NOEXCEPT
{
+ __glibcxx_requires_nonempty();
iterator __tmp = end();
--__tmp;
return *__tmp;
@@ -1465,6 +1485,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_reference
back() const _GLIBCXX_NOEXCEPT
{
+ __glibcxx_requires_nonempty();
const_iterator __tmp = end();
--__tmp;
return *__tmp;
@@ -1486,8 +1507,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
{
_Alloc_traits::construct(this->_M_impl,
- this->_M_impl._M_start._M_cur - 1,
- __x);
+ this->_M_impl._M_start._M_cur - 1,
+ __x);
--this->_M_impl._M_start._M_cur;
}
else
@@ -1500,8 +1521,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ emplace_front(std::move(__x)); }
template<typename... _Args>
- void
- emplace_front(_Args&&... __args);
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
+ emplace_front(_Args&&... __args);
#endif
/**
@@ -1520,7 +1545,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
!= this->_M_impl._M_finish._M_last - 1)
{
_Alloc_traits::construct(this->_M_impl,
- this->_M_impl._M_finish._M_cur, __x);
+ this->_M_impl._M_finish._M_cur, __x);
++this->_M_impl._M_finish._M_cur;
}
else
@@ -1533,8 +1558,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ emplace_back(std::move(__x)); }
template<typename... _Args>
- void
- emplace_back(_Args&&... __args);
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
+ emplace_back(_Args&&... __args);
#endif
/**
@@ -1548,11 +1577,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
pop_front() _GLIBCXX_NOEXCEPT
{
+ __glibcxx_requires_nonempty();
if (this->_M_impl._M_start._M_cur
!= this->_M_impl._M_start._M_last - 1)
{
_Alloc_traits::destroy(this->_M_impl,
- this->_M_impl._M_start._M_cur);
+ this->_M_impl._M_start._M_cur);
++this->_M_impl._M_start._M_cur;
}
else
@@ -1570,12 +1600,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
pop_back() _GLIBCXX_NOEXCEPT
{
+ __glibcxx_requires_nonempty();
if (this->_M_impl._M_finish._M_cur
!= this->_M_impl._M_finish._M_first)
{
--this->_M_impl._M_finish._M_cur;
_Alloc_traits::destroy(this->_M_impl,
- this->_M_impl._M_finish._M_cur);
+ this->_M_impl._M_finish._M_cur);
}
else
_M_pop_back_aux();
@@ -1592,8 +1623,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* with T(std::forward<Args>(args)...) before the specified location.
*/
template<typename... _Args>
- iterator
- emplace(const_iterator __position, _Args&&... __args);
+ iterator
+ emplace(const_iterator __position, _Args&&... __args);
/**
* @brief Inserts given value into %deque before specified iterator.
@@ -1645,7 +1676,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
iterator
insert(const_iterator __p, initializer_list<value_type> __l)
- { return this->insert(__p, __l.begin(), __l.end()); }
+ {
+ auto __offset = __p - cbegin();
+ _M_range_insert_aux(__p._M_const_cast(), __l.begin(), __l.end(),
+ std::random_access_iterator_tag());
+ return begin() + __offset;
+ }
#endif
#if __cplusplus >= 201103L
@@ -1695,10 +1731,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- iterator
- insert(const_iterator __position, _InputIterator __first,
+ iterator
+ insert(const_iterator __position, _InputIterator __first,
_InputIterator __last)
- {
+ {
difference_type __offset = __position - cbegin();
_M_insert_dispatch(__position._M_const_cast(),
__first, __last, __false_type());
@@ -1716,10 +1752,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* by @a __position. This is known as <em>range insert</em>.
*/
template<typename _InputIterator>
- void
- insert(iterator __position, _InputIterator __first,
+ void
+ insert(iterator __position, _InputIterator __first,
_InputIterator __last)
- {
+ {
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_insert_dispatch(__position, __first, __last, _Integral());
@@ -1779,10 +1815,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* (Four pointers, so it should be quite fast.)
* Note that the global std::swap() function is specialized such that
* std::swap(d1,d2) will feed to this function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(deque& __x) _GLIBCXX_NOEXCEPT
{
+#if __cplusplus >= 201103L
+ __glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value
+ || _M_get_Tp_allocator() == __x._M_get_Tp_allocator());
+#endif
_M_impl._M_swap_data(__x._M_impl);
_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
__x._M_get_Tp_allocator());
@@ -1806,22 +1848,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
- {
+ void
+ _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
+ {
_M_initialize_map(static_cast<size_type>(__n));
_M_fill_initialize(__x);
}
// called by the range constructor to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+ void
+ _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
- {
- typedef typename std::iterator_traits<_InputIterator>::
- iterator_category _IterCategory;
- _M_range_initialize(__first, __last, _IterCategory());
+ {
+ _M_range_initialize(__first, __last,
+ std::__iterator_category(__first));
}
// called by the second initialize_dispatch above
@@ -1837,14 +1878,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* push_back on each value from the iterator.
*/
template<typename _InputIterator>
- void
- _M_range_initialize(_InputIterator __first, _InputIterator __last,
+ void
+ _M_range_initialize(_InputIterator __first, _InputIterator __last,
std::input_iterator_tag);
// called by the second initialize_dispatch above
template<typename _ForwardIterator>
- void
- _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
+ void
+ _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
std::forward_iterator_tag);
//@}
@@ -1875,40 +1916,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
- { _M_fill_assign(__n, __val); }
+ void
+ _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+ { _M_fill_assign(__n, __val); }
// called by the range assign to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
+ void
+ _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
- {
- typedef typename std::iterator_traits<_InputIterator>::
- iterator_category _IterCategory;
- _M_assign_aux(__first, __last, _IterCategory());
- }
+ { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
// called by the second assign_dispatch above
template<typename _InputIterator>
- void
- _M_assign_aux(_InputIterator __first, _InputIterator __last,
+ void
+ _M_assign_aux(_InputIterator __first, _InputIterator __last,
std::input_iterator_tag);
// called by the second assign_dispatch above
template<typename _ForwardIterator>
- void
- _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+ void
+ _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
std::forward_iterator_tag)
- {
+ {
const size_type __len = std::distance(__first, __last);
if (__len > size())
{
_ForwardIterator __mid = __first;
std::advance(__mid, size());
std::copy(__first, __mid, begin());
- insert(end(), __mid, __last);
+ _M_range_insert_aux(end(), __mid, __last,
+ std::__iterator_category(__first));
}
else
_M_erase_at_end(std::copy(__first, __last, begin()));
@@ -1922,7 +1960,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (__n > size())
{
std::fill(begin(), end(), __val);
- insert(end(), __n - size(), __val);
+ _M_fill_insert(end(), __n - size(), __val);
}
else
{
@@ -1939,10 +1977,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void _M_push_front_aux(const value_type&);
#else
template<typename... _Args>
- void _M_push_back_aux(_Args&&... __args);
+ void _M_push_back_aux(_Args&&... __args);
template<typename... _Args>
- void _M_push_front_aux(_Args&&... __args);
+ void _M_push_front_aux(_Args&&... __args);
#endif
void _M_pop_back_aux();
@@ -1958,33 +1996,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_insert_dispatch(iterator __pos,
+ void
+ _M_insert_dispatch(iterator __pos,
_Integer __n, _Integer __x, __true_type)
- { _M_fill_insert(__pos, __n, __x); }
+ { _M_fill_insert(__pos, __n, __x); }
// called by the range insert to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_insert_dispatch(iterator __pos,
+ void
+ _M_insert_dispatch(iterator __pos,
_InputIterator __first, _InputIterator __last,
__false_type)
- {
- typedef typename std::iterator_traits<_InputIterator>::
- iterator_category _IterCategory;
- _M_range_insert_aux(__pos, __first, __last, _IterCategory());
+ {
+ _M_range_insert_aux(__pos, __first, __last,
+ std::__iterator_category(__first));
}
// called by the second insert_dispatch above
template<typename _InputIterator>
- void
- _M_range_insert_aux(iterator __pos, _InputIterator __first,
+ void
+ _M_range_insert_aux(iterator __pos, _InputIterator __first,
_InputIterator __last, std::input_iterator_tag);
// called by the second insert_dispatch above
template<typename _ForwardIterator>
- void
- _M_range_insert_aux(iterator __pos, _ForwardIterator __first,
+ void
+ _M_range_insert_aux(iterator __pos, _ForwardIterator __first,
_ForwardIterator __last, std::forward_iterator_tag);
// Called by insert(p,n,x), and the range insert when it turns out to be
@@ -1999,8 +2036,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_insert_aux(iterator __pos, const value_type& __x);
#else
template<typename... _Args>
- iterator
- _M_insert_aux(iterator __pos, _Args&&... __args);
+ iterator
+ _M_insert_aux(iterator __pos, _Args&&... __args);
#endif
// called by insert(p,n,x) via fill_insert
@@ -2009,8 +2046,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// called by range_insert_aux for forward iterators
template<typename _ForwardIterator>
- void
- _M_insert_aux(iterator __pos,
+ void
+ _M_insert_aux(iterator __pos,
_ForwardIterator __first, _ForwardIterator __last,
size_type __n);
@@ -2023,9 +2060,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Called by ~deque().
// NB: Doesn't deallocate the nodes.
template<typename _Alloc1>
- void
- _M_destroy_data(iterator __first, iterator __last, const _Alloc1&)
- { _M_destroy_data_aux(__first, __last); }
+ void
+ _M_destroy_data(iterator __first, iterator __last, const _Alloc1&)
+ { _M_destroy_data_aux(__first, __last); }
void
_M_destroy_data(iterator __first, iterator __last,
@@ -2076,7 +2113,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_reserve_elements_at_front(size_type __n)
{
const size_type __vacancies = this->_M_impl._M_start._M_cur
- - this->_M_impl._M_start._M_first;
+ - this->_M_impl._M_start._M_first;
if (__n > __vacancies)
_M_new_elements_at_front(__n - __vacancies);
return this->_M_impl._M_start - difference_type(__n);
@@ -2196,8 +2233,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
// The rvalue's allocator cannot be moved and is not equal,
// so we need to individually move each element.
- this->assign(std::__make_move_if_noexcept_iterator(__x.begin()),
- std::__make_move_if_noexcept_iterator(__x.end()));
+ _M_assign_aux(std::__make_move_if_noexcept_iterator(__x.begin()),
+ std::__make_move_if_noexcept_iterator(__x.end()),
+ std::random_access_iterator_tag());
__x.clear();
}
}
@@ -2220,7 +2258,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
operator==(const deque<_Tp, _Alloc>& __x,
const deque<_Tp, _Alloc>& __y)
{ return __x.size() == __y.size()
- && std::equal(__x.begin(), __x.end(), __y.begin()); }
+ && std::equal(__x.begin(), __x.end(), __y.begin()); }
/**
* @brief Deque ordering relation.
diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index 68f39ff269..4fbcdb91f5 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -1,6 +1,6 @@
// Functor implementations -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -224,7 +224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus > 201103L
-#define __cpp_lib_transparent_operators 201210
+#define __cpp_lib_transparent_operators 201510
template<>
struct plus<void>
diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h
index 5b405dbab5..f8cd0c0542 100644
--- a/libstdc++-v3/include/bits/stl_heap.h
+++ b/libstdc++-v3/include/bits/stl_heap.h
@@ -1,6 +1,6 @@
// Heap implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -72,7 +72,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Compare>
_Distance
__is_heap_until(_RandomAccessIterator __first, _Distance __n,
- _Compare __comp)
+ _Compare& __comp)
{
_Distance __parent = 0;
for (_Distance __child = 1; __child < __n; ++__child)
@@ -91,8 +91,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline bool
__is_heap(_RandomAccessIterator __first, _Distance __n)
{
- return std::__is_heap_until(__first, __n,
- __gnu_cxx::__ops::__iter_less_iter()) == __n;
+ __gnu_cxx::__ops::_Iter_less_iter __comp;
+ return std::__is_heap_until(__first, __n, __comp) == __n;
}
template<typename _RandomAccessIterator, typename _Compare,
@@ -100,8 +100,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline bool
__is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
{
- return std::__is_heap_until(__first, __n,
- __gnu_cxx::__ops::__iter_comp_iter(__comp)) == __n;
+ typedef __decltype(__comp) _Cmp;
+ __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
+ return std::__is_heap_until(__first, __n, __cmp) == __n;
}
template<typename _RandomAccessIterator>
@@ -113,7 +114,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
- { return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
+ {
+ return std::__is_heap(__first, _GLIBCXX_MOVE(__comp),
+ std::distance(__first, __last));
+ }
// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap,
// + is_heap and is_heap_until in C++0x.
@@ -123,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
__push_heap(_RandomAccessIterator __first,
_Distance __holeIndex, _Distance __topIndex, _Tp __value,
- _Compare __comp)
+ _Compare& __comp)
{
_Distance __parent = (__holeIndex - 1) / 2;
while (__holeIndex > __topIndex && __comp(__first + __parent, __value))
@@ -162,10 +166,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_irreflexive(__first, __last);
__glibcxx_requires_heap(__first, __last - 1);
+ __gnu_cxx::__ops::_Iter_less_val __comp;
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
std::__push_heap(__first, _DistanceType((__last - __first) - 1),
- _DistanceType(0), _GLIBCXX_MOVE(__value),
- __gnu_cxx::__ops::__iter_less_val());
+ _DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
}
/**
@@ -197,10 +201,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
__glibcxx_requires_heap_pred(__first, __last - 1, __comp);
+ __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
+ __cmp(_GLIBCXX_MOVE(__comp));
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
std::__push_heap(__first, _DistanceType((__last - __first) - 1),
- _DistanceType(0), _GLIBCXX_MOVE(__value),
- __gnu_cxx::__ops::__iter_comp_val(__comp));
+ _DistanceType(0), _GLIBCXX_MOVE(__value), __cmp);
}
template<typename _RandomAccessIterator, typename _Distance,
@@ -227,15 +232,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+ (__secondChild - 1)));
__holeIndex = __secondChild - 1;
}
- std::__push_heap(__first, __holeIndex, __topIndex,
- _GLIBCXX_MOVE(__value),
- __gnu_cxx::__ops::__iter_comp_val(__comp));
+ __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
+ __cmp(_GLIBCXX_MOVE(__comp));
+ std::__push_heap(__first, __holeIndex, __topIndex,
+ _GLIBCXX_MOVE(__value), __cmp);
}
template<typename _RandomAccessIterator, typename _Compare>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _RandomAccessIterator __result, _Compare __comp)
+ _RandomAccessIterator __result, _Compare& __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
@@ -277,8 +283,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__last - __first > 1)
{
--__last;
- std::__pop_heap(__first, __last, __last,
- __gnu_cxx::__ops::__iter_less_iter());
+ __gnu_cxx::__ops::_Iter_less_iter __comp;
+ std::__pop_heap(__first, __last, __last, __comp);
}
}
@@ -308,16 +314,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__last - __first > 1)
{
+ typedef __decltype(__comp) _Cmp;
+ __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
--__last;
- std::__pop_heap(__first, __last, __last,
- __gnu_cxx::__ops::__iter_comp_iter(__comp));
+ std::__pop_heap(__first, __last, __last, __cmp);
}
}
template<typename _RandomAccessIterator, typename _Compare>
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Compare __comp)
+ _Compare& __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
@@ -360,8 +367,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
- std::__make_heap(__first, __last,
- __gnu_cxx::__ops::__iter_less_iter());
+ __gnu_cxx::__ops::_Iter_less_iter __comp;
+ std::__make_heap(__first, __last, __comp);
}
/**
@@ -385,14 +392,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- std::__make_heap(__first, __last,
- __gnu_cxx::__ops::__iter_comp_iter(__comp));
+ typedef __decltype(__comp) _Cmp;
+ __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
+ std::__make_heap(__first, __last, __cmp);
}
template<typename _RandomAccessIterator, typename _Compare>
void
__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Compare __comp)
+ _Compare& __comp)
{
while (__last - __first > 1)
{
@@ -422,8 +430,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_irreflexive(__first, __last);
__glibcxx_requires_heap(__first, __last);
- std::__sort_heap(__first, __last,
- __gnu_cxx::__ops::__iter_less_iter());
+ __gnu_cxx::__ops::_Iter_less_iter __comp;
+ std::__sort_heap(__first, __last, __comp);
}
/**
@@ -448,8 +456,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
__glibcxx_requires_heap_pred(__first, __last, __comp);
- std::__sort_heap(__first, __last,
- __gnu_cxx::__ops::__iter_comp_iter(__comp));
+ typedef __decltype(__comp) _Cmp;
+ __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
+ std::__sort_heap(__first, __last, __cmp);
}
#if __cplusplus >= 201103L
@@ -475,9 +484,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
+ __gnu_cxx::__ops::_Iter_less_iter __comp;
return __first +
- std::__is_heap_until(__first, std::distance(__first, __last),
- __gnu_cxx::__ops::__iter_less_iter());
+ std::__is_heap_until(__first, std::distance(__first, __last), __comp);
}
/**
@@ -502,9 +511,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
+ typedef __decltype(__comp) _Cmp;
+ __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
return __first
- + std::__is_heap_until(__first, std::distance(__first, __last),
- __gnu_cxx::__ops::__iter_comp_iter(__comp));
+ + std::__is_heap_until(__first, std::distance(__first, __last), __cmp);
}
/**
@@ -531,7 +541,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
- { return std::is_heap_until(__first, __last, __comp) == __last; }
+ {
+ // concept requirements
+ __glibcxx_function_requires(_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+ __glibcxx_requires_valid_range(__first, __last);
+ __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
+
+ const auto __dist = std::distance(__first, __last);
+ typedef __decltype(__comp) _Cmp;
+ __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
+ return std::__is_heap_until(__first, __dist, __cmp) == __dist;
+ }
#endif
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index 3401cd0fb7..e6ef784ce1 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1,6 +1,6 @@
// Iterators -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -65,6 +65,10 @@
#include <bits/move.h>
#include <bits/ptr_traits.h>
+#if __cplusplus > 201402L
+# define __cpp_lib_array_constexpr 201603
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -118,17 +122,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 235 No specification of default ctor for reverse_iterator
+ _GLIBCXX17_CONSTEXPR
reverse_iterator() : current() { }
/**
* This %iterator will move in the opposite direction that @p x does.
*/
- explicit
+ explicit _GLIBCXX17_CONSTEXPR
reverse_iterator(iterator_type __x) : current(__x) { }
/**
* The copy constructor is normal.
*/
+ _GLIBCXX17_CONSTEXPR
reverse_iterator(const reverse_iterator& __x)
: current(__x.current) { }
@@ -137,13 +143,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* underlying %iterator can be converted to the type of @c current.
*/
template<typename _Iter>
+ _GLIBCXX17_CONSTEXPR
reverse_iterator(const reverse_iterator<_Iter>& __x)
: current(__x.base()) { }
/**
* @return @c current, the %iterator used for underlying work.
*/
- iterator_type
+ _GLIBCXX17_CONSTEXPR iterator_type
base() const
{ return current; }
@@ -157,7 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @c *x remains valid after @c x has been modified or
* destroyed. This is a bug: http://gcc.gnu.org/PR51823
*/
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator*() const
{
_Iterator __tmp = current;
@@ -169,7 +176,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* This requires that @c --current is dereferenceable.
*/
- pointer
+ _GLIBCXX17_CONSTEXPR pointer
operator->() const
{ return &(operator*()); }
@@ -178,7 +185,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Decrements the underlying iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator++()
{
--current;
@@ -190,7 +197,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Decrements the underlying iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator++(int)
{
reverse_iterator __tmp = *this;
@@ -203,7 +210,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Increments the underlying iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator--()
{
++current;
@@ -215,7 +222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Increments the underlying iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator--(int)
{
reverse_iterator __tmp = *this;
@@ -228,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator+(difference_type __n) const
{ return reverse_iterator(current - __n); }
@@ -238,7 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Moves the underlying iterator backwards @a __n steps.
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator+=(difference_type __n)
{
current -= __n;
@@ -250,7 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator-(difference_type __n) const
{ return reverse_iterator(current + __n); }
@@ -260,7 +267,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Moves the underlying iterator forwards @a __n steps.
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator-=(difference_type __n)
{
current += __n;
@@ -272,7 +279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* The underlying iterator must be a Random Access Iterator.
*/
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator[](difference_type __n) const
{ return *(*this + __n); }
};
@@ -288,110 +295,113 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
*/
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __x.base() == __y.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y.base() < __x.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__x == __y); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y < __x; }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__y < __x); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__x < __y); }
- template<typename _Iterator>
- inline typename reverse_iterator<_Iterator>::difference_type
- operator-(const reverse_iterator<_Iterator>& __x,
- const reverse_iterator<_Iterator>& __y)
- { return __y.base() - __x.base(); }
-
- template<typename _Iterator>
- inline reverse_iterator<_Iterator>
- operator+(typename reverse_iterator<_Iterator>::difference_type __n,
- const reverse_iterator<_Iterator>& __x)
- { return reverse_iterator<_Iterator>(__x.base() - __n); }
-
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 280. Comparison of reverse_iterator to const reverse_iterator.
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() == __y.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __y.base() < __x.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return !(__x == __y); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __y < __x; }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return !(__y < __x); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return !(__x < __y); }
+ //@}
+
+#if __cplusplus < 201103L
+ template<typename _Iterator>
+ inline typename reverse_iterator<_Iterator>::difference_type
+ operator-(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return __y.base() - __x.base(); }
template<typename _IteratorL, typename _IteratorR>
-#if __cplusplus >= 201103L
- // DR 685.
- inline auto
+ inline typename reverse_iterator<_IteratorL>::difference_type
operator-(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
- -> decltype(__y.base() - __x.base())
+ { return __y.base() - __x.base(); }
#else
- inline typename reverse_iterator<_IteratorL>::difference_type
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 685. reverse_iterator/move_iterator difference has invalid signatures
+ template<typename _IteratorL, typename _IteratorR>
+ inline _GLIBCXX17_CONSTEXPR auto
operator-(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
-#endif
+ -> decltype(__y.base() - __x.base())
{ return __y.base() - __x.base(); }
- //@}
+#endif
+
+ template<typename _Iterator>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
+ operator+(typename reverse_iterator<_Iterator>::difference_type __n,
+ const reverse_iterator<_Iterator>& __x)
+ { return reverse_iterator<_Iterator>(__x.base() - __n); }
#if __cplusplus >= 201103L
// Same as C++14 make_reverse_iterator but used in C++03 mode too.
template<typename _Iterator>
- inline reverse_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
__make_reverse_iterator(_Iterator __i)
{ return reverse_iterator<_Iterator>(__i); }
@@ -402,7 +412,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// DR 2285. make_reverse_iterator
/// Generator function for reverse_iterator.
template<typename _Iterator>
- inline reverse_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
make_reverse_iterator(_Iterator __i)
{ return reverse_iterator<_Iterator>(__i); }
# endif
@@ -1018,37 +1028,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename remove_reference<__base_ref>::type&&,
__base_ref>::type reference;
+ _GLIBCXX17_CONSTEXPR
move_iterator()
: _M_current() { }
- explicit
+ explicit _GLIBCXX17_CONSTEXPR
move_iterator(iterator_type __i)
: _M_current(__i) { }
template<typename _Iter>
+ _GLIBCXX17_CONSTEXPR
move_iterator(const move_iterator<_Iter>& __i)
: _M_current(__i.base()) { }
- iterator_type
+ _GLIBCXX17_CONSTEXPR iterator_type
base() const
{ return _M_current; }
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator*() const
{ return static_cast<reference>(*_M_current); }
- pointer
+ _GLIBCXX17_CONSTEXPR pointer
operator->() const
{ return _M_current; }
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator++()
{
++_M_current;
return *this;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator++(int)
{
move_iterator __tmp = *this;
@@ -1056,14 +1068,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __tmp;
}
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator--()
{
--_M_current;
return *this;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator--(int)
{
move_iterator __tmp = *this;
@@ -1071,29 +1083,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __tmp;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator+(difference_type __n) const
{ return move_iterator(_M_current + __n); }
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator+=(difference_type __n)
{
_M_current += __n;
return *this;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator-(difference_type __n) const
{ return move_iterator(_M_current - __n); }
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator-=(difference_type __n)
{
_M_current -= __n;
return *this;
}
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator[](difference_type __n) const
{ return std::move(_M_current[__n]); }
};
@@ -1102,100 +1114,93 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// why there are always 2 versions for most of the move_iterator
// operators.
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return __x.base() == __y.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return __x.base() == __y.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return !(__x == __y); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return !(__x == __y); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return __x.base() < __y.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return __x.base() < __y.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return !(__y < __x); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return !(__y < __x); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return __y < __x; }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return __y < __x; }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return !(__x < __y); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return !(__x < __y); }
// DR 685.
template<typename _IteratorL, typename _IteratorR>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
operator-(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
-> decltype(__x.base() - __y.base())
{ return __x.base() - __y.base(); }
template<typename _Iterator>
- inline auto
- operator-(const move_iterator<_Iterator>& __x,
- const move_iterator<_Iterator>& __y)
- -> decltype(__x.base() - __y.base())
- { return __x.base() - __y.base(); }
-
- template<typename _Iterator>
- inline move_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
operator+(typename move_iterator<_Iterator>::difference_type __n,
const move_iterator<_Iterator>& __x)
{ return __x + __n; }
template<typename _Iterator>
- inline move_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
make_move_iterator(_Iterator __i)
{ return move_iterator<_Iterator>(__i); }
@@ -1203,7 +1208,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= typename conditional<__move_if_noexcept_cond
<typename iterator_traits<_Iterator>::value_type>::value,
_Iterator, move_iterator<_Iterator>>::type>
- inline _ReturnType
+ inline _GLIBCXX17_CONSTEXPR _ReturnType
__make_move_if_noexcept_iterator(_Iterator __i)
{ return _ReturnType(__i); }
@@ -1212,7 +1217,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _ReturnType
= typename conditional<__move_if_noexcept_cond<_Tp>::value,
const _Tp*, move_iterator<_Tp*>>::type>
- inline _ReturnType
+ inline _GLIBCXX17_CONSTEXPR _ReturnType
__make_move_if_noexcept_iterator(_Tp* __i)
{ return _ReturnType(__i); }
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
index a8b156d1ec..ce6c3d20e0 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
@@ -1,6 +1,6 @@
// Functions used by iterators -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -75,7 +75,8 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator>
- inline typename iterator_traits<_InputIterator>::difference_type
+ inline _GLIBCXX14_CONSTEXPR
+ typename iterator_traits<_InputIterator>::difference_type
__distance(_InputIterator __first, _InputIterator __last,
input_iterator_tag)
{
@@ -92,7 +93,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator>
- inline typename iterator_traits<_RandomAccessIterator>::difference_type
+ inline _GLIBCXX14_CONSTEXPR
+ typename iterator_traits<_RandomAccessIterator>::difference_type
__distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
random_access_iterator_tag)
{
@@ -131,7 +133,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator>
- inline typename iterator_traits<_InputIterator>::difference_type
+ inline _GLIBCXX17_CONSTEXPR
+ typename iterator_traits<_InputIterator>::difference_type
distance(_InputIterator __first, _InputIterator __last)
{
// concept requirements -- taken care of in __distance
@@ -140,7 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _InputIterator, typename _Distance>
- inline void
+ inline _GLIBCXX14_CONSTEXPR void
__advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
{
// concept requirements
@@ -151,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _BidirectionalIterator, typename _Distance>
- inline void
+ inline _GLIBCXX14_CONSTEXPR void
__advance(_BidirectionalIterator& __i, _Distance __n,
bidirectional_iterator_tag)
{
@@ -167,7 +170,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator, typename _Distance>
- inline void
+ inline _GLIBCXX14_CONSTEXPR void
__advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag)
{
@@ -190,7 +193,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator, typename _Distance>
- inline void
+ inline _GLIBCXX17_CONSTEXPR void
advance(_InputIterator& __i, _Distance __n)
{
// concept requirements -- taken care of in __advance
@@ -201,7 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _ForwardIterator>
- inline _ForwardIterator
+ inline _GLIBCXX17_CONSTEXPR _ForwardIterator
next(_ForwardIterator __x, typename
iterator_traits<_ForwardIterator>::difference_type __n = 1)
{
@@ -213,7 +216,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _BidirectionalIterator>
- inline _BidirectionalIterator
+ inline _GLIBCXX17_CONSTEXPR _BidirectionalIterator
prev(_BidirectionalIterator __x, typename
iterator_traits<_BidirectionalIterator>::difference_type __n = 1)
{
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_types.h b/libstdc++-v3/include/bits/stl_iterator_base_types.h
index 380fbdda9e..24ed016b91 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_types.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_types.h
@@ -1,6 +1,6 @@
// Types used in iterator implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index 1f875177a7..0420dbfbba 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1,6 +1,6 @@
// List implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -76,7 +76,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
// "needless" static_cast'ing later on, but it's all safe
// downcasting.
- /// Common part of a node in the %list.
+ /// Common part of a node in the %list.
struct _List_node_base
{
_List_node_base* _M_next;
@@ -127,14 +127,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp>
struct _List_iterator
{
- typedef _List_iterator<_Tp> _Self;
- typedef _List_node<_Tp> _Node;
+ typedef _List_iterator<_Tp> _Self;
+ typedef _List_node<_Tp> _Node;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
- typedef _Tp value_type;
- typedef _Tp* pointer;
- typedef _Tp& reference;
+ typedef ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef _Tp* pointer;
+ typedef _Tp& reference;
_List_iterator() _GLIBCXX_NOEXCEPT
: _M_node() { }
@@ -206,15 +206,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp>
struct _List_const_iterator
{
- typedef _List_const_iterator<_Tp> _Self;
- typedef const _List_node<_Tp> _Node;
- typedef _List_iterator<_Tp> iterator;
+ typedef _List_const_iterator<_Tp> _Self;
+ typedef const _List_node<_Tp> _Node;
+ typedef _List_iterator<_Tp> iterator;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
- typedef _Tp value_type;
- typedef const _Tp* pointer;
- typedef const _Tp& reference;
+ typedef ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef _Tp value_type;
+ typedef const _Tp* pointer;
+ typedef const _Tp& reference;
_List_const_iterator() _GLIBCXX_NOEXCEPT
: _M_node() { }
@@ -291,7 +291,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Val>
inline bool
operator!=(const _List_iterator<_Val>& __x,
- const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
+ const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
{ return __x._M_node != __y._M_node; }
_GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -447,8 +447,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
void
_M_init() _GLIBCXX_NOEXCEPT
{
- this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
- this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
+ this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
+ this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
_M_set_size(0);
}
};
@@ -497,35 +497,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* pointing to @e D, not to @e A! To get to the head of the %list,
* we start at the tail and move forward by one. When this member
* iterator's next/previous pointers refer to itself, the %list is
- * %empty.
+ * %empty.
*/
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class list : protected _List_base<_Tp, _Alloc>
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
- typedef typename _Alloc::value_type _Alloc_value_type;
+ typedef typename _Alloc::value_type _Alloc_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+# endif
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
+#endif
- typedef _List_base<_Tp, _Alloc> _Base;
- typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
- typedef typename _Base::_Tp_alloc_traits _Tp_alloc_traits;
- typedef typename _Base::_Node_alloc_type _Node_alloc_type;
- typedef typename _Base::_Node_alloc_traits _Node_alloc_traits;
+ typedef _List_base<_Tp, _Alloc> _Base;
+ typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
+ typedef typename _Base::_Tp_alloc_traits _Tp_alloc_traits;
+ typedef typename _Base::_Node_alloc_type _Node_alloc_type;
+ typedef typename _Base::_Node_alloc_traits _Node_alloc_traits;
public:
- typedef _Tp value_type;
+ typedef _Tp value_type;
typedef typename _Tp_alloc_traits::pointer pointer;
typedef typename _Tp_alloc_traits::const_pointer const_pointer;
typedef typename _Tp_alloc_traits::reference reference;
typedef typename _Tp_alloc_traits::const_reference const_reference;
typedef _List_iterator<_Tp> iterator;
typedef _List_const_iterator<_Tp> const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Alloc allocator_type;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Alloc allocator_type;
protected:
// Note that pointers-to-_Node's can be ctor-converted to
@@ -562,8 +566,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
}
#else
template<typename... _Args>
- _Node*
- _M_create_node(_Args&&... __args)
+ _Node*
+ _M_create_node(_Args&&... __args)
{
auto __p = this->_M_get_node();
auto& __alloc = _M_get_Node_allocator();
@@ -643,7 +647,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @param __x A %list of identical element and allocator types.
*
* The newly-created %list uses a copy of the allocation object used
- * by @a __x.
+ * by @a __x (unless the allocator traits dictate a different object).
*/
list(const list& __x)
: _Base(_Node_alloc_traits::
@@ -670,7 +674,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* initializer_list @a __l. This is linear in __l.size().
*/
list(initializer_list<value_type> __l,
- const allocator_type& __a = allocator_type())
+ const allocator_type& __a = allocator_type())
: _Base(_Node_alloc_type(__a))
{ _M_initialize_dispatch(__l.begin(), __l.end(), __false_type()); }
@@ -702,22 +706,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- list(_InputIterator __first, _InputIterator __last,
+ list(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(_Node_alloc_type(__a))
- { _M_initialize_dispatch(__first, __last, __false_type()); }
+ { _M_initialize_dispatch(__first, __last, __false_type()); }
#else
template<typename _InputIterator>
- list(_InputIterator __first, _InputIterator __last,
+ list(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(_Node_alloc_type(__a))
- {
+ {
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
}
#endif
+#if __cplusplus >= 201103L
/**
* No explicit dtor needed as the _Base dtor takes care of
* things. The _Base dtor only erases the elements, and note
@@ -725,13 +730,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* memory is not touched in any way. Managing the pointer is
* the user's responsibility.
*/
+ ~list() = default;
+#endif
/**
* @brief %List assignment operator.
* @param __x A %list of identical element and allocator types.
*
- * All the elements of @a __x are copied, but unlike the copy
- * constructor, the allocator object is not copied.
+ * All the elements of @a __x are copied.
+ *
+ * Whether the allocator is copied depends on the allocator traits.
*/
list&
operator=(const list& __x);
@@ -742,16 +750,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @param __x A %list of identical element and allocator types.
*
* The contents of @a __x are moved into this %list (without copying).
- * @a __x is a valid, but unspecified %list
+ *
+ * Afterwards @a __x is a valid, but unspecified %list
+ *
+ * Whether the allocator is moved depends on the allocator traits.
*/
list&
operator=(list&& __x)
noexcept(_Node_alloc_traits::_S_nothrow_move())
{
constexpr bool __move_storage =
- _Node_alloc_traits::_S_propagate_on_move_assign()
- || _Node_alloc_traits::_S_always_equal();
- _M_move_assign(std::move(__x), __bool_constant<__move_storage>());
+ _Node_alloc_traits::_S_propagate_on_move_assign()
+ || _Node_alloc_traits::_S_always_equal();
+ _M_move_assign(std::move(__x), __bool_constant<__move_storage>());
return *this;
}
@@ -778,7 +789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* This function fills a %list with @a __n copies of the given
* value. Note that the assignment completely changes the %list
* and that the resulting %list's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
void
assign(size_type __n, const value_type& __val)
@@ -794,19 +805,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*
* Note that the assignment completely changes the %list and
* that the resulting %list's size is the same as the number of
- * elements assigned. Old data may be lost.
+ * elements assigned.
*/
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- void
- assign(_InputIterator __first, _InputIterator __last)
- { _M_assign_dispatch(__first, __last, __false_type()); }
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ { _M_assign_dispatch(__first, __last, __false_type()); }
#else
template<typename _InputIterator>
- void
- assign(_InputIterator __first, _InputIterator __last)
- {
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_assign_dispatch(__first, __last, _Integral());
@@ -823,7 +834,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
void
assign(initializer_list<value_type> __l)
- { this->assign(__l.begin(), __l.end()); }
+ { this->_M_assign_dispatch(__l.begin(), __l.end(), __false_type()); }
#endif
/// Get a copy of the memory allocation object.
@@ -1023,7 +1034,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
reference
back() _GLIBCXX_NOEXCEPT
- {
+ {
iterator __tmp = end();
--__tmp;
return *__tmp;
@@ -1035,7 +1046,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
const_reference
back() const _GLIBCXX_NOEXCEPT
- {
+ {
const_iterator __tmp = end();
--__tmp;
return *__tmp;
@@ -1062,9 +1073,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ this->_M_insert(begin(), std::move(__x)); }
template<typename... _Args>
- void
- emplace_front(_Args&&... __args)
- { this->_M_insert(begin(), std::forward<_Args>(__args)...); }
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
+ emplace_front(_Args&&... __args)
+ {
+ this->_M_insert(begin(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return front();
+#endif
+ }
#endif
/**
@@ -1103,9 +1123,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ this->_M_insert(end(), std::move(__x)); }
template<typename... _Args>
- void
- emplace_back(_Args&&... __args)
- { this->_M_insert(end(), std::forward<_Args>(__args)...); }
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
+ emplace_back(_Args&&... __args)
+ {
+ this->_M_insert(end(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return back();
+#endif
+ }
#endif
/**
@@ -1137,8 +1166,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* and references.
*/
template<typename... _Args>
- iterator
- emplace(const_iterator __position, _Args&&... __args);
+ iterator
+ emplace(const_iterator __position, _Args&&... __args);
/**
* @brief Inserts given value into %list before specified iterator.
@@ -1180,7 +1209,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* the specified location. Due to the nature of a %list this
* operation can be done in constant time, and does not
* invalidate iterators and references.
- */
+ */
iterator
insert(const_iterator __position, value_type&& __x)
{ return emplace(__position, std::move(__x)); }
@@ -1279,10 +1308,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* does not invalidate iterators and references.
*/
template<typename _InputIterator>
- void
- insert(iterator __position, _InputIterator __first,
+ void
+ insert(iterator __position, _InputIterator __first,
_InputIterator __last)
- {
+ {
list __tmp(__first, __last, get_allocator());
splice(__position, __tmp);
}
@@ -1348,19 +1377,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* time. Note that the global std::swap() function is
* specialized such that std::swap(l1,l2) will feed to this
* function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(list& __x) _GLIBCXX_NOEXCEPT
{
__detail::_List_node_base::swap(this->_M_impl._M_node,
- __x._M_impl._M_node);
+ __x._M_impl._M_node);
size_t __xsize = __x._M_get_size();
__x._M_set_size(this->_M_get_size());
this->_M_set_size(__xsize);
_Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(),
- __x._M_get_Node_allocator());
+ __x._M_get_Node_allocator());
}
/**
@@ -1372,8 +1403,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
void
clear() _GLIBCXX_NOEXCEPT
{
- _Base::_M_clear();
- _Base::_M_init();
+ _Base::_M_clear();
+ _Base::_M_init();
}
// [23.2.2.4] list operations
@@ -1567,8 +1598,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* responsibility.
*/
template<typename _Predicate>
- void
- remove_if(_Predicate);
+ void
+ remove_if(_Predicate);
/**
* @brief Remove consecutive duplicate elements.
@@ -1596,8 +1627,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Managing the pointer is the user's responsibility.
*/
template<typename _BinaryPredicate>
- void
- unique(_BinaryPredicate);
+ void
+ unique(_BinaryPredicate);
/**
* @brief Merge sorted lists.
@@ -1635,17 +1666,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
#if __cplusplus >= 201103L
template<typename _StrictWeakOrdering>
- void
- merge(list&& __x, _StrictWeakOrdering __comp);
+ void
+ merge(list&& __x, _StrictWeakOrdering __comp);
template<typename _StrictWeakOrdering>
- void
- merge(list& __x, _StrictWeakOrdering __comp)
- { merge(std::move(__x), __comp); }
+ void
+ merge(list& __x, _StrictWeakOrdering __comp)
+ { merge(std::move(__x), __comp); }
#else
template<typename _StrictWeakOrdering>
- void
- merge(list& __x, _StrictWeakOrdering __comp);
+ void
+ merge(list& __x, _StrictWeakOrdering __comp);
#endif
/**
@@ -1673,8 +1704,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* elements remain in list order.
*/
template<typename _StrictWeakOrdering>
- void
- sort(_StrictWeakOrdering);
+ void
+ sort(_StrictWeakOrdering);
protected:
// Internal constructor functions follow.
@@ -1684,16 +1715,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
- { _M_fill_initialize(static_cast<size_type>(__n), __x); }
+ void
+ _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
+ { _M_fill_initialize(static_cast<size_type>(__n), __x); }
// Called by the range constructor to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+ void
+ _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
- {
+ {
for (; __first != __last; ++__first)
#if __cplusplus >= 201103L
emplace_back(*__first);
@@ -1732,14 +1763,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
- { _M_fill_assign(__n, __val); }
+ void
+ _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+ { _M_fill_assign(__n, __val); }
// Called by the range assign to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
+ void
+ _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type);
// Called by assign(n,t), and the range assign when it turns out
@@ -1758,8 +1789,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
void
_M_insert(iterator __position, const value_type& __x)
{
- _Node* __tmp = _M_create_node(__x);
- __tmp->_M_hook(__position._M_node);
+ _Node* __tmp = _M_create_node(__x);
+ __tmp->_M_hook(__position._M_node);
this->_M_inc_size(1);
}
#else
@@ -1778,15 +1809,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_erase(iterator __position) _GLIBCXX_NOEXCEPT
{
this->_M_dec_size(1);
- __position._M_node->_M_unhook();
- _Node* __n = static_cast<_Node*>(__position._M_node);
+ __position._M_node->_M_unhook();
+ _Node* __n = static_cast<_Node*>(__position._M_node);
#if __cplusplus >= 201103L
_Node_alloc_traits::destroy(_M_get_Node_allocator(), __n->_M_valptr());
#else
_Tp_alloc_type(_M_get_Node_allocator()).destroy(__n->_M_valptr());
#endif
- _M_put_node(__n);
+ _M_put_node(__n);
}
// To implement the splice (and merge) bits of N1599.
@@ -1818,16 +1849,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
this->_M_set_size(__x._M_get_size());
__x._M_init();
}
- std::__alloc_on_move(this->_M_get_Node_allocator(),
- __x._M_get_Node_allocator());
+ std::__alloc_on_move(this->_M_get_Node_allocator(),
+ __x._M_get_Node_allocator());
}
void
_M_move_assign(list&& __x, false_type)
{
if (__x._M_get_Node_allocator() == this->_M_get_Node_allocator())
- _M_move_assign(std::move(__x), true_type{});
- else
+ _M_move_assign(std::move(__x), true_type{});
+ else
// The rvalue's allocator cannot be moved, or is not equal,
// so we need to individually move each element.
_M_assign_dispatch(std::__make_move_if_noexcept_iterator(__x.begin()),
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index b259509206..30339536f5 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -1,6 +1,6 @@
// Map implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -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.
@@ -76,7 +79,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @tparam _Key Type of key objects.
* @tparam _Tp Type of mapped objects.
* @tparam _Compare Comparison function object type, defaults to less<_Key>.
- * @tparam _Alloc Allocator type, defaults to
+ * @tparam _Alloc Allocator type, defaults to
* allocator<pair<const _Key, _Tp>.
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
@@ -92,23 +95,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* called (*_unique versus *_equal, same as the standard).
*/
template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
- typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
+ typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class map
{
public:
- typedef _Key key_type;
- typedef _Tp mapped_type;
- typedef std::pair<const _Key, _Tp> value_type;
- typedef _Compare key_compare;
- typedef _Alloc allocator_type;
+ typedef _Key key_type;
+ typedef _Tp mapped_type;
+ typedef std::pair<const _Key, _Tp> value_type;
+ typedef _Compare key_compare;
+ typedef _Alloc allocator_type;
private:
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
- typedef typename _Alloc::value_type _Alloc_value_type;
+ typedef typename _Alloc::value_type _Alloc_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+# endif
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
+#endif
public:
class value_compare
@@ -127,7 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
};
private:
- /// This turns a red-black tree into a [multi]map.
+ /// This turns a red-black tree into a [multi]map.
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
rebind<value_type>::other _Pair_alloc_type;
@@ -142,28 +149,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Alloc_traits::pointer pointer;
- typedef typename _Alloc_traits::const_pointer const_pointer;
- typedef typename _Alloc_traits::reference reference;
- typedef typename _Alloc_traits::const_reference const_reference;
- typedef typename _Rep_type::iterator iterator;
- typedef typename _Rep_type::const_iterator const_iterator;
- typedef typename _Rep_type::size_type size_type;
- typedef typename _Rep_type::difference_type difference_type;
- typedef typename _Rep_type::reverse_iterator reverse_iterator;
+ typedef typename _Alloc_traits::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
+ typedef typename _Rep_type::iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
+ 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)
/**
* @brief Default constructor creates no elements.
*/
- map()
-#if __cplusplus >= 201103L
- noexcept(is_nothrow_default_constructible<allocator_type>::value)
+#if __cplusplus < 201103L
+ map() : _M_t() { }
+#else
+ map() = default;
#endif
- : _M_t() { }
/**
* @brief Creates a %map with no elements.
@@ -177,25 +189,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief %Map copy constructor.
- * @param __x A %map of identical element and allocator types.
*
- * The newly-created %map uses a copy of the allocation object
- * used by @a __x.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
map(const map& __x)
: _M_t(__x._M_t) { }
+#else
+ map(const map&) = default;
-#if __cplusplus >= 201103L
/**
* @brief %Map move constructor.
- * @param __x A %map of identical element and allocator types.
*
- * The newly-created %map contains the exact contents of @a __x.
- * The contents of @a __x are a valid, but unspecified %map.
+ * The newly-created %map contains the exact contents of the moved
+ * instance. The moved instance is a valid, but unspecified, %map.
*/
- map(map&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _M_t(std::move(__x._M_t)) { }
+ map(map&&) = default;
/**
* @brief Builds a %map from an initializer_list.
@@ -236,10 +245,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Allocator-extended range constructor.
template<typename _InputIterator>
- map(_InputIterator __first, _InputIterator __last,
+ map(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: _M_t(_Compare(), _Pair_alloc_type(__a))
- { _M_t._M_insert_unique(__first, __last); }
+ { _M_t._M_insert_unique(__first, __last); }
#endif
/**
@@ -253,9 +262,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* distance(__first,__last)).
*/
template<typename _InputIterator>
- map(_InputIterator __first, _InputIterator __last)
+ map(_InputIterator __first, _InputIterator __last)
: _M_t()
- { _M_t._M_insert_unique(__first, __last); }
+ { _M_t._M_insert_unique(__first, __last); }
/**
* @brief Builds a %map from a range.
@@ -270,36 +279,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* distance(__first,__last)).
*/
template<typename _InputIterator>
- map(_InputIterator __first, _InputIterator __last,
+ map(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
- { _M_t._M_insert_unique(__first, __last); }
+ { _M_t._M_insert_unique(__first, __last); }
- // FIXME There is no dtor declared, but we should have something
- // generated by Doxygen. I don't know what tags to add to this
- // paragraph to make that happen:
+#if __cplusplus >= 201103L
/**
* The dtor only erases the elements, and note that if the elements
* themselves are pointers, the pointed-to memory is not touched in any
* way. Managing the pointer is the user's responsibility.
*/
+ ~map() = default;
+#endif
/**
* @brief %Map assignment operator.
- * @param __x A %map of identical element and allocator types.
*
- * All the elements of @a __x are copied, but unlike the copy
- * constructor, the allocator object is not copied.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
map&
operator=(const map& __x)
{
_M_t = __x._M_t;
return *this;
}
+#else
+ map&
+ operator=(const map&) = default;
-#if __cplusplus >= 201103L
/// Move assignment operator.
map&
operator=(map&&) = default;
@@ -313,7 +323,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %map and
* that the resulting %map's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
map&
operator=(initializer_list<value_type> __l)
@@ -484,7 +494,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::tuple<const key_type&>(__k),
std::tuple<>());
#else
- __i = insert(__i, value_type(__k, mapped_type()));
+ __i = insert(__i, value_type(__k, mapped_type()));
#endif
return (*__i).second;
}
@@ -593,13 +603,67 @@ _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.
*
* @param __k Key to use for finding a possibly existing pair in
* the map.
- * @param __args Arguments used to generate the .second for a new pair
+ * @param __args Arguments used to generate the .second for a new pair
* instance.
*
* @return A pair, of which the first element is an iterator that points
@@ -615,37 +679,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Insertion requires logarithmic time.
*/
template <typename... _Args>
- pair<iterator, bool>
- try_emplace(const key_type& __k, _Args&&... __args)
- {
- iterator __i = lower_bound(__k);
- if (__i == end() || key_comp()(__k, (*__i).first))
- {
- __i = emplace_hint(__i, std::piecewise_construct,
- std::forward_as_tuple(__k),
- std::forward_as_tuple(
- std::forward<_Args>(__args)...));
- return {__i, true};
- }
- return {__i, false};
- }
+ pair<iterator, bool>
+ try_emplace(const key_type& __k, _Args&&... __args)
+ {
+ iterator __i = lower_bound(__k);
+ if (__i == end() || key_comp()(__k, (*__i).first))
+ {
+ __i = emplace_hint(__i, std::piecewise_construct,
+ std::forward_as_tuple(__k),
+ std::forward_as_tuple(
+ std::forward<_Args>(__args)...));
+ return {__i, true};
+ }
+ return {__i, false};
+ }
// move-capable overload
template <typename... _Args>
- pair<iterator, bool>
- try_emplace(key_type&& __k, _Args&&... __args)
- {
- iterator __i = lower_bound(__k);
- if (__i == end() || key_comp()(__k, (*__i).first))
- {
- __i = emplace_hint(__i, std::piecewise_construct,
- std::forward_as_tuple(std::move(__k)),
- std::forward_as_tuple(
- std::forward<_Args>(__args)...));
- return {__i, true};
- }
- return {__i, false};
- }
+ pair<iterator, bool>
+ try_emplace(key_type&& __k, _Args&&... __args)
+ {
+ iterator __i = lower_bound(__k);
+ if (__i == end() || key_comp()(__k, (*__i).first))
+ {
+ __i = emplace_hint(__i, std::piecewise_construct,
+ std::forward_as_tuple(std::move(__k)),
+ std::forward_as_tuple(
+ std::forward<_Args>(__args)...));
+ return {__i, true};
+ }
+ return {__i, false};
+ }
/**
* @brief Attempts to build and insert a std::pair into the %map.
@@ -654,14 +718,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* pair should be inserted.
* @param __k Key to use for finding a possibly existing pair in
* the map.
- * @param __args Arguments used to generate the .second for a new pair
+ * @param __args Arguments used to generate the .second for a new pair
* instance.
* @return An iterator that points to the element with key of the
* std::pair built from @a __args (may or may not be that
* std::pair).
*
* This function is not concerned about whether the insertion took place,
- * and thus does not return a boolean like the single-argument
+ * and thus does not return a boolean like the single-argument
* try_emplace() does. However, if insertion did not take place,
* this function has no effect.
* Note that the first parameter is only a hint and can potentially
@@ -675,40 +739,40 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Insertion requires logarithmic time (if the hint is not taken).
*/
template <typename... _Args>
- iterator
- try_emplace(const_iterator __hint, const key_type& __k,
- _Args&&... __args)
- {
- iterator __i;
- auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
- if (__true_hint.second)
- __i = emplace_hint(iterator(__true_hint.second),
- std::piecewise_construct,
- std::forward_as_tuple(__k),
- std::forward_as_tuple(
- std::forward<_Args>(__args)...));
- else
- __i = iterator(__true_hint.first);
- return __i;
- }
+ iterator
+ try_emplace(const_iterator __hint, const key_type& __k,
+ _Args&&... __args)
+ {
+ iterator __i;
+ auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
+ if (__true_hint.second)
+ __i = emplace_hint(iterator(__true_hint.second),
+ std::piecewise_construct,
+ std::forward_as_tuple(__k),
+ std::forward_as_tuple(
+ std::forward<_Args>(__args)...));
+ else
+ __i = iterator(__true_hint.first);
+ return __i;
+ }
// move-capable overload
template <typename... _Args>
- iterator
- try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
- {
- iterator __i;
- auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
- if (__true_hint.second)
- __i = emplace_hint(iterator(__true_hint.second),
- std::piecewise_construct,
- std::forward_as_tuple(std::move(__k)),
- std::forward_as_tuple(
- std::forward<_Args>(__args)...));
- else
- __i = iterator(__true_hint.first);
- return __i;
- }
+ iterator
+ try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
+ {
+ iterator __i;
+ auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
+ if (__true_hint.second)
+ __i = emplace_hint(iterator(__true_hint.second),
+ std::piecewise_construct,
+ std::forward_as_tuple(std::move(__k)),
+ std::forward_as_tuple(
+ std::forward<_Args>(__args)...));
+ else
+ __i = iterator(__true_hint.first);
+ return __i;
+ }
#endif
/**
@@ -717,8 +781,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @param __x Pair to be inserted (see std::make_pair for easy
* creation of pairs).
*
- * @return A pair, of which the first element is an iterator that
- * points to the possibly inserted pair, and the second is
+ * @return A pair, of which the first element is an iterator that
+ * points to the possibly inserted pair, and the second is
* a bool that is true if the pair was actually inserted.
*
* This function attempts to insert a (key, value) %pair into the %map.
@@ -735,9 +799,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
- std::pair<iterator, bool>
- insert(_Pair&& __x)
- { return _M_t._M_insert_unique(std::forward<_Pair>(__x)); }
+ std::pair<iterator, bool>
+ insert(_Pair&& __x)
+ { return _M_t._M_insert_unique(std::forward<_Pair>(__x)); }
#endif
#if __cplusplus >= 201103L
@@ -788,9 +852,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
- iterator
- insert(const_iterator __position, _Pair&& __x)
- { return _M_t._M_insert_unique_(__position,
+ iterator
+ insert(const_iterator __position, _Pair&& __x)
+ { return _M_t._M_insert_unique_(__position,
std::forward<_Pair>(__x)); }
#endif
@@ -803,9 +867,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Complexity similar to that of the range constructor.
*/
template<typename _InputIterator>
- void
- insert(_InputIterator __first, _InputIterator __last)
- { _M_t._M_insert_unique(__first, __last); }
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ { _M_t._M_insert_unique(__first, __last); }
#if __cplusplus > 201402L
#define __cpp_lib_map_insertion 201411
@@ -813,11 +877,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief Attempts to insert or assign a std::pair into the %map.
* @param __k Key to use for finding a possibly existing pair in
* the map.
- * @param __obj Argument used to generate the .second for a pair
+ * @param __obj Argument used to generate the .second for a pair
* instance.
*
- * @return A pair, of which the first element is an iterator that
- * points to the possibly inserted pair, and the second is
+ * @return A pair, of which the first element is an iterator that
+ * points to the possibly inserted pair, and the second is
* a bool that is true if the pair was actually inserted.
*
* This function attempts to insert a (key, value) %pair into the %map.
@@ -829,39 +893,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Insertion requires logarithmic time.
*/
template <typename _Obj>
- pair<iterator, bool>
- insert_or_assign(const key_type& __k, _Obj&& __obj)
- {
- iterator __i = lower_bound(__k);
- if (__i == end() || key_comp()(__k, (*__i).first))
- {
- __i = emplace_hint(__i, std::piecewise_construct,
- std::forward_as_tuple(__k),
- std::forward_as_tuple(
- std::forward<_Obj>(__obj)));
- return {__i, true};
- }
- (*__i).second = std::forward<_Obj>(__obj);
- return {__i, false};
- }
+ pair<iterator, bool>
+ insert_or_assign(const key_type& __k, _Obj&& __obj)
+ {
+ iterator __i = lower_bound(__k);
+ if (__i == end() || key_comp()(__k, (*__i).first))
+ {
+ __i = emplace_hint(__i, std::piecewise_construct,
+ std::forward_as_tuple(__k),
+ std::forward_as_tuple(
+ std::forward<_Obj>(__obj)));
+ return {__i, true};
+ }
+ (*__i).second = std::forward<_Obj>(__obj);
+ return {__i, false};
+ }
// move-capable overload
template <typename _Obj>
- pair<iterator, bool>
- insert_or_assign(key_type&& __k, _Obj&& __obj)
- {
- iterator __i = lower_bound(__k);
- if (__i == end() || key_comp()(__k, (*__i).first))
- {
- __i = emplace_hint(__i, std::piecewise_construct,
- std::forward_as_tuple(std::move(__k)),
- std::forward_as_tuple(
- std::forward<_Obj>(__obj)));
- return {__i, true};
- }
- (*__i).second = std::forward<_Obj>(__obj);
- return {__i, false};
- }
+ pair<iterator, bool>
+ insert_or_assign(key_type&& __k, _Obj&& __obj)
+ {
+ iterator __i = lower_bound(__k);
+ if (__i == end() || key_comp()(__k, (*__i).first))
+ {
+ __i = emplace_hint(__i, std::piecewise_construct,
+ std::forward_as_tuple(std::move(__k)),
+ std::forward_as_tuple(
+ std::forward<_Obj>(__obj)));
+ return {__i, true};
+ }
+ (*__i).second = std::forward<_Obj>(__obj);
+ return {__i, false};
+ }
/**
* @brief Attempts to insert or assign a std::pair into the %map.
@@ -869,7 +933,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* pair should be inserted.
* @param __k Key to use for finding a possibly existing pair in
* the map.
- * @param __obj Argument used to generate the .second for a pair
+ * @param __obj Argument used to generate the .second for a pair
* instance.
*
* @return An iterator that points to the element with key of
@@ -884,44 +948,44 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Insertion requires logarithmic time.
*/
template <typename _Obj>
- iterator
- insert_or_assign(const_iterator __hint,
- const key_type& __k, _Obj&& __obj)
- {
- iterator __i;
- auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
- if (__true_hint.second)
- {
- return emplace_hint(iterator(__true_hint.second),
- std::piecewise_construct,
- std::forward_as_tuple(__k),
- std::forward_as_tuple(
- std::forward<_Obj>(__obj)));
- }
- __i = iterator(__true_hint.first);
- (*__i).second = std::forward<_Obj>(__obj);
- return __i;
- }
+ iterator
+ insert_or_assign(const_iterator __hint,
+ const key_type& __k, _Obj&& __obj)
+ {
+ iterator __i;
+ auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
+ if (__true_hint.second)
+ {
+ return emplace_hint(iterator(__true_hint.second),
+ std::piecewise_construct,
+ std::forward_as_tuple(__k),
+ std::forward_as_tuple(
+ std::forward<_Obj>(__obj)));
+ }
+ __i = iterator(__true_hint.first);
+ (*__i).second = std::forward<_Obj>(__obj);
+ return __i;
+ }
// move-capable overload
template <typename _Obj>
- iterator
- insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
- {
- iterator __i;
- auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
- if (__true_hint.second)
- {
- return emplace_hint(iterator(__true_hint.second),
- std::piecewise_construct,
- std::forward_as_tuple(std::move(__k)),
- std::forward_as_tuple(
- std::forward<_Obj>(__obj)));
- }
- __i = iterator(__true_hint.first);
- (*__i).second = std::forward<_Obj>(__obj);
- return __i;
- }
+ iterator
+ insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
+ {
+ iterator __i;
+ auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
+ if (__true_hint.second)
+ {
+ return emplace_hint(iterator(__true_hint.second),
+ std::piecewise_construct,
+ std::forward_as_tuple(std::move(__k)),
+ std::forward_as_tuple(
+ std::forward<_Obj>(__obj)));
+ }
+ __i = iterator(__true_hint.first);
+ (*__i).second = std::forward<_Obj>(__obj);
+ return __i;
+ }
#endif
#if __cplusplus >= 201103L
@@ -931,7 +995,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief Erases an element from a %map.
* @param __position An iterator pointing to the element to be erased.
* @return An iterator pointing to the element immediately following
- * @a position prior to the element being erased. If no such
+ * @a position prior to the element being erased. If no such
* element exists, end() is returned.
*
* This function erases an element, pointed to by the given
@@ -939,6 +1003,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* the element, and that if the element is itself a pointer,
* the pointed-to memory is not touched in any way. Managing
* the pointer is the user's responsibility.
+ *
+ * @{
*/
iterator
erase(const_iterator __position)
@@ -949,6 +1015,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator
erase(iterator __position)
{ return _M_t.erase(__position); }
+ // @}
#else
/**
* @brief Erases an element from a %map.
@@ -1027,6 +1094,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* stateless and empty), so it should be quite fast.) Note
* that the global std::swap() function is specialized such
* that std::swap(m1,m2) will feed to this function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(map& __x)
@@ -1129,7 +1198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
- { return _M_t._M_find_tr(__x) == _M_t.end() ? 0 : 1; }
+ { return _M_t._M_count_tr(__x); }
#endif
//@}
@@ -1153,8 +1222,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
+ { return iterator(_M_t._M_lower_bound_tr(__x)); }
#endif
//@}
@@ -1178,8 +1247,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x)))
+ { return const_iterator(_M_t._M_lower_bound_tr(__x)); }
#endif
//@}
@@ -1198,8 +1267,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
+ { return iterator(_M_t._M_upper_bound_tr(__x)); }
#endif
//@}
@@ -1218,8 +1287,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(const_iterator(_M_t._M_upper_bound_tr(__x)))
+ { return const_iterator(_M_t._M_upper_bound_tr(__x)); }
#endif
//@}
@@ -1247,8 +1316,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
equal_range(const _Kt& __x)
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
+ { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
#endif
//@}
@@ -1276,19 +1345,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<const_iterator, const_iterator>(
+ _M_t._M_equal_range_tr(__x)))
+ {
+ return pair<const_iterator, const_iterator>(
+ _M_t._M_equal_range_tr(__x));
+ }
#endif
//@}
template<typename _K1, typename _T1, typename _C1, typename _A1>
- friend bool
- operator==(const map<_K1, _T1, _C1, _A1>&,
+ friend bool
+ operator==(const map<_K1, _T1, _C1, _A1>&,
const map<_K1, _T1, _C1, _A1>&);
template<typename _K1, typename _T1, typename _C1, typename _A1>
- friend bool
- operator<(const map<_K1, _T1, _C1, _A1>&,
+ friend bool
+ operator<(const map<_K1, _T1, _C1, _A1>&,
const map<_K1, _T1, _C1, _A1>&);
};
@@ -1305,7 +1378,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x,
- const map<_Key, _Tp, _Compare, _Alloc>& __y)
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
@@ -1322,35 +1395,35 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x,
- const map<_Key, _Tp, _Compare, _Alloc>& __y)
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Based on operator==
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
- const map<_Key, _Tp, _Compare, _Alloc>& __y)
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x,
- const map<_Key, _Tp, _Compare, _Alloc>& __y)
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
- const map<_Key, _Tp, _Compare, _Alloc>& __y)
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
- const map<_Key, _Tp, _Compare, _Alloc>& __y)
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::map::swap().
@@ -1362,6 +1435,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 94ebf6ebc8..7dc22a96a5 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -1,6 +1,6 @@
// Multimap implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -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.
@@ -74,7 +77,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @tparam _Key Type of key objects.
* @tparam _Tp Type of mapped objects.
* @tparam _Compare Comparison function object type, defaults to less<_Key>.
- * @tparam _Alloc Allocator type, defaults to
+ * @tparam _Alloc Allocator type, defaults to
* allocator<pair<const _Key, _Tp>.
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
@@ -95,19 +98,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class multimap
{
public:
- typedef _Key key_type;
- typedef _Tp mapped_type;
- typedef std::pair<const _Key, _Tp> value_type;
- typedef _Compare key_compare;
- typedef _Alloc allocator_type;
+ typedef _Key key_type;
+ typedef _Tp mapped_type;
+ typedef std::pair<const _Key, _Tp> value_type;
+ typedef _Compare key_compare;
+ typedef _Alloc allocator_type;
private:
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
- typedef typename _Alloc::value_type _Alloc_value_type;
+ typedef typename _Alloc::value_type _Alloc_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+# endif
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
+#endif
public:
class value_compare
@@ -140,28 +147,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Alloc_traits::pointer pointer;
- typedef typename _Alloc_traits::const_pointer const_pointer;
- typedef typename _Alloc_traits::reference reference;
- typedef typename _Alloc_traits::const_reference const_reference;
- typedef typename _Rep_type::iterator iterator;
- typedef typename _Rep_type::const_iterator const_iterator;
- typedef typename _Rep_type::size_type size_type;
- typedef typename _Rep_type::difference_type difference_type;
- typedef typename _Rep_type::reverse_iterator reverse_iterator;
+ typedef typename _Alloc_traits::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
+ typedef typename _Rep_type::iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
+ 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)
/**
* @brief Default constructor creates no elements.
*/
- multimap()
-#if __cplusplus >= 201103L
- noexcept(is_nothrow_default_constructible<allocator_type>::value)
+#if __cplusplus < 201103L
+ multimap() : _M_t() { }
+#else
+ multimap() = default;
#endif
- : _M_t() { }
/**
* @brief Creates a %multimap with no elements.
@@ -175,25 +186,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief %Multimap copy constructor.
- * @param __x A %multimap of identical element and allocator types.
*
- * The newly-created %multimap uses a copy of the allocation object
- * used by @a __x.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
multimap(const multimap& __x)
: _M_t(__x._M_t) { }
+#else
+ multimap(const multimap&) = default;
-#if __cplusplus >= 201103L
/**
* @brief %Multimap move constructor.
- * @param __x A %multimap of identical element and allocator types.
*
- * The newly-created %multimap contains the exact contents of @a __x.
- * The contents of @a __x are a valid, but unspecified %multimap.
+ * The newly-created %multimap contains the exact contents of the
+ * moved instance. The moved instance is a valid, but unspecified
+ * %multimap.
*/
- multimap(multimap&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _M_t(std::move(__x._M_t)) { }
+ multimap(multimap&&) = default;
/**
* @brief Builds a %multimap from an initializer_list.
@@ -233,10 +242,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Allocator-extended range constructor.
template<typename _InputIterator>
- multimap(_InputIterator __first, _InputIterator __last,
+ multimap(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: _M_t(_Compare(), _Pair_alloc_type(__a))
- { _M_t._M_insert_equal(__first, __last); }
+ { _M_t._M_insert_equal(__first, __last); }
#endif
/**
@@ -249,9 +258,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
- multimap(_InputIterator __first, _InputIterator __last)
+ multimap(_InputIterator __first, _InputIterator __last)
: _M_t()
- { _M_t._M_insert_equal(__first, __last); }
+ { _M_t._M_insert_equal(__first, __last); }
/**
* @brief Builds a %multimap from a range.
@@ -265,36 +274,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
- multimap(_InputIterator __first, _InputIterator __last,
+ multimap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
- { _M_t._M_insert_equal(__first, __last); }
+ { _M_t._M_insert_equal(__first, __last); }
- // FIXME There is no dtor declared, but we should have something generated
- // by Doxygen. I don't know what tags to add to this paragraph to make
- // that happen:
+#if __cplusplus >= 201103L
/**
* The dtor only erases the elements, and note that if the elements
* themselves are pointers, the pointed-to memory is not touched in any
- * way. Managing the pointer is the user's responsibility.
+ * way. Managing the pointer is the user's responsibility.
*/
+ ~multimap() = default;
+#endif
/**
* @brief %Multimap assignment operator.
- * @param __x A %multimap of identical element and allocator types.
*
- * All the elements of @a __x are copied, but unlike the copy
- * constructor, the allocator object is not copied.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
multimap&
operator=(const multimap& __x)
{
_M_t = __x._M_t;
return *this;
}
+#else
+ multimap&
+ operator=(const multimap&) = default;
-#if __cplusplus >= 201103L
/// Move assignment operator.
multimap&
operator=(multimap&&) = default;
@@ -308,7 +318,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %multimap and
* that the resulting %multimap's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
multimap&
operator=(initializer_list<value_type> __l)
@@ -320,7 +330,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Get a copy of the memory allocation object.
allocator_type
- get_allocator() const _GLIBCXX_NOEXCEPT
+ get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_t.get_allocator()); }
// iterators
@@ -524,9 +534,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
- iterator
- insert(_Pair&& __x)
- { return _M_t._M_insert_equal(std::forward<_Pair>(__x)); }
+ iterator
+ insert(_Pair&& __x)
+ { return _M_t._M_insert_equal(std::forward<_Pair>(__x)); }
#endif
/**
@@ -561,9 +571,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
- iterator
- insert(const_iterator __position, _Pair&& __x)
- { return _M_t._M_insert_equal_(__position,
+ iterator
+ insert(const_iterator __position, _Pair&& __x)
+ { return _M_t._M_insert_equal_(__position,
std::forward<_Pair>(__x)); }
#endif
@@ -577,9 +587,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Complexity similar to that of the range constructor.
*/
template<typename _InputIterator>
- void
- insert(_InputIterator __first, _InputIterator __last)
- { _M_t._M_insert_equal(__first, __last); }
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ { _M_t._M_insert_equal(__first, __last); }
#if __cplusplus >= 201103L
/**
@@ -594,6 +604,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.
@@ -601,7 +665,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief Erases an element from a %multimap.
* @param __position An iterator pointing to the element to be erased.
* @return An iterator pointing to the element immediately following
- * @a position prior to the element being erased. If no such
+ * @a position prior to the element being erased. If no such
* element exists, end() is returned.
*
* This function erases an element, pointed to by the given iterator,
@@ -609,6 +673,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* and that if the element is itself a pointer, the pointed-to memory is
* not touched in any way. Managing the pointer is the user's
* responsibility.
+ *
+ * @{
*/
iterator
erase(const_iterator __position)
@@ -619,6 +685,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator
erase(iterator __position)
{ return _M_t.erase(__position); }
+ // @}
#else
/**
* @brief Erases an element from a %multimap.
@@ -701,6 +768,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* should be quite fast.)
* Note that the global std::swap() function is specialized such that
* std::swap(m1,m2) will feed to this function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(multimap& __x)
@@ -822,8 +891,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
+ { return iterator(_M_t._M_lower_bound_tr(__x)); }
#endif
//@}
@@ -847,8 +916,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x)))
+ { return const_iterator(_M_t._M_lower_bound_tr(__x)); }
#endif
//@}
@@ -867,8 +936,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
+ { return iterator(_M_t._M_upper_bound_tr(__x)); }
#endif
//@}
@@ -887,8 +956,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(const_iterator(_M_t._M_upper_bound_tr(__x)))
+ { return const_iterator(_M_t._M_upper_bound_tr(__x)); }
#endif
//@}
@@ -914,8 +983,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
equal_range(const _Kt& __x)
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
+ { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
#endif
//@}
@@ -941,19 +1010,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<const_iterator, const_iterator>(
+ _M_t._M_equal_range_tr(__x)))
+ {
+ return pair<const_iterator, const_iterator>(
+ _M_t._M_equal_range_tr(__x));
+ }
#endif
//@}
template<typename _K1, typename _T1, typename _C1, typename _A1>
- friend bool
- operator==(const multimap<_K1, _T1, _C1, _A1>&,
+ friend bool
+ operator==(const multimap<_K1, _T1, _C1, _A1>&,
const multimap<_K1, _T1, _C1, _A1>&);
template<typename _K1, typename _T1, typename _C1, typename _A1>
- friend bool
- operator<(const multimap<_K1, _T1, _C1, _A1>&,
+ friend bool
+ operator<(const multimap<_K1, _T1, _C1, _A1>&,
const multimap<_K1, _T1, _C1, _A1>&);
};
@@ -970,7 +1043,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
@@ -987,46 +1060,70 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Based on operator==
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::multimap::swap().
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline void
swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ multimap<_Key, _Tp, _Compare, _Alloc>& __y)
_GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
{ __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 cc13b3cea3..60a3db844c 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -1,6 +1,6 @@
// Multiset implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -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.
@@ -91,12 +94,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typename _Alloc = std::allocator<_Key> >
class multiset
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
- typedef typename _Alloc::value_type _Alloc_value_type;
+ typedef typename _Alloc::value_type _Alloc_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
+# endif
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
- __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
+ __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
+#endif
public:
// typedefs:
@@ -119,29 +126,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;
public:
- typedef typename _Alloc_traits::pointer pointer;
- typedef typename _Alloc_traits::const_pointer const_pointer;
- typedef typename _Alloc_traits::reference reference;
- typedef typename _Alloc_traits::const_reference const_reference;
+ typedef typename _Alloc_traits::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
- typedef typename _Rep_type::const_iterator iterator;
- typedef typename _Rep_type::const_iterator const_iterator;
- typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
- typedef typename _Rep_type::size_type size_type;
- typedef typename _Rep_type::difference_type difference_type;
+ 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.
*/
- multiset()
-#if __cplusplus >= 201103L
- noexcept(is_nothrow_default_constructible<allocator_type>::value)
+#if __cplusplus < 201103L
+ multiset() : _M_t() { }
+#else
+ multiset() = default;
#endif
- : _M_t() { }
/**
* @brief Creates a %multiset with no elements.
@@ -163,9 +174,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
- multiset(_InputIterator __first, _InputIterator __last)
+ multiset(_InputIterator __first, _InputIterator __last)
: _M_t()
- { _M_t._M_insert_equal(__first, __last); }
+ { _M_t._M_insert_equal(__first, __last); }
/**
* @brief Builds a %multiset from a range.
@@ -179,33 +190,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
- multiset(_InputIterator __first, _InputIterator __last,
+ multiset(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
- { _M_t._M_insert_equal(__first, __last); }
+ { _M_t._M_insert_equal(__first, __last); }
/**
* @brief %Multiset copy constructor.
- * @param __x A %multiset of identical element and allocator types.
*
- * The newly-created %multiset uses a copy of the allocation object used
- * by @a __x.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
multiset(const multiset& __x)
: _M_t(__x._M_t) { }
+#else
+ multiset(const multiset&) = default;
-#if __cplusplus >= 201103L
/**
* @brief %Multiset move constructor.
- * @param __x A %multiset of identical element and allocator types.
*
- * The newly-created %multiset contains the exact contents of @a __x.
- * The contents of @a __x are a valid, but unspecified %multiset.
+ * The newly-created %multiset contains the exact contents of the
+ * moved instance. The moved instance is a valid, but unspecified
+ * %multiset.
*/
- multiset(multiset&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _M_t(std::move(__x._M_t)) { }
+ multiset(multiset&&) = default;
/**
* @brief Builds a %multiset from an initializer_list.
@@ -245,27 +254,35 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Allocator-extended range constructor.
template<typename _InputIterator>
- multiset(_InputIterator __first, _InputIterator __last,
+ multiset(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: _M_t(_Compare(), _Key_alloc_type(__a))
- { _M_t._M_insert_equal(__first, __last); }
+ { _M_t._M_insert_equal(__first, __last); }
+
+ /**
+ * The dtor only erases the elements, and note that if the elements
+ * themselves are pointers, the pointed-to memory is not touched in any
+ * way. Managing the pointer is the user's responsibility.
+ */
+ ~multiset() = default;
#endif
/**
* @brief %Multiset assignment operator.
- * @param __x A %multiset of identical element and allocator types.
*
- * All the elements of @a __x are copied, but unlike the copy
- * constructor, the allocator object is not copied.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
multiset&
operator=(const multiset& __x)
{
_M_t = __x._M_t;
return *this;
}
+#else
+ multiset&
+ operator=(const multiset&) = default;
-#if __cplusplus >= 201103L
/// Move assignment operator.
multiset&
operator=(multiset&&) = default;
@@ -279,7 +296,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %multiset and
* that the resulting %multiset's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
multiset&
operator=(initializer_list<value_type> __l)
@@ -403,6 +420,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* be quite fast.)
* Note that the global std::swap() function is specialized such that
* std::swap(s1,s2) will feed to this function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(multiset& __x)
@@ -518,9 +537,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Complexity similar to that of the range constructor.
*/
template<typename _InputIterator>
- void
- insert(_InputIterator __first, _InputIterator __last)
- { _M_t._M_insert_equal(__first, __last); }
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ { _M_t._M_insert_equal(__first, __last); }
#if __cplusplus >= 201103L
/**
@@ -535,6 +554,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.
@@ -542,7 +615,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief Erases an element from a %multiset.
* @param __position An iterator pointing to the element to be erased.
* @return An iterator pointing to the element immediately following
- * @a position prior to the element being erased. If no such
+ * @a position prior to the element being erased. If no such
* element exists, end() is returned.
*
* This function erases an element, pointed to by the given iterator,
@@ -716,14 +789,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
+ { return iterator(_M_t._M_lower_bound_tr(__x)); }
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
+ { return iterator(_M_t._M_lower_bound_tr(__x)); }
#endif
//@}
@@ -746,14 +819,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
+ { return iterator(_M_t._M_upper_bound_tr(__x)); }
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
+ { return iterator(_M_t._M_upper_bound_tr(__x)); }
#endif
//@}
@@ -785,25 +858,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
equal_range(const _Kt& __x)
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
+ { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
+ { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
#endif
//@}
template<typename _K1, typename _C1, typename _A1>
- friend bool
- operator==(const multiset<_K1, _C1, _A1>&,
+ friend bool
+ operator==(const multiset<_K1, _C1, _A1>&,
const multiset<_K1, _C1, _A1>&);
template<typename _K1, typename _C1, typename _A1>
- friend bool
- operator< (const multiset<_K1, _C1, _A1>&,
+ friend bool
+ operator< (const multiset<_K1, _C1, _A1>&,
const multiset<_K1, _C1, _A1>&);
};
@@ -878,6 +951,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_numeric.h b/libstdc++-v3/include/bits/stl_numeric.h
index a414b029f5..9f9816428c 100644
--- a/libstdc++-v3/include/bits/stl_numeric.h
+++ b/libstdc++-v3/include/bits/stl_numeric.h
@@ -1,6 +1,6 @@
// Numeric functions implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index 37ee5cc405..b6245b65cd 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -1,6 +1,6 @@
// Pair implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -76,7 +76,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
/// piecewise_construct
- constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
+ _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
+ piecewise_construct_t();
// Forward declarations.
template<typename...>
@@ -88,52 +89,102 @@ _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;
+ }
+ };
+
+ // PR libstdc++/79141, a utility type for preventing
+ // initialization of an argument of a disabled assignment
+ // operator from a pair of empty braces.
+ struct __nonesuch_no_braces : std::__nonesuch {
+ explicit __nonesuch_no_braces(const __nonesuch&) = delete;
+ };
#endif
@@ -186,16 +237,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 +265,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 +294,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 +364,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_no_braces&>::type __p)
{
first = __p.first;
second = __p.second;
@@ -312,7 +375,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_no_braces&>::type __p) = delete;
+
+ pair&
+ operator=(typename conditional<
+ __and_<is_move_assignable<_T1>,
+ is_move_assignable<_T2>>::value,
+ pair&&, __nonesuch_no_braces&&>::type __p)
noexcept(__and_<is_nothrow_move_assignable<_T1>,
is_nothrow_move_assignable<_T2>>::value)
{
@@ -322,7 +394,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 +405,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);
@@ -341,8 +417,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
swap(pair& __p)
- noexcept(__is_nothrow_swappable<_T1>::value
- && __is_nothrow_swappable<_T2>::value)
+ noexcept(__and_<__is_nothrow_swappable<_T1>,
+ __is_nothrow_swappable<_T2>>::value)
{
using std::swap;
swap(first, __p.first);
@@ -357,6 +433,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
};
+#if __cpp_deduction_guides >= 201606
+ template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
+#endif
+
/// Two pairs of the same type are equal iff their members are equal.
template<typename _T1, typename _T2>
inline _GLIBCXX_CONSTEXPR bool
@@ -399,11 +479,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Note: no std::swap overloads in C++03 mode, this has performance
// implications, see, eg, libstdc++/38466.
template<typename _T1, typename _T2>
- inline void
+ inline
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ // Constrained free swap overload, see p0185r1
+ typename enable_if<__and_<__is_swappable<_T1>,
+ __is_swappable<_T2>>::value>::type
+#else
+ void
+#endif
swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
+
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ template<typename _T1, typename _T2>
+ typename enable_if<!__and_<__is_swappable<_T1>,
+ __is_swappable<_T2>>::value>::type
+ swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
#endif
+#endif // __cplusplus >= 201103L
/**
* @brief A convenience wrapper for creating a pair from two objects.
diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h
index 9caca03cd0..c49f371fbc 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -1,6 +1,6 @@
// Queue implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -95,20 +95,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Sequence = deque<_Tp> >
class queue
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
typedef typename _Sequence::value_type _Sequence_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+# endif
__glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
__glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
__glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
+#endif
template<typename _Tp1, typename _Seq1>
- friend bool
- operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
+ friend bool
+ operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
template<typename _Tp1, typename _Seq1>
- friend bool
- operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
+ friend bool
+ operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
#if __cplusplus >= 201103L
template<typename _Alloc>
@@ -117,21 +121,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
public:
- typedef typename _Sequence::value_type value_type;
- typedef typename _Sequence::reference reference;
- typedef typename _Sequence::const_reference const_reference;
- typedef typename _Sequence::size_type size_type;
- typedef _Sequence container_type;
+ typedef typename _Sequence::value_type value_type;
+ typedef typename _Sequence::reference reference;
+ typedef typename _Sequence::const_reference const_reference;
+ typedef typename _Sequence::size_type size_type;
+ typedef _Sequence container_type;
protected:
- /**
- * 'c' is the underlying container. Maintainers wondering why
- * this isn't uglified as per style guidelines should note that
- * this name is specified in the standard, [23.2.3.1]. (Why?
- * Presumably for the same reason that it's protected instead
+ /* Maintainers wondering why this isn't uglified as per style
+ * guidelines should note that this name is specified in the standard,
+ * C++98 [23.2.3.1].
+ * (Why? Presumably for the same reason that it's protected instead
* of private: to allow derivation. But none of the other
* containers allow for derivation. Odd.)
*/
+ /// @c c is the underlying container.
_Sequence c;
public:
@@ -143,12 +147,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
queue(const _Sequence& __c = _Sequence())
: c(__c) { }
#else
+ template<typename _Seq = _Sequence, typename _Requires = typename
+ enable_if<is_default_constructible<_Seq>::value>::type>
+ queue()
+ : c() { }
+
explicit
queue(const _Sequence& __c)
: c(__c) { }
explicit
- queue(_Sequence&& __c = _Sequence())
+ queue(_Sequence&& __c)
: c(std::move(__c)) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
@@ -247,11 +256,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
push(value_type&& __x)
{ c.push_back(std::move(__x)); }
+#if __cplusplus > 201402L
template<typename... _Args>
- void
- emplace(_Args&&... __args)
+ decltype(auto)
+ emplace(_Args&&... __args)
+ { return c.emplace_back(std::forward<_Args>(__args)...); }
+#else
+ template<typename... _Args>
+ void
+ emplace(_Args&&... __args)
{ c.emplace_back(std::forward<_Args>(__args)...); }
#endif
+#endif
/**
* @brief Removes first element.
@@ -274,12 +290,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
void
swap(queue& __q)
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ noexcept(__is_nothrow_swappable<_Sequence>::value)
+#else
noexcept(__is_nothrow_swappable<_Tp>::value)
+#endif
{
using std::swap;
swap(c, __q.c);
}
-#endif
+#endif // __cplusplus >= 201103L
};
/**
@@ -342,7 +362,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _Tp, typename _Seq>
- inline void
+ inline
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ // Constrained free swap overload, see p0185r1
+ typename enable_if<__is_swappable<_Seq>::value>::type
+#else
+ void
+#endif
swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
@@ -350,7 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Seq, typename _Alloc>
struct uses_allocator<queue<_Tp, _Seq>, _Alloc>
: public uses_allocator<_Seq, _Alloc>::type { };
-#endif
+#endif // __cplusplus >= 201103L
/**
* @brief A standard container automatically sorting its contents.
@@ -359,12 +385,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* @tparam _Tp Type of element.
* @tparam _Sequence Type of underlying sequence, defaults to vector<_Tp>.
- * @tparam _Compare Comparison function object type, defaults to
+ * @tparam _Compare Comparison function object type, defaults to
* less<_Sequence::value_type>.
*
* This is not a true container, but an @e adaptor. It holds
* another container, and provides a wrapper interface to that
- * container. The wrapper is what enforces priority-based sorting
+ * container. The wrapper is what enforces priority-based sorting
* and %queue behavior. Very few of the standard container/sequence
* interface requirements are met (e.g., iterators).
*
@@ -396,14 +422,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Compare = less<typename _Sequence::value_type> >
class priority_queue
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
typedef typename _Sequence::value_type _Sequence_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+# endif
__glibcxx_class_requires(_Sequence, _SequenceConcept)
__glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
__glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
__glibcxx_class_requires4(_Compare, bool, _Tp, _Tp,
_BinaryFunctionConcept)
+#endif
#if __cplusplus >= 201103L
template<typename _Alloc>
@@ -412,11 +442,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
public:
- typedef typename _Sequence::value_type value_type;
- typedef typename _Sequence::reference reference;
- typedef typename _Sequence::const_reference const_reference;
- typedef typename _Sequence::size_type size_type;
- typedef _Sequence container_type;
+ typedef typename _Sequence::value_type value_type;
+ typedef typename _Sequence::reference reference;
+ typedef typename _Sequence::const_reference const_reference;
+ typedef typename _Sequence::size_type size_type;
+ typedef _Sequence container_type;
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 2684. priority_queue lacking comparator typedef
+ typedef _Compare value_compare;
protected:
// See queue::c for notes on these names.
@@ -434,43 +467,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: c(__s), comp(__x)
{ std::make_heap(c.begin(), c.end(), comp); }
#else
+ template<typename _Seq = _Sequence, typename _Requires = typename
+ enable_if<__and_<is_default_constructible<_Compare>,
+ is_default_constructible<_Seq>>::value>::type>
+ priority_queue()
+ : c(), comp() { }
+
explicit
- priority_queue(const _Compare& __x,
- const _Sequence& __s)
+ priority_queue(const _Compare& __x, const _Sequence& __s)
: c(__s), comp(__x)
{ std::make_heap(c.begin(), c.end(), comp); }
explicit
- priority_queue(const _Compare& __x = _Compare(),
- _Sequence&& __s = _Sequence())
+ priority_queue(const _Compare& __x, _Sequence&& __s = _Sequence())
: c(std::move(__s)), comp(__x)
{ std::make_heap(c.begin(), c.end(), comp); }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
explicit
priority_queue(const _Alloc& __a)
- : c(__a) { }
+ : c(__a), comp() { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
priority_queue(const _Compare& __x, const _Alloc& __a)
- : c(__x, __a) { }
+ : c(__a), comp(__x) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
priority_queue(const _Compare& __x, const _Sequence& __c,
const _Alloc& __a)
- : c(__x, __c, __a) { }
+ : c(__c, __a), comp(__x) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
priority_queue(const _Compare& __x, _Sequence&& __c, const _Alloc& __a)
- : c(__x, std::move(__c), __a) { }
+ : c(std::move(__c), __a), comp(__x) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
priority_queue(const priority_queue& __q, const _Alloc& __a)
- : c(__q.c, __a) { }
+ : c(__q.c, __a), comp(__q.comp) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
priority_queue(priority_queue&& __q, const _Alloc& __a)
- : c(std::move(__q.c), __a) { }
+ : c(std::move(__q.c), __a), comp(std::move(__q.comp)) { }
#endif
/**
@@ -490,33 +527,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
#if __cplusplus < 201103L
template<typename _InputIterator>
- priority_queue(_InputIterator __first, _InputIterator __last,
+ priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x = _Compare(),
const _Sequence& __s = _Sequence())
: c(__s), comp(__x)
- {
+ {
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
#else
template<typename _InputIterator>
- priority_queue(_InputIterator __first, _InputIterator __last,
+ priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x,
const _Sequence& __s)
: c(__s), comp(__x)
- {
+ {
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
template<typename _InputIterator>
- priority_queue(_InputIterator __first, _InputIterator __last,
+ priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x = _Compare(),
_Sequence&& __s = _Sequence())
: c(std::move(__s)), comp(__x)
- {
+ {
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
@@ -570,8 +607,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename... _Args>
- void
- emplace(_Args&&... __args)
+ void
+ emplace(_Args&&... __args)
{
c.emplace_back(std::forward<_Args>(__args)...);
std::push_heap(c.begin(), c.end(), comp);
@@ -600,21 +637,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
void
swap(priority_queue& __pq)
- noexcept(__is_nothrow_swappable<_Tp>::value
- && __is_nothrow_swappable<_Compare>::value)
+ noexcept(__and_<
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ __is_nothrow_swappable<_Sequence>,
+#else
+ __is_nothrow_swappable<_Tp>,
+#endif
+ __is_nothrow_swappable<_Compare>
+ >::value)
{
using std::swap;
swap(c, __pq.c);
swap(comp, __pq.comp);
}
-#endif
+#endif // __cplusplus >= 201103L
};
// No equality/comparison operators are provided for priority_queue.
#if __cplusplus >= 201103L
template<typename _Tp, typename _Sequence, typename _Compare>
- inline void
+ inline
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ // Constrained free swap overload, see p0185r1
+ typename enable_if<__and_<__is_swappable<_Sequence>,
+ __is_swappable<_Compare>>::value>::type
+#else
+ void
+#endif
swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
priority_queue<_Tp, _Sequence, _Compare>& __y)
noexcept(noexcept(__x.swap(__y)))
@@ -624,7 +674,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Alloc>
struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc>
: public uses_allocator<_Sequence, _Alloc>::type { };
-#endif
+#endif // __cplusplus >= 201103L
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/stl_raw_storage_iter.h b/libstdc++-v3/include/bits/stl_raw_storage_iter.h
index 8b5e793dbc..4ad9a91377 100644
--- a/libstdc++-v3/include/bits/stl_raw_storage_iter.h
+++ b/libstdc++-v3/include/bits/stl_raw_storage_iter.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -86,17 +86,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
- raw_storage_iterator<_OutputIterator, _Tp>&
+#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2127. Move-construction with raw_storage_iterator
+ raw_storage_iterator&
+ operator=(_Tp&& __element)
+ {
+ std::_Construct(std::__addressof(*_M_iter), std::move(__element));
+ return *this;
+ }
+#endif
+
+ raw_storage_iterator&
operator++()
{
++_M_iter;
return *this;
}
- raw_storage_iterator<_OutputIterator, _Tp>
+ raw_storage_iterator
operator++(int)
{
- raw_storage_iterator<_OutputIterator, _Tp> __tmp = *this;
+ raw_storage_iterator __tmp = *this;
++_M_iter;
return __tmp;
}
diff --git a/libstdc++-v3/include/bits/stl_relops.h b/libstdc++-v3/include/bits/stl_relops.h
index 2e19dd1328..a2614bd304 100644
--- a/libstdc++-v3/include/bits/stl_relops.h
+++ b/libstdc++-v3/include/bits/stl_relops.h
@@ -1,6 +1,6 @@
// std::rel_ops implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index f5e0603d42..817bc2d870 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -1,6 +1,6 @@
// Set implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -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.
@@ -89,12 +92,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typename _Alloc = std::allocator<_Key> >
class set
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
- typedef typename _Alloc::value_type _Alloc_value_type;
+ typedef typename _Alloc::value_type _Alloc_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
+# endif
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
+#endif
public:
// typedefs:
@@ -120,30 +127,35 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
public:
//@{
/// Iterator-related typedefs.
- typedef typename _Alloc_traits::pointer pointer;
- typedef typename _Alloc_traits::const_pointer const_pointer;
- typedef typename _Alloc_traits::reference reference;
- typedef typename _Alloc_traits::const_reference const_reference;
+ typedef typename _Alloc_traits::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
- typedef typename _Rep_type::const_iterator iterator;
- typedef typename _Rep_type::const_iterator const_iterator;
- typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
- typedef typename _Rep_type::size_type size_type;
- typedef typename _Rep_type::difference_type difference_type;
+ 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;
+ using insert_return_type = typename _Rep_type::insert_return_type;
+#endif
+
// allocation/deallocation
/**
* @brief Default constructor creates no elements.
*/
- set()
-#if __cplusplus >= 201103L
- noexcept(is_nothrow_default_constructible<allocator_type>::value)
+#if __cplusplus < 201103L
+ set() : _M_t() { }
+#else
+ set() = default;
#endif
- : _M_t() { }
/**
* @brief Creates a %set with no elements.
@@ -187,29 +199,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
- { _M_t._M_insert_unique(__first, __last); }
+ { _M_t._M_insert_unique(__first, __last); }
/**
* @brief %Set copy constructor.
- * @param __x A %set of identical element and allocator types.
*
- * The newly-created %set uses a copy of the allocation object used
- * by @a __x.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
set(const set& __x)
: _M_t(__x._M_t) { }
+#else
+ set(const set&) = default;
-#if __cplusplus >= 201103L
/**
* @brief %Set move constructor
- * @param __x A %set of identical element and allocator types.
*
- * The newly-created %set contains the exact contents of @a x.
- * The contents of @a x are a valid, but unspecified %set.
+ * The newly-created %set contains the exact contents of the moved
+ * instance. The moved instance is a valid, but unspecified, %set.
*/
- set(set&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _M_t(std::move(__x._M_t)) { }
+ set(set&&) = default;
/**
* @brief Builds a %set from an initializer_list.
@@ -249,27 +258,35 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Allocator-extended range constructor.
template<typename _InputIterator>
- set(_InputIterator __first, _InputIterator __last,
+ set(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: _M_t(_Compare(), _Key_alloc_type(__a))
- { _M_t._M_insert_unique(__first, __last); }
+ { _M_t._M_insert_unique(__first, __last); }
+
+ /**
+ * The dtor only erases the elements, and note that if the elements
+ * themselves are pointers, the pointed-to memory is not touched in any
+ * way. Managing the pointer is the user's responsibility.
+ */
+ ~set() = default;
#endif
/**
* @brief %Set assignment operator.
- * @param __x A %set of identical element and allocator types.
*
- * All the elements of @a __x are copied, but unlike the copy
- * constructor, the allocator object is not copied.
+ * Whether the allocator is copied depends on the allocator traits.
*/
+#if __cplusplus < 201103L
set&
operator=(const set& __x)
{
_M_t = __x._M_t;
return *this;
}
+#else
+ set&
+ operator=(const set&) = default;
-#if __cplusplus >= 201103L
/// Move assignment operator.
set&
operator=(set&&) = default;
@@ -283,7 +300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %set and
* that the resulting %set's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
set&
operator=(initializer_list<value_type> __l)
@@ -407,6 +424,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* stateless and empty), so it should be quite fast.) Note
* that the global std::swap() function is specialized such
* that std::swap(s1,s2) will feed to this function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(set& __x)
@@ -550,6 +569,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.
@@ -670,7 +743,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
auto
count(const _Kt& __x) const
-> decltype(_M_t._M_count_tr(__x))
- { return _M_t._M_find_tr(__x) == _M_t.end() ? 0 : 1; }
+ { return _M_t._M_count_tr(__x); }
#endif
//@}
@@ -735,14 +808,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
+ { return iterator(_M_t._M_lower_bound_tr(__x)); }
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
- -> decltype(_M_t._M_lower_bound_tr(__x))
- { return _M_t._M_lower_bound_tr(__x); }
+ -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x)))
+ { return const_iterator(_M_t._M_lower_bound_tr(__x)); }
#endif
//@}
@@ -765,14 +838,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
+ { return iterator(_M_t._M_upper_bound_tr(__x)); }
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
- -> decltype(_M_t._M_upper_bound_tr(__x))
- { return _M_t._M_upper_bound_tr(__x); }
+ -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
+ { return const_iterator(_M_t._M_upper_bound_tr(__x)); }
#endif
//@}
@@ -804,14 +877,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Kt>
auto
equal_range(const _Kt& __x)
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
+ { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
- -> decltype(_M_t._M_equal_range_tr(__x))
- { return _M_t._M_equal_range_tr(__x); }
+ -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
+ { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
#endif
//@}
@@ -894,5 +967,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_stack.h b/libstdc++-v3/include/bits/stl_stack.h
index ea1d149b56..ac59ec715c 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -1,6 +1,6 @@
// Stack implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -98,21 +98,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Sequence = deque<_Tp> >
class stack
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// concept requirements
typedef typename _Sequence::value_type _Sequence_value_type;
-#if __cplusplus < 201103L
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
-#endif
+# endif
__glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
+#endif
template<typename _Tp1, typename _Seq1>
- friend bool
- operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
+ friend bool
+ operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
template<typename _Tp1, typename _Seq1>
- friend bool
- operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
+ friend bool
+ operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
#if __cplusplus >= 201103L
template<typename _Alloc>
@@ -121,11 +123,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
public:
- typedef typename _Sequence::value_type value_type;
- typedef typename _Sequence::reference reference;
- typedef typename _Sequence::const_reference const_reference;
- typedef typename _Sequence::size_type size_type;
- typedef _Sequence container_type;
+ typedef typename _Sequence::value_type value_type;
+ typedef typename _Sequence::reference reference;
+ typedef typename _Sequence::const_reference const_reference;
+ typedef typename _Sequence::size_type size_type;
+ typedef _Sequence container_type;
protected:
// See queue::c for notes on this name.
@@ -141,12 +143,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
stack(const _Sequence& __c = _Sequence())
: c(__c) { }
#else
+ template<typename _Seq = _Sequence, typename _Requires = typename
+ enable_if<is_default_constructible<_Seq>::value>::type>
+ stack()
+ : c() { }
+
explicit
stack(const _Sequence& __c)
: c(__c) { }
explicit
- stack(_Sequence&& __c = _Sequence())
+ stack(_Sequence&& __c)
: c(std::move(__c)) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
@@ -223,11 +230,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
push(value_type&& __x)
{ c.push_back(std::move(__x)); }
+#if __cplusplus > 201402L
template<typename... _Args>
- void
- emplace(_Args&&... __args)
+ decltype(auto)
+ emplace(_Args&&... __args)
+ { return c.emplace_back(std::forward<_Args>(__args)...); }
+#else
+ template<typename... _Args>
+ void
+ emplace(_Args&&... __args)
{ c.emplace_back(std::forward<_Args>(__args)...); }
#endif
+#endif
/**
* @brief Removes first element.
@@ -250,12 +264,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
void
swap(stack& __s)
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ noexcept(__is_nothrow_swappable<_Sequence>::value)
+#else
noexcept(__is_nothrow_swappable<_Tp>::value)
+#endif
{
using std::swap;
swap(c, __s.c);
}
-#endif
+#endif // __cplusplus >= 201103L
};
/**
@@ -319,7 +337,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _Tp, typename _Seq>
- inline void
+ inline
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ // Constrained free swap overload, see p0185r1
+ typename enable_if<__is_swappable<_Seq>::value>::type
+#else
+ void
+#endif
swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>& __y)
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
@@ -327,7 +351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Seq, typename _Alloc>
struct uses_allocator<stack<_Tp, _Seq>, _Alloc>
: public uses_allocator<_Seq, _Alloc>::type { };
-#endif
+#endif // __cplusplus >= 201103L
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h
index 0dc2b70345..03b4cd29ff 100644
--- a/libstdc++-v3/include/bits/stl_tempbuf.h
+++ b/libstdc++-v3/include/bits/stl_tempbuf.h
@@ -1,6 +1,6 @@
// Temporary buffer implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 8697a711a5..ce7ecdaa87 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -1,6 +1,6 @@
// RB tree implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -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)
@@ -134,6 +137,81 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
+ // Helper type offering value initialization guarantee on the compare functor.
+ template<typename _Key_compare>
+ struct _Rb_tree_key_compare
+ {
+ _Key_compare _M_key_compare;
+
+ _Rb_tree_key_compare()
+ _GLIBCXX_NOEXCEPT_IF(
+ is_nothrow_default_constructible<_Key_compare>::value)
+ : _M_key_compare()
+ { }
+
+ _Rb_tree_key_compare(const _Key_compare& __comp)
+ : _M_key_compare(__comp)
+ { }
+
+#if __cplusplus >= 201103L
+ // Copy constructor added for consistency with C++98 mode.
+ _Rb_tree_key_compare(const _Rb_tree_key_compare&) = default;
+
+ _Rb_tree_key_compare(_Rb_tree_key_compare&& __x)
+ noexcept(is_nothrow_copy_constructible<_Key_compare>::value)
+ : _M_key_compare(__x._M_key_compare)
+ { }
+#endif
+ };
+
+ // Helper type to manage default initialization of node count and header.
+ struct _Rb_tree_header
+ {
+ _Rb_tree_node_base _M_header;
+ size_t _M_node_count; // Keeps track of size of tree.
+
+ _Rb_tree_header() _GLIBCXX_NOEXCEPT
+ {
+ _M_header._M_color = _S_red;
+ _M_reset();
+ }
+
+#if __cplusplus >= 201103L
+ _Rb_tree_header(_Rb_tree_header&& __x) noexcept
+ {
+ if (__x._M_header._M_parent != nullptr)
+ _M_move_data(__x);
+ else
+ {
+ _M_header._M_color = _S_red;
+ _M_reset();
+ }
+ }
+#endif
+
+ void
+ _M_move_data(_Rb_tree_header& __from)
+ {
+ _M_header._M_color = __from._M_header._M_color;
+ _M_header._M_parent = __from._M_header._M_parent;
+ _M_header._M_left = __from._M_header._M_left;
+ _M_header._M_right = __from._M_header._M_right;
+ _M_header._M_parent->_M_parent = &_M_header;
+ _M_node_count = __from._M_node_count;
+
+ __from._M_reset();
+ }
+
+ void
+ _M_reset()
+ {
+ _M_header._M_parent = 0;
+ _M_header._M_left = &_M_header;
+ _M_header._M_right = &_M_header;
+ _M_node_count = 0;
+ }
+ };
+
template<typename _Val>
struct _Rb_tree_node : public _Rb_tree_node_base
{
@@ -356,6 +434,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
@@ -591,47 +674,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Unused _Is_pod_comparator is kept as it is part of mangled name.
template<typename _Key_compare,
bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
- struct _Rb_tree_impl : public _Node_allocator
+ struct _Rb_tree_impl
+ : public _Node_allocator
+ , public _Rb_tree_key_compare<_Key_compare>
+ , public _Rb_tree_header
{
- _Key_compare _M_key_compare;
- _Rb_tree_node_base _M_header;
- size_type _M_node_count; // Keeps track of size of tree.
+ typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare;
+#if __cplusplus < 201103L
_Rb_tree_impl()
- : _Node_allocator(), _M_key_compare(), _M_header(),
- _M_node_count(0)
- { _M_initialize(); }
+ { }
+#else
+ _Rb_tree_impl() = default;
+ _Rb_tree_impl(_Rb_tree_impl&&) = default;
+#endif
- _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
- : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
- _M_node_count(0)
- { _M_initialize(); }
+ _Rb_tree_impl(const _Rb_tree_impl& __x)
+ : _Node_allocator(_Alloc_traits::_S_select_on_copy(__x))
+ , _Base_key_compare(__x._M_key_compare)
+ { }
-#if __cplusplus >= 201103L
+#if __cplusplus < 201103L
+ _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
+ : _Node_allocator(__a), _Base_key_compare(__comp)
+ { }
+#else
_Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
- : _Node_allocator(std::move(__a)), _M_key_compare(__comp),
- _M_header(), _M_node_count(0)
- { _M_initialize(); }
+ : _Node_allocator(std::move(__a)), _Base_key_compare(__comp)
+ { }
#endif
-
- void
- _M_reset()
- {
- this->_M_header._M_parent = 0;
- this->_M_header._M_left = &this->_M_header;
- this->_M_header._M_right = &this->_M_header;
- this->_M_node_count = 0;
- }
-
- private:
- void
- _M_initialize()
- {
- this->_M_header._M_color = _S_red;
- this->_M_header._M_parent = 0;
- this->_M_header._M_left = &this->_M_header;
- this->_M_header._M_right = &this->_M_header;
- }
};
_Rb_tree_impl<_Compare> _M_impl;
@@ -735,6 +806,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);
@@ -790,11 +866,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Link_type
_M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&);
+ template<typename _NodeGen>
+ _Link_type
+ _M_copy(const _Rb_tree& __x, _NodeGen& __gen)
+ {
+ _Link_type __root = _M_copy(__x._M_begin(), _M_end(), __gen);
+ _M_leftmost() = _S_minimum(__root);
+ _M_rightmost() = _S_maximum(__root);
+ _M_impl._M_node_count = __x._M_impl._M_node_count;
+ return __root;
+ }
+
_Link_type
- _M_copy(_Const_Link_type __x, _Base_ptr __p)
+ _M_copy(const _Rb_tree& __x)
{
_Alloc_node __an(*this);
- return _M_copy(__x, __p, __an);
+ return _M_copy(__x, __an);
}
void
@@ -818,23 +905,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public:
// allocation/deallocation
+#if __cplusplus < 201103L
_Rb_tree() { }
+#else
+ _Rb_tree() = default;
+#endif
_Rb_tree(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_impl(__comp, _Node_allocator(__a)) { }
_Rb_tree(const _Rb_tree& __x)
- : _M_impl(__x._M_impl._M_key_compare,
- _Alloc_traits::_S_select_on_copy(__x._M_get_Node_allocator()))
+ : _M_impl(__x._M_impl)
{
if (__x._M_root() != 0)
- {
- _M_root() = _M_copy(__x._M_begin(), _M_end());
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
- _M_impl._M_node_count = __x._M_impl._M_node_count;
- }
+ _M_root() = _M_copy(__x);
}
#if __cplusplus >= 201103L
@@ -846,21 +931,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
{
if (__x._M_root() != nullptr)
- {
- _M_root() = _M_copy(__x._M_begin(), _M_end());
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
- _M_impl._M_node_count = __x._M_impl._M_node_count;
- }
+ _M_root() = _M_copy(__x);
}
- _Rb_tree(_Rb_tree&& __x)
- : _M_impl(__x._M_impl._M_key_compare,
- std::move(__x._M_get_Node_allocator()))
- {
- if (__x._M_root() != 0)
- _M_move_data(__x, std::true_type());
- }
+ _Rb_tree(_Rb_tree&&) = default;
_Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
: _Rb_tree(std::move(__x), _Node_allocator(__a))
@@ -1031,6 +1105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
iterator
erase(const_iterator __position)
{
+ __glibcxx_assert(__position != end());
const_iterator __result = __position;
++__result;
_M_erase_aux(__position);
@@ -1042,6 +1117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
iterator
erase(iterator __position)
{
+ __glibcxx_assert(__position != end());
iterator __result = __position;
++__result;
_M_erase_aux(__position);
@@ -1050,11 +1126,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#else
void
erase(iterator __position)
- { _M_erase_aux(__position); }
+ {
+ __glibcxx_assert(__position != end());
+ _M_erase_aux(__position);
+ }
void
erase(const_iterator __position)
- { _M_erase_aux(__position); }
+ {
+ __glibcxx_assert(__position != end());
+ _M_erase_aux(__position);
+ }
#endif
size_type
erase(const key_type& __x);
@@ -1258,13 +1340,189 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
// Move elements from container with equal allocator.
void
- _M_move_data(_Rb_tree&, std::true_type);
+ _M_move_data(_Rb_tree& __x, std::true_type)
+ { _M_impl._M_move_data(__x._M_impl); }
// Move elements from container with possibly non-equal allocator,
// which might result in a copy not a move.
void
_M_move_data(_Rb_tree&, std::false_type);
+
+ // Move assignment from container with equal allocator.
+ void
+ _M_move_assign(_Rb_tree&, std::true_type);
+
+ // Move assignment from container with possibly non-equal allocator,
+ // which might result in a copy not a move.
+ 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,
@@ -1338,29 +1596,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Compare, typename _Alloc>
void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
- _M_move_data(_Rb_tree& __x, std::true_type)
- {
- _M_root() = __x._M_root();
- _M_leftmost() = __x._M_leftmost();
- _M_rightmost() = __x._M_rightmost();
- _M_root()->_M_parent = _M_end();
-
- __x._M_root() = 0;
- __x._M_leftmost() = __x._M_end();
- __x._M_rightmost() = __x._M_end();
-
- this->_M_impl._M_node_count = __x._M_impl._M_node_count;
- __x._M_impl._M_node_count = 0;
- }
-
- template<typename _Key, typename _Val, typename _KeyOfValue,
- typename _Compare, typename _Alloc>
- void
- _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_move_data(_Rb_tree& __x, std::false_type)
{
if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
- _M_move_data(__x, std::true_type());
+ _M_move_data(__x, std::true_type());
else
{
_Alloc_node __an(*this);
@@ -1370,33 +1609,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto& __val = const_cast<value_type&>(__cval);
return __an(std::move_if_noexcept(__val));
};
- _M_root() = _M_copy(__x._M_begin(), _M_end(), __lbd);
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
- _M_impl._M_node_count = __x._M_impl._M_node_count;
+ _M_root() = _M_copy(__x, __lbd);
}
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
- _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
+ inline void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
- operator=(_Rb_tree&& __x)
- noexcept(_Alloc_traits::_S_nothrow_move()
- && is_nothrow_move_assignable<_Compare>::value)
+ _M_move_assign(_Rb_tree& __x, true_type)
{
- _M_impl._M_key_compare = __x._M_impl._M_key_compare;
- if (_Alloc_traits::_S_propagate_on_move_assign()
- || _Alloc_traits::_S_always_equal()
- || _M_get_Node_allocator() == __x._M_get_Node_allocator())
- {
- clear();
- if (__x._M_root() != nullptr)
- _M_move_data(__x, std::true_type());
- std::__alloc_on_move(_M_get_Node_allocator(),
- __x._M_get_Node_allocator());
- return *this;
- }
+ clear();
+ if (__x._M_root() != nullptr)
+ _M_move_data(__x, std::true_type());
+ std::__alloc_on_move(_M_get_Node_allocator(),
+ __x._M_get_Node_allocator());
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ void
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_move_assign(_Rb_tree& __x, false_type)
+ {
+ if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
+ return _M_move_assign(__x, true_type{});
// Try to move each node reusing existing nodes and copying __x nodes
// structure.
@@ -1410,12 +1647,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto& __val = const_cast<value_type&>(__cval);
return __roan(std::move_if_noexcept(__val));
};
- _M_root() = _M_copy(__x._M_begin(), _M_end(), __lbd);
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
- _M_impl._M_node_count = __x._M_impl._M_node_count;
+ _M_root() = _M_copy(__x, __lbd);
__x.clear();
}
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ operator=(_Rb_tree&& __x)
+ noexcept(_Alloc_traits::_S_nothrow_move()
+ && is_nothrow_move_assignable<_Compare>::value)
+ {
+ _M_impl._M_key_compare = std::move(__x._M_impl._M_key_compare);
+ _M_move_assign(__x, __bool_constant<_Alloc_traits::_S_nothrow_move()>());
return *this;
}
@@ -1475,12 +1721,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_impl._M_reset();
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (__x._M_root() != 0)
- {
- _M_root() = _M_copy(__x._M_begin(), _M_end(), __roan);
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
- _M_impl._M_node_count = __x._M_impl._M_node_count;
- }
+ _M_root() = _M_copy(__x, __roan);
}
return *this;
@@ -1755,26 +1996,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (_M_root() == 0)
{
if (__t._M_root() != 0)
- {
- _M_root() = __t._M_root();
- _M_leftmost() = __t._M_leftmost();
- _M_rightmost() = __t._M_rightmost();
- _M_root()->_M_parent = _M_end();
- _M_impl._M_node_count = __t._M_impl._M_node_count;
-
- __t._M_impl._M_reset();
- }
+ _M_impl._M_move_data(__t._M_impl);
}
else if (__t._M_root() == 0)
- {
- __t._M_root() = _M_root();
- __t._M_leftmost() = _M_leftmost();
- __t._M_rightmost() = _M_rightmost();
- __t._M_root()->_M_parent = __t._M_end();
- __t._M_impl._M_node_count = _M_impl._M_node_count;
-
- _M_impl._M_reset();
- }
+ __t._M_impl._M_move_data(_M_impl);
else
{
std::swap(_M_root(),__t._M_root());
@@ -2261,7 +2486,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
clear();
else
while (__first != __last)
- erase(__first++);
+ _M_erase_aux(__first++);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -2272,7 +2497,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
pair<iterator, iterator> __p = equal_range(__x);
const size_type __old_size = size();
- erase(__p.first, __p.second);
+ _M_erase_aux(__p.first, __p.second);
return __old_size - size();
}
@@ -2365,6 +2590,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 6cfba13cb9..d0e2b2d33e 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -1,6 +1,6 @@
// Raw memory manipulators -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -56,6 +56,14 @@
#ifndef _STL_UNINITIALIZED_H
#define _STL_UNINITIALIZED_H 1
+#if __cplusplus > 201402L
+#include <utility>
+#endif
+
+#if __cplusplus >= 201103L
+#include <type_traits>
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -636,6 +644,99 @@ _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)
+ { return std::next(__first, __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>
@@ -665,6 +766,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.
@@ -680,8 +813,95 @@ _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
+ template <typename _ForwardIterator>
+ inline void
+ uninitialized_default_construct(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ __uninitialized_default_novalue(__first, __last);
+ }
+
+ template <typename _ForwardIterator, typename _Size>
+ inline _ForwardIterator
+ uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
+ {
+ return __uninitialized_default_novalue_n(__first, __count);
+ }
+
+ template <typename _ForwardIterator>
+ inline void
+ uninitialized_value_construct(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ return __uninitialized_default(__first, __last);
+ }
+
+ template <typename _ForwardIterator, typename _Size>
+ inline _ForwardIterator
+ uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
+ {
+ return __uninitialized_default_n(__first, __count);
+ }
+
+ template <typename _InputIterator, typename _ForwardIterator>
+ inline _ForwardIterator
+ uninitialized_move(_InputIterator __first, _InputIterator __last,
+ _ForwardIterator __result)
+ {
+ return std::uninitialized_copy
+ (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
+ _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
+ }
+
+ template <typename _InputIterator, typename _Size, typename _ForwardIterator>
+ inline pair<_InputIterator, _ForwardIterator>
+ uninitialized_move_n(_InputIterator __first, _Size __count,
+ _ForwardIterator __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)
+ {
+ std::_Destroy(__location);
+ }
+
+ template <typename _ForwardIterator>
+ inline void
+ destroy(_ForwardIterator __first, _ForwardIterator __last)
+ {
+ std::_Destroy(__first, __last);
+ }
+
+ template <typename _ForwardIterator, typename _Size>
+ inline _ForwardIterator
+ destroy_n(_ForwardIterator __first, _Size __count)
+ {
+ return std::_Destroy_n(__first, __count);
+ }
+
+#endif
+
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 9b6d258f6c..fb882126cf 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1,6 +1,6 @@
// Vector implementation -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -63,6 +63,8 @@
#include <initializer_list>
#endif
+#include <debug/assertions.h>
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
@@ -72,11 +74,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
struct _Vector_base
{
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
- rebind<_Tp>::other _Tp_alloc_type;
+ rebind<_Tp>::other _Tp_alloc_type;
typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
pointer;
- struct _Vector_impl
+ struct _Vector_impl
: public _Tp_alloc_type
{
pointer _M_start;
@@ -105,7 +107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::swap(_M_end_of_storage, __x._M_end_of_storage);
}
};
-
+
public:
typedef _Alloc allocator_type;
@@ -213,31 +215,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
+#ifdef _GLIBCXX_CONCEPT_CHECKS
// Concept requirements.
- typedef typename _Alloc::value_type _Alloc_value_type;
-#if __cplusplus < 201103L
+ typedef typename _Alloc::value_type _Alloc_value_type;
+# if __cplusplus < 201103L
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
-#endif
+# endif
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
-
- typedef _Vector_base<_Tp, _Alloc> _Base;
- typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
- typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
+#endif
+
+ typedef _Vector_base<_Tp, _Alloc> _Base;
+ typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
+ typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
public:
- typedef _Tp value_type;
- typedef typename _Base::pointer pointer;
- typedef typename _Alloc_traits::const_pointer const_pointer;
- typedef typename _Alloc_traits::reference reference;
- typedef typename _Alloc_traits::const_reference const_reference;
+ typedef _Tp value_type;
+ typedef typename _Base::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Alloc allocator_type;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Alloc allocator_type;
protected:
using _Base::_M_allocate;
@@ -312,15 +316,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Vector copy constructor.
* @param __x A %vector of identical element and allocator types.
*
- * The newly-created %vector uses a copy of the allocation
- * object used by @a __x. All the elements of @a __x are copied,
- * but any extra memory in
- * @a __x (for fast expansion) will not be copied.
+ * All the elements of @a __x are copied, but any unused capacity in
+ * @a __x will not be copied
+ * (i.e. capacity() == size() in the new %vector).
+ *
+ * The newly-created %vector uses a copy of the allocator object used
+ * by @a __x (unless the allocator traits dictate a different object).
*/
vector(const vector& __x)
: _Base(__x.size(),
- _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
- { this->_M_impl._M_finish =
+ _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
+ {
+ this->_M_impl._M_finish =
std::__uninitialized_copy_a(__x.begin(), __x.end(),
this->_M_impl._M_start,
_M_get_Tp_allocator());
@@ -340,7 +347,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Copy constructor with alternative allocator
vector(const vector& __x, const allocator_type& __a)
: _Base(__x.size(), __a)
- { this->_M_impl._M_finish =
+ {
+ this->_M_impl._M_finish =
std::__uninitialized_copy_a(__x.begin(), __x.end(),
this->_M_impl._M_start,
_M_get_Tp_allocator());
@@ -400,16 +408,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- vector(_InputIterator __first, _InputIterator __last,
+ vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
- { _M_initialize_dispatch(__first, __last, __false_type()); }
+ { _M_initialize_dispatch(__first, __last, __false_type()); }
#else
template<typename _InputIterator>
- vector(_InputIterator __first, _InputIterator __last,
+ vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
- {
+ {
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
@@ -430,9 +438,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Vector assignment operator.
* @param __x A %vector of identical element and allocator types.
*
- * All the elements of @a __x are copied, but any extra memory in
- * @a __x (for fast expansion) will not be copied. Unlike the
- * copy constructor, the allocator object is not copied.
+ * All the elements of @a __x are copied, but any unused capacity in
+ * @a __x will not be copied.
+ *
+ * Whether the allocator is copied depends on the allocator traits.
*/
vector&
operator=(const vector& __x);
@@ -444,15 +453,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* The contents of @a __x are moved into this %vector (without copying,
* if the allocators permit it).
- * @a __x is a valid, but unspecified %vector.
+ * Afterwards @a __x is a valid, but unspecified %vector.
+ *
+ * Whether the allocator is moved depends on the allocator traits.
*/
vector&
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- constexpr bool __move_storage =
- _Alloc_traits::_S_propagate_on_move_assign()
- || _Alloc_traits::_S_always_equal();
- _M_move_assign(std::move(__x), __bool_constant<__move_storage>());
+ constexpr bool __move_storage =
+ _Alloc_traits::_S_propagate_on_move_assign()
+ || _Alloc_traits::_S_always_equal();
+ _M_move_assign(std::move(__x), __bool_constant<__move_storage>());
return *this;
}
@@ -465,12 +476,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %vector and
* that the resulting %vector's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
vector&
operator=(initializer_list<value_type> __l)
{
- this->assign(__l.begin(), __l.end());
+ this->_M_assign_aux(__l.begin(), __l.end(),
+ random_access_iterator_tag());
return *this;
}
#endif
@@ -483,7 +495,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* This function fills a %vector with @a __n copies of the given
* value. Note that the assignment completely changes the
* %vector and that the resulting %vector's size is the same as
- * the number of elements assigned. Old data may be lost.
+ * the number of elements assigned.
*/
void
assign(size_type __n, const value_type& __val)
@@ -499,19 +511,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %vector and
* that the resulting %vector's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- void
- assign(_InputIterator __first, _InputIterator __last)
- { _M_assign_dispatch(__first, __last, __false_type()); }
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ { _M_assign_dispatch(__first, __last, __false_type()); }
#else
template<typename _InputIterator>
- void
- assign(_InputIterator __first, _InputIterator __last)
- {
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ {
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_assign_dispatch(__first, __last, _Integral());
@@ -528,11 +540,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %vector and
* that the resulting %vector's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
void
assign(initializer_list<value_type> __l)
- { this->assign(__l.begin(), __l.end()); }
+ {
+ this->_M_assign_aux(__l.begin(), __l.end(),
+ random_access_iterator_tag());
+ }
#endif
/// Get a copy of the memory allocation object.
@@ -694,7 +709,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
resize(size_type __new_size, const value_type& __x)
{
if (__new_size > size())
- insert(end(), __new_size - size(), __x);
+ _M_fill_insert(end(), __new_size - size(), __x);
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
@@ -714,7 +729,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
resize(size_type __new_size, value_type __x = value_type())
{
if (__new_size > size())
- insert(end(), __new_size - size(), __x);
+ _M_fill_insert(end(), __new_size - size(), __x);
else if (__new_size < size())
_M_erase_at_end(this->_M_impl._M_start + __new_size);
}
@@ -778,7 +793,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
operator[](size_type __n) _GLIBCXX_NOEXCEPT
- { return *(this->_M_impl._M_start + __n); }
+ {
+ __glibcxx_requires_subscript(__n);
+ return *(this->_M_impl._M_start + __n);
+ }
/**
* @brief Subscript access to the data contained in the %vector.
@@ -793,7 +811,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
const_reference
operator[](size_type __n) const _GLIBCXX_NOEXCEPT
- { return *(this->_M_impl._M_start + __n); }
+ {
+ __glibcxx_requires_subscript(__n);
+ return *(this->_M_impl._M_start + __n);
+ }
protected:
/// Safety check used only from at().
@@ -823,7 +844,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
at(size_type __n)
{
_M_range_check(__n);
- return (*this)[__n];
+ return (*this)[__n];
}
/**
@@ -850,7 +871,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
front() _GLIBCXX_NOEXCEPT
- { return *begin(); }
+ {
+ __glibcxx_requires_nonempty();
+ return *begin();
+ }
/**
* Returns a read-only (constant) reference to the data at the first
@@ -858,7 +882,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
const_reference
front() const _GLIBCXX_NOEXCEPT
- { return *begin(); }
+ {
+ __glibcxx_requires_nonempty();
+ return *begin();
+ }
/**
* Returns a read/write reference to the data at the last
@@ -866,15 +893,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
back() _GLIBCXX_NOEXCEPT
- { return *(end() - 1); }
-
+ {
+ __glibcxx_requires_nonempty();
+ return *(end() - 1);
+ }
+
/**
* Returns a read-only (constant) reference to the data at the
* last element of the %vector.
*/
const_reference
back() const _GLIBCXX_NOEXCEPT
- { return *(end() - 1); }
+ {
+ __glibcxx_requires_nonempty();
+ return *(end() - 1);
+ }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 464. Suggestion for new member functions in standard containers.
@@ -883,19 +916,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Returns a pointer such that [data(), data() + size()) is a valid
* range. For a non-empty %vector, data() == &front().
*/
-#if __cplusplus >= 201103L
_Tp*
-#else
- pointer
-#endif
data() _GLIBCXX_NOEXCEPT
{ return _M_data_ptr(this->_M_impl._M_start); }
-#if __cplusplus >= 201103L
const _Tp*
-#else
- const_pointer
-#endif
data() const _GLIBCXX_NOEXCEPT
{ return _M_data_ptr(this->_M_impl._M_start); }
@@ -916,15 +941,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
{
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
- __x);
+ __x);
++this->_M_impl._M_finish;
}
else
-#if __cplusplus >= 201103L
- _M_emplace_back_aux(__x);
-#else
- _M_insert_aux(end(), __x);
-#endif
+ _M_realloc_insert(end(), __x);
}
#if __cplusplus >= 201103L
@@ -933,8 +954,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ emplace_back(std::move(__x)); }
template<typename... _Args>
- void
- emplace_back(_Args&&... __args);
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
+ emplace_back(_Args&&... __args);
#endif
/**
@@ -949,6 +974,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
pop_back() _GLIBCXX_NOEXCEPT
{
+ __glibcxx_requires_nonempty();
--this->_M_impl._M_finish;
_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
}
@@ -967,8 +993,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* std::list.
*/
template<typename... _Args>
- iterator
- emplace(const_iterator __position, _Args&&... __args);
+ iterator
+ emplace(const_iterator __position, _Args&&... __args)
+ { return _M_emplace_aux(__position, std::forward<_Args>(__args)...); }
/**
* @brief Inserts given value into %vector before specified iterator.
@@ -1013,14 +1040,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
iterator
insert(const_iterator __position, value_type&& __x)
- { return emplace(__position, std::move(__x)); }
+ { return _M_insert_rval(__position, std::move(__x)); }
/**
* @brief Inserts an initializer_list into the %vector.
* @param __position An iterator into the %vector.
* @param __l An initializer_list.
*
- * This function will insert copies of the data in the
+ * This function will insert copies of the data in the
* initializer_list @a l into the %vector before the location
* specified by @a position.
*
@@ -1030,7 +1057,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
iterator
insert(const_iterator __position, initializer_list<value_type> __l)
- { return this->insert(__position, __l.begin(), __l.end()); }
+ {
+ auto __offset = __position - cbegin();
+ _M_range_insert(begin() + __offset, __l.begin(), __l.end(),
+ std::random_access_iterator_tag());
+ return begin() + __offset;
+ }
#endif
#if __cplusplus >= 201103L
@@ -1092,10 +1124,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
- iterator
- insert(const_iterator __position, _InputIterator __first,
+ iterator
+ insert(const_iterator __position, _InputIterator __first,
_InputIterator __last)
- {
+ {
difference_type __offset = __position - cbegin();
_M_insert_dispatch(begin() + __offset,
__first, __last, __false_type());
@@ -1117,10 +1149,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* consider using std::list.
*/
template<typename _InputIterator>
- void
- insert(iterator __position, _InputIterator __first,
+ void
+ insert(iterator __position, _InputIterator __first,
_InputIterator __last)
- {
+ {
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_insert_dispatch(__position, __first, __last, _Integral());
@@ -1190,13 +1222,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* (Three pointers, so it should be quite fast.)
* Note that the global std::swap() function is specialized such that
* std::swap(v1,v2) will feed to this function.
+ *
+ * Whether the allocators are swapped depends on the allocator traits.
*/
void
swap(vector& __x) _GLIBCXX_NOEXCEPT
{
+#if __cplusplus >= 201103L
+ __glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value
+ || _M_get_Tp_allocator() == __x._M_get_Tp_allocator());
+#endif
this->_M_impl._M_swap_data(__x._M_impl);
_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
- __x._M_get_Tp_allocator());
+ __x._M_get_Tp_allocator());
}
/**
@@ -1215,10 +1253,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* obtain @a n bytes of memory, and then copies [first,last) into it.
*/
template<typename _ForwardIterator>
- pointer
- _M_allocate_and_copy(size_type __n,
+ pointer
+ _M_allocate_and_copy(size_type __n,
_ForwardIterator __first, _ForwardIterator __last)
- {
+ {
pointer __result = this->_M_allocate(__n);
__try
{
@@ -1241,9 +1279,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
- {
+ void
+ _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
+ {
this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n));
this->_M_impl._M_end_of_storage =
this->_M_impl._M_start + static_cast<size_type>(__n);
@@ -1252,10 +1290,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Called by the range constructor to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+ void
+ _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
- {
+ {
typedef typename std::iterator_traits<_InputIterator>::
iterator_category _IterCategory;
_M_range_initialize(__first, __last, _IterCategory());
@@ -1263,10 +1301,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Called by the second initialize_dispatch above
template<typename _InputIterator>
- void
- _M_range_initialize(_InputIterator __first,
+ void
+ _M_range_initialize(_InputIterator __first,
_InputIterator __last, std::input_iterator_tag)
- {
+ {
for (; __first != __last; ++__first)
#if __cplusplus >= 201103L
emplace_back(*__first);
@@ -1277,10 +1315,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Called by the second initialize_dispatch above
template<typename _ForwardIterator>
- void
- _M_range_initialize(_ForwardIterator __first,
+ void
+ _M_range_initialize(_ForwardIterator __first,
_ForwardIterator __last, std::forward_iterator_tag)
- {
+ {
const size_type __n = std::distance(__first, __last);
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
@@ -1319,31 +1357,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
- { _M_fill_assign(__n, __val); }
+ void
+ _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+ { _M_fill_assign(__n, __val); }
// Called by the range assign to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
+ void
+ _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
- {
- typedef typename std::iterator_traits<_InputIterator>::
- iterator_category _IterCategory;
- _M_assign_aux(__first, __last, _IterCategory());
- }
+ { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
// Called by the second assign_dispatch above
template<typename _InputIterator>
- void
- _M_assign_aux(_InputIterator __first, _InputIterator __last,
+ void
+ _M_assign_aux(_InputIterator __first, _InputIterator __last,
std::input_iterator_tag);
// Called by the second assign_dispatch above
template<typename _ForwardIterator>
- void
- _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+ void
+ _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
std::forward_iterator_tag);
// Called by assign(n,t), and the range assign when it turns out
@@ -1351,7 +1385,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
_M_fill_assign(size_type __n, const value_type& __val);
-
// Internal insert functions follow.
// Called by the range insert to implement [23.1.1]/9
@@ -1359,32 +1392,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause
template<typename _Integer>
- void
- _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
+ void
+ _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
__true_type)
- { _M_fill_insert(__pos, __n, __val); }
+ { _M_fill_insert(__pos, __n, __val); }
// Called by the range insert to implement [23.1.1]/9
template<typename _InputIterator>
- void
- _M_insert_dispatch(iterator __pos, _InputIterator __first,
+ void
+ _M_insert_dispatch(iterator __pos, _InputIterator __first,
_InputIterator __last, __false_type)
- {
- typedef typename std::iterator_traits<_InputIterator>::
- iterator_category _IterCategory;
- _M_range_insert(__pos, __first, __last, _IterCategory());
+ {
+ _M_range_insert(__pos, __first, __last,
+ std::__iterator_category(__first));
}
// Called by the second insert_dispatch above
template<typename _InputIterator>
- void
- _M_range_insert(iterator __pos, _InputIterator __first,
+ void
+ _M_range_insert(iterator __pos, _InputIterator __first,
_InputIterator __last, std::input_iterator_tag);
// Called by the second insert_dispatch above
template<typename _ForwardIterator>
- void
- _M_range_insert(iterator __pos, _ForwardIterator __first,
+ void
+ _M_range_insert(iterator __pos, _ForwardIterator __first,
_ForwardIterator __last, std::forward_iterator_tag);
// Called by insert(p,n,x), and the range insert when it turns out to be
@@ -1401,21 +1433,66 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_shrink_to_fit();
#endif
- // Called by insert(p,x)
#if __cplusplus < 201103L
+ // Called by insert(p,x)
void
_M_insert_aux(iterator __position, const value_type& __x);
+
+ void
+ _M_realloc_insert(iterator __position, const value_type& __x);
#else
+ // A value_type object constructed with _Alloc_traits::construct()
+ // and destroyed with _Alloc_traits::destroy().
+ struct _Temporary_value
+ {
+ template<typename... _Args>
+ explicit
+ _Temporary_value(vector* __vec, _Args&&... __args) : _M_this(__vec)
+ {
+ _Alloc_traits::construct(_M_this->_M_impl, _M_ptr(),
+ std::forward<_Args>(__args)...);
+ }
+
+ ~_Temporary_value()
+ { _Alloc_traits::destroy(_M_this->_M_impl, _M_ptr()); }
+
+ value_type&
+ _M_val() { return *reinterpret_cast<_Tp*>(&__buf); }
+
+ private:
+ pointer
+ _M_ptr() { return pointer_traits<pointer>::pointer_to(_M_val()); }
+
+ vector* _M_this;
+ typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __buf;
+ };
+
+ // Called by insert(p,x) and other functions when insertion needs to
+ // reallocate or move existing elements. _Arg is either _Tp& or _Tp.
+ template<typename _Arg>
+ void
+ _M_insert_aux(iterator __position, _Arg&& __arg);
+
template<typename... _Args>
- void
- _M_insert_aux(iterator __position, _Args&&... __args);
+ void
+ _M_realloc_insert(iterator __position, _Args&&... __args);
+
+ // Either move-construct at the end, or forward to _M_insert_aux.
+ iterator
+ _M_insert_rval(const_iterator __position, value_type&& __v);
+ // Try to emplace at the end, otherwise forward to _M_insert_aux.
template<typename... _Args>
- void
- _M_emplace_back_aux(_Args&&... __args);
+ iterator
+ _M_emplace_aux(const_iterator __position, _Args&&... __args);
+
+ // Emplacing an rvalue of the correct type can use _M_insert_rval.
+ iterator
+ _M_emplace_aux(const_iterator __position, value_type&& __v)
+ { return _M_insert_rval(__position, std::move(__v)); }
#endif
- // Called by the latter.
+ // Called by _M_fill_insert, _M_insert_aux etc.
size_type
_M_check_len(size_type __n, const char* __s) const
{
@@ -1475,21 +1552,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
#endif
-#if __cplusplus >= 201103L
template<typename _Up>
_Up*
- _M_data_ptr(_Up* __ptr) const
+ _M_data_ptr(_Up* __ptr) const _GLIBCXX_NOEXCEPT
{ return __ptr; }
+#if __cplusplus >= 201103L
template<typename _Ptr>
typename std::pointer_traits<_Ptr>::element_type*
_M_data_ptr(_Ptr __ptr) const
{ return empty() ? nullptr : std::__addressof(*__ptr); }
#else
+ template<typename _Up>
+ _Up*
+ _M_data_ptr(_Up* __ptr) _GLIBCXX_NOEXCEPT
+ { return __ptr; }
+
template<typename _Ptr>
- _Ptr
+ value_type*
+ _M_data_ptr(_Ptr __ptr)
+ { return __ptr.operator->(); }
+
+ template<typename _Ptr>
+ const value_type*
_M_data_ptr(_Ptr __ptr) const
- { return __ptr; }
+ { return __ptr.operator->(); }
#endif
};
diff --git a/libstdc++-v3/include/bits/stream_iterator.h b/libstdc++-v3/include/bits/stream_iterator.h
index f9c6ba67c5..552ed36d8b 100644
--- a/libstdc++-v3/include/bits/stream_iterator.h
+++ b/libstdc++-v3/include/bits/stream_iterator.h
@@ -1,6 +1,6 @@
// Stream iterators
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -66,7 +66,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Construct start of input stream iterator.
istream_iterator(istream_type& __s)
- : _M_stream(&__s)
+ : _M_stream(std::__addressof(__s))
{ _M_read(); }
istream_iterator(const istream_iterator& __obj)
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
const _Tp*
- operator->() const { return &(operator*()); }
+ operator->() const { return std::__addressof((operator*())); }
istream_iterator&
operator++()
@@ -168,7 +168,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public:
/// Construct from an ostream.
- ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
+ ostream_iterator(ostream_type& __s)
+ : _M_stream(std::__addressof(__s)), _M_string(0) {}
/**
* Construct from an ostream.
diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc
index ff479ecd58..a8ac056c27 100644
--- a/libstdc++-v3/include/bits/streambuf.tcc
+++ b/libstdc++-v3/include/bits/streambuf.tcc
@@ -1,6 +1,6 @@
// Stream buffer classes -*- C++ -*-
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h
index 2230e94612..f0451b12ce 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -1,6 +1,6 @@
// Streambuf iterators
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/string_view.tcc b/libstdc++-v3/include/bits/string_view.tcc
new file mode 100644
index 0000000000..ffdcc30cae
--- /dev/null
+++ b/libstdc++-v3/include/bits/string_view.tcc
@@ -0,0 +1,227 @@
+// Components for manipulating non-owning sequences of characters -*- C++ -*-
+
+// Copyright (C) 2013-2017 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/string_view.tcc
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{string_view}
+ */
+
+//
+// N3762 basic_string_view library
+//
+
+#ifndef _GLIBCXX_STRING_VIEW_TCC
+#define _GLIBCXX_STRING_VIEW_TCC 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201402L
+# include <bits/c++17_warning.h>
+#else
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
+ {
+ __glibcxx_requires_string_len(__str, __n);
+
+ if (__n == 0)
+ return __pos <= this->_M_len ? __pos : npos;
+
+ if (__n <= this->_M_len)
+ {
+ for (; __pos <= this->_M_len - __n; ++__pos)
+ if (traits_type::eq(this->_M_str[__pos], __str[0])
+ && traits_type::compare(this->_M_str + __pos + 1,
+ __str + 1, __n - 1) == 0)
+ return __pos;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find(_CharT __c, size_type __pos) const noexcept
+ {
+ size_type __ret = npos;
+ if (__pos < this->_M_len)
+ {
+ const size_type __n = this->_M_len - __pos;
+ const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c);
+ if (__p)
+ __ret = __p - this->_M_str;
+ }
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept
+ {
+ __glibcxx_requires_string_len(__str, __n);
+
+ if (__n <= this->_M_len)
+ {
+ __pos = std::min(size_type(this->_M_len - __n), __pos);
+ do
+ {
+ if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0)
+ return __pos;
+ }
+ while (__pos-- > 0);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ rfind(_CharT __c, size_type __pos) const noexcept
+ {
+ size_type __size = this->_M_len;
+ if (__size > 0)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ for (++__size; __size-- > 0; )
+ if (traits_type::eq(this->_M_str[__size], __c))
+ return __size;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_first_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ __glibcxx_requires_string_len(__str, __n);
+ for (; __n && __pos < this->_M_len; ++__pos)
+ {
+ const _CharT* __p = traits_type::find(__str, __n,
+ this->_M_str[__pos]);
+ if (__p)
+ return __pos;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_last_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ __glibcxx_requires_string_len(__str, __n);
+ size_type __size = this->size();
+ if (__size && __n)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (traits_type::find(__str, __n, this->_M_str[__size]))
+ return __size;
+ }
+ while (__size-- != 0);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ __glibcxx_requires_string_len(__str, __n);
+ for (; __pos < this->_M_len; ++__pos)
+ if (!traits_type::find(__str, __n, this->_M_str[__pos]))
+ return __pos;
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_first_not_of(_CharT __c, size_type __pos) const noexcept
+ {
+ for (; __pos < this->_M_len; ++__pos)
+ if (!traits_type::eq(this->_M_str[__pos], __c))
+ return __pos;
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ __glibcxx_requires_string_len(__str, __n);
+ size_type __size = this->_M_len;
+ if (__size)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (!traits_type::find(__str, __n, this->_M_str[__size]))
+ return __size;
+ }
+ while (__size--);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_last_not_of(_CharT __c, size_type __pos) const noexcept
+ {
+ size_type __size = this->_M_len;
+ if (__size)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (!traits_type::eq(this->_M_str[__size], __c))
+ return __size;
+ }
+ while (__size--);
+ }
+ return npos;
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // __cplusplus <= 201402L
+
+#endif // _GLIBCXX_STRING_VIEW_TCC
diff --git a/libstdc++-v3/include/bits/stringfwd.h b/libstdc++-v3/include/bits/stringfwd.h
index 98f7a43eb0..15db187f93 100644
--- a/libstdc++-v3/include/bits/stringfwd.h
+++ b/libstdc++-v3/include/bits/stringfwd.h
@@ -1,6 +1,6 @@
// <string> Forward declarations -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
diff --git a/libstdc++-v3/include/bits/uniform_int_dist.h b/libstdc++-v3/include/bits/uniform_int_dist.h
index 393aa77b7f..af7ac14bcc 100644
--- a/libstdc++-v3/include/bits/uniform_int_dist.h
+++ b/libstdc++-v3/include/bits/uniform_int_dist.h
@@ -1,6 +1,6 @@
// Class template uniform_int_distribution -*- C++ -*-
-// Copyright (C) 2009-2016 Free Software Foundation, Inc.
+// Copyright (C) 2009-2017 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
@@ -36,10 +36,10 @@
namespace std _GLIBCXX_VISIBILITY(default)
{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __detail
{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
/* Determine whether number is a power of 2. */
template<typename _Tp>
inline bool
@@ -47,8 +47,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
return ((__x - 1) & __x) == 0;
};
+_GLIBCXX_END_NAMESPACE_VERSION
}
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Uniform discrete distribution for random numbers.
* A discrete random distribution on the range @f$[min, max]@f$ with equal
@@ -58,7 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class uniform_int_distribution
{
static_assert(std::is_integral<_IntType>::value,
- "template argument not an integral type");
+ "template argument must be an integral type");
public:
/** The type of the range of the distribution. */
@@ -88,6 +91,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const param_type& __p1, const param_type& __p2)
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
+ friend bool
+ operator!=(const param_type& __p1, const param_type& __p2)
+ { return !(__p1 == __p2); }
+
private:
_IntType _M_a;
_IntType _M_b;
@@ -360,6 +367,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*__f++ = __uctype(__urng()) - __urngmin + __param.a();
}
+ // operator!= and operator<< and operator>> are defined in <bits/random.h>
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index db31b54a43..a31cd67d6e 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -1,6 +1,6 @@
// unique_ptr implementation -*- C++ -*-
-// Copyright (C) 2008-2016 Free Software Foundation, Inc.
+// Copyright (C) 2008-2017 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
@@ -35,6 +35,8 @@
#include <type_traits>
#include <utility>
#include <tuple>
+#include <bits/stl_function.h>
+#include <bits/functional_hash.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -111,33 +113,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
- /// 20.7.1.2 unique_ptr for single objects.
- template <typename _Tp, typename _Dp = default_delete<_Tp> >
- class unique_ptr
+ template <typename _Tp, typename _Dp>
+ class __uniq_ptr_impl
{
- // use SFINAE to determine whether _Del::pointer exists
- class _Pointer
- {
- template<typename _Up>
- static typename _Up::pointer __test(typename _Up::pointer*);
+ template <typename _Up, typename _Ep, typename = void>
+ struct _Ptr
+ {
+ using type = _Up*;
+ };
- template<typename _Up>
- static _Tp* __test(...);
+ template <typename _Up, typename _Ep>
+ struct
+ _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
+ {
+ using type = typename remove_reference<_Ep>::type::pointer;
+ };
- typedef typename remove_reference<_Dp>::type _Del;
+ public:
+ using _DeleterConstraint = enable_if<
+ __and_<__not_<is_pointer<_Dp>>,
+ is_default_constructible<_Dp>>::value>;
- public:
- typedef decltype(__test<_Del>(0)) type;
- };
+ using pointer = typename _Ptr<_Tp, _Dp>::type;
- typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
- __tuple_type _M_t;
+ __uniq_ptr_impl() = default;
+ __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
- public:
- typedef typename _Pointer::type pointer;
- typedef _Tp element_type;
- typedef _Dp deleter_type;
+ template<typename _Del>
+ __uniq_ptr_impl(pointer __p, _Del&& __d)
+ : _M_t(__p, std::forward<_Del>(__d)) { }
+ pointer& _M_ptr() { return std::get<0>(_M_t); }
+ pointer _M_ptr() const { return std::get<0>(_M_t); }
+ _Dp& _M_deleter() { return std::get<1>(_M_t); }
+ const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
+
+ private:
+ tuple<pointer, _Dp> _M_t;
+ };
+
+ /// 20.7.1.2 unique_ptr for single objects.
+ template <typename _Tp, typename _Dp = default_delete<_Tp>>
+ class unique_ptr
+ {
+ template <class _Up>
+ using _DeleterConstraint =
+ typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
+
+ __uniq_ptr_impl<_Tp, _Dp> _M_t;
+
+ public:
+ using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
+ using element_type = _Tp;
+ using deleter_type = _Dp;
// helper template for detecting a safe conversion from another
// unique_ptr
@@ -155,10 +183,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Constructors.
/// Default constructor, creates a unique_ptr that owns nothing.
- constexpr unique_ptr() noexcept
- : _M_t()
- { static_assert(!is_pointer<deleter_type>::value,
- "constructed with null function pointer deleter"); }
+ template <typename _Up = _Dp,
+ typename = _DeleterConstraint<_Up>>
+ constexpr unique_ptr() noexcept
+ : _M_t()
+ { }
/** Takes ownership of a pointer.
*
@@ -166,11 +195,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* The deleter will be value-initialized.
*/
- explicit
- unique_ptr(pointer __p) noexcept
- : _M_t(__p, deleter_type())
- { static_assert(!is_pointer<deleter_type>::value,
- "constructed with null function pointer deleter"); }
+ template <typename _Up = _Dp,
+ typename = _DeleterConstraint<_Up>>
+ explicit
+ unique_ptr(pointer __p) noexcept
+ : _M_t(__p)
+ { }
/** Takes ownership of a pointer.
*
@@ -198,7 +228,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"rvalue deleter bound to reference"); }
/// Creates a unique_ptr that owns nothing.
- constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+ template <typename _Up = _Dp,
+ typename = _DeleterConstraint<_Up>>
+ constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
// Move constructors.
@@ -231,7 +263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Destructor, invokes the deleter if the stored pointer is not null.
~unique_ptr() noexcept
{
- auto& __ptr = std::get<0>(_M_t);
+ auto& __ptr = _M_t._M_ptr();
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
@@ -302,17 +334,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Return the stored pointer.
pointer
get() const noexcept
- { return std::get<0>(_M_t); }
+ { return _M_t._M_ptr(); }
/// Return a reference to the stored deleter.
deleter_type&
get_deleter() noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return a reference to the stored deleter.
const deleter_type&
get_deleter() const noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return @c true if the stored pointer is not null.
explicit operator bool() const noexcept
@@ -325,7 +357,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
release() noexcept
{
pointer __p = get();
- std::get<0>(_M_t) = pointer();
+ _M_t._M_ptr() = pointer();
return __p;
}
@@ -339,7 +371,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reset(pointer __p = pointer()) noexcept
{
using std::swap;
- swap(std::get<0>(_M_t), __p);
+ swap(_M_t._M_ptr(), __p);
if (__p != pointer())
get_deleter()(__p);
}
@@ -364,23 +396,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Dp>
class unique_ptr<_Tp[], _Dp>
{
- // use SFINAE to determine whether _Del::pointer exists
- class _Pointer
- {
- template<typename _Up>
- static typename _Up::pointer __test(typename _Up::pointer*);
-
- template<typename _Up>
- static _Tp* __test(...);
-
- typedef typename remove_reference<_Dp>::type _Del;
+ template <typename _Up>
+ using _DeleterConstraint =
+ typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
- public:
- typedef decltype(__test<_Del>(0)) type;
- };
-
- typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
- __tuple_type _M_t;
+ __uniq_ptr_impl<_Tp, _Dp> _M_t;
template<typename _Up>
using __remove_cv = typename remove_cv<_Up>::type;
@@ -391,11 +411,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= __and_< is_base_of<_Tp, _Up>,
__not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
-
public:
- typedef typename _Pointer::type pointer;
- typedef _Tp element_type;
- typedef _Dp deleter_type;
+ using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
+ using element_type = _Tp;
+ using deleter_type = _Dp;
// helper template for detecting a safe conversion from another
// unique_ptr
@@ -429,10 +448,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Constructors.
/// Default constructor, creates a unique_ptr that owns nothing.
- constexpr unique_ptr() noexcept
- : _M_t()
- { static_assert(!std::is_pointer<deleter_type>::value,
- "constructed with null function pointer deleter"); }
+ template <typename _Up = _Dp,
+ typename = _DeleterConstraint<_Up>>
+ constexpr unique_ptr() noexcept
+ : _M_t()
+ { }
/** Takes ownership of a pointer.
*
@@ -442,13 +462,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* The deleter will be value-initialized.
*/
template<typename _Up,
- typename = typename enable_if<
+ typename _Vp = _Dp,
+ typename = _DeleterConstraint<_Vp>,
+ typename = typename enable_if<
__safe_conversion_raw<_Up>::value, bool>::type>
- explicit
- unique_ptr(_Up __p) noexcept
- : _M_t(__p, deleter_type())
- { static_assert(!is_pointer<deleter_type>::value,
- "constructed with null function pointer deleter"); }
+ explicit
+ unique_ptr(_Up __p) noexcept
+ : _M_t(__p)
+ { }
/** Takes ownership of a pointer.
*
@@ -488,7 +509,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
/// Creates a unique_ptr that owns nothing.
- constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+ template <typename _Up = _Dp,
+ typename = _DeleterConstraint<_Up>>
+ constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
template<typename _Up, typename _Ep,
typename = _Require<__safe_conversion_up<_Up, _Ep>>>
@@ -499,7 +522,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Destructor, invokes the deleter if the stored pointer is not null.
~unique_ptr()
{
- auto& __ptr = std::get<0>(_M_t);
+ auto& __ptr = _M_t._M_ptr();
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
@@ -562,17 +585,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Return the stored pointer.
pointer
get() const noexcept
- { return std::get<0>(_M_t); }
+ { return _M_t._M_ptr(); }
/// Return a reference to the stored deleter.
deleter_type&
get_deleter() noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return a reference to the stored deleter.
const deleter_type&
get_deleter() const noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return @c true if the stored pointer is not null.
explicit operator bool() const noexcept
@@ -585,7 +608,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
release() noexcept
{
pointer __p = get();
- std::get<0>(_M_t) = pointer();
+ _M_t._M_ptr() = pointer();
return __p;
}
@@ -610,10 +633,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
reset(_Up __p) noexcept
{
+ pointer __ptr = __p;
using std::swap;
- swap(std::get<0>(_M_t), __p);
- if (__p != nullptr)
- get_deleter()(__p);
+ swap(_M_t._M_ptr(), __ptr);
+ if (__ptr != nullptr)
+ get_deleter()(__ptr);
}
void reset(nullptr_t = nullptr) noexcept
@@ -635,11 +659,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
template<typename _Tp, typename _Dp>
- inline void
+ inline
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ // Constrained free swap overload, see p0185r1
+ typename enable_if<__is_swappable<_Dp>::value>::type
+#else
+ void
+#endif
swap(unique_ptr<_Tp, _Dp>& __x,
unique_ptr<_Tp, _Dp>& __y) noexcept
{ __x.swap(__y); }
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+ template<typename _Tp, typename _Dp>
+ typename enable_if<!__is_swappable<_Dp>::value>::type
+ swap(unique_ptr<_Tp, _Dp>&,
+ unique_ptr<_Tp, _Dp>&) = delete;
+#endif
+
template<typename _Tp, typename _Dp,
typename _Up, typename _Ep>
inline bool
@@ -754,7 +791,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// std::hash specialization for unique_ptr.
template<typename _Tp, typename _Dp>
struct hash<unique_ptr<_Tp, _Dp>>
- : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
+ : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
+ private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
{
size_t
operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index d6f5ab7af0..4ef30ccccd 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -1,6 +1,6 @@
// unordered_map implementation -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -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.
@@ -274,7 +282,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %unordered_map and
* that the resulting %unordered_map's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
unordered_map&
operator=(initializer_list<value_type> __l)
@@ -283,8 +291,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
- /// Returns the allocator object with which the %unordered_map was
- /// constructed.
+ /// Returns the allocator object used by the %unordered_map.
allocator_type
get_allocator() const noexcept
{ return _M_h.get_allocator(); }
@@ -410,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
@@ -525,7 +554,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::forward<_Args>(__args)...));
return __i;
}
-#endif
+#endif // C++17
//@{
/**
@@ -818,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
@@ -1053,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>&);
};
/**
@@ -1115,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.
@@ -1258,12 +1322,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Unordered_multimap list assignment operator.
* @param __l An initializer_list.
*
- * This function fills an %unordered_multimap with copies of the elements
- * in the initializer list @a __l.
+ * This function fills an %unordered_multimap with copies of the
+ * elements in the initializer list @a __l.
*
* Note that the assignment completely changes the %unordered_multimap
* and that the resulting %unordered_multimap's size is the same as the
- * number of elements assigned. Old data may be lost.
+ * number of elements assigned.
*/
unordered_multimap&
operator=(initializer_list<value_type> __l)
@@ -1272,8 +1336,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
- /// Returns the allocator object with which the %unordered_multimap was
- /// constructed.
+ /// Returns the allocator object used by the %unordered_multimap.
allocator_type
get_allocator() const noexcept
{ return _M_h.get_allocator(); }
@@ -1470,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.
@@ -1553,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
@@ -1788,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 3efd1f94c7..85c2562f89 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -1,6 +1,6 @@
// unordered_set implementation -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -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.
@@ -268,7 +276,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %unordered_set and
* that the resulting %unordered_set's size is the same as the number
- * of elements assigned. Old data may be lost.
+ * of elements assigned.
*/
unordered_set&
operator=(initializer_list<value_type> __l)
@@ -277,8 +285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
- /// Returns the allocator object with which the %unordered_set was
- /// constructed.
+ /// Returns the allocator object used by the %unordered_set.
allocator_type
get_allocator() const noexcept
{ return _M_h.get_allocator(); }
@@ -471,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.
@@ -553,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
@@ -794,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.
@@ -942,7 +1009,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Note that the assignment completely changes the %unordered_multiset
* and that the resulting %unordered_multiset's size is the same as the
- * number of elements assigned. Old data may be lost.
+ * number of elements assigned.
*/
unordered_multiset&
operator=(initializer_list<value_type> __l)
@@ -951,8 +1018,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
- /// Returns the allocator object with which the %unordered_multiset was
- /// constructed.
+ /// Returns the allocator object used by the %unordered_multiset.
allocator_type
get_allocator() const noexcept
{ return _M_h.get_allocator(); }
@@ -1123,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.
@@ -1210,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
@@ -1431,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 b1ff58a294..89d4e43565 100644
--- a/libstdc++-v3/include/bits/uses_allocator.h
+++ b/libstdc++-v3/include/bits/uses_allocator.h
@@ -1,6 +1,6 @@
// Uses-allocator Construction -*- C++ -*-
-// Copyright (C) 2010-2016 Free Software Foundation, Inc.
+// Copyright (C) 2010-2017 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
@@ -45,7 +45,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// [allocator.tag]
struct allocator_arg_t { explicit allocator_arg_t() = default; };
- constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+ _GLIBCXX17_INLINE constexpr allocator_arg_t allocator_arg =
+ allocator_arg_t();
template<typename _Tp, typename _Alloc, typename = __void_t<>>
struct __uses_allocator_helper
@@ -108,6 +109,70 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__ret._M_a = std::__addressof(__a);
return __ret;
}
+#if __cplusplus > 201402L
+ template <typename _Tp, typename _Alloc>
+ inline constexpr bool uses_allocator_v =
+ uses_allocator<_Tp, _Alloc>::value;
+#endif // C++17
+
+ template<template<typename...> class _Predicate,
+ typename _Tp, typename _Alloc, typename... _Args>
+ struct __is_uses_allocator_predicate
+ : conditional<uses_allocator<_Tp, _Alloc>::value,
+ __or_<_Predicate<_Tp, allocator_arg_t, _Alloc, _Args...>,
+ _Predicate<_Tp, _Args..., _Alloc>>,
+ _Predicate<_Tp, _Args...>>::type { };
+
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ struct __is_uses_allocator_constructible
+ : __is_uses_allocator_predicate<is_constructible, _Tp, _Alloc, _Args...>
+ { };
+
+#if __cplusplus >= 201402L
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ _GLIBCXX17_INLINE constexpr bool __is_uses_allocator_constructible_v =
+ __is_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value;
+#endif // C++14
+
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ struct __is_nothrow_uses_allocator_constructible
+ : __is_uses_allocator_predicate<is_nothrow_constructible,
+ _Tp, _Alloc, _Args...>
+ { };
+
+
+#if __cplusplus >= 201402L
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ _GLIBCXX17_INLINE constexpr bool
+ __is_nothrow_uses_allocator_constructible_v =
+ __is_nothrow_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value;
+#endif // C++14
+
+ template<typename _Tp, typename... _Args>
+ void __uses_allocator_construct_impl(__uses_alloc0 __a, _Tp* __ptr,
+ _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 ((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 ((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, std::forward<_Args>(__args)...);
+ }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/bits/valarray_after.h b/libstdc++-v3/include/bits/valarray_after.h
index 53dab52880..54ba7fed61 100644
--- a/libstdc++-v3/include/bits/valarray_after.h
+++ b/libstdc++-v3/include/bits/valarray_after.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- internal _Meta class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h
index d6f8e7a23f..f169edd972 100644
--- a/libstdc++-v3/include/bits/valarray_array.h
+++ b/libstdc++-v3/include/bits/valarray_array.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- internal _Array helper class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/valarray_array.tcc b/libstdc++-v3/include/bits/valarray_array.tcc
index 812d94b454..9879c52810 100644
--- a/libstdc++-v3/include/bits/valarray_array.tcc
+++ b/libstdc++-v3/include/bits/valarray_array.tcc
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- internal _Array helper class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/valarray_before.h b/libstdc++-v3/include/bits/valarray_before.h
index 86136f438c..67603e1099 100644
--- a/libstdc++-v3/include/bits/valarray_before.h
+++ b/libstdc++-v3/include/bits/valarray_before.h
@@ -1,6 +1,6 @@
// The template and inlines for the -*- C++ -*- internal _Meta class.
-// Copyright (C) 1997-2016 Free Software Foundation, Inc.
+// Copyright (C) 1997-2017 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
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 715b83eb67..8d688661c8 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -1,6 +1,6 @@
// Vector implementation (out of line) -*- C++ -*-
-// Copyright (C) 2001-2016 Free Software Foundation, Inc.
+// Copyright (C) 2001-2017 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
@@ -87,7 +87,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
template<typename... _Args>
+#if __cplusplus > 201402L
+ typename vector<_Tp, _Alloc>::reference
+#else
void
+#endif
vector<_Tp, _Alloc>::
emplace_back(_Args&&... __args)
{
@@ -98,7 +102,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
++this->_M_impl._M_finish;
}
else
- _M_emplace_back_aux(std::forward<_Args>(__args)...);
+ _M_realloc_insert(end(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return back();
+#endif
}
#endif
@@ -112,27 +119,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
{
const size_type __n = __position - begin();
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
- && __position == end())
- {
- _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x);
- ++this->_M_impl._M_finish;
- }
- else
- {
+ if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+ if (__position == end())
+ {
+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+ __x);
+ ++this->_M_impl._M_finish;
+ }
+ else
+ {
#if __cplusplus >= 201103L
- const auto __pos = begin() + (__position - cbegin());
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
- {
- _Tp __x_copy = __x;
- _M_insert_aux(__pos, std::move(__x_copy));
- }
- else
- _M_insert_aux(__pos, __x);
+ const auto __pos = begin() + (__position - cbegin());
+ // __x could be an existing element of this vector, so make a
+ // copy of it before _M_insert_aux moves elements around.
+ _Temporary_value __x_copy(this, __x);
+ _M_insert_aux(__pos, std::move(__x_copy._M_val()));
#else
_M_insert_aux(__position, __x);
#endif
- }
+ }
+ else
+#if __cplusplus >= 201103L
+ _M_realloc_insert(begin() + (__position - cbegin()), __x);
+#else
+ _M_realloc_insert(__position, __x);
+#endif
+
return iterator(this->_M_impl._M_start + __n);
}
@@ -256,7 +268,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (__first == __last)
_M_erase_at_end(__cur);
else
- insert(end(), __first, __last);
+ _M_range_insert(end(), __first, __last,
+ std::__iterator_category(__first));
}
template<typename _Tp, typename _Alloc>
@@ -296,30 +309,60 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
- template<typename... _Args>
- typename vector<_Tp, _Alloc>::iterator
- vector<_Tp, _Alloc>::
- emplace(const_iterator __position, _Args&&... __args)
- {
- const size_type __n = __position - begin();
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
- && __position == end())
+ auto
+ vector<_Tp, _Alloc>::
+ _M_insert_rval(const_iterator __position, value_type&& __v) -> iterator
+ {
+ const auto __n = __position - cbegin();
+ if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+ if (__position == cend())
{
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
- std::forward<_Args>(__args)...);
+ std::move(__v));
++this->_M_impl._M_finish;
}
else
- _M_insert_aux(begin() + (__position - cbegin()),
- std::forward<_Args>(__args)...);
+ _M_insert_aux(begin() + __n, std::move(__v));
+ else
+ _M_realloc_insert(begin() + __n, std::move(__v));
+
+ return iterator(this->_M_impl._M_start + __n);
+ }
+
+ template<typename _Tp, typename _Alloc>
+ template<typename... _Args>
+ auto
+ vector<_Tp, _Alloc>::
+ _M_emplace_aux(const_iterator __position, _Args&&... __args)
+ -> iterator
+ {
+ const auto __n = __position - cbegin();
+ if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+ if (__position == cend())
+ {
+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+ std::forward<_Args>(__args)...);
+ ++this->_M_impl._M_finish;
+ }
+ else
+ {
+ // We need to construct a temporary because something in __args...
+ // could alias one of the elements of the container and so we
+ // need to use it before _M_insert_aux moves elements around.
+ _Temporary_value __tmp(this, std::forward<_Args>(__args)...);
+ _M_insert_aux(begin() + __n, std::move(__tmp._M_val()));
+ }
+ else
+ _M_realloc_insert(begin() + __n, std::forward<_Args>(__args)...);
+
return iterator(this->_M_impl._M_start + __n);
}
template<typename _Tp, typename _Alloc>
- template<typename... _Args>
+ template<typename _Arg>
void
vector<_Tp, _Alloc>::
- _M_insert_aux(iterator __position, _Args&&... __args)
+ _M_insert_aux(iterator __position, _Arg&& __arg)
#else
template<typename _Tp, typename _Alloc>
void
@@ -327,77 +370,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_insert_aux(iterator __position, const _Tp& __x)
#endif
{
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
- {
- _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
- _GLIBCXX_MOVE(*(this->_M_impl._M_finish
- - 1)));
- ++this->_M_impl._M_finish;
+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+ _GLIBCXX_MOVE(*(this->_M_impl._M_finish
+ - 1)));
+ ++this->_M_impl._M_finish;
#if __cplusplus < 201103L
- _Tp __x_copy = __x;
+ _Tp __x_copy = __x;
#endif
- _GLIBCXX_MOVE_BACKWARD3(__position.base(),
- this->_M_impl._M_finish - 2,
- this->_M_impl._M_finish - 1);
+ _GLIBCXX_MOVE_BACKWARD3(__position.base(),
+ this->_M_impl._M_finish - 2,
+ this->_M_impl._M_finish - 1);
#if __cplusplus < 201103L
- *__position = __x_copy;
-#else
- *__position = _Tp(std::forward<_Args>(__args)...);
-#endif
- }
- else
- {
- const size_type __len =
- _M_check_len(size_type(1), "vector::_M_insert_aux");
- const size_type __elems_before = __position - begin();
- pointer __new_start(this->_M_allocate(__len));
- pointer __new_finish(__new_start);
- __try
- {
- // The order of the three operations is dictated by the C++0x
- // case, where the moves could alter a new element belonging
- // to the existing vector. This is an issue only for callers
- // taking the element by const lvalue ref (see 23.1/13).
- _Alloc_traits::construct(this->_M_impl,
- __new_start + __elems_before,
-#if __cplusplus >= 201103L
- std::forward<_Args>(__args)...);
+ *__position = __x_copy;
#else
- __x);
+ *__position = std::forward<_Arg>(__arg);
#endif
- __new_finish = pointer();
-
- __new_finish
- = std::__uninitialized_move_if_noexcept_a
- (this->_M_impl._M_start, __position.base(),
- __new_start, _M_get_Tp_allocator());
-
- ++__new_finish;
-
- __new_finish
- = std::__uninitialized_move_if_noexcept_a
- (__position.base(), this->_M_impl._M_finish,
- __new_finish, _M_get_Tp_allocator());
- }
- __catch(...)
- {
- if (!__new_finish)
- _Alloc_traits::destroy(this->_M_impl,
- __new_start + __elems_before);
- else
- std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
- _M_deallocate(__new_start, __len);
- __throw_exception_again;
- }
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- _M_get_Tp_allocator());
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage
- - this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start;
- this->_M_impl._M_finish = __new_finish;
- this->_M_impl._M_end_of_storage = __new_start + __len;
- }
}
#if __cplusplus >= 201103L
@@ -405,44 +392,66 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename... _Args>
void
vector<_Tp, _Alloc>::
- _M_emplace_back_aux(_Args&&... __args)
- {
- const size_type __len =
- _M_check_len(size_type(1), "vector::_M_emplace_back_aux");
- pointer __new_start(this->_M_allocate(__len));
- pointer __new_finish(__new_start);
- __try
- {
- _Alloc_traits::construct(this->_M_impl, __new_start + size(),
- std::forward<_Args>(__args)...);
- __new_finish = pointer();
+ _M_realloc_insert(iterator __position, _Args&&... __args)
+#else
+ template<typename _Tp, typename _Alloc>
+ void
+ vector<_Tp, _Alloc>::
+ _M_realloc_insert(iterator __position, const _Tp& __x)
+#endif
+ {
+ const size_type __len =
+ _M_check_len(size_type(1), "vector::_M_realloc_insert");
+ const size_type __elems_before = __position - begin();
+ pointer __new_start(this->_M_allocate(__len));
+ pointer __new_finish(__new_start);
+ __try
+ {
+ // The order of the three operations is dictated by the C++11
+ // case, where the moves could alter a new element belonging
+ // to the existing vector. This is an issue only for callers
+ // taking the element by lvalue ref (see last bullet of C++11
+ // [res.on.arguments]).
+ _Alloc_traits::construct(this->_M_impl,
+ __new_start + __elems_before,
+#if __cplusplus >= 201103L
+ std::forward<_Args>(__args)...);
+#else
+ __x);
+#endif
+ __new_finish = pointer();
- __new_finish
- = std::__uninitialized_move_if_noexcept_a
- (this->_M_impl._M_start, this->_M_impl._M_finish,
- __new_start, _M_get_Tp_allocator());
+ __new_finish
+ = std::__uninitialized_move_if_noexcept_a
+ (this->_M_impl._M_start, __position.base(),
+ __new_start, _M_get_Tp_allocator());
- ++__new_finish;
- }
- __catch(...)
- {
- if (!__new_finish)
- _Alloc_traits::destroy(this->_M_impl, __new_start + size());
- else
- std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
- _M_deallocate(__new_start, __len);
- __throw_exception_again;
- }
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- _M_get_Tp_allocator());
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage
- - this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start;
- this->_M_impl._M_finish = __new_finish;
- this->_M_impl._M_end_of_storage = __new_start + __len;
- }
-#endif
+ ++__new_finish;
+
+ __new_finish
+ = std::__uninitialized_move_if_noexcept_a
+ (__position.base(), this->_M_impl._M_finish,
+ __new_finish, _M_get_Tp_allocator());
+ }
+ __catch(...)
+ {
+ if (!__new_finish)
+ _Alloc_traits::destroy(this->_M_impl,
+ __new_start + __elems_before);
+ else
+ std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
+ _M_deallocate(__new_start, __len);
+ __throw_exception_again;
+ }
+ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
+ _M_get_Tp_allocator());
+ _M_deallocate(this->_M_impl._M_start,
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
+ this->_M_impl._M_start = __new_start;
+ this->_M_impl._M_finish = __new_finish;
+ this->_M_impl._M_end_of_storage = __new_start + __len;
+ }
template<typename _Tp, typename _Alloc>
void
@@ -454,7 +463,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (size_type(this->_M_impl._M_end_of_storage
- this->_M_impl._M_finish) >= __n)
{
+#if __cplusplus < 201103L
value_type __x_copy = __x;
+#else
+ _Temporary_value __tmp(this, __x);
+ value_type& __x_copy = __tmp._M_val();
+#endif
const size_type __elems_after = end() - __position;
pointer __old_finish(this->_M_impl._M_finish);
if (__elems_after > __n)
@@ -492,7 +506,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
pointer __new_finish(__new_start);
__try
{
- // See _M_insert_aux above.
+ // See _M_realloc_insert above.
std::__uninitialized_fill_n_a(__new_start + __elems_before,
__n, __x,
_M_get_Tp_allocator());
@@ -701,9 +715,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
_Bit_pointer __q = this->_M_allocate(__n);
iterator __start(std::__addressof(*__q), 0);
- this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), __start);
+ iterator __finish(_M_copy_aligned(begin(), end(), __start));
this->_M_deallocate();
this->_M_impl._M_start = __start;
+ this->_M_impl._M_finish = __finish;
this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
}
@@ -729,11 +744,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __start(std::__addressof(*__q), 0);
iterator __i = _M_copy_aligned(begin(), __position, __start);
std::fill(__i, __i + difference_type(__n), __x);
- this->_M_impl._M_finish = std::copy(__position, end(),
- __i + difference_type(__n));
+ iterator __finish = std::copy(__position, end(),
+ __i + difference_type(__n));
this->_M_deallocate();
this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
this->_M_impl._M_start = __start;
+ this->_M_impl._M_finish = __finish;
}
}
@@ -763,10 +779,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __start(std::__addressof(*__q), 0);
iterator __i = _M_copy_aligned(begin(), __position, __start);
__i = std::copy(__first, __last, __i);
- this->_M_impl._M_finish = std::copy(__position, end(), __i);
+ iterator __finish = std::copy(__position, end(), __i);
this->_M_deallocate();
this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
this->_M_impl._M_start = __start;
+ this->_M_impl._M_finish = __finish;
}
}
}
@@ -791,10 +808,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __start(std::__addressof(*__q), 0);
iterator __i = _M_copy_aligned(begin(), __position, __start);
*__i++ = __x;
- this->_M_impl._M_finish = std::copy(__position, end(), __i);
+ iterator __finish = std::copy(__position, end(), __i);
this->_M_deallocate();
this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
this->_M_impl._M_start = __start;
+ this->_M_impl._M_finish = __finish;
}
}