summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-27 09:08:20 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-27 09:08:20 +0000
commit131f3644ef87d5406722ee42b0989cb5783156fa (patch)
tree6f9c3016cb1696987ba7b0cc8c1b8c5400c6157d /libstdc++-v3/include
parent851ccf1afd9b0e045e7dda2539a3dfa30c16bb64 (diff)
downloadgcc-131f3644ef87d5406722ee42b0989cb5783156fa.tar.gz
2015-05-27 Basile Starynkevitch <basile@starynkevitch.net>
{{merged with almost GCC 5. i.e. trunk r222129 from 2015-04-15, using svn merge -r219880:222129 svn+ssh://bstarynk@gcc.gnu.org/svn/gcc/trunk }} [gcc/] 2015-05-27 Basile Starynkevitch <basile@starynkevitch.net> {{merged with GCC 5, so}} * melt-runtime.h (melt_fatal_error, melt_fatal_error_at_line): Pass UNKNOWN_LOCATION for GCC 5. Re-indented with command: astyle --style=gnu -s2 * melt-runtime.cc: Re-indented with command: astyle --style=gnu -s2 (melt_branch_process_arguments, melt_ggcstart_callback) (melt_reserved_allocation_failure): Use melt_fatal_error instead of fatal_error. * melt/generated/meltrunsup-inc.cc: Manually edited for fatal_error. * melt/generated/warmelt-first.cc: Ditto. * melt/warmelt-first.melt (melt_assert_failure_fun): Ditto. * melt/warmelt-modes.melt (generate_runtypesupport_scanning): Ditto, in the emitted code. * Makefile.in: mention s-gtype instead of gt-melt-runtime.h in dependencies. (TEXI_GCCINT_FILES): Add meltgendoc.texi. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@223739 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/bits/algorithmfwd.h9
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h31
-rw-r--r--libstdc++-v3/include/bits/atomic_futex.h2
-rw-r--r--libstdc++-v3/include/bits/basic_string.h5
-rw-r--r--libstdc++-v3/include/bits/c++config8
-rw-r--r--libstdc++-v3/include/bits/codecvt.h50
-rw-r--r--libstdc++-v3/include/bits/locale_classes.h34
-rw-r--r--libstdc++-v3/include/bits/locale_conv.h15
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h22
-rw-r--r--libstdc++-v3/include/bits/locale_facets_nonio.h24
-rw-r--r--libstdc++-v3/include/bits/regex.h108
-rw-r--r--libstdc++-v3/include/bits/regex.tcc42
-rw-r--r--libstdc++-v3/include/bits/regex_constants.h393
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h5
-rw-r--r--libstdc++-v3/include/bits/stl_iterator_base_funcs.h21
-rw-r--r--libstdc++-v3/include/bits/stl_list.h39
-rw-r--r--libstdc++-v3/include/bits/stl_map.h90
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h88
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h63
-rw-r--r--libstdc++-v3/include/bits/stl_set.h64
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h131
-rw-r--r--libstdc++-v3/include/c_global/cstdio2
-rw-r--r--libstdc++-v3/include/c_std/cstdio2
-rw-r--r--libstdc++-v3/include/experimental/optional4
-rw-r--r--libstdc++-v3/include/experimental/system_error2
-rw-r--r--libstdc++-v3/include/ext/codecvt_specializations.h5
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp2
-rw-r--r--libstdc++-v3/include/std/atomic28
-rw-r--r--libstdc++-v3/include/std/chrono9
-rw-r--r--libstdc++-v3/include/std/codecvt4
-rw-r--r--libstdc++-v3/include/std/future2
-rw-r--r--libstdc++-v3/include/std/istream5
-rw-r--r--libstdc++-v3/include/std/ostream5
-rw-r--r--libstdc++-v3/include/std/scoped_allocator10
-rw-r--r--libstdc++-v3/include/std/shared_mutex235
-rw-r--r--libstdc++-v3/include/std/stdexcept2
-rw-r--r--libstdc++-v3/include/std/thread8
37 files changed, 1185 insertions, 384 deletions
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h
index 11361bb948a..1dfc4ad7b15 100644
--- a/libstdc++-v3/include/bits/algorithmfwd.h
+++ b/libstdc++-v3/include/bits/algorithmfwd.h
@@ -530,9 +530,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_OIter
reverse_copy(_BIter, _BIter, _OIter);
- template<typename _FIter>
- _FIter
- rotate(_FIter, _FIter, _FIter);
+ inline namespace _V2
+ {
+ template<typename _FIter>
+ _FIter
+ rotate(_FIter, _FIter, _FIter);
+ }
template<typename _FIter, typename _OIter>
_OIter
diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index 5e610f1c3ee..79769cf46d8 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -37,7 +37,7 @@
#include <bits/atomic_lockfree_defines.h>
#ifndef _GLIBCXX_ALWAYS_INLINE
-#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((always_inline))
+#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
#endif
namespace std _GLIBCXX_VISIBILITY(default)
@@ -240,7 +240,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
typedef _ITp __int_type;
- __int_type _M_i;
+ static constexpr int _S_alignment =
+ sizeof(_ITp) > alignof(_ITp) ? sizeof(_ITp) : alignof(_ITp);
+
+ alignas(_S_alignment) __int_type _M_i;
public:
__atomic_base() noexcept = default;
@@ -346,11 +349,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
is_lock_free() const noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
+ {
+ // Produce a fake, minimally aligned pointer.
+ void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ return __atomic_is_lock_free(sizeof(_M_i), __a);
+ }
bool
is_lock_free() const volatile noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
+ {
+ // Produce a fake, minimally aligned pointer.
+ void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ return __atomic_is_lock_free(sizeof(_M_i), __a);
+ }
_GLIBCXX_ALWAYS_INLINE void
store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
@@ -653,11 +664,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
is_lock_free() const noexcept
- { return __atomic_is_lock_free(sizeof(__pointer_type), nullptr); }
+ {
+ // Produce a fake, minimally aligned pointer.
+ void *__a = reinterpret_cast<void *>(-__alignof(_M_p));
+ return __atomic_is_lock_free(sizeof(_M_p), __a);
+ }
bool
is_lock_free() const volatile noexcept
- { return __atomic_is_lock_free(sizeof(__pointer_type), nullptr); }
+ {
+ // Produce a fake, minimally aligned pointer.
+ void *__a = reinterpret_cast<void *>(-__alignof(_M_p));
+ return __atomic_is_lock_free(sizeof(_M_p), __a);
+ }
_GLIBCXX_ALWAYS_INLINE void
store(__pointer_type __p,
diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h
index 51b9c7e5737..ca3260d4ee2 100644
--- a/libstdc++-v3/include/bits/atomic_futex.h
+++ b/libstdc++-v3/include/bits/atomic_futex.h
@@ -41,7 +41,7 @@
#endif
#ifndef _GLIBCXX_ALWAYS_INLINE
-#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((always_inline))
+#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
#endif
namespace std _GLIBCXX_VISIBILITY(default)
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 71a47f5b177..3b2603fc650 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -476,9 +476,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{
if (__str._M_is_local())
{
- if (__str.length())
- traits_type::copy(_M_local_buf, __str._M_local_buf,
- _S_local_capacity + 1);
+ traits_type::copy(_M_local_buf, __str._M_local_buf,
+ _S_local_capacity + 1);
}
else
{
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 721778a1997..ae3065feaae 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -215,7 +215,11 @@ namespace std
#if _GLIBCXX_USE_CXX11_ABI
namespace std
{
- inline namespace __cxx11 __attribute__((abi_tag)) { }
+ inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+ inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
}
# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
@@ -290,7 +294,7 @@ namespace std
# endif
# if _GLIBCXX_USE_CXX11_ABI
- inline namespace __cxx11 __attribute__((abi_tag)) { }
+ inline namespace __cxx11 __attribute__((__abi_tag__)) { }
# endif
}
diff --git a/libstdc++-v3/include/bits/codecvt.h b/libstdc++-v3/include/bits/codecvt.h
index a6e59b5128f..c76215f87f5 100644
--- a/libstdc++-v3/include/bits/codecvt.h
+++ b/libstdc++-v3/include/bits/codecvt.h
@@ -594,11 +594,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+#if __cplusplus >= 201103L
+ explicit
+ codecvt_byname(const string& __s, size_t __refs = 0)
+ : codecvt_byname(__s.c_str(), __refs) { }
+#endif
+
+ protected:
+ virtual
+ ~codecvt_byname() { }
+ };
+
+#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+ template<>
+ class codecvt_byname<char16_t, char, mbstate_t>
+ : public codecvt<char16_t, char, mbstate_t>
+ {
+ public:
+ explicit
+ codecvt_byname(const char* __s, size_t __refs = 0)
+ : codecvt<char16_t, char, mbstate_t>(__refs) { }
+
+ explicit
+ codecvt_byname(const string& __s, size_t __refs = 0)
+ : codecvt_byname(__s.c_str(), __refs) { }
+
protected:
virtual
~codecvt_byname() { }
};
+ template<>
+ class codecvt_byname<char32_t, char, mbstate_t>
+ : public codecvt<char32_t, char, mbstate_t>
+ {
+ public:
+ explicit
+ codecvt_byname(const char* __s, size_t __refs = 0)
+ : codecvt<char32_t, char, mbstate_t>(__refs) { }
+
+ explicit
+ codecvt_byname(const string& __s, size_t __refs = 0)
+ : codecvt_byname(__s.c_str(), __refs) { }
+
+ protected:
+ virtual
+ ~codecvt_byname() { }
+ };
+#endif
+
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
@@ -623,6 +667,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
#endif
+
+#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+ extern template class codecvt_byname<char16_t, char, mbstate_t>;
+ extern template class codecvt_byname<char32_t, char, mbstate_t>;
+#endif
+
#endif
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h
index f591437f148..f3898ebf7b2 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -150,6 +150,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
locale(const locale& __base, const char* __s, category __cat);
+#if __cplusplus >= 201103L
+ /**
+ * @brief Named locale constructor.
+ *
+ * Constructs a copy of the named C library locale.
+ *
+ * @param __s Name of the locale to construct.
+ * @throw std::runtime_error if __s is an undefined locale.
+ */
+ explicit
+ locale(const std::string& __s) : locale(__s.c_str()) { }
+
+ /**
+ * @brief Construct locale with facets from another locale.
+ *
+ * Constructs a copy of the locale @a base. The facets specified by @a
+ * cat are replaced with those from the locale named by @a s. If base is
+ * named, this locale instance will also be named.
+ *
+ * @param __base The locale to copy.
+ * @param __s Name of the locale to use facets from.
+ * @param __cat Set of categories defining the facets to use from __s.
+ * @throw std::runtime_error if __s is an undefined locale.
+ */
+ locale(const locale& __base, const std::string& __s, category __cat)
+ : locale(__base, __s.c_str(), __cat) { }
+#endif
+
/**
* @brief Construct locale with facets from another locale.
*
@@ -797,6 +825,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+#if __cplusplus >= 201103L
+ explicit
+ collate_byname(const string& __s, size_t __refs = 0)
+ : collate_byname(__s.c_str(), __refs) { }
+#endif
+
protected:
virtual
~collate_byname() { }
diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h
index c8a44f42421..9b49617b7a9 100644
--- a/libstdc++-v3/include/bits/locale_conv.h
+++ b/libstdc++-v3/include/bits/locale_conv.h
@@ -198,18 +198,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto __outstr = __err ? _OutStr(__err->get_allocator()) : _OutStr();
size_t __outchars = 0;
auto __next = __first;
+ const auto __maxlen = _M_cvt->max_length();
codecvt_base::result __result;
do
{
- __outstr.resize(__outstr.size() + (__last - __next));
+ __outstr.resize(__outstr.size() + (__last - __next) + __maxlen);
auto __outnext = &__outstr.front() + __outchars;
auto const __outlast = &__outstr.back() + 1;
__result = ((*_M_cvt).*__memfn)(_M_state, __next, __last, __next,
__outnext, __outlast, __outnext);
__outchars = __outnext - &__outstr.front();
}
- while (__result == codecvt_base::partial && __next != __last);
+ while (__result == codecvt_base::partial && __next != __last
+ && (__outstr.size() - __outchars) < __maxlen);
+
+ if (__result == codecvt_base::noconv)
+ {
+ __outstr.assign(__first, __last);
+ _M_count = __outstr.size();
+ return __outstr;
+ }
__outstr.resize(__outchars);
_M_count = __next - __first;
@@ -428,7 +437,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return _M_put(__next, __pending);
if (!_M_put(__outbuf, __outnext - __outbuf))
- return false;
+ return false;
}
while (__next != __last && __next != __start);
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 77932a5060b..0226b497c30 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -1479,6 +1479,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit
ctype_byname(const char* __s, size_t __refs = 0);
+#if __cplusplus >= 201103L
+ explicit
+ ctype_byname(const string& __s, size_t __refs = 0)
+ : ctype_byname(__s.c_str(), __refs) { }
+#endif
+
protected:
virtual
~ctype_byname() { };
@@ -1492,6 +1498,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit
ctype_byname(const char* __s, size_t __refs = 0);
+#if __cplusplus >= 201103L
+ explicit
+ ctype_byname(const string& __s, size_t __refs = 0);
+#endif
+
protected:
virtual
~ctype_byname();
@@ -1505,6 +1516,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit
ctype_byname(const char* __s, size_t __refs = 0);
+#if __cplusplus >= 201103L
+ explicit
+ ctype_byname(const string& __s, size_t __refs = 0);
+#endif
+
protected:
virtual
~ctype_byname();
@@ -1900,6 +1916,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
}
}
+#if __cplusplus >= 201103L
+ explicit
+ numpunct_byname(const string& __s, size_t __refs = 0)
+ : numpunct_byname(__s.c_str(), __refs) { }
+#endif
+
protected:
virtual
~numpunct_byname() { }
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h
index 0c49880b0d3..7eae6c80653 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.h
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.h
@@ -766,6 +766,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
time_get_byname(const char*, size_t __refs = 0)
: time_get<_CharT, _InIter>(__refs) { }
+#if __cplusplus >= 201103L
+ explicit
+ time_get_byname(const string& __s, size_t __refs = 0)
+ : time_get_byname(__s.c_str(), __refs) { }
+#endif
+
protected:
virtual
~time_get_byname() { }
@@ -894,6 +900,12 @@ _GLIBCXX_END_NAMESPACE_CXX11
: time_put<_CharT, _OutIter>(__refs)
{ };
+#if __cplusplus >= 201103L
+ explicit
+ time_put_byname(const string& __s, size_t __refs = 0)
+ : time_put_byname(__s.c_str(), __refs) { }
+#endif
+
protected:
virtual
~time_put_byname() { }
@@ -1419,6 +1431,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
}
}
+#if __cplusplus >= 201103L
+ explicit
+ moneypunct_byname(const string& __s, size_t __refs = 0)
+ : moneypunct_byname(__s.c_str(), __refs) { }
+#endif
+
protected:
virtual
~moneypunct_byname() { }
@@ -1969,6 +1987,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
explicit
messages_byname(const char* __s, size_t __refs = 0);
+#if __cplusplus >= 201103L
+ explicit
+ messages_byname(const string& __s, size_t __refs = 0)
+ : messages_byname(__s.c_str(), __refs) { }
+#endif
+
protected:
virtual
~messages_byname()
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 6de883a7859..a23c2c9b3ce 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -442,7 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
explicit
basic_regex(const _Ch_type* __p, flag_type __f = ECMAScript)
- : basic_regex(__p, __p + _Rx_traits::length(__p), __f)
+ : basic_regex(__p, __p + char_traits<_Ch_type>::length(__p), __f)
{ }
/**
@@ -553,7 +553,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
basic_regex&
operator=(const _Ch_type* __p)
- { return this->assign(__p, flags()); }
+ { return this->assign(__p); }
+
+ /**
+ * @brief Replaces a regular expression with a new one constructed from
+ * an initializer list.
+ *
+ * @param __l The initializer list.
+ *
+ * @throws regex_error if @p __l is not a valid regular expression.
+ */
+ basic_regex&
+ operator=(initializer_list<_Ch_type> __l)
+ { return this->assign(__l.begin(), __l.end()); }
/**
* @brief Replaces a regular expression with a new one constructed from
@@ -564,7 +576,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
template<typename _Ch_traits, typename _Alloc>
basic_regex&
operator=(const basic_string<_Ch_type, _Ch_traits, _Alloc>& __s)
- { return this->assign(__s, flags()); }
+ { return this->assign(__s); }
// [7.8.3] assign
/**
@@ -644,7 +656,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
flag_type __flags = ECMAScript)
{
return this->assign(basic_regex(__s.data(), __s.data() + __s.size(),
- _M_loc, _M_flags));
+ _M_loc, __flags));
}
/**
@@ -712,7 +724,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
imbue(locale_type __loc)
{
std::swap(__loc, _M_loc);
- _M_automaton = nullptr;
+ _M_automaton.reset();
return __loc;
}
@@ -1471,17 +1483,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// [7.10] Class template match_results
- /*
- * Special sub_match object representing an unmatched sub-expression.
- */
- template<typename _Bi_iter>
- inline const sub_match<_Bi_iter>&
- __unmatched_sub()
- {
- static const sub_match<_Bi_iter> __unmatched = sub_match<_Bi_iter>();
- return __unmatched;
- }
-
/**
* @brief The results of a match or search operation.
*
@@ -1511,15 +1512,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{
private:
/*
- * The vector base is empty if this does not represent a successful match.
- * Otherwise it contains n+3 elements where n is the number of marked
+ * The vector base is empty if this does not represent a match (!ready());
+ * Otherwise if it's a match failure, it contains 3 elements:
+ * [0] unmatched
+ * [1] prefix
+ * [2] suffix
+ * Otherwise it contains n+4 elements where n is the number of marked
* sub-expressions:
* [0] entire match
* [1] 1st marked subexpression
* ...
* [n] nth marked subexpression
- * [n+1] prefix
- * [n+2] suffix
+ * [n+1] unmatched
+ * [n+2] prefix
+ * [n+3] suffix
*/
typedef std::vector<sub_match<_Bi_iter>, _Alloc> _Base_type;
typedef std::iterator_traits<_Bi_iter> __iter_traits;
@@ -1611,10 +1617,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
size_type
size() const
- {
- size_type __size = _Base_type::size();
- return (__size && _Base_type::operator[](0).matched) ? __size - 2 : 0;
- }
+ { return _Base_type::empty() ? 0 : _Base_type::size() - 3; }
size_type
max_size() const
@@ -1658,15 +1661,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* is zero (the default), in which case this function returns the offset
* from the beginning of the target sequence to the beginning of the
* match.
- *
- * Returns -1 if @p __sub is out of range.
*/
difference_type
position(size_type __sub = 0) const
- {
- return __sub < size() ? std::distance(_M_begin,
- (*this)[__sub].first) : -1;
- }
+ { return std::distance(_M_begin, (*this)[__sub].first); }
/**
* @brief Gets the match or submatch converted to a string type.
@@ -1679,7 +1677,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
string_type
str(size_type __sub = 0) const
- { return (*this)[__sub].str(); }
+ { return string_type((*this)[__sub]); }
/**
* @brief Gets a %sub_match reference for the match or submatch.
@@ -1695,10 +1693,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
const_reference
operator[](size_type __sub) const
{
- _GLIBCXX_DEBUG_ASSERT( ready() );
- return __sub < size()
- ? _Base_type::operator[](__sub)
- : __unmatched_sub<_Bi_iter>();
+ _GLIBCXX_DEBUG_ASSERT( ready() );
+ return __sub < size()
+ ? _Base_type::operator[](__sub)
+ : _M_unmatched_sub();
}
/**
@@ -1712,10 +1710,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
const_reference
prefix() const
{
- _GLIBCXX_DEBUG_ASSERT( ready() );
- return !empty()
- ? _Base_type::operator[](_Base_type::size() - 2)
- : __unmatched_sub<_Bi_iter>();
+ _GLIBCXX_DEBUG_ASSERT( ready() );
+ return !empty() ? _M_prefix() : _M_unmatched_sub();
}
/**
@@ -1730,9 +1726,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
suffix() const
{
_GLIBCXX_DEBUG_ASSERT( ready() );
- return !empty()
- ? _Base_type::operator[](_Base_type::size() - 1)
- : __unmatched_sub<_Bi_iter>();
+ return !empty() ? _M_suffix() : _M_unmatched_sub();
}
/**
@@ -1754,7 +1748,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
const_iterator
end() const
- { return _Base_type::end() - 2; }
+ { return _Base_type::end() - 3; }
/**
* @brief Gets an iterator to one-past-the-end of the collection.
@@ -1871,6 +1865,34 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
const basic_regex<_Cp, _Rp>&,
regex_constants::match_flag_type);
+ void
+ _M_resize(unsigned int __size)
+ { _Base_type::resize(__size + 3); }
+
+ const_reference
+ _M_unmatched_sub() const
+ { return _Base_type::operator[](_Base_type::size() - 3); }
+
+ sub_match<_Bi_iter>&
+ _M_unmatched_sub()
+ { return _Base_type::operator[](_Base_type::size() - 3); }
+
+ const_reference
+ _M_prefix() const
+ { return _Base_type::operator[](_Base_type::size() - 2); }
+
+ sub_match<_Bi_iter>&
+ _M_prefix()
+ { return _Base_type::operator[](_Base_type::size() - 2); }
+
+ const_reference
+ _M_suffix() const
+ { return _Base_type::operator[](_Base_type::size() - 1); }
+
+ sub_match<_Bi_iter>&
+ _M_suffix()
+ { return _Base_type::operator[](_Base_type::size() - 1); }
+
_Bi_iter _M_begin;
};
diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc
index 3f16e66ab2a..823ad51c3e8 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -63,7 +63,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m;
__m._M_begin = __s;
- __res.resize(__re._M_automaton->_M_sub_count() + 2);
+ __m._M_resize(__re._M_automaton->_M_sub_count());
for (auto& __it : __res)
__it.matched = false;
@@ -99,8 +99,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
for (auto& __it : __res)
if (!__it.matched)
__it.first = __it.second = __e;
- auto& __pre = __res[__res.size()-2];
- auto& __suf = __res[__res.size()-1];
+ auto& __pre = __m._M_prefix();
+ auto& __suf = __m._M_suffix();
if (__match_mode)
{
__pre.matched = false;
@@ -120,6 +120,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__suf.matched = (__suf.first != __suf.second);
}
}
+ else
+ {
+ __m._M_resize(0);
+ for (auto& __it : __res)
+ {
+ __it.matched = false;
+ __it.first = __it.second = __e;
+ }
+ }
return __ret;
}
@@ -269,7 +278,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"DEL",
};
- string __s(__first, __last);
+ string __s;
+ for (; __first != __last; ++__first)
+ __s += __fctyp.narrow(*__first, 0);
+
for (const auto& __it : __collatenames)
if (__s == __it)
return string_type(1, __fctyp.widen(
@@ -311,8 +323,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
string __s;
- for (auto __cur = __first; __cur != __last; ++__cur)
- __s += __fctyp.narrow(__fctyp.tolower(*__cur), '?');
+ for (; __first != __last; ++__first)
+ __s += __fctyp.narrow(__fctyp.tolower(*__first), 0);
for (const auto& __it : __classnames)
if (__s == __it.first)
@@ -371,7 +383,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto __output = [&](size_t __idx)
{
- auto& __sub = _Base_type::operator[](__idx);
+ auto& __sub = (*this)[__idx];
if (__sub.matched)
__out = std::copy(__sub.first, __sub.second, __out);
};
@@ -422,9 +434,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else if (__eat('&'))
__output(0);
else if (__eat('`'))
- __output(_Base_type::size()-2);
+ {
+ auto& __sub = _M_prefix();
+ if (__sub.matched)
+ __out = std::copy(__sub.first, __sub.second, __out);
+ }
else if (__eat('\''))
- __output(_Base_type::size()-1);
+ {
+ auto& __sub = _M_suffix();
+ if (__sub.matched)
+ __out = std::copy(__sub.first, __sub.second, __out);
+ }
else if (__fctyp.is(__ctype_type::digit, *__next))
{
long __num = __traits.value(*__next, 10);
@@ -529,7 +549,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
| regex_constants::match_continuous))
{
_GLIBCXX_DEBUG_ASSERT(_M_match[0].matched);
- auto& __prefix = _M_match.at(_M_match.size());
+ auto& __prefix = _M_match._M_prefix();
__prefix.first = __prefix_first;
__prefix.matched = __prefix.first != __prefix.second;
// [28.12.1.4.5]
@@ -544,7 +564,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
{
_GLIBCXX_DEBUG_ASSERT(_M_match[0].matched);
- auto& __prefix = _M_match.at(_M_match.size());
+ auto& __prefix = _M_match._M_prefix();
__prefix.first = __prefix_first;
__prefix.matched = __prefix.first != __prefix.second;
// [28.12.1.4.5]
diff --git a/libstdc++-v3/include/bits/regex_constants.h b/libstdc++-v3/include/bits/regex_constants.h
index 1ef5a43e841..e2c763178ea 100644
--- a/libstdc++-v3/include/bits/regex_constants.h
+++ b/libstdc++-v3/include/bits/regex_constants.h
@@ -77,88 +77,97 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep
* %set.
*/
- enum syntax_option_type : unsigned int
- {
- /**
- * Specifies that the matching of regular expressions against a character
- * sequence shall be performed without regard to case.
- */
- icase = 1 << _S_icase,
-
- /**
- * Specifies that when a regular expression is matched against a character
- * container sequence, no sub-expression matches are to be stored in the
- * supplied match_results structure.
- */
- nosubs = 1 << _S_nosubs,
-
- /**
- * Specifies that the regular expression engine should pay more attention to
- * the speed with which regular expressions are matched, and less to the
- * speed with which regular expression objects are constructed. Otherwise
- * it has no detectable effect on the program output.
- */
- optimize = 1 << _S_optimize,
-
- /**
- * Specifies that character ranges of the form [a-b] should be locale
- * sensitive.
- */
- collate = 1 << _S_collate,
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript
- * Language Specification, Standard Ecma-262, third edition, 1999], as
- * modified in section [28.13]. This grammar is similar to that defined
- * in the PERL scripting language but extended with elements found in the
- * POSIX regular expression grammar.
- */
- ECMAScript = 1 << _S_ECMAScript,
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001,
- * Portable Operating System Interface (POSIX), Base Definitions and
- * Headers, Section 9, Regular Expressions [IEEE, Information Technology --
- * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
- */
- basic = 1 << _S_basic,
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001,
- * Portable Operating System Interface (POSIX), Base Definitions and
- * Headers, Section 9, Regular Expressions.
- */
- extended = 1 << _S_extended,
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is
- * identical to syntax_option_type extended, except that C-style escape
- * sequences are supported. These sequences are:
- * \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos,, &apos,,
- * and \\ddd (where ddd is one, two, or three octal digits).
- */
- awk = 1 << _S_awk,
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is
- * identical to syntax_option_type basic, except that newlines are treated
- * as whitespace.
- */
- grep = 1 << _S_grep,
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX utility grep when given the -E option in
- * IEEE Std 1003.1-2001. This option is identical to syntax_option_type
- * extended, except that newlines are treated as whitespace.
- */
- egrep = 1 << _S_egrep,
- };
+ enum syntax_option_type : unsigned int { };
+
+ /**
+ * Specifies that the matching of regular expressions against a character
+ * sequence shall be performed without regard to case.
+ */
+ constexpr syntax_option_type icase =
+ static_cast<syntax_option_type>(1 << _S_icase);
+
+ /**
+ * Specifies that when a regular expression is matched against a character
+ * container sequence, no sub-expression matches are to be stored in the
+ * supplied match_results structure.
+ */
+ constexpr syntax_option_type nosubs =
+ static_cast<syntax_option_type>(1 << _S_nosubs);
+
+ /**
+ * Specifies that the regular expression engine should pay more attention to
+ * the speed with which regular expressions are matched, and less to the
+ * speed with which regular expression objects are constructed. Otherwise
+ * it has no detectable effect on the program output.
+ */
+ 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 =
+ static_cast<syntax_option_type>(1 << _S_collate);
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript
+ * Language Specification, Standard Ecma-262, third edition, 1999], as
+ * modified in section [28.13]. This grammar is similar to that defined
+ * in the PERL scripting language but extended with elements found in the
+ * POSIX regular expression grammar.
+ */
+ constexpr syntax_option_type ECMAScript =
+ static_cast<syntax_option_type>(1 << _S_ECMAScript);
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001,
+ * Portable Operating System Interface (POSIX), Base Definitions and
+ * Headers, Section 9, Regular Expressions [IEEE, Information Technology --
+ * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
+ */
+ constexpr syntax_option_type basic =
+ static_cast<syntax_option_type>(1 << _S_basic);
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001,
+ * Portable Operating System Interface (POSIX), Base Definitions and
+ * Headers, Section 9, Regular Expressions.
+ */
+ constexpr syntax_option_type extended =
+ static_cast<syntax_option_type>(1 << _S_extended);
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is
+ * identical to syntax_option_type extended, except that C-style escape
+ * sequences are supported. These sequences are:
+ * \\\\, \\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 =
+ static_cast<syntax_option_type>(1 << _S_awk);
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is
+ * identical to syntax_option_type basic, except that newlines are treated
+ * as whitespace.
+ */
+ constexpr syntax_option_type grep =
+ static_cast<syntax_option_type>(1 << _S_grep);
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX utility grep when given the -E option in
+ * 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 =
+ static_cast<syntax_option_type>(1 << _S_egrep);
constexpr inline syntax_option_type
operator&(syntax_option_type __a, syntax_option_type __b)
@@ -233,111 +242,121 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* perform bitwise operations on these values and expect the right thing to
* happen.
*/
- enum match_flag_type : unsigned int
- {
- /**
- * The default matching rules.
- */
- match_default = 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).
- */
- match_not_bol = 1 << _S_not_bol,
-
- /**
- * The last character in the sequence [first, last) is treated as though it
- * is not at the end of a line, so the character ($) in the regular
- * expression shall not match [last, last).
- */
- match_not_eol = 1 << _S_not_eol,
-
- /**
- * The expression \\b is not matched against the sub-sequence
- * [first,first).
- */
- match_not_bow = 1 << _S_not_bow,
-
- /**
- * The expression \\b should not be matched against the sub-sequence
- * [last,last).
- */
- match_not_eow = 1 << _S_not_eow,
-
- /**
- * If more than one match is possible then any match is an acceptable
- * result.
- */
- match_any = 1 << _S_any,
-
- /**
- * The expression does not match an empty sequence.
- */
- match_not_null = 1 << _S_not_null,
-
- /**
- * The expression only matches a sub-sequence that begins at first .
- */
- match_continuous = 1 << _S_continuous,
-
- /**
- * --first is a valid iterator position. When this flag is set then the
- * flags match_not_bol and match_not_bow are ignored by the regular
- * expression algorithms 28.11 and iterators 28.12.
- */
- match_prev_avail = 1 << _S_prev_avail,
-
- /**
- * When a regular expression match is to be replaced by a new string, the
- * new string is constructed using the rules used by the ECMAScript replace
- * function in ECMA- 262 [Ecma International, ECMAScript Language
- * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11
- * String.prototype.replace. In addition, during search and replace
- * operations all non-overlapping occurrences of the regular expression
- * are located and replaced, and sections of the input that did not match
- * the expression are copied unchanged to the output string.
- *
- * Format strings (from ECMA-262 [15.5.4.11]):
- * @li $$ The dollar-sign itself ($)
- * @li $& The matched substring.
- * @li $` The portion of @a string that precedes the matched substring.
- * This would be match_results::prefix().
- * @li $' The portion of @a string that follows the matched substring.
- * This would be match_results::suffix().
- * @li $n The nth capture, where n is in [1,9] and $n is not followed by a
- * decimal digit. If n <= match_results::size() and the nth capture
- * is undefined, use the empty string instead. If n >
- * match_results::size(), the result is implementation-defined.
- * @li $nn The nnth capture, where nn is a two-digit decimal number on
- * [01, 99]. If nn <= match_results::size() and the nth capture is
- * undefined, use the empty string instead. If
- * nn > match_results::size(), the result is implementation-defined.
- */
- format_default = 0,
-
- /**
- * When a regular expression match is to be replaced by a new string, the
- * new string is constructed using the rules used by the POSIX sed utility
- * in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable
- * Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
- */
- format_sed = 1 << _S_sed,
-
- /**
- * During a search and replace operation, sections of the character
- * container sequence being searched that do not match the regular
- * expression shall not be copied to the output string.
- */
- format_no_copy = 1 << _S_no_copy,
-
- /**
- * When specified during a search and replace operation, only the first
- * occurrence of the regular expression shall be replaced.
- */
- format_first_only = 1 << _S_first_only,
- };
+ enum match_flag_type : unsigned int { };
+
+ /**
+ * The default matching rules.
+ */
+ 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 =
+ static_cast<match_flag_type>(1 << _S_not_bol);
+
+ /**
+ * The last character in the sequence [first, last) is treated as though it
+ * 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 =
+ 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 =
+ 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 =
+ 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 =
+ static_cast<match_flag_type>(1 << _S_any);
+
+ /**
+ * The expression does not match an empty sequence.
+ */
+ 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 =
+ static_cast<match_flag_type>(1 << _S_continuous);
+
+ /**
+ * --first is a valid iterator position. When this flag is set then the
+ * 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 =
+ static_cast<match_flag_type>(1 << _S_prev_avail);
+
+ /**
+ * When a regular expression match is to be replaced by a new string, the
+ * new string is constructed using the rules used by the ECMAScript replace
+ * function in ECMA- 262 [Ecma International, ECMAScript Language
+ * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11
+ * String.prototype.replace. In addition, during search and replace
+ * operations all non-overlapping occurrences of the regular expression
+ * are located and replaced, and sections of the input that did not match
+ * the expression are copied unchanged to the output string.
+ *
+ * Format strings (from ECMA-262 [15.5.4.11]):
+ * @li $$ The dollar-sign itself ($)
+ * @li $& The matched substring.
+ * @li $` The portion of @a string that precedes the matched substring.
+ * This would be match_results::prefix().
+ * @li $' The portion of @a string that follows the matched substring.
+ * This would be match_results::suffix().
+ * @li $n The nth capture, where n is in [1,9] and $n is not followed by a
+ * decimal digit. If n <= match_results::size() and the nth capture
+ * is undefined, use the empty string instead. If n >
+ * match_results::size(), the result is implementation-defined.
+ * @li $nn The nnth capture, where nn is a two-digit decimal number on
+ * [01, 99]. If nn <= match_results::size() and the nth capture is
+ * 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);
+
+ /**
+ * When a regular expression match is to be replaced by a new string, the
+ * new string is constructed using the rules used by the POSIX sed utility
+ * 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 =
+ static_cast<match_flag_type>(1 << _S_sed);
+
+ /**
+ * During a search and replace operation, sections of the character
+ * 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 =
+ 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 =
+ static_cast<match_flag_type>(1 << _S_first_only);
constexpr inline match_flag_type
operator&(match_flag_type __a, match_flag_type __b)
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index c27c092c455..53c455b16f3 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -1237,6 +1237,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __m;
}
+ inline namespace _V2
+ {
+
/// This is a helper function for the rotate algorithm.
template<typename _ForwardIterator>
_ForwardIterator
@@ -1438,6 +1441,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::__iterator_category(__first));
}
+ } // namespace _V2
+
/**
* @brief Copy a sequence, rotating its elements.
* @ingroup mutating_algorithms
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
index a146611b25f..6ee2ffbc5f2 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
@@ -66,6 +66,12 @@
namespace std _GLIBCXX_VISIBILITY(default)
{
+_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
+ // Forward declaration for the overloads of __distance.
+ template <typename> struct _List_iterator;
+ template <typename> struct _List_const_iterator;
+_GLIBCXX_END_NAMESPACE_CONTAINER
+
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator>
@@ -96,6 +102,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __last - __first;
}
+#if _GLIBCXX_USE_CXX11_ABI
+ // Forward declaration because of the qualified call in distance.
+ template<typename _Tp>
+ ptrdiff_t
+ __distance(_GLIBCXX_STD_C::_List_iterator<_Tp>,
+ _GLIBCXX_STD_C::_List_iterator<_Tp>,
+ input_iterator_tag);
+
+ template<typename _Tp>
+ ptrdiff_t
+ __distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp>,
+ _GLIBCXX_STD_C::_List_const_iterator<_Tp>,
+ input_iterator_tag);
+#endif
+
/**
* @brief A generalization of pointer arithmetic.
* @param __first An input iterator.
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index f8bfff18b19..3401e5b4d25 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1868,6 +1868,45 @@ _GLIBCXX_END_NAMESPACE_CXX11
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
+
+#if _GLIBCXX_USE_CXX11_ABI
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ // Detect when distance is used to compute the size of the whole list.
+ template<typename _Tp>
+ inline ptrdiff_t
+ __distance(_GLIBCXX_STD_C::_List_iterator<_Tp> __first,
+ _GLIBCXX_STD_C::_List_iterator<_Tp> __last,
+ input_iterator_tag __tag)
+ {
+ typedef _GLIBCXX_STD_C::_List_const_iterator<_Tp> _CIter;
+ return std::__distance(_CIter(__first), _CIter(__last), __tag);
+ }
+
+ template<typename _Tp>
+ inline ptrdiff_t
+ __distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp> __first,
+ _GLIBCXX_STD_C::_List_const_iterator<_Tp> __last,
+ input_iterator_tag)
+ {
+ typedef _GLIBCXX_STD_C::_List_node<size_t> _Sentinel;
+ _GLIBCXX_STD_C::_List_const_iterator<_Tp> __beyond = __last;
+ ++__beyond;
+ bool __whole = __first == __beyond;
+ if (__builtin_constant_p (__whole) && __whole)
+ return static_cast<const _Sentinel*>(__last._M_node)->_M_data;
+
+ ptrdiff_t __n = 0;
+ while (__first != __last)
+ {
+ ++__first;
+ ++__n;
+ }
+ return __n;
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+#endif
} // namespace std
#endif /* _STL_LIST_H */
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index 3bac4e08982..df18973931e 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -824,6 +824,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return value_compare(_M_t.key_comp()); }
// [23.3.1.3] map operations
+
+ //@{
/**
* @brief Tries to locate an element in a %map.
* @param __x Key of (key, value) %pair to be located.
@@ -835,10 +837,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* pointing to the sought after %pair. If unsuccessful it returns the
* past-the-end ( @c end() ) iterator.
*/
+
iterator
find(const key_type& __x)
{ return _M_t.find(__x); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Tries to locate an element in a %map.
* @param __x Key of (key, value) %pair to be located.
@@ -850,10 +862,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* iterator pointing to the sought after %pair. If unsuccessful it
* returns the past-the-end ( @c end() ) iterator.
*/
+
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the number of elements with given key.
* @param __x Key of (key, value) pairs to be located.
@@ -866,6 +888,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
+#if __cplusplus > 201103L
+ 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; }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -881,6 +912,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x)
{ return _M_t.lower_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -896,6 +937,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -906,6 +957,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x)
{ return _M_t.upper_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -916,6 +977,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@@ -935,6 +1006,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@@ -954,6 +1035,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator==(const map<_K1, _T1, _C1, _A1>&,
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 5a81f8ffad6..f3d21ab8bea 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -734,6 +734,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return value_compare(_M_t.key_comp()); }
// multimap operations
+
+ //@{
/**
* @brief Tries to locate an element in a %multimap.
* @param __x Key of (key, value) pair to be located.
@@ -749,6 +751,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
find(const key_type& __x)
{ return _M_t.find(__x); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Tries to locate an element in a %multimap.
* @param __x Key of (key, value) pair to be located.
@@ -764,6 +775,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
find(const key_type& __x) const
{ return _M_t.find(__x); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the number of elements with given key.
* @param __x Key of (key, value) pairs to be located.
@@ -773,6 +793,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.count(__x); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
+ { return _M_t._M_count_tr(__x); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -788,6 +817,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x)
{ return _M_t.lower_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -803,6 +842,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -813,6 +862,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x)
{ return _M_t.upper_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@@ -823,6 +882,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@@ -840,6 +909,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
+ //@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@@ -857,6 +936,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
+#if __cplusplus > 201103L
+ 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); }
+#endif
+ //@}
+
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator==(const multimap<_K1, _T1, _C1, _A1>&,
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index be04221bd12..7e92836aaec 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -636,6 +636,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// multiset operations:
+ //@{
/**
* @brief Finds the number of elements with given key.
* @param __x Key of elements to be located.
@@ -645,6 +646,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.count(__x); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
+ { return _M_t._M_count_tr(__x); }
+#endif
+ //@}
+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
//@{
@@ -666,6 +675,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
+
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+#endif
//@}
//@{
@@ -687,6 +708,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
+
+#if __cplusplus > 201103L
+ 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); }
+
+ 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); }
+#endif
//@}
//@{
@@ -703,6 +738,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
+
+#if __cplusplus > 201103L
+ 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); }
+
+ 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); }
+#endif
//@}
//@{
@@ -728,6 +777,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
+
+#if __cplusplus > 201103L
+ 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); }
+
+ 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); }
+#endif
//@}
template<typename _K1, typename _C1, typename _A1>
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 3944bcd52f7..51892343570 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -651,6 +651,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// set operations:
+ //@{
/**
* @brief Finds the number of elements.
* @param __x Element to located.
@@ -663,6 +664,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
+#if __cplusplus > 201103L
+ 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; }
+#endif
+ //@}
+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
//@{
@@ -684,6 +694,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
+
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+
+ template<typename _Kt>
+ auto
+ find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
+ { return _M_t._M_find_tr(__x); }
+#endif
//@}
//@{
@@ -705,6 +727,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
+
+#if __cplusplus > 201103L
+ 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); }
+
+ 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); }
+#endif
//@}
//@{
@@ -721,6 +757,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
+
+#if __cplusplus > 201103L
+ 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); }
+
+ 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); }
+#endif
//@}
//@{
@@ -746,6 +796,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
+
+#if __cplusplus > 201103L
+ 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); }
+
+ 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); }
+#endif
//@}
template<typename _K1, typename _C1, typename _A1>
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index e78b2db1726..5ca8e28ef43 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -1118,6 +1118,137 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pair<const_iterator, const_iterator>
equal_range(const key_type& __k) const;
+#if __cplusplus > 201103L
+ template<typename _Cmp, typename _Kt, typename = __void_t<>>
+ struct __is_transparent { };
+
+ template<typename _Cmp, typename _Kt>
+ struct
+ __is_transparent<_Cmp, _Kt, __void_t<typename _Cmp::is_transparent>>
+ { typedef void type; };
+
+ static auto _S_iter(_Link_type __x) { return iterator(__x); }
+
+ static auto _S_iter(_Const_Link_type __x) { return const_iterator(__x); }
+
+ template<typename _Cmp, typename _Link, typename _Kt>
+ static auto
+ _S_lower_bound_tr(_Cmp& __cmp, _Link __x, _Link __y, const _Kt& __k)
+ {
+ while (__x != 0)
+ if (!__cmp(_S_key(__x), __k))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+ return _S_iter(__y);
+ }
+
+ template<typename _Cmp, typename _Link, typename _Kt>
+ static auto
+ _S_upper_bound_tr(_Cmp& __cmp, _Link __x, _Link __y, const _Kt& __k)
+ {
+ while (__x != 0)
+ if (__cmp(__k, _S_key(__x)))
+ __y = __x, __x = _S_left(__x);
+ else
+ __x = _S_right(__x);
+ return _S_iter(__y);
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ iterator
+ _M_find_tr(const _Kt& __k)
+ {
+ auto& __cmp = _M_impl._M_key_compare;
+ auto __j = _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+ return (__j == end() || __cmp(__k, _S_key(__j._M_node)))
+ ? end() : __j;
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ const_iterator
+ _M_find_tr(const _Kt& __k) const
+ {
+ auto& __cmp = _M_impl._M_key_compare;
+ auto __j = _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+ return (__j == end() || __cmp(__k, _S_key(__j._M_node)))
+ ? end() : __j;
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ size_type
+ _M_count_tr(const _Kt& __k) const
+ {
+ auto __p = _M_equal_range_tr(__k);
+ return std::distance(__p.first, __p.second);
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ iterator
+ _M_lower_bound_tr(const _Kt& __k)
+ {
+ auto& __cmp = _M_impl._M_key_compare;
+ return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ const_iterator
+ _M_lower_bound_tr(const _Kt& __k) const
+ {
+ auto& __cmp = _M_impl._M_key_compare;
+ return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ iterator
+ _M_upper_bound_tr(const _Kt& __k)
+ {
+ auto& __cmp = _M_impl._M_key_compare;
+ return _S_upper_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ const_iterator
+ _M_upper_bound_tr(const _Kt& __k) const
+ {
+ auto& __cmp = _M_impl._M_key_compare;
+ return _S_upper_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ pair<iterator, iterator>
+ _M_equal_range_tr(const _Kt& __k)
+ {
+ auto __low = _M_lower_bound_tr(__k);
+ auto __high = __low;
+ auto& __cmp = _M_impl._M_key_compare;
+ while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
+ ++__high;
+ return { __low, __high };
+ }
+
+ template<typename _Kt,
+ typename _Req = typename __is_transparent<_Compare, _Kt>::type>
+ pair<const_iterator, const_iterator>
+ _M_equal_range_tr(const _Kt& __k) const
+ {
+ auto __low = _M_lower_bound_tr(__k);
+ auto __high = __low;
+ auto& __cmp = _M_impl._M_key_compare;
+ while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
+ ++__high;
+ return { __low, __high };
+ }
+#endif
+
// Debugging.
bool
__rb_verify() const;
diff --git a/libstdc++-v3/include/c_global/cstdio b/libstdc++-v3/include/c_global/cstdio
index ef024bf8dbe..d1c958b6383 100644
--- a/libstdc++-v3/include/c_global/cstdio
+++ b/libstdc++-v3/include/c_global/cstdio
@@ -45,7 +45,7 @@
#define _GLIBCXX_CSTDIO 1
#ifndef _GLIBCXX_HAVE_GETS
-extern "C" char* gets (char* __s) __attribute__((deprecated));
+extern "C" char* gets (char* __s) __attribute__((__deprecated__));
#endif
// Get rid of those macros defined in <stdio.h> in lieu of real functions.
diff --git a/libstdc++-v3/include/c_std/cstdio b/libstdc++-v3/include/c_std/cstdio
index 1f8ae7c90e8..37f01cad70a 100644
--- a/libstdc++-v3/include/c_std/cstdio
+++ b/libstdc++-v3/include/c_std/cstdio
@@ -45,7 +45,7 @@
#include <stdio.h>
#ifndef _GLIBCXX_HAVE_GETS
-extern "C" char* gets (char* __s) __attribute__((deprecated));
+extern "C" char* gets (char* __s) __attribute__((__deprecated__));
#endif
// Get rid of those macros defined in <stdio.h> in lieu of real functions.
diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional
index 206b945998a..811235bfce4 100644
--- a/libstdc++-v3/include/experimental/optional
+++ b/libstdc++-v3/include/experimental/optional
@@ -110,9 +110,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class bad_optional_access : public logic_error
{
public:
- // XXX Should not be inline
- explicit bad_optional_access(const string& __arg) : logic_error(__arg) { }
+ bad_optional_access() : logic_error("bad optional access") { }
+ // XXX This constructor is non-standard. Should not be inline
explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
virtual ~bad_optional_access() noexcept = default;
diff --git a/libstdc++-v3/include/experimental/system_error b/libstdc++-v3/include/experimental/system_error
index 5c49ac751d4..ba3f8befd83 100644
--- a/libstdc++-v3/include/experimental/system_error
+++ b/libstdc++-v3/include/experimental/system_error
@@ -31,7 +31,7 @@
//
#ifndef _GLIBCXX_EXPERIMENTAL_SYSTEM_ERROR
-#define _GLIBCXX_EXPERIMENTAL_CHRONO 1
+#define _GLIBCXX_EXPERIMENTAL_SYSTEM_ERROR 1
#pragma GCC system_header
diff --git a/libstdc++-v3/include/ext/codecvt_specializations.h b/libstdc++-v3/include/ext/codecvt_specializations.h
index a24adfcfd13..34e90bdf3f1 100644
--- a/libstdc++-v3/include/ext/codecvt_specializations.h
+++ b/libstdc++-v3/include/ext/codecvt_specializations.h
@@ -41,6 +41,7 @@
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
+_GLIBCXX_BEGIN_NAMESPACE_CXX11
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Extension to use iconv for dealing with character encodings.
@@ -207,13 +208,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// associated fpos<encoding_state> for the position type, all other
// bits equivalent to the required char_traits instantiations.
template<typename _CharT>
- struct encoding_char_traits : public std::char_traits<_CharT>
+ struct encoding_char_traits
+ : public std::char_traits<_CharT>
{
typedef encoding_state state_type;
typedef typename std::fpos<state_type> pos_type;
};
_GLIBCXX_END_NAMESPACE_VERSION
+_GLIBCXX_END_NAMESPACE_CXX11
} // namespace
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp
index 0b71817c41d..a402bef3a61 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp
@@ -162,7 +162,7 @@ namespace __gnu_pbds
empty_entry_status,
valid_entry_status,
erased_entry_status
- } __attribute__ ((packed));
+ } __attribute__ ((__packed__));
struct entry : public traits_base::stored_data_type
{
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 43cf4f339fd..125e37a2838 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -165,7 +165,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct atomic
{
private:
- _Tp _M_i;
+ // Align 1/2/4/8/16-byte types to at least their size.
+ static constexpr int _S_min_alignment
+ = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
+ ? 0 : sizeof(_Tp);
+
+ static constexpr int _S_alignment
+ = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
+
+ alignas(_S_alignment) _Tp _M_i;
static_assert(__is_trivially_copyable(_Tp),
"std::atomic requires a trivially copyable type");
@@ -198,11 +206,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
is_lock_free() const noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
+ {
+ // Produce a fake, minimally aligned pointer.
+ void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ return __atomic_is_lock_free(sizeof(_M_i), __a);
+ }
bool
is_lock_free() const volatile noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
+ {
+ // Produce a fake, minimally aligned pointer.
+ void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ return __atomic_is_lock_free(sizeof(_M_i), __a);
+ }
void
store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
@@ -921,11 +937,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ITp>
inline void
- atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
+ atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
+ { __a->store(__i, memory_order_relaxed); }
template<typename _ITp>
inline void
- atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
+ atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
+ { __a->store(__i, memory_order_relaxed); }
template<typename _ITp>
inline void
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index e5baa5689ea..50a2bbfca9c 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -866,6 +866,15 @@ _GLIBCXX_END_NAMESPACE_VERSION
} // inline namespace chrono_literals
} // inline namespace literals
+ namespace chrono
+ {
+ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ using namespace literals::chrono_literals;
+
+ _GLIBCXX_END_NAMESPACE_VERSION
+ } // namespace chrono
+
#endif // __cplusplus > 201103L
// @} group chrono
diff --git a/libstdc++-v3/include/std/codecvt b/libstdc++-v3/include/std/codecvt
index d58a0ecd673..e4a7d5bbb60 100644
--- a/libstdc++-v3/include/std/codecvt
+++ b/libstdc++-v3/include/std/codecvt
@@ -148,7 +148,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public: \
explicit \
_NAME(size_t __refs = 0) \
- : __ ## _NAME ## _base<_ELEM>(_Maxcode, _Mode, __refs) { } \
+ : __ ## _NAME ## _base<_ELEM>(std::min(_Maxcode, 0x10fffful), \
+ _Mode, __refs) \
+ { } \
}
template<typename _Elem> class __codecvt_utf8_base;
diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index cb0226dec4c..fc3f8162ae6 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -98,7 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public:
explicit future_error(error_code __ec)
- : logic_error("std::future_error"), _M_code(__ec)
+ : logic_error("std::future_error: " + __ec.message()), _M_code(__ec)
{ }
virtual ~future_error() noexcept;
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index 9deef435c76..74c0d81e0a3 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -922,7 +922,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits, typename _Tp>
inline basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)
- { return (__is >> __x); }
+ {
+ __is >> __x;
+ return __is;
+ }
#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index decb29a5fa3..151c42bede2 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -626,7 +626,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits, typename _Tp>
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
- { return (__os << __x); }
+ {
+ __os << __x;
+ return __os;
+ }
#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator
index 1be10b294cd..d163edd109a 100644
--- a/libstdc++-v3/include/std/scoped_allocator
+++ b/libstdc++-v3/include/std/scoped_allocator
@@ -105,6 +105,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__inner_type_impl() = default;
__inner_type_impl(const __inner_type_impl&) = default;
__inner_type_impl(__inner_type_impl&&) = default;
+ __inner_type_impl& operator=(const __inner_type_impl&) = default;
+ __inner_type_impl& operator=(__inner_type_impl&&) = default;
template<typename _Alloc>
__inner_type_impl(const __inner_type_impl<_Alloc>& __other)
@@ -136,6 +138,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__inner_type_impl() = default;
__inner_type_impl(const __inner_type_impl&) = default;
__inner_type_impl(__inner_type_impl&&) = default;
+ __inner_type_impl& operator=(const __inner_type_impl&) = default;
+ __inner_type_impl& operator=(__inner_type_impl&&) = default;
template<typename... _Allocs>
__inner_type_impl(const __inner_type_impl<_Allocs...>& __other)
@@ -310,6 +314,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_inner(std::move(__other._M_inner))
{ }
+ scoped_allocator_adaptor&
+ operator=(const scoped_allocator_adaptor&) = default;
+
+ scoped_allocator_adaptor&
+ operator=(scoped_allocator_adaptor&&) = default;
+
inner_allocator_type& inner_allocator() noexcept
{ return _M_inner._M_get(this); }
diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc++-v3/include/std/shared_mutex
index 643768c6f8b..b72a822a57b 100644
--- a/libstdc++-v3/include/std/shared_mutex
+++ b/libstdc++-v3/include/std/shared_mutex
@@ -57,10 +57,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// shared_timed_mutex
class shared_timed_mutex
{
-#if defined(__GTHREADS_CXX0X)
+#if _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK
typedef chrono::system_clock __clock_t;
- pthread_rwlock_t _M_rwlock;
+#ifdef PTHREAD_RWLOCK_INITIALIZER
+ pthread_rwlock_t _M_rwlock = PTHREAD_RWLOCK_INITIALIZER;
+
+ public:
+ shared_timed_mutex() = default;
+ ~shared_timed_mutex() = default;
+#else
+ pthread_rwlock_t _M_rwlock;
public:
shared_timed_mutex()
@@ -78,10 +85,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
~shared_timed_mutex()
{
- int __ret __attribute((unused)) = pthread_rwlock_destroy(&_M_rwlock);
+ int __ret __attribute((__unused__)) = pthread_rwlock_destroy(&_M_rwlock);
// Errors not handled: EBUSY, EINVAL
_GLIBCXX_DEBUG_ASSERT(__ret == 0);
}
+#endif
shared_timed_mutex(const shared_timed_mutex&) = delete;
shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
@@ -153,7 +161,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
unlock()
{
- int __ret __attribute((unused)) = pthread_rwlock_unlock(&_M_rwlock);
+ int __ret __attribute((__unused__)) = pthread_rwlock_unlock(&_M_rwlock);
// Errors not handled: EPERM, EBUSY, EINVAL
_GLIBCXX_DEBUG_ASSERT(__ret == 0);
}
@@ -163,12 +171,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
lock_shared()
{
- int __ret = pthread_rwlock_rdlock(&_M_rwlock);
+ int __ret;
+ // We retry if we exceeded the maximum number of read locks supported by
+ // the POSIX implementation; this can result in busy-waiting, but this
+ // is okay based on the current specification of forward progress
+ // guarantees by the standard.
+ do
+ __ret = pthread_rwlock_rdlock(&_M_rwlock);
+ while (__ret == EAGAIN);
if (__ret == EDEADLK)
__throw_system_error(int(errc::resource_deadlock_would_occur));
- if (__ret == EAGAIN)
- // Maximum number of read locks has been exceeded.
- __throw_system_error(int(errc::device_or_resource_busy));
// Errors not handled: EINVAL
_GLIBCXX_DEBUG_ASSERT(__ret == 0);
}
@@ -207,11 +219,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_cast<long>(__ns.count())
};
- int __ret = pthread_rwlock_timedrdlock(&_M_rwlock, &__ts);
- // If the maximum number of read locks has been exceeded, or we would
- // deadlock, we just fail to acquire the lock. Unlike for lock(),
- // we are not allowed to throw an exception.
- if (__ret == ETIMEDOUT || __ret == EAGAIN || __ret == EDEADLK)
+ int __ret;
+ // Unlike for lock(), we are not allowed to throw an exception so if
+ // the maximum number of read locks has been exceeded, or we would
+ // deadlock, we just try to acquire the lock again (and will time out
+ // eventually).
+ // In cases where we would exceed the maximum number of read locks
+ // throughout the whole time until the timeout, we will fail to
+ // acquire the lock even if it would be logically free; however, this
+ // is allowed by the standard, and we made a "strong effort"
+ // (see C++14 30.4.1.4p26).
+ // For cases where the implementation detects a deadlock we
+ // intentionally block and timeout so that an early return isn't
+ // mistaken for a spurious failure, which might help users realise
+ // there is a deadlock.
+ do
+ __ret = pthread_rwlock_timedrdlock(&_M_rwlock, &__ts);
+ while (__ret == EAGAIN || __ret == EDEADLK);
+ if (__ret == ETIMEDOUT)
return false;
// Errors not handled: EINVAL
_GLIBCXX_DEBUG_ASSERT(__ret == 0);
@@ -237,35 +262,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
unlock();
}
-#else // defined(__GTHREADS_CXX0X)
-
-#if _GTHREAD_USE_MUTEX_TIMEDLOCK
- struct _Mutex : mutex, __timed_mutex_impl<_Mutex>
- {
- template<typename _Rep, typename _Period>
- bool
- try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
- { return _M_try_lock_for(__rtime); }
-
- template<typename _Clock, typename _Duration>
- bool
- try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
- { return _M_try_lock_until(__atime); }
- };
-#else
- typedef mutex _Mutex;
-#endif
+#else // ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK)
- // Based on Howard Hinnant's reference implementation from N2406
+ // Must use the same clock as condition_variable
+ typedef chrono::system_clock __clock_t;
- _Mutex _M_mut;
+ // Based on Howard Hinnant's reference implementation from N2406.
+
+ // The high bit of _M_state is the write-entered flag which is set to
+ // indicate a writer has taken the lock or is queuing to take the lock.
+ // The remaining bits are the count of reader locks.
+ //
+ // To take a reader lock, block on gate1 while the write-entered flag is
+ // set or the maximum number of reader locks is held, then increment the
+ // reader lock count.
+ // To release, decrement the count, then if the write-entered flag is set
+ // and the count is zero then signal gate2 to wake a queued writer,
+ // otherwise if the maximum number of reader locks was held signal gate1
+ // to wake a reader.
+ //
+ // To take a writer lock, block on gate1 while the write-entered flag is
+ // set, then set the write-entered flag to start queueing, then block on
+ // gate2 while the number of reader locks is non-zero.
+ // To release, unset the write-entered flag and signal gate1 to wake all
+ // blocked readers and writers.
+ //
+ // This means that when no reader locks are held readers and writers get
+ // equal priority. When one or more reader locks is held a writer gets
+ // priority and no more reader locks can be taken while the writer is
+ // queued.
+
+ // Only locked when accessing _M_state or waiting on condition variables.
+ mutex _M_mut;
+ // Used to block while write-entered is set or reader count at maximum.
condition_variable _M_gate1;
+ // Used to block queued writers while reader count is non-zero.
condition_variable _M_gate2;
+ // The write-entered flag and reader count.
unsigned _M_state;
static constexpr unsigned _S_write_entered
= 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
- static constexpr unsigned _M_n_readers = ~_S_write_entered;
+ static constexpr unsigned _S_max_readers = ~_S_write_entered;
+
+ // Test whether the write-entered flag is set. _M_mut must be locked.
+ bool _M_write_entered() const { return _M_state & _S_write_entered; }
+
+ // The number of reader locks currently held. _M_mut must be locked.
+ unsigned _M_readers() const { return _M_state & _S_max_readers; }
public:
shared_timed_mutex() : _M_state(0) {}
@@ -284,11 +328,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lock()
{
unique_lock<mutex> __lk(_M_mut);
- while (_M_state & _S_write_entered)
- _M_gate1.wait(__lk);
+ // Wait until we can set the write-entered flag.
+ _M_gate1.wait(__lk, [=]{ return !_M_write_entered(); });
_M_state |= _S_write_entered;
- while (_M_state & _M_n_readers)
- _M_gate2.wait(__lk);
+ // Then wait until there are no more readers.
+ _M_gate2.wait(__lk, [=]{ return _M_readers() == 0; });
}
bool
@@ -303,41 +347,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}
-#if _GTHREAD_USE_MUTEX_TIMEDLOCK
template<typename _Rep, typename _Period>
bool
try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
{
- unique_lock<_Mutex> __lk(_M_mut, __rel_time);
- if (__lk.owns_lock() && _M_state == 0)
- {
- _M_state = _S_write_entered;
- return true;
- }
- return false;
+ return try_lock_until(__clock_t::now() + __rel_time);
}
template<typename _Clock, typename _Duration>
bool
try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
{
- unique_lock<_Mutex> __lk(_M_mut, __abs_time);
- if (__lk.owns_lock() && _M_state == 0)
+ unique_lock<mutex> __lk(_M_mut);
+ if (!_M_gate1.wait_until(__lk, __abs_time,
+ [=]{ return !_M_write_entered(); }))
{
- _M_state = _S_write_entered;
- return true;
+ return false;
}
- return false;
+ _M_state |= _S_write_entered;
+ if (!_M_gate2.wait_until(__lk, __abs_time,
+ [=]{ return _M_readers() == 0; }))
+ {
+ _M_state ^= _S_write_entered;
+ // Wake all threads blocked while the write-entered flag was set.
+ _M_gate1.notify_all();
+ return false;
+ }
+ return true;
}
-#endif
void
unlock()
{
- {
- lock_guard<_Mutex> __lk(_M_mut);
- _M_state = 0;
- }
+ lock_guard<mutex> __lk(_M_mut);
+ _GLIBCXX_DEBUG_ASSERT( _M_write_entered() );
+ _M_state = 0;
+ // call notify_all() while mutex is held so that another thread can't
+ // lock and unlock the mutex then destroy *this before we make the call.
_M_gate1.notify_all();
}
@@ -347,51 +393,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lock_shared()
{
unique_lock<mutex> __lk(_M_mut);
- while ((_M_state & _S_write_entered)
- || (_M_state & _M_n_readers) == _M_n_readers)
- {
- _M_gate1.wait(__lk);
- }
- unsigned __num_readers = (_M_state & _M_n_readers) + 1;
- _M_state &= ~_M_n_readers;
- _M_state |= __num_readers;
+ _M_gate1.wait(__lk, [=]{ return _M_state < _S_max_readers; });
+ ++_M_state;
}
bool
try_lock_shared()
{
- unique_lock<_Mutex> __lk(_M_mut, try_to_lock);
- unsigned __num_readers = _M_state & _M_n_readers;
- if (__lk.owns_lock() && !(_M_state & _S_write_entered)
- && __num_readers != _M_n_readers)
+ unique_lock<mutex> __lk(_M_mut, try_to_lock);
+ if (!__lk.owns_lock())
+ return false;
+ if (_M_state < _S_max_readers)
{
- ++__num_readers;
- _M_state &= ~_M_n_readers;
- _M_state |= __num_readers;
+ ++_M_state;
return true;
}
return false;
}
-#if _GTHREAD_USE_MUTEX_TIMEDLOCK
template<typename _Rep, typename _Period>
bool
try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
{
- unique_lock<_Mutex> __lk(_M_mut, __rel_time);
- if (__lk.owns_lock())
- {
- unsigned __num_readers = _M_state & _M_n_readers;
- if (!(_M_state & _S_write_entered)
- && __num_readers != _M_n_readers)
- {
- ++__num_readers;
- _M_state &= ~_M_n_readers;
- _M_state |= __num_readers;
- return true;
- }
- }
- return false;
+ return try_lock_shared_until(__clock_t::now() + __rel_time);
}
template <typename _Clock, typename _Duration>
@@ -399,42 +423,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
try_lock_shared_until(const chrono::time_point<_Clock,
_Duration>& __abs_time)
{
- unique_lock<_Mutex> __lk(_M_mut, __abs_time);
- if (__lk.owns_lock())
+ unique_lock<mutex> __lk(_M_mut);
+ if (!_M_gate1.wait_until(__lk, __abs_time,
+ [=]{ return _M_state < _S_max_readers; }))
{
- unsigned __num_readers = _M_state & _M_n_readers;
- if (!(_M_state & _S_write_entered)
- && __num_readers != _M_n_readers)
- {
- ++__num_readers;
- _M_state &= ~_M_n_readers;
- _M_state |= __num_readers;
- return true;
- }
+ return false;
}
- return false;
+ ++_M_state;
+ return true;
}
-#endif
void
unlock_shared()
{
- lock_guard<_Mutex> __lk(_M_mut);
- unsigned __num_readers = (_M_state & _M_n_readers) - 1;
- _M_state &= ~_M_n_readers;
- _M_state |= __num_readers;
- if (_M_state & _S_write_entered)
+ lock_guard<mutex> __lk(_M_mut);
+ _GLIBCXX_DEBUG_ASSERT( _M_readers() > 0 );
+ auto __prev = _M_state--;
+ if (_M_write_entered())
{
- if (__num_readers == 0)
+ // Wake the queued writer if there are no more readers.
+ if (_M_readers() == 0)
_M_gate2.notify_one();
+ // No need to notify gate1 because we give priority to the queued
+ // writer, and that writer will eventually notify gate1 after it
+ // clears the write-entered flag.
}
else
{
- if (__num_readers == _M_n_readers - 1)
+ // Wake any thread that was blocked on reader overflow.
+ if (__prev == _S_max_readers)
_M_gate1.notify_one();
}
}
-#endif // !defined(__GTHREADS_CXX0X)
+#endif // _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK
};
#endif // _GLIBCXX_HAS_GTHREADS
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index bf3e618128c..24289194d01 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -80,7 +80,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
union {
__str _M_s;
- char _M_bytes[sizeof(_M_s)];
+ char _M_bytes[sizeof(__str)];
};
__sso_string() _GLIBCXX_USE_NOEXCEPT;
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 2f9e69a88cd..ebbda62fa72 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -279,6 +279,8 @@ _GLIBCXX_END_NAMESPACE_VERSION
inline void
sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
{
+ if (__rtime <= __rtime.zero())
+ return;
auto __s = chrono::duration_cast<chrono::seconds>(__rtime);
auto __ns = chrono::duration_cast<chrono::nanoseconds>(__rtime - __s);
#ifdef _GLIBCXX_USE_NANOSLEEP
@@ -297,7 +299,11 @@ _GLIBCXX_END_NAMESPACE_VERSION
template<typename _Clock, typename _Duration>
inline void
sleep_until(const chrono::time_point<_Clock, _Duration>& __atime)
- { sleep_for(__atime - _Clock::now()); }
+ {
+ auto __now = _Clock::now();
+ if (__now < __atime)
+ sleep_for(__atime - __now);
+ }
_GLIBCXX_END_NAMESPACE_VERSION
}