summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-22 14:58:36 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-22 14:58:36 +0000
commitcfea6514a4b6ced0930593ebb48d0037e9716d87 (patch)
treeeeccf866e18463f7dc7ea882ea944247d4ed1010 /libstdc++-v3/include
parent9456798d72d0e81a2a553287f436dcb05cff175a (diff)
downloadgcc-cfea6514a4b6ced0930593ebb48d0037e9716d87.tar.gz
[./]
2013-11-22 Basile Starynkevitch <basile@starynkevitch.net> {{merge with trunk GCC 4.9 svn rev 205247 now in stage 3}} [gcc/] 2013-11-22 Basile Starynkevitch <basile@starynkevitch.net> {{merge with trunk GCC 4.9 svn rev 205247 now in stage 3}} * Makefile.in (MELT_GCC_VERSION_NUM): New make variable. (melt-run-md5.h, melt-run.h): Use it. * melt-runtime.cc: With GCC 4.9 include print-tree.h, gimple-iterator.h, gimple-walk.h. (meltgc_start_all_new_modules, meltgc_start_flavored_module) (meltgc_do_initial_mode, meltgc_set_user_options) (meltgc_load_modules_and_do_mode): Improve debugprintf... (melt_gt_ggc_mx_gimple_seq_d): Handle GCC 4.9 specifically. * melt-runtime.h (gt_ggc_mx_gimple_statement_d): Temporarily define this macro. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@205264 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/Makefile.am4
-rw-r--r--libstdc++-v3/include/Makefile.in4
-rw-r--r--libstdc++-v3/include/bits/alloc_traits.h18
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h2
-rw-r--r--libstdc++-v3/include/bits/forward_list.h2
-rw-r--r--libstdc++-v3/include/bits/hashtable_policy.h2
-rw-r--r--libstdc++-v3/include/bits/random.h8
-rw-r--r--libstdc++-v3/include/bits/shared_ptr_base.h43
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h13
-rw-r--r--libstdc++-v3/include/bits/stl_map.h59
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h59
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h60
-rw-r--r--libstdc++-v3/include/bits/stl_set.h60
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h202
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h1
-rw-r--r--libstdc++-v3/include/bits/unordered_map.h4
-rw-r--r--libstdc++-v3/include/bits/unordered_set.h4
-rw-r--r--libstdc++-v3/include/experimental/string_view705
-rw-r--r--libstdc++-v3/include/experimental/string_view.tcc234
-rw-r--r--libstdc++-v3/include/ext/cast.h2
-rw-r--r--libstdc++-v3/include/ext/pod_char_traits.h34
-rw-r--r--libstdc++-v3/include/ext/pointer.h2
-rw-r--r--libstdc++-v3/include/ext/random261
-rw-r--r--libstdc++-v3/include/ext/random.tcc108
-rw-r--r--libstdc++-v3/include/std/future84
25 files changed, 1800 insertions, 175 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 505679af5ae..6371e5d1b7e 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -638,7 +638,9 @@ decimal_headers = \
experimental_srcdir = ${glibcxx_srcdir}/include/experimental
experimental_builddir = ./experimental
experimental_headers = \
- ${experimental_srcdir}/optional
+ ${experimental_srcdir}/optional \
+ ${experimental_srcdir}/string_view \
+ ${experimental_srcdir}/string_view.tcc
# This is the common subset of C++ files that all three "C" header models use.
c_base_srcdir = $(C_INCLUDE_DIR)
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 9d8a7491b7a..249b2d278d5 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -926,7 +926,9 @@ decimal_headers = \
experimental_srcdir = ${glibcxx_srcdir}/include/experimental
experimental_builddir = ./experimental
experimental_headers = \
- ${experimental_srcdir}/optional
+ ${experimental_srcdir}/optional \
+ ${experimental_srcdir}/string_view \
+ ${experimental_srcdir}/string_view.tcc
# This is the common subset of C++ files that all three "C" header models use.
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index e68d3171095..815c4b8b998 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -541,24 +541,6 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
: is_copy_constructible<_Tp>
{ };
- // Used to allow copy construction of unordered containers
- template<bool> struct __allow_copy_cons { };
-
- // Used to delete copy constructor of unordered containers
- template<>
- struct __allow_copy_cons<false>
- {
- __allow_copy_cons() = default;
- __allow_copy_cons(const __allow_copy_cons&) = delete;
- __allow_copy_cons(__allow_copy_cons&&) = default;
- __allow_copy_cons& operator=(const __allow_copy_cons&) = default;
- __allow_copy_cons& operator=(__allow_copy_cons&&) = default;
- };
-
- template<typename _Alloc>
- using __check_copy_constructible
- = __allow_copy_cons<__is_copy_insertable<_Alloc>::value>;
-
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index d9d755abba9..54bf2133d0d 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -255,7 +255,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Base type is POD with data, allowing atomic_flag to derive from
* it and meet the standard layout type requirement. In addition to
- * compatibilty with a C interface, this allows different
+ * compatibility with a C interface, this allows different
* implementations of atomic_flag to use the same atomic operation
* functions, via a standard conversion to the __atomic_flag_base
* argument.
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 9ac9d22523b..e469dbfd803 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -352,7 +352,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
_Tp_alloc_type __a(_M_get_Node_allocator());
typedef allocator_traits<_Tp_alloc_type> _Alloc_traits;
- ::new ((void*)__node) _Node();
+ ::new ((void*)__node) _Node;
_Alloc_traits::construct(__a, __node->_M_valptr(),
std::forward<_Args>(__args)...);
}
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index ed9e9dd870a..930a785d0a5 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -1862,7 +1862,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__try
{
__value_alloc_type __a(_M_node_allocator());
- ::new ((void*)__n) __node_type();
+ ::new ((void*)__n) __node_type;
__value_alloc_traits::construct(__a, __n->_M_valptr(),
std::forward<_Args>(__args)...);
return __n;
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index dde2dd45f9e..5613bdf5ec0 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -5685,11 +5685,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __d1._M_param == __d2._M_param; }
/**
- * @brief Inserts a %piecewise_constan_distribution random
+ * @brief Inserts a %piecewise_constant_distribution random
* number distribution @p __x into the output stream @p __os.
*
* @param __os An output stream.
- * @param __x A %piecewise_constan_distribution random number
+ * @param __x A %piecewise_constant_distribution random number
* distribution.
*
* @returns The output stream with the state of @p __x inserted or in
@@ -5701,11 +5701,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const std::piecewise_constant_distribution<_RealType1>& __x);
/**
- * @brief Extracts a %piecewise_constan_distribution random
+ * @brief Extracts a %piecewise_constant_distribution random
* number distribution @p __x from the input stream @p __is.
*
* @param __is An input stream.
- * @param __x A %piecewise_constan_distribution random number
+ * @param __x A %piecewise_constant_distribution random number
* generator engine.
*
* @returns The input stream with @p __x extracted or in an error
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
index cf90d7a7cb3..68ccc9e1150 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -209,11 +209,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Sp_counted_base<_S_single>::
_M_add_ref_lock()
{
- if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
- {
- _M_use_count = 0;
- __throw_bad_weak_ptr();
- }
+ if (_M_use_count == 0)
+ __throw_bad_weak_ptr();
+ ++_M_use_count;
}
template<>
@@ -248,6 +246,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__ATOMIC_RELAXED));
}
+ template<>
+ inline void
+ _Sp_counted_base<_S_single>::_M_add_ref_copy()
+ { ++_M_use_count; }
+
+ template<>
+ inline void
+ _Sp_counted_base<_S_single>::_M_release() noexcept
+ {
+ if (--_M_use_count == 0)
+ {
+ _M_dispose();
+ if (--_M_weak_count == 0)
+ _M_destroy();
+ }
+ }
+
+ template<>
+ inline void
+ _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
+ { ++_M_weak_count; }
+
+ template<>
+ inline void
+ _Sp_counted_base<_S_single>::_M_weak_release() noexcept
+ {
+ if (--_M_weak_count == 0)
+ _M_destroy();
+ }
+
+ template<>
+ inline long
+ _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
+ { return _M_use_count; }
+
// Forward declarations.
template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 8e4b0230614..3b5a0c2b63e 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -971,7 +971,18 @@ template<typename _Alloc>
clear() _GLIBCXX_NOEXCEPT
{ _M_erase_at_end(begin()); }
-
+#if __cplusplus >= 201103L
+ template<typename... _Args>
+ void
+ emplace_back(_Args&&... __args)
+ { push_back(bool(__args...)); }
+
+ template<typename... _Args>
+ iterator
+ emplace(const_iterator __pos, _Args&&... __args)
+ { return insert(__pos, bool(__args...)); }
+#endif
+
protected:
// Precondition: __first._M_offset == 0 && __result._M_offset == 0.
iterator
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index d05e4b9ab7d..5b73f19084e 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -128,8 +128,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
private:
/// This turns a red-black tree into a [multi]map.
- typedef typename _Alloc::template rebind<value_type>::other
- _Pair_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<value_type>::other _Pair_alloc_type;
typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
key_compare, _Pair_alloc_type> _Rep_type;
@@ -137,13 +137,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// The actual tree structure.
_Rep_type _M_t;
+ typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
+
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Pair_alloc_type::pointer pointer;
- typedef typename _Pair_alloc_type::const_pointer const_pointer;
- typedef typename _Pair_alloc_type::reference reference;
- typedef typename _Pair_alloc_type::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;
typedef typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
@@ -208,6 +210,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
{ _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ map(const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ map(const map& __m, const allocator_type& __a)
+ : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ map(map&& __m, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ map(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ map(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_unique(__first, __last); }
#endif
/**
@@ -276,12 +305,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @a __x is a valid, but unspecified %map.
*/
map&
- operator=(map&& __x)
+ operator=(map&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x.begin()),
+ std::__make_move_if_noexcept_iterator(__x.end()));
+ __x.clear();
+ }
return *this;
}
@@ -776,6 +810,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(map& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
/**
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 809ea540b8a..3f9690fb3e1 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -127,21 +127,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
private:
/// This turns a red-black tree into a [multi]map.
- typedef typename _Alloc::template rebind<value_type>::other
- _Pair_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<value_type>::other _Pair_alloc_type;
typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
key_compare, _Pair_alloc_type> _Rep_type;
/// The actual tree structure.
_Rep_type _M_t;
+ typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
+
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Pair_alloc_type::pointer pointer;
- typedef typename _Pair_alloc_type::const_pointer const_pointer;
- typedef typename _Pair_alloc_type::reference reference;
- typedef typename _Pair_alloc_type::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;
typedef typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
@@ -204,6 +206,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
{ _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ multimap(const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ multimap(const multimap& __m, const allocator_type& __a)
+ : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ multimap(multimap&& __m, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ multimap(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ multimap(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_equal(__first, __last); }
#endif
/**
@@ -270,12 +299,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @a __x is a valid, but unspecified multimap.
*/
multimap&
- operator=(multimap&& __x)
+ operator=(multimap&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x.begin()),
+ std::__make_move_if_noexcept_iterator(__x.end()));
+ __x.clear();
+ }
return *this;
}
@@ -685,6 +719,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(multimap& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
/**
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 8ceb02ac65f..5605801671c 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -108,18 +108,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
private:
/// This turns a red-black tree into a [multi]set.
- typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
/// The actual tree structure.
_Rep_type _M_t;
+ typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;
+
public:
- typedef typename _Key_alloc_type::pointer pointer;
- typedef typename _Key_alloc_type::const_pointer const_pointer;
- typedef typename _Key_alloc_type::reference reference;
- typedef typename _Key_alloc_type::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.
@@ -216,6 +219,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ multiset(const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ multiset(const multiset& __m, const allocator_type& __a)
+ : _M_t(__m._M_t, _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ multiset(multiset&& __m, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__m._M_t), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ multiset(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ multiset(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_equal(__first, __last); }
#endif
/**
@@ -242,12 +272,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* %multiset.
*/
multiset&
- operator=(multiset&& __x)
+ operator=(multiset&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
+ std::__make_move_if_noexcept_iterator(__x._M_t.end()));
+ __x.clear();
+ }
return *this;
}
@@ -388,6 +423,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(multiset& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -747,7 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @return True iff @a __x is lexicographically less than @a __y.
*
* This is a total ordering relation. It is linear in the size of the
- * maps. The elements must be comparable with @c <.
+ * sets. The elements must be comparable with @c <.
*
* See std::lexicographical_compare() for how the determination is made.
*/
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 44eb5897f0e..b405c491e47 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -108,19 +108,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
//@}
private:
- typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
_Rep_type _M_t; // Red-black tree representing set.
+ typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;
+
public:
//@{
/// Iterator-related typedefs.
- typedef typename _Key_alloc_type::pointer pointer;
- typedef typename _Key_alloc_type::const_pointer const_pointer;
- typedef typename _Key_alloc_type::reference reference;
- typedef typename _Key_alloc_type::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.
@@ -220,6 +223,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ set(const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ set(const set& __x, const allocator_type& __a)
+ : _M_t(__x._M_t, _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ set(set&& __x, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__x._M_t), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ set(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ set(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_unique(__first, __last); }
#endif
/**
@@ -245,12 +275,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @a __x is a valid, but unspecified %set.
*/
set&
- operator=(set&& __x)
+ operator=(set&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
+ std::__make_move_if_noexcept_iterator(__x._M_t.end()));
+ __x.clear();
+ }
return *this;
}
@@ -391,6 +426,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(set& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -762,7 +800,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @return True iff @a __x is lexicographically less than @a __y.
*
* This is a total ordering relation. It is linear in the size of the
- * maps. The elements must be comparable with @c <.
+ * sets. The elements must be comparable with @c <.
*
* See std::lexicographical_compare() for how the determination is made.
*/
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 5ed3760633e..778fe2592fa 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -62,8 +62,9 @@
#include <bits/allocator.h>
#include <bits/stl_function.h>
#include <bits/cpp_type_traits.h>
+#include <ext/alloc_traits.h>
#if __cplusplus >= 201103L
-#include <bits/alloc_traits.h>
+#include <ext/aligned_buffer.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
@@ -131,13 +132,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct _Rb_tree_node : public _Rb_tree_node_base
{
typedef _Rb_tree_node<_Val>* _Link_type;
+
+#if __cplusplus < 201103L
_Val _M_value_field;
-#if __cplusplus >= 201103L
- template<typename... _Args>
- _Rb_tree_node(_Args&&... __args)
- : _Rb_tree_node_base(),
- _M_value_field(std::forward<_Args>(__args)...) { }
+ _Val*
+ _M_valptr()
+ { return std::__addressof(_M_value_field); }
+
+ const _Val*
+ _M_valptr() const
+ { return std::__addressof(_M_value_field); }
+#else
+ __gnu_cxx::__aligned_buffer<_Val> _M_storage;
+
+ _Val*
+ _M_valptr()
+ { return _M_storage._M_ptr(); }
+
+ const _Val*
+ _M_valptr() const
+ { return _M_storage._M_ptr(); }
#endif
};
@@ -176,12 +191,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reference
operator*() const _GLIBCXX_NOEXCEPT
- { return static_cast<_Link_type>(_M_node)->_M_value_field; }
+ { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
pointer
operator->() const _GLIBCXX_NOEXCEPT
- { return std::__addressof(static_cast<_Link_type>
- (_M_node)->_M_value_field); }
+ { return static_cast<_Link_type> (_M_node)->_M_valptr(); }
_Self&
operator++() _GLIBCXX_NOEXCEPT
@@ -257,12 +271,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reference
operator*() const _GLIBCXX_NOEXCEPT
- { return static_cast<_Link_type>(_M_node)->_M_value_field; }
+ { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
pointer
operator->() const _GLIBCXX_NOEXCEPT
- { return std::__addressof(static_cast<_Link_type>
- (_M_node)->_M_value_field); }
+ { return static_cast<_Link_type>(_M_node)->_M_valptr(); }
_Self&
operator++() _GLIBCXX_NOEXCEPT
@@ -332,8 +345,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Compare, typename _Alloc = allocator<_Val> >
class _Rb_tree
{
- typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
- _Node_allocator;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
+
+ typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
protected:
typedef _Rb_tree_node_base* _Base_ptr;
@@ -367,11 +382,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
protected:
_Link_type
_M_get_node()
- { return _M_impl._Node_allocator::allocate(1); }
+ { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
void
_M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT
- { _M_impl._Node_allocator::deallocate(__p, 1); }
+ { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
#if __cplusplus < 201103L
_Link_type
@@ -379,8 +394,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_Link_type __tmp = _M_get_node();
__try
- { get_allocator().construct
- (std::__addressof(__tmp->_M_value_field), __x); }
+ { get_allocator().construct(__tmp->_M_valptr(), __x); }
__catch(...)
{
_M_put_node(__tmp);
@@ -392,7 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_destroy_node(_Link_type __p)
{
- get_allocator().destroy(std::__addressof(__p->_M_value_field));
+ get_allocator().destroy(__p->_M_valptr());
_M_put_node(__p);
}
#else
@@ -403,9 +417,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Link_type __tmp = _M_get_node();
__try
{
- allocator_traits<_Node_allocator>::
- construct(_M_get_Node_allocator(), __tmp,
- std::forward<_Args>(__args)...);
+ ::new(__tmp) _Rb_tree_node<_Val>;
+ _Alloc_traits::construct(_M_get_Node_allocator(),
+ __tmp->_M_valptr(),
+ std::forward<_Args>(__args)...);
}
__catch(...)
{
@@ -418,7 +433,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_destroy_node(_Link_type __p) noexcept
{
- _M_get_Node_allocator().destroy(__p);
+ _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
+ __p->~_Rb_tree_node<_Val>();
_M_put_node(__p);
}
#endif
@@ -426,7 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Link_type
_M_clone_node(_Const_Link_type __x)
{
- _Link_type __tmp = _M_create_node(__x->_M_value_field);
+ _Link_type __tmp = _M_create_node(*__x->_M_valptr());
__tmp->_M_color = __x->_M_color;
__tmp->_M_left = 0;
__tmp->_M_right = 0;
@@ -518,7 +534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static const_reference
_S_value(_Const_Link_type __x)
- { return __x->_M_value_field; }
+ { return *__x->_M_valptr(); }
static const _Key&
_S_key(_Const_Link_type __x)
@@ -542,7 +558,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static const_reference
_S_value(_Const_Base_ptr __x)
- { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
+ { return *static_cast<_Const_Link_type>(__x)->_M_valptr(); }
static const _Key&
_S_key(_Const_Base_ptr __x)
@@ -652,7 +668,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_impl(__comp, _Node_allocator(__a)) { }
_Rb_tree(const _Rb_tree& __x)
- : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
+ : _M_impl(__x._M_impl._M_key_compare,
+ _Alloc_traits::_S_select_on_copy(__x._M_get_Node_allocator()))
{
if (__x._M_root() != 0)
{
@@ -664,7 +681,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#if __cplusplus >= 201103L
- _Rb_tree(_Rb_tree&& __x);
+ _Rb_tree(const allocator_type& __a)
+ : _M_impl(_Compare(), _Node_allocator(__a))
+ { }
+
+ _Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
+ : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
+ {
+ 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;
+ }
+ }
+
+ _Rb_tree(_Rb_tree&& __x)
+ : _Rb_tree(std::move(__x), std::move(__x._M_get_Node_allocator()))
+ { }
+
+ _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
+ : _Rb_tree(std::move(__x), _Node_allocator(__a))
+ { }
+
+ _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a);
#endif
~_Rb_tree() _GLIBCXX_NOEXCEPT
@@ -729,10 +770,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_type
max_size() const _GLIBCXX_NOEXCEPT
- { return _M_get_Node_allocator().max_size(); }
+ { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
void
- swap(_Rb_tree& __t);
+#if __cplusplus >= 201103L
+ swap(_Rb_tree& __t) noexcept(_Alloc_traits::_S_nothrow_swap());
+#else
+ swap(_Rb_tree& __t);
+#endif
// Insert/erase.
#if __cplusplus >= 201103L
@@ -899,6 +944,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Debugging.
bool
__rb_verify() const;
+
+#if __cplusplus >= 201103L
+ bool
+ _M_move_assign(_Rb_tree&);
+#endif
};
template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -960,24 +1010,67 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
- _Rb_tree(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __x)
- : _M_impl(__x._M_impl._M_key_compare,
- std::move(__x._M_get_Node_allocator()))
+ _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
+ : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
{
if (__x._M_root() != 0)
{
- _M_root() = __x._M_root();
- _M_leftmost() = __x._M_leftmost();
- _M_rightmost() = __x._M_rightmost();
- _M_root()->_M_parent = _M_end();
+ if (!_Alloc_traits::_S_always_equal()
+ && __x._M_get_Node_allocator() != __a)
+ {
+ _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;
+ }
+ else
+ {
+ _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>
+ bool
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_move_assign(_Rb_tree& __x)
+ {
+ 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() != 0)
+ {
+ _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();
+ __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;
+ this->_M_impl._M_node_count = __x._M_impl._M_node_count;
+ __x._M_impl._M_node_count = 0;
+ }
+ if (_Alloc_traits::_S_propagate_on_move_assign())
+ std::__alloc_on_move(_M_get_Node_allocator(),
+ __x._M_get_Node_allocator());
+ return true;
}
+ return false;
}
#endif
@@ -985,12 +1078,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Compare, typename _Alloc>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
- operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
+ operator=(const _Rb_tree& __x)
{
if (this != &__x)
{
// Note that _Key may be a constant type.
clear();
+#if __cplusplus >= 201103L
+ if (_Alloc_traits::_S_propagate_on_copy_assign())
+ {
+ auto& __this_alloc = this->_M_get_Node_allocator();
+ auto& __that_alloc = __x._M_get_Node_allocator();
+ if (!_Alloc_traits::_S_always_equal()
+ && __this_alloc != __that_alloc)
+ {
+ std::__alloc_on_copy(__this_alloc, __that_alloc);
+ }
+ }
+#endif
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (__x._M_root() != 0)
{
@@ -1260,6 +1365,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{
if (_M_root() == 0)
{
@@ -1298,11 +1406,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// No need to swap header's color as it does not change.
std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 431. Swapping containers with unequal allocators.
- std::__alloc_swap<_Node_allocator>::
- _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
+
+ _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
+ __t._M_get_Node_allocator());
}
template<typename _Key, typename _Val, typename _KeyOfValue,
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 376f39af216..5c8c16151e2 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -332,6 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Move constructor with alternative allocator
vector(vector&& __rv, const allocator_type& __m)
+ noexcept(_Alloc_traits::_S_always_equal())
: _Base(std::move(__rv), __m)
{
if (__rv.get_allocator() != __m)
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index 6d5b29e09d2..a1b99acd217 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -95,7 +95,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Key>,
class _Pred = std::equal_to<_Key>,
class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
- class unordered_map : __check_copy_constructible<_Alloc>
+ class unordered_map
{
typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
@@ -807,7 +807,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Key>,
class _Pred = std::equal_to<_Key>,
class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
- class unordered_multimap : __check_copy_constructible<_Alloc>
+ class unordered_multimap
{
typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index 89deb496f11..22bddecf083 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -90,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Value>,
class _Pred = std::equal_to<_Value>,
class _Alloc = std::allocator<_Value> >
- class unordered_set : __check_copy_constructible<_Alloc>
+ class unordered_set
{
typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
@@ -725,7 +725,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Value>,
class _Pred = std::equal_to<_Value>,
class _Alloc = std::allocator<_Value> >
- class unordered_multiset : __check_copy_constructible<_Alloc>
+ class unordered_multiset
{
typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
new file mode 100644
index 00000000000..000d317c5c5
--- /dev/null
+++ b/libstdc++-v3/include/experimental/string_view
@@ -0,0 +1,705 @@
+// Components for manipulating non-owning sequences of characters -*- C++ -*-
+
+// Copyright (C) 2013 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 experimental/string_view
+ * This is a Standard C++ Library header.
+ */
+
+//
+// N3762 basic_string_view library
+//
+
+#ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW
+#define _GLIBCXX_EXPERIMENTAL_STRING_VIEW 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include <bits/c++14_warning.h>
+#else
+
+#include <debug/debug.h>
+#include <string>
+#include <limits>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @class basic_string_view <string_view>
+ * @brief A non-owning reference to a string.
+ *
+ * @ingroup strings
+ * @ingroup sequences
+ *
+ * @tparam _CharT Type of character
+ * @tparam _Traits Traits for character type, defaults to
+ * char_traits<_CharT>.
+ *
+ * A basic_string_view looks like this:
+ *
+ * @code
+ * _CharT* _M_str
+ * size_t _M_len
+ * @endcode
+ *
+ * A basic_string_view represents an empty string with a static constexpr
+ * length one string:
+ *
+ * @code
+ * static constexpr value_type _S_empty_str[1]{0};
+ * @endcode
+ */
+ template<typename _CharT, typename _Traits = char_traits<_CharT>>
+ class basic_string_view
+ {
+
+ public:
+
+ // types
+ using traits_type = _Traits;
+ using value_type = _CharT;
+ using pointer = const _CharT*;
+ using const_pointer = const _CharT*;
+ using reference = const _CharT&;
+ using const_reference = const _CharT&;
+ using const_iterator = const _CharT*;
+ using iterator = const_iterator;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ using reverse_iterator = const_reverse_iterator;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ static constexpr size_type npos = size_type(-1);
+
+ // [string.view.cons], construct/copy
+
+ constexpr
+ basic_string_view() noexcept
+ : _M_len{0}, _M_str{_S_empty_str}
+ { }
+
+ constexpr basic_string_view(const basic_string_view&) noexcept = default;
+
+ template<typename _Allocator>
+ basic_string_view(const basic_string<_CharT, _Traits,
+ _Allocator>& __str) noexcept
+ : _M_len{__str.length()}, _M_str{__str.data()}
+ { }
+
+ constexpr basic_string_view(const _CharT* __str)
+ : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
+ _M_str{__str == nullptr ? _S_empty_str : __str}
+ { }
+
+ constexpr basic_string_view(const _CharT* __str, size_type __len)
+ : _M_len{__str == nullptr ? 0 :__len},
+ _M_str{__str == nullptr || __len == 0 ? _S_empty_str : __str}
+ { }
+
+ basic_string_view&
+ operator=(const basic_string_view&) noexcept = default;
+
+ // [string.view.iterators], iterators
+
+ constexpr const_iterator
+ begin() const noexcept
+ { return this->_M_str; }
+
+ constexpr const_iterator
+ end() const noexcept
+ { return this->_M_str + this->_M_len; }
+
+ constexpr const_iterator
+ cbegin() const noexcept
+ { return this->_M_str; }
+
+ constexpr const_iterator
+ cend() const noexcept
+ { return this->_M_str + this->_M_len; }
+
+ const_reverse_iterator
+ rbegin() const noexcept
+ { return std::reverse_iterator<const_iterator>(this->end()); }
+
+ const_reverse_iterator
+ rend() const noexcept
+ { return std::reverse_iterator<const_iterator>(this->begin()); }
+
+ const_reverse_iterator
+ crbegin() const noexcept
+ { return std::reverse_iterator<const_iterator>(this->end()); }
+
+ const_reverse_iterator
+ crend() const noexcept
+ { return std::reverse_iterator<const_iterator>(this->begin()); }
+
+ // [string.view.capacity], capacity
+
+ constexpr size_type
+ size() const noexcept
+ { return this->_M_len; }
+
+ constexpr size_type
+ length() const noexcept
+ { return _M_len; }
+
+ constexpr size_type
+ max_size() const noexcept
+ { return ((npos - sizeof(size_type) - sizeof(void*))
+ / sizeof(value_type) / 4); }
+
+ constexpr bool
+ empty() const noexcept
+ { return this->_M_len == 0; }
+
+ // [string.view.access], element access
+
+ constexpr const _CharT&
+ operator[](size_type __pos) const
+ {
+ _GLIBCXX_DEBUG_ASSERT(__pos <= this->_M_len);
+ return *(this->_M_str + __pos);
+ }
+
+ constexpr const _CharT&
+ at(size_type __pos) const
+ {
+ return __pos < this->_M_len
+ ? *(this->_M_str + __pos)
+ : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
+ "(which is %zu) >= this->size() "
+ "(which is %zu)"),
+ __pos, this->size()),
+ _S_empty_str[0]);
+ }
+
+ constexpr const _CharT&
+ front() const
+ {
+ _GLIBCXX_DEBUG_ASSERT(this->_M_len > 0);
+ return *this->_M_str;
+ }
+
+ constexpr const _CharT&
+ back() const
+ {
+ _GLIBCXX_DEBUG_ASSERT(this->_M_len > 0);
+ return *(this->_M_str + this->_M_len - 1);
+ }
+
+ constexpr const _CharT*
+ data() const noexcept
+ { return this->_M_str; }
+
+ // [string.view.modifiers], modifiers:
+ void
+ clear() noexcept
+ {
+ this->_M_len = 0;
+ this->_M_str = _S_empty_str;
+ }
+
+ void
+ remove_prefix(size_type __n)
+ {
+ _GLIBCXX_DEBUG_ASSERT(this->_M_len >= __n);
+ this->_M_str += __n;
+ this->_M_len -= __n;
+ }
+
+ void
+ remove_suffix(size_type __n)
+ { this->_M_len -= __n; }
+
+ void
+ swap(basic_string_view& __sv) noexcept
+ {
+ std::swap(this->_M_len, __sv._M_len);
+ std::swap(this->_M_str, __sv._M_str);
+ }
+
+
+ // [string.view.ops], string operations:
+
+ template<typename _Allocator>
+ explicit operator basic_string<_CharT, _Traits, _Allocator>() const
+ {
+ return basic_string<_CharT, _Traits, _Allocator>
+ (this->_M_len, this->_M_str);
+ }
+
+ size_type
+ copy(_CharT* __str, size_type __n, size_type __pos = 0) const
+ {
+ __glibcxx_requires_string_len(__str, __n);
+ if (__pos >= this->_M_len)
+ __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
+ "(which is %zu) >= this->size() "
+ "(which is %zu)"),
+ __pos, this->size());
+ size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})};
+ for (auto __begin = this->_M_str + __pos,
+ __end = this->_M_str + __rlen; __begin != __end;)
+ *__str++ = *__begin++;
+ return __rlen;
+ }
+
+
+ // [string.view.ops], string operations:
+
+ constexpr basic_string_view
+ substr(size_type __pos, size_type __n=npos) const
+ {
+ return __pos < this->_M_len
+ ? basic_string_view{this->_M_str + __pos,
+ std::min(__n, size_type{this->_M_len - __pos})}
+ : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
+ "(which is %zu) >= this->size() "
+ "(which is %zu)"),
+ __pos, this->size()), basic_string_view{});
+ }
+
+ int
+ compare(basic_string_view __str) const noexcept
+ {
+ int __ret = traits_type::compare(this->_M_str, __str._M_str,
+ std::min(this->_M_len, __str._M_len));
+ if (__ret == 0)
+ __ret = _S_compare(this->_M_len, __str._M_len);
+ return __ret;
+ }
+
+ int
+ compare(size_type __pos1, size_type __n1, basic_string_view __str) const
+ { return this->substr(__pos1, __n1).compare(__str); }
+
+ int
+ compare(size_type __pos1, size_type __n1,
+ basic_string_view __str, size_type __pos2, size_type __n2) const
+ { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); }
+
+ int
+ compare(const _CharT* __str) const noexcept
+ { return this->compare(basic_string_view{__str}); }
+
+ int
+ compare(size_type __pos1, size_type __n1, const _CharT* __str) const
+ { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
+
+ int
+ compare(size_type __pos1, size_type __n1,
+ const _CharT* __str, size_type __n2) const
+ {
+ return this->substr(__pos1, __n1)
+ .compare(basic_string_view(__str, __n2));
+ }
+
+ size_type
+ find(basic_string_view __str, size_type __pos = 0) const noexcept
+ { return this->find(__str._M_str, __pos, __str._M_len); }
+
+ size_type
+ find(_CharT __c, size_type __pos=0) const noexcept;
+
+ size_type
+ find(const _CharT* __str, size_type __pos, size_type __n) const;
+
+ size_type
+ find(const _CharT* __str, size_type __pos=0) const noexcept
+ { return this->find(__str, __pos, traits_type::length(__str)); }
+
+ size_type
+ rfind(basic_string_view __str, size_type __pos = npos) const noexcept
+ { return this->rfind(__str._M_str, __pos, __str._M_len); }
+
+ size_type
+ rfind(_CharT __c, size_type __pos = npos) const noexcept;
+
+ size_type
+ rfind(const _CharT* __str, size_type __pos, size_type __n) const;
+
+ size_type
+ rfind(const _CharT* __str, size_type __pos = npos) const noexcept
+ { return this->rfind(__str, __pos, traits_type::length(__str)); }
+
+ size_type
+ find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
+ { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
+
+ size_type
+ find_first_of(_CharT __c, size_type __pos = 0) const noexcept
+ { return this->find(__c, __pos); }
+
+ size_type
+ find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
+
+ size_type
+ find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
+ { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
+
+ size_type
+ find_last_of(basic_string_view __str,
+ size_type __pos = npos) const noexcept
+ { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
+
+ size_type
+ find_last_of(_CharT __c, size_type __pos=npos) const noexcept
+ { return this->rfind(__c, __pos); }
+
+ size_type
+ find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
+
+ size_type
+ find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
+ { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
+
+ size_type
+ find_first_not_of(basic_string_view __str,
+ size_type __pos = 0) const noexcept
+ { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
+
+ size_type
+ find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
+
+ size_type
+ find_first_not_of(const _CharT* __str,
+ size_type __pos, size_type __n) const;
+
+ size_type
+ find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
+ {
+ return this->find_first_not_of(__str, __pos,
+ traits_type::length(__str));
+ }
+
+ size_type
+ find_last_not_of(basic_string_view __str,
+ size_type __pos = npos) const noexcept
+ { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
+
+ size_type
+ find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
+
+ size_type
+ find_last_not_of(const _CharT* __str,
+ size_type __pos, size_type __n) const;
+
+ size_type
+ find_last_not_of(const _CharT* __str,
+ size_type __pos = npos) const noexcept
+ {
+ return this->find_last_not_of(__str, __pos,
+ traits_type::length(__str));
+ }
+
+ private:
+
+ static constexpr const int
+ _S_compare(size_type __n1, size_type __n2) noexcept
+ {
+ return difference_type{__n1 - __n2} > std::numeric_limits<int>::max()
+ ? std::numeric_limits<int>::max()
+ : difference_type{__n1 - __n2} < std::numeric_limits<int>::min()
+ ? std::numeric_limits<int>::min()
+ : static_cast<int>(difference_type{__n1 - __n2});
+ }
+
+ static constexpr value_type _S_empty_str[1]{};
+
+ size_t _M_len;
+ const _CharT* _M_str;
+ };
+
+
+ // [string.view.comparison], non-member basic_string_view comparison functions
+
+ namespace __detail
+ {
+ // Identity transform to make ADL work with just one argument.
+ // See n3766.html.
+ template<typename _Tp = void>
+ struct __identity
+ { typedef _Tp type; };
+
+ template<>
+ struct __identity<void>;
+
+ template<typename _Tp>
+ using __idt = typename __identity<_Tp>::type;
+ }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator==(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) == 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator==(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) == 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) == 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator!=(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return !(__x == __y); }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator!=(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return !(__x == __y); }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return !(__x == __y); }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator< (basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) < 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator< (basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) < 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) < 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator> (basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) > 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator> (basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) > 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) > 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator<=(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) <= 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator<=(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) <= 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) <= 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator>=(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) >= 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator>=(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) >= 0; }
+
+ template<typename _CharT, typename _Traits>
+ bool
+ operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) >= 0; }
+
+ // [string.view.comparison], sufficient additional overloads of comparison functions
+
+ // [string.view.nonmem], other non-member basic_string_view functions
+ template<typename _CharT, typename _Traits = char_traits<_CharT>,
+ typename _Allocator = allocator<_CharT>>
+ basic_string<_CharT, _Traits, _Allocator>
+ to_string(basic_string_view<_CharT, _Traits> __str,
+ const _Allocator& __alloc = _Allocator())
+ {
+ return basic_string<_CharT, _Traits, _Allocator>
+ (__str.begin(), __str.end(), __alloc);
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __os,
+ basic_string_view<_CharT,_Traits> __str)
+ { return __ostream_insert(__os, __str.data(), __str.size()); }
+
+
+ // basic_string_view typedef names
+
+ using string_view = basic_string_view<char>;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ using wstring_view = basic_string_view<wchar_t>;
+#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ using u16string_view = basic_string_view<char16_t>;
+ using u32string_view = basic_string_view<char32_t>;
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace experimental
+
+
+ // [string.view.hash], hash support:
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ template<typename _Tp>
+ struct hash;
+
+ template<>
+ struct hash<experimental::string_view>
+ : public __hash_base<size_t, experimental::string_view>
+ {
+ size_t
+ operator()(const experimental::string_view& __str) const noexcept
+ { return std::_Hash_impl::hash(__str.data(), __str.length()); }
+ };
+
+ template<>
+ struct __is_fast_hash<hash<experimental::string_view>> : std::false_type
+ { };
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ template<>
+ struct hash<experimental::wstring_view>
+ : public __hash_base<size_t, wstring>
+ {
+ size_t
+ operator()(const experimental::wstring_view& __s) const noexcept
+ { return std::_Hash_impl::hash(__s.data(),
+ __s.length() * sizeof(wchar_t)); }
+ };
+
+ template<>
+ struct __is_fast_hash<hash<experimental::wstring_view>> : std::false_type
+ { };
+#endif
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ template<>
+ struct hash<experimental::u16string_view>
+ : public __hash_base<size_t, experimental::u16string_view>
+ {
+ size_t
+ operator()(const experimental::u16string_view& __s) const noexcept
+ { return std::_Hash_impl::hash(__s.data(),
+ __s.length() * sizeof(char16_t)); }
+ };
+
+ template<>
+ struct __is_fast_hash<hash<experimental::u16string_view>> : std::false_type
+ { };
+
+ template<>
+ struct hash<experimental::u32string_view>
+ : public __hash_base<size_t, experimental::u32string_view>
+ {
+ size_t
+ operator()(const experimental::u32string_view& __s) const noexcept
+ { return std::_Hash_impl::hash(__s.data(),
+ __s.length() * sizeof(char32_t)); }
+ };
+
+ template<>
+ struct __is_fast_hash<hash<experimental::u32string_view>> : std::false_type
+ { };
+#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+
+namespace experimental
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ // I added these EMSR.
+ inline namespace literals
+ {
+ inline namespace string_view_literals
+ {
+
+ inline basic_string_view<char>
+ operator""sv(const char* __str, size_t __len)
+ { return basic_string_view<char>{__str, __len}; }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ inline basic_string_view<wchar_t>
+ operator""sv(const wchar_t* __str, size_t __len)
+ { return basic_string_view<wchar_t>{__str, __len}; }
+#endif
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ inline basic_string_view<char16_t>
+ operator""sv(const char16_t* __str, size_t __len)
+ { return basic_string_view<char16_t>{__str, __len}; }
+
+ inline basic_string_view<char32_t>
+ operator""sv(const char32_t* __str, size_t __len)
+ { return basic_string_view<char32_t>{__str, __len}; }
+#endif
+
+ }
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace experimental
+} // namespace std
+
+#include <experimental/string_view.tcc>
+
+#endif // __cplusplus <= 201103L
+
+#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
diff --git a/libstdc++-v3/include/experimental/string_view.tcc b/libstdc++-v3/include/experimental/string_view.tcc
new file mode 100644
index 00000000000..eeccb026344
--- /dev/null
+++ b/libstdc++-v3/include/experimental/string_view.tcc
@@ -0,0 +1,234 @@
+// Components for manipulating non-owning sequences of characters -*- C++ -*-
+
+// Copyright (C) 2013 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 experimental/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_EXPERIMENTAL_STRING_VIEW_TCC
+#define _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include <bits/c++14_warning.h>
+#else
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ template<typename _CharT, typename _Traits>
+ constexpr _CharT
+ basic_string_view<_CharT, _Traits>::_S_empty_str[1];
+
+ 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 experimental
+} // namespace std
+
+#endif // __cplusplus <= 201103L
+
+#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC
diff --git a/libstdc++-v3/include/ext/cast.h b/libstdc++-v3/include/ext/cast.h
index 961a962558c..fb220f39f70 100644
--- a/libstdc++-v3/include/ext/cast.h
+++ b/libstdc++-v3/include/ext/cast.h
@@ -38,7 +38,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* These functions are here to allow containers to support non standard
* pointer types. For normal pointers, these resolve to the use of the
* standard cast operation. For other types the functions will perform
- * the apprpriate cast to/from the custom pointer class so long as that
+ * the appropriate cast to/from the custom pointer class so long as that
* class meets the following conditions:
* 1) has a typedef element_type which names tehe type it points to.
* 2) has a get() const method which returns element_type*.
diff --git a/libstdc++-v3/include/ext/pod_char_traits.h b/libstdc++-v3/include/ext/pod_char_traits.h
index dcd86ff9842..8e3ad9884d9 100644
--- a/libstdc++-v3/include/ext/pod_char_traits.h
+++ b/libstdc++-v3/include/ext/pod_char_traits.h
@@ -45,13 +45,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// int_type to properly hold the full range of char_type values as
// well as EOF.
/// @brief A POD class that serves as a character abstraction class.
- template<typename V, typename I, typename S = std::mbstate_t>
+ template<typename _Value, typename _Int, typename _St = std::mbstate_t>
struct character
{
- typedef V value_type;
- typedef I int_type;
- typedef S state_type;
- typedef character<V, I, S> char_type;
+ typedef _Value value_type;
+ typedef _Int int_type;
+ typedef _St state_type;
+ typedef character<_Value, _Int, _St> char_type;
value_type value;
@@ -73,14 +73,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
- template<typename V, typename I, typename S>
+ template<typename _Value, typename _Int, typename _St>
inline bool
- operator==(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
+ operator==(const character<_Value, _Int, _St>& lhs,
+ const character<_Value, _Int, _St>& rhs)
{ return lhs.value == rhs.value; }
- template<typename V, typename I, typename S>
+ template<typename _Value, typename _Int, typename _St>
inline bool
- operator<(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
+ operator<(const character<_Value, _Int, _St>& lhs,
+ const character<_Value, _Int, _St>& rhs)
{ return lhs.value < rhs.value; }
_GLIBCXX_END_NAMESPACE_VERSION
@@ -91,14 +93,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// char_traits<__gnu_cxx::character> specialization.
- template<typename V, typename I, typename S>
- struct char_traits<__gnu_cxx::character<V, I, S> >
+ template<typename _Value, typename _Int, typename _St>
+ struct char_traits<__gnu_cxx::character<_Value, _Int, _St> >
{
- typedef __gnu_cxx::character<V, I, S> char_type;
- typedef typename char_type::int_type int_type;
- typedef typename char_type::state_type state_type;
- typedef fpos<state_type> pos_type;
- typedef streamoff off_type;
+ typedef __gnu_cxx::character<_Value, _Int, _St> char_type;
+ typedef typename char_type::int_type int_type;
+ typedef typename char_type::state_type state_type;
+ typedef fpos<state_type> pos_type;
+ typedef streamoff off_type;
static void
assign(char_type& __c1, const char_type& __c2)
diff --git a/libstdc++-v3/include/ext/pointer.h b/libstdc++-v3/include/ext/pointer.h
index 12bc749c063..d1730be07f2 100644
--- a/libstdc++-v3/include/ext/pointer.h
+++ b/libstdc++-v3/include/ext/pointer.h
@@ -580,7 +580,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up>
using rebind = typename __gnu_cxx::_Pointer_adapter<
- typename pointer_traits<_Storage_policy>::rebind<_Up>>;
+ typename pointer_traits<_Storage_policy>::template rebind<_Up>>;
static pointer pointer_to(typename pointer::reference __r) noexcept
{ return pointer(std::addressof(__r)); }
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index 347ebed449c..c82430e0746 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -2845,6 +2845,267 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
{ return !(__d1 == __d2); }
+
+ /**
+ * @brief A discrete hypergeometric random number distribution.
+ *
+ * The hypergeometric distribution is a discrete probability distribution
+ * that describes the probability of @p k successes in @p n draws @a without
+ * replacement from a finite population of size @p N containing exactly @p K
+ * successes.
+ *
+ * The formula for the hypergeometric probability density function is
+ * @f[
+ * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}}
+ * @f]
+ * where @f$N@f$ is the total population of the distribution,
+ * @f$K@f$ is the total population of the distribution.
+ *
+ * <table border=1 cellpadding=10 cellspacing=0>
+ * <caption align=top>Distribution Statistics</caption>
+ * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr>
+ * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}
+ * @f$</td></tr>
+ * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr>
+ * </table>
+ */
+ template<typename _UIntType = unsigned int>
+ class hypergeometric_distribution
+ {
+ static_assert(std::is_unsigned<_UIntType>::value, "template argument "
+ "substituting _UIntType not an unsigned integral type");
+
+ public:
+ /** The type of the range of the distribution. */
+ typedef _UIntType result_type;
+
+ /** Parameter type. */
+ struct param_type
+ {
+ typedef hypergeometric_distribution<_UIntType> distribution_type;
+ friend class hypergeometric_distribution<_UIntType>;
+
+ explicit
+ param_type(result_type __N = 10, result_type __K = 5,
+ result_type __n = 1)
+ : _M_N{__N}, _M_K{__K}, _M_n{__n}
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_N >= _M_K);
+ _GLIBCXX_DEBUG_ASSERT(_M_N >= _M_n);
+ }
+
+ result_type
+ total_size() const
+ { return _M_N; }
+
+ result_type
+ successful_size() const
+ { return _M_K; }
+
+ result_type
+ unsuccessful_size() const
+ { return _M_N - _M_K; }
+
+ result_type
+ total_draws() const
+ { return _M_n; }
+
+ friend bool
+ operator==(const param_type& __p1, const param_type& __p2)
+ { return (__p1._M_N == __p2._M_N)
+ && (__p1._M_K == __p2._M_K)
+ && (__p1._M_n == __p2._M_n); }
+
+ private:
+
+ result_type _M_N;
+ result_type _M_K;
+ result_type _M_n;
+ };
+
+ // constructors and member function
+ explicit
+ hypergeometric_distribution(result_type __N = 10, result_type __K = 5,
+ result_type __n = 1)
+ : _M_param{__N, __K, __n}
+ { }
+
+ explicit
+ hypergeometric_distribution(const param_type& __p)
+ : _M_param{__p}
+ { }
+
+ /**
+ * @brief Resets the distribution state.
+ */
+ void
+ reset()
+ { }
+
+ /**
+ * @brief Returns the distribution parameter @p N,
+ * the total number of items.
+ */
+ result_type
+ total_size() const
+ { return this->_M_param.total_size(); }
+
+ /**
+ * @brief Returns the distribution parameter @p K,
+ * the total number of successful items.
+ */
+ result_type
+ successful_size() const
+ { return this->_M_param.successful_size(); }
+
+ /**
+ * @brief Returns the total number of unsuccessful items @f$ N - K @f$.
+ */
+ result_type
+ unsuccessful_size() const
+ { return this->_M_param.unsuccessful_size(); }
+
+ /**
+ * @brief Returns the distribution parameter @p n,
+ * the total number of draws.
+ */
+ result_type
+ total_draws() const
+ { return this->_M_param.total_draws(); }
+
+ /**
+ * @brief Returns the parameter set of the distribution.
+ */
+ param_type
+ param() const
+ { return this->_M_param; }
+
+ /**
+ * @brief Sets the parameter set of the distribution.
+ * @param __param The new parameter set of the distribution.
+ */
+ void
+ param(const param_type& __param)
+ { this->_M_param = __param; }
+
+ /**
+ * @brief Returns the greatest lower bound value of the distribution.
+ */
+ result_type
+ min() const
+ {
+ using _IntType = typename std::make_signed<result_type>::type;
+ return static_cast<result_type>(std::max(static_cast<_IntType>(0),
+ static_cast<_IntType>(this->total_draws()
+ - this->unsuccessful_size())));
+ }
+
+ /**
+ * @brief Returns the least upper bound value of the distribution.
+ */
+ result_type
+ max() const
+ { return std::min(this->successful_size(), this->total_draws()); }
+
+ /**
+ * @brief Generating functions.
+ */
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ { return this->operator()(__urng, this->_M_param); }
+
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng)
+ { this->__generate(__f, __t, __urng, this->_M_param); }
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ template<typename _UniformRandomNumberGenerator>
+ void
+ __generate(result_type* __f, result_type* __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ /**
+ * @brief Return true if two hypergeometric distributions have the same
+ * parameters and the sequences that would be generated
+ * are equal.
+ */
+ friend bool
+ operator==(const hypergeometric_distribution& __d1,
+ const hypergeometric_distribution& __d2)
+ { return __d1._M_param == __d2._M_param; }
+
+ /**
+ * @brief Inserts a %hypergeometric_distribution random number
+ * distribution @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %hypergeometric_distribution random number
+ * distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _UIntType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
+ __x);
+
+ /**
+ * @brief Extracts a %hypergeometric_distribution random number
+ * distribution @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %hypergeometric_distribution random number generator
+ * distribution.
+ *
+ * @returns The input stream with @p __x extracted or in an error
+ * state.
+ */
+ template<typename _UIntType1, typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x);
+
+ private:
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ param_type _M_param;
+ };
+
+ /**
+ * @brief Return true if two hypergeometric distributions are different.
+ */
+ template<typename _UIntType>
+ inline bool
+ operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
+ const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
+ { return !(__d1 == __d2); }
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index 009e0effba8..7d68958c093 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -32,7 +32,6 @@
#pragma GCC system_header
-
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -1307,6 +1306,113 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __is;
}
+
+ template<typename _UIntType>
+ template<typename _UniformRandomNumberGenerator>
+ typename hypergeometric_distribution<_UIntType>::result_type
+ hypergeometric_distribution<_UIntType>::
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __param)
+ {
+ std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
+ __aurng(__urng);
+
+ result_type __a = __param.successful_size();
+ result_type __b = __param.total_size();
+ result_type __k = 0;
+
+ if (__param.total_draws() < __param.total_size() / 2)
+ {
+ for (result_type __i = 0; __i < __param.total_draws(); ++__i)
+ {
+ if (__b * __aurng() < __a)
+ {
+ ++__k;
+ if (__k == __param.successful_size())
+ return __k;
+ --__a;
+ }
+ --__b;
+ }
+ return __k;
+ }
+ else
+ {
+ for (result_type __i = 0; __i < __param.unsuccessful_size(); ++__i)
+ {
+ if (__b * __aurng() < __a)
+ {
+ ++__k;
+ if (__k == __param.successful_size())
+ return __param.successful_size() - __k;
+ --__a;
+ }
+ --__b;
+ }
+ return __param.successful_size() - __k;
+ }
+ }
+
+ template<typename _UIntType>
+ template<typename _OutputIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ hypergeometric_distribution<_UIntType>::
+ __generate_impl(_OutputIterator __f, _OutputIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __param)
+ {
+ __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator>)
+
+ while (__f != __t)
+ *__f++ = this->operator()(__urng);
+ }
+
+ template<typename _UIntType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const __gnu_cxx::hypergeometric_distribution<_UIntType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(std::numeric_limits<_UIntType>::max_digits10);
+
+ __os << __x.total_size() << __space << __x.successful_size() << __space
+ << __x.total_draws();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _UIntType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ __gnu_cxx::hypergeometric_distribution<_UIntType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ _UIntType __total_size, __successful_size, __total_draws;
+ __is >> __total_size >> __successful_size >> __total_draws;
+ __x.param(typename __gnu_cxx::hypergeometric_distribution<_UIntType>::
+ param_type(__total_size, __successful_size, __total_draws));
+
+ __is.flags(__flags);
+ return __is;
+ }
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index 6d6b32b1f4d..b37578600d9 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -298,7 +298,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Base class for state between a promise and one or more
/// associated futures.
- class _State_base
+ class _State_baseV2
{
typedef _Ptr<_Result_base> _Ptr_type;
@@ -309,15 +309,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
once_flag _M_once;
public:
- _State_base() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
- _State_base(const _State_base&) = delete;
- _State_base& operator=(const _State_base&) = delete;
- virtual ~_State_base();
+ _State_baseV2() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT)
+ { }
+ _State_baseV2(const _State_baseV2&) = delete;
+ _State_baseV2& operator=(const _State_baseV2&) = delete;
+ virtual ~_State_baseV2() = default;
_Result_base&
wait()
{
- _M_run_deferred();
+ _M_complete_async();
unique_lock<mutex> __lock(_M_mutex);
_M_cond.wait(__lock, [&] { return _M_ready(); });
return *_M_result;
@@ -328,8 +329,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
wait_for(const chrono::duration<_Rep, _Period>& __rel)
{
unique_lock<mutex> __lock(_M_mutex);
- if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
+ if (_M_ready())
return future_status::ready;
+ if (_M_has_deferred())
+ return future_status::deferred;
+ if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2100. timed waiting functions must also join
+ _M_complete_async();
+ return future_status::ready;
+ }
return future_status::timeout;
}
@@ -338,8 +348,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
{
unique_lock<mutex> __lock(_M_mutex);
- if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
+ if (_M_ready())
return future_status::ready;
+ if (_M_has_deferred())
+ return future_status::deferred;
+ if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2100. timed waiting functions must also join
+ _M_complete_async();
+ return future_status::ready;
+ }
return future_status::timeout;
}
@@ -349,7 +368,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool __set = __ignore_failure;
// all calls to this function are serialized,
// side-effects of invoking __res only happen once
- call_once(_M_once, &_State_base::_M_do_set, this, ref(__res),
+ call_once(_M_once, &_State_baseV2::_M_do_set, this, ref(__res),
ref(__set));
if (!__set)
__throw_future_error(int(future_errc::promise_already_satisfied));
@@ -393,7 +412,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename promise<_Res>::_Ptr_type operator()()
{
- _State_base::_S_check(_M_promise->_M_future);
+ _State_baseV2::_S_check(_M_promise->_M_future);
_M_promise->_M_storage->_M_set(_M_arg);
return std::move(_M_promise->_M_storage);
}
@@ -407,7 +426,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typename promise<_Res>::_Ptr_type operator()()
{
- _State_base::_S_check(_M_promise->_M_future);
+ _State_baseV2::_S_check(_M_promise->_M_future);
_M_promise->_M_storage->_M_set(std::move(_M_arg));
return std::move(_M_promise->_M_storage);
}
@@ -423,7 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typename promise<_Res>::_Ptr_type operator()()
{
- _State_base::_S_check(_M_promise->_M_future);
+ _State_baseV2::_S_check(_M_promise->_M_future);
_M_promise->_M_storage->_M_error = _M_ex;
return std::move(_M_promise->_M_storage);
}
@@ -472,15 +491,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool _M_ready() const noexcept { return static_cast<bool>(_M_result); }
- // Misnamed: waits for completion of async function.
- virtual void _M_run_deferred() { }
+ // Wait for completion of async function.
+ virtual void _M_complete_async() { }
+
+ // Return true if state contains a deferred function.
+ virtual bool _M_has_deferred() const { return false; }
};
+#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
+ class _State_base;
+ class _Async_state_common;
+#else
+ using _State_base = _State_baseV2;
+ class _Async_state_commonV2;
+#endif
+
template<typename _BoundFn, typename = typename _BoundFn::result_type>
class _Deferred_state;
- class _Async_state_common;
-
template<typename _BoundFn, typename = typename _BoundFn::result_type>
class _Async_state_impl;
@@ -538,6 +566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void _M_destroy() { delete this; }
};
+#ifndef _GLIBCXX_ASYNC_ABI_COMPAT
/// Common implementation for future and shared_future.
template<typename _Res>
@@ -1439,26 +1468,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ptr_type _M_result;
_BoundFn _M_fn;
+ // Run the deferred function.
virtual void
- _M_run_deferred()
+ _M_complete_async()
{
// safe to call multiple times so ignore failure
_M_set_result(_S_task_setter(_M_result, _M_fn), true);
}
+
+ virtual bool
+ _M_has_deferred() const { return static_cast<bool>(_M_result); }
};
- class __future_base::_Async_state_common : public __future_base::_State_base
+ class __future_base::_Async_state_commonV2
+ : public __future_base::_State_base
{
protected:
-#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
- ~_Async_state_common();
-#else
- ~_Async_state_common() = default;
-#endif
+ ~_Async_state_commonV2() = default;
- // Allow non-timed waiting functions to block until the thread completes,
- // as if joined.
- virtual void _M_run_deferred() { _M_join(); }
+ // Make waiting functions block until the thread completes, as if joined.
+ virtual void _M_complete_async() { _M_join(); }
void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); }
@@ -1468,7 +1497,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _BoundFn, typename _Res>
class __future_base::_Async_state_impl final
- : public __future_base::_Async_state_common
+ : public __future_base::_Async_state_commonV2
{
public:
explicit
@@ -1536,6 +1565,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::forward<_Args>(__args)...);
}
+#endif // _GLIBCXX_ASYNC_ABI_COMPAT
#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
// && ATOMIC_INT_LOCK_FREE