diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-22 14:58:36 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-22 14:58:36 +0000 |
commit | cfea6514a4b6ced0930593ebb48d0037e9716d87 (patch) | |
tree | eeccf866e18463f7dc7ea882ea944247d4ed1010 /libstdc++-v3/include | |
parent | 9456798d72d0e81a2a553287f436dcb05cff175a (diff) | |
download | gcc-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')
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 |