summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-11-05 17:19:35 +0000
committerRichard Sandiford <richard.sandiford@linaro.org>2017-11-05 17:19:35 +0000
commit648f8fc59b2cc39abd24f4c22388b346cdebcc31 (patch)
tree3a07eccc4c22b265261edd75c9ec3910d9c626f5 /libstdc++-v3/include
parent7bef5b82e4109778a0988d20e19e1ed29dadd835 (diff)
parent8c089b5c15a7b35644750ca393f1e66071ad9aa9 (diff)
downloadgcc-648f8fc59b2cc39abd24f4c22388b346cdebcc31.tar.gz
Merge trunk into sve
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/Makefile.am9
-rw-r--r--libstdc++-v3/include/Makefile.in9
-rw-r--r--libstdc++-v3/include/bits/fs_dir.h525
-rw-r--r--libstdc++-v3/include/bits/fs_fwd.h348
-rw-r--r--libstdc++-v3/include/bits/fs_ops.h311
-rw-r--r--libstdc++-v3/include/bits/fs_path.h1166
-rw-r--r--libstdc++-v3/include/bits/hashtable_policy.h4
-rw-r--r--libstdc++-v3/include/bits/node_handle.h21
-rw-r--r--libstdc++-v3/include/bits/specfun.h2
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h4
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h6
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h2
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h21
-rw-r--r--libstdc++-v3/include/bits/stl_map.h51
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h49
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h38
-rw-r--r--libstdc++-v3/include/bits/stl_set.h35
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h14
-rw-r--r--libstdc++-v3/include/bits/string_view.tcc12
-rw-r--r--libstdc++-v3/include/bits/unordered_map.h174
-rw-r--r--libstdc++-v3/include/bits/unordered_set.h133
-rw-r--r--libstdc++-v3/include/c_compatibility/math.h4
-rw-r--r--libstdc++-v3/include/c_global/cstddef4
-rw-r--r--libstdc++-v3/include/debug/array8
-rw-r--r--libstdc++-v3/include/debug/deque10
-rw-r--r--libstdc++-v3/include/debug/forward_list10
-rw-r--r--libstdc++-v3/include/debug/list10
-rw-r--r--libstdc++-v3/include/debug/map.h33
-rw-r--r--libstdc++-v3/include/debug/multimap.h33
-rw-r--r--libstdc++-v3/include/debug/multiset.h37
-rw-r--r--libstdc++-v3/include/debug/set.h36
-rw-r--r--libstdc++-v3/include/debug/unordered_map152
-rw-r--r--libstdc++-v3/include/debug/unordered_set132
-rw-r--r--libstdc++-v3/include/debug/vector10
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_dir.h4
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_fwd.h4
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_ops.h4
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_path.h8
-rw-r--r--libstdc++-v3/include/experimental/filesystem30
-rw-r--r--libstdc++-v3/include/experimental/string_view8
-rw-r--r--libstdc++-v3/include/precompiled/stdc++.h3
-rw-r--r--libstdc++-v3/include/std/array12
-rw-r--r--libstdc++-v3/include/std/chrono4
-rw-r--r--libstdc++-v3/include/std/filesystem45
-rw-r--r--libstdc++-v3/include/std/fstream162
-rw-r--r--libstdc++-v3/include/std/mutex6
-rw-r--r--libstdc++-v3/include/std/string_view95
-rw-r--r--libstdc++-v3/include/std/tuple16
-rw-r--r--libstdc++-v3/include/std/type_traits14
-rw-r--r--libstdc++-v3/include/std/unordered_map3
-rw-r--r--libstdc++-v3/include/std/unordered_set3
-rw-r--r--libstdc++-v3/include/std/utility25
52 files changed, 3670 insertions, 189 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 236c2d6059f..add2277df80 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -37,6 +37,7 @@ std_headers = \
${std_srcdir}/complex \
${std_srcdir}/condition_variable \
${std_srcdir}/deque \
+ ${std_srcdir}/filesystem \
${std_srcdir}/forward_list \
${std_srcdir}/fstream \
${std_srcdir}/functional \
@@ -104,6 +105,10 @@ bits_headers = \
${bits_srcdir}/enable_special_members.h \
${bits_srcdir}/forward_list.h \
${bits_srcdir}/forward_list.tcc \
+ ${bits_srcdir}/fs_dir.h \
+ ${bits_srcdir}/fs_fwd.h \
+ ${bits_srcdir}/fs_ops.h \
+ ${bits_srcdir}/fs_path.h \
${bits_srcdir}/fstream.tcc \
${bits_srcdir}/functexcept.h \
${bits_srcdir}/functional_hash.h \
@@ -125,7 +130,6 @@ bits_headers = \
${bits_srcdir}/locale_facets_nonio.tcc \
${bits_srcdir}/localefwd.h \
${bits_srcdir}/mask_array.h \
- ${bits_srcdir}/specfun.h \
${bits_srcdir}/memoryfwd.h \
${bits_srcdir}/move.h \
${bits_srcdir}/node_handle.h \
@@ -156,6 +160,7 @@ bits_headers = \
${bits_srcdir}/shared_ptr_atomic.h \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
+ ${bits_srcdir}/specfun.h \
${bits_srcdir}/sstream.tcc \
${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_function.h \
@@ -1026,7 +1031,7 @@ stamp-bits: ${bits_headers}
@$(STAMP) stamp-bits
stamp-bits-sup: stamp-bits ${bits_sup_headers}
- @-cd ${bits_builddir} && $(LN_S) $? . 2>/dev/null
+ @-cd ${bits_builddir} && $(LN_S) ${bits_sup_headers} . 2>/dev/null
@$(STAMP) stamp-bits-sup
stamp-c_base: ${c_base_headers}
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 39dfede549b..0e3fe49142e 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -330,6 +330,7 @@ std_headers = \
${std_srcdir}/complex \
${std_srcdir}/condition_variable \
${std_srcdir}/deque \
+ ${std_srcdir}/filesystem \
${std_srcdir}/forward_list \
${std_srcdir}/fstream \
${std_srcdir}/functional \
@@ -397,6 +398,10 @@ bits_headers = \
${bits_srcdir}/enable_special_members.h \
${bits_srcdir}/forward_list.h \
${bits_srcdir}/forward_list.tcc \
+ ${bits_srcdir}/fs_dir.h \
+ ${bits_srcdir}/fs_fwd.h \
+ ${bits_srcdir}/fs_ops.h \
+ ${bits_srcdir}/fs_path.h \
${bits_srcdir}/fstream.tcc \
${bits_srcdir}/functexcept.h \
${bits_srcdir}/functional_hash.h \
@@ -418,7 +423,6 @@ bits_headers = \
${bits_srcdir}/locale_facets_nonio.tcc \
${bits_srcdir}/localefwd.h \
${bits_srcdir}/mask_array.h \
- ${bits_srcdir}/specfun.h \
${bits_srcdir}/memoryfwd.h \
${bits_srcdir}/move.h \
${bits_srcdir}/node_handle.h \
@@ -449,6 +453,7 @@ bits_headers = \
${bits_srcdir}/shared_ptr_atomic.h \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
+ ${bits_srcdir}/specfun.h \
${bits_srcdir}/sstream.tcc \
${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_function.h \
@@ -1475,7 +1480,7 @@ stamp-bits: ${bits_headers}
@$(STAMP) stamp-bits
stamp-bits-sup: stamp-bits ${bits_sup_headers}
- @-cd ${bits_builddir} && $(LN_S) $? . 2>/dev/null
+ @-cd ${bits_builddir} && $(LN_S) ${bits_sup_headers} . 2>/dev/null
@$(STAMP) stamp-bits-sup
stamp-c_base: ${c_base_headers}
diff --git a/libstdc++-v3/include/bits/fs_dir.h b/libstdc++-v3/include/bits/fs_dir.h
new file mode 100644
index 00000000000..579a269711e
--- /dev/null
+++ b/libstdc++-v3/include/bits/fs_dir.h
@@ -0,0 +1,525 @@
+// Filesystem directory utilities -*- C++ -*-
+
+// Copyright (C) 2014-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/fs_dir.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{filesystem}
+ */
+
+#ifndef _GLIBCXX_FS_DIR_H
+#define _GLIBCXX_FS_DIR_H 1
+
+#if __cplusplus >= 201703L
+# include <typeinfo>
+# include <ext/concurrence.h>
+# include <bits/unique_ptr.h>
+# include <bits/shared_ptr.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace filesystem
+{
+ /**
+ * @ingroup filesystem
+ * @{
+ */
+
+ class file_status
+ {
+ public:
+ // constructors and destructor
+ file_status() noexcept : file_status(file_type::none) {}
+
+ explicit
+ file_status(file_type __ft, perms __prms = perms::unknown) noexcept
+ : _M_type(__ft), _M_perms(__prms) { }
+
+ file_status(const file_status&) noexcept = default;
+ file_status(file_status&&) noexcept = default;
+ ~file_status() = default;
+
+ file_status& operator=(const file_status&) noexcept = default;
+ file_status& operator=(file_status&&) noexcept = default;
+
+ // observers
+ file_type type() const noexcept { return _M_type; }
+ perms permissions() const noexcept { return _M_perms; }
+
+ // modifiers
+ void type(file_type __ft) noexcept { _M_type = __ft; }
+ void permissions(perms __prms) noexcept { _M_perms = __prms; }
+
+ private:
+ file_type _M_type;
+ perms _M_perms;
+ };
+
+_GLIBCXX_BEGIN_NAMESPACE_CXX11
+
+ struct _Dir;
+ class directory_iterator;
+ class recursive_directory_iterator;
+
+ class directory_entry
+ {
+ public:
+ // constructors and destructor
+ directory_entry() noexcept = default;
+ directory_entry(const directory_entry&) = default;
+ directory_entry(directory_entry&&) noexcept = default;
+
+ explicit
+ directory_entry(const filesystem::path& __p)
+ : _M_path(__p)
+ { refresh(); }
+
+ directory_entry(const filesystem::path& __p, error_code& __ec)
+ : _M_path(__p)
+ {
+ refresh(__ec);
+ if (__ec)
+ _M_path.clear();
+ }
+
+ ~directory_entry() = default;
+
+ // modifiers
+ directory_entry& operator=(const directory_entry&) = default;
+ directory_entry& operator=(directory_entry&&) noexcept = default;
+
+ void
+ assign(const filesystem::path& __p)
+ {
+ _M_path = __p;
+ refresh();
+ }
+
+ void
+ assign(const filesystem::path& __p, error_code& __ec)
+ {
+ _M_path = __p;
+ refresh(__ec);
+ }
+
+ void
+ replace_filename(const filesystem::path& __p)
+ {
+ _M_path.replace_filename(__p);
+ refresh();
+ }
+
+ void
+ replace_filename(const filesystem::path& __p, error_code& __ec)
+ {
+ _M_path.replace_filename(__p);
+ refresh(__ec);
+ }
+
+ void refresh() { _M_type = symlink_status().type(); }
+ void refresh(error_code& __ec) { _M_type = symlink_status(__ec).type(); }
+
+ // observers
+ const filesystem::path& path() const noexcept { return _M_path; }
+ operator const filesystem::path& () const noexcept { return _M_path; }
+
+ bool
+ exists() const
+ { return filesystem::exists(file_status{_M_file_type()}); }
+
+ bool
+ exists(error_code& __ec) const noexcept
+ { return filesystem::exists(file_status{_M_file_type(__ec)}); }
+
+ bool
+ is_block_file() const
+ { return _M_file_type() == file_type::block; }
+
+ bool
+ is_block_file(error_code& __ec) const noexcept
+ { return _M_file_type(__ec) == file_type::block; }
+
+ bool
+ is_character_file() const
+ { return _M_file_type() == file_type::character; }
+
+ bool
+ is_character_file(error_code& __ec) const noexcept
+ { return _M_file_type(__ec) == file_type::character; }
+
+ bool
+ is_directory() const
+ { return _M_file_type() == file_type::directory; }
+
+ bool
+ is_directory(error_code& __ec) const noexcept
+ { return _M_file_type(__ec) == file_type::directory; }
+
+ bool
+ is_fifo() const
+ { return _M_file_type() == file_type::fifo; }
+
+ bool
+ is_fifo(error_code& __ec) const noexcept
+ { return _M_file_type(__ec) == file_type::fifo; }
+
+ bool
+ is_other() const
+ { return filesystem::is_other(file_status{_M_file_type()}); }
+
+ bool
+ is_other(error_code& __ec) const noexcept
+ { return filesystem::is_other(file_status{_M_file_type(__ec)}); }
+
+ bool
+ is_regular_file() const
+ { return _M_file_type() == file_type::regular; }
+
+ bool
+ is_regular_file(error_code& __ec) const noexcept
+ { return _M_file_type(__ec) == file_type::regular; }
+
+ bool
+ is_socket() const
+ { return _M_file_type() == file_type::socket; }
+
+ bool
+ is_socket(error_code& __ec) const noexcept
+ { return _M_file_type(__ec) == file_type::socket; }
+
+ bool
+ is_symlink() const
+ {
+ if (_M_type != file_type::none)
+ return _M_type == file_type::symlink;
+ return symlink_status().type() == file_type::symlink;
+ }
+
+ bool
+ is_symlink(error_code& __ec) const noexcept
+ {
+ if (_M_type != file_type::none)
+ return _M_type == file_type::symlink;
+ return symlink_status(__ec).type() == file_type::symlink;
+ }
+
+ uintmax_t
+ file_size() const
+ { return filesystem::file_size(_M_path); }
+
+ uintmax_t
+ file_size(error_code& __ec) const noexcept
+ { return filesystem::file_size(_M_path, __ec); }
+
+ uintmax_t
+ hard_link_count() const
+ { return filesystem::hard_link_count(_M_path); }
+
+ uintmax_t
+ hard_link_count(error_code& __ec) const noexcept
+ { return filesystem::hard_link_count(_M_path, __ec); }
+
+ file_time_type
+ last_write_time() const
+ { return filesystem::last_write_time(_M_path); }
+
+
+ file_time_type
+ last_write_time(error_code& __ec) const noexcept
+ { return filesystem::last_write_time(_M_path, __ec); }
+
+ file_status
+ status() const
+ { return filesystem::status(_M_path); }
+
+ file_status
+ status(error_code& __ec) const noexcept
+ { return filesystem::status(_M_path, __ec); }
+
+ file_status
+ symlink_status() const
+ { return filesystem::symlink_status(_M_path); }
+
+ file_status
+ symlink_status(error_code& __ec) const noexcept
+ { return filesystem::symlink_status(_M_path, __ec); }
+
+ bool
+ operator< (const directory_entry& __rhs) const noexcept
+ { return _M_path < __rhs._M_path; }
+
+ bool
+ operator==(const directory_entry& __rhs) const noexcept
+ { return _M_path == __rhs._M_path; }
+
+ bool
+ operator!=(const directory_entry& __rhs) const noexcept
+ { return _M_path != __rhs._M_path; }
+
+ bool
+ operator<=(const directory_entry& __rhs) const noexcept
+ { return _M_path <= __rhs._M_path; }
+
+ bool
+ operator> (const directory_entry& __rhs) const noexcept
+ { return _M_path > __rhs._M_path; }
+
+ bool
+ operator>=(const directory_entry& __rhs) const noexcept
+ { return _M_path >= __rhs._M_path; }
+
+ private:
+ friend class _Dir;
+ friend class directory_iterator;
+ friend class recursive_directory_iterator;
+
+ directory_entry(const filesystem::path& __p, file_type __t)
+ : _M_path(__p), _M_type(__t)
+ { }
+
+ // Equivalent to status().type() but uses cached value, if any.
+ file_type
+ _M_file_type() const
+ {
+ if (_M_type != file_type::none && _M_type != file_type::symlink)
+ return _M_type;
+ return status().type();
+ }
+
+ // Equivalent to status(__ec).type() but uses cached value, if any.
+ file_type
+ _M_file_type(error_code& __ec) const noexcept
+ {
+ if (_M_type != file_type::none && _M_type != file_type::symlink)
+ return _M_type;
+ return status(__ec).type();
+ }
+
+ filesystem::path _M_path;
+ file_type _M_type = file_type::none;
+ };
+
+ struct __directory_iterator_proxy
+ {
+ const directory_entry& operator*() const& noexcept { return _M_entry; }
+
+ directory_entry operator*() && noexcept { return std::move(_M_entry); }
+
+ private:
+ friend class directory_iterator;
+ friend class recursive_directory_iterator;
+
+ explicit
+ __directory_iterator_proxy(const directory_entry& __e) : _M_entry(__e) { }
+
+ directory_entry _M_entry;
+ };
+
+ class directory_iterator
+ {
+ public:
+ typedef directory_entry value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const directory_entry* pointer;
+ typedef const directory_entry& reference;
+ typedef input_iterator_tag iterator_category;
+
+ directory_iterator() = default;
+
+ explicit
+ directory_iterator(const path& __p)
+ : directory_iterator(__p, directory_options::none, nullptr) { }
+
+ directory_iterator(const path& __p, directory_options __options)
+ : directory_iterator(__p, __options, nullptr) { }
+
+ directory_iterator(const path& __p, error_code& __ec)
+ : directory_iterator(__p, directory_options::none, __ec) { }
+
+ directory_iterator(const path& __p, directory_options __options,
+ error_code& __ec)
+ : directory_iterator(__p, __options, &__ec) { }
+
+ directory_iterator(const directory_iterator& __rhs) = default;
+
+ directory_iterator(directory_iterator&& __rhs) noexcept = default;
+
+ ~directory_iterator() = default;
+
+ directory_iterator&
+ operator=(const directory_iterator& __rhs) = default;
+
+ directory_iterator&
+ operator=(directory_iterator&& __rhs) noexcept = default;
+
+ const directory_entry& operator*() const;
+ const directory_entry* operator->() const { return &**this; }
+ directory_iterator& operator++();
+ directory_iterator& increment(error_code& __ec);
+
+ __directory_iterator_proxy operator++(int)
+ {
+ __directory_iterator_proxy __pr{**this};
+ ++*this;
+ return __pr;
+ }
+
+ private:
+ directory_iterator(const path&, directory_options, error_code*);
+
+ friend bool
+ operator==(const directory_iterator& __lhs,
+ const directory_iterator& __rhs);
+
+ friend class recursive_directory_iterator;
+
+ std::shared_ptr<_Dir> _M_dir;
+ };
+
+ inline directory_iterator
+ begin(directory_iterator __iter) noexcept
+ { return __iter; }
+
+ inline directory_iterator
+ end(directory_iterator) noexcept
+ { return directory_iterator(); }
+
+ inline bool
+ operator==(const directory_iterator& __lhs, const directory_iterator& __rhs)
+ {
+ return !__rhs._M_dir.owner_before(__lhs._M_dir)
+ && !__lhs._M_dir.owner_before(__rhs._M_dir);
+ }
+
+ inline bool
+ operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs)
+ { return !(__lhs == __rhs); }
+
+ class recursive_directory_iterator
+ {
+ public:
+ typedef directory_entry value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const directory_entry* pointer;
+ typedef const directory_entry& reference;
+ typedef input_iterator_tag iterator_category;
+
+ recursive_directory_iterator() = default;
+
+ explicit
+ recursive_directory_iterator(const path& __p)
+ : recursive_directory_iterator(__p, directory_options::none, nullptr) { }
+
+ recursive_directory_iterator(const path& __p, directory_options __options)
+ : recursive_directory_iterator(__p, __options, nullptr) { }
+
+ recursive_directory_iterator(const path& __p, directory_options __options,
+ error_code& __ec)
+ : recursive_directory_iterator(__p, __options, &__ec) { }
+
+ recursive_directory_iterator(const path& __p, error_code& __ec)
+ : recursive_directory_iterator(__p, directory_options::none, &__ec) { }
+
+ recursive_directory_iterator(
+ const recursive_directory_iterator&) = default;
+
+ recursive_directory_iterator(recursive_directory_iterator&&) = default;
+
+ ~recursive_directory_iterator();
+
+ // observers
+ directory_options options() const { return _M_options; }
+ int depth() const;
+ bool recursion_pending() const { return _M_pending; }
+
+ const directory_entry& operator*() const;
+ const directory_entry* operator->() const { return &**this; }
+
+ // modifiers
+ recursive_directory_iterator&
+ operator=(const recursive_directory_iterator& __rhs) noexcept;
+ recursive_directory_iterator&
+ operator=(recursive_directory_iterator&& __rhs) noexcept;
+
+ recursive_directory_iterator& operator++();
+ recursive_directory_iterator& increment(error_code& __ec);
+
+ __directory_iterator_proxy operator++(int)
+ {
+ __directory_iterator_proxy __pr{**this};
+ ++*this;
+ return __pr;
+ }
+
+ void pop();
+ void pop(error_code&);
+
+ void disable_recursion_pending() { _M_pending = false; }
+
+ private:
+ recursive_directory_iterator(const path&, directory_options, error_code*);
+
+ friend bool
+ operator==(const recursive_directory_iterator& __lhs,
+ const recursive_directory_iterator& __rhs);
+
+ struct _Dir_stack;
+ std::shared_ptr<_Dir_stack> _M_dirs;
+ directory_options _M_options = {};
+ bool _M_pending = false;
+ };
+
+ inline recursive_directory_iterator
+ begin(recursive_directory_iterator __iter) noexcept
+ { return __iter; }
+
+ inline recursive_directory_iterator
+ end(recursive_directory_iterator) noexcept
+ { return recursive_directory_iterator(); }
+
+ inline bool
+ operator==(const recursive_directory_iterator& __lhs,
+ const recursive_directory_iterator& __rhs)
+ {
+ return !__rhs._M_dirs.owner_before(__lhs._M_dirs)
+ && !__lhs._M_dirs.owner_before(__rhs._M_dirs);
+ }
+
+ inline bool
+ operator!=(const recursive_directory_iterator& __lhs,
+ const recursive_directory_iterator& __rhs)
+ { return !(__lhs == __rhs); }
+
+_GLIBCXX_END_NAMESPACE_CXX11
+
+ // @} group filesystem
+} // namespace filesystem
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++17
+
+#endif // _GLIBCXX_FS_DIR_H
diff --git a/libstdc++-v3/include/bits/fs_fwd.h b/libstdc++-v3/include/bits/fs_fwd.h
new file mode 100644
index 00000000000..f408a39b974
--- /dev/null
+++ b/libstdc++-v3/include/bits/fs_fwd.h
@@ -0,0 +1,348 @@
+// Filesystem declarations -*- C++ -*-
+
+// Copyright (C) 2014-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/fs_fwd.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{filesystem}
+ */
+
+#ifndef _GLIBCXX_FS_FWD_H
+#define _GLIBCXX_FS_FWD_H 1
+
+#if __cplusplus >= 201703L
+
+#include <system_error>
+#include <cstdint>
+#include <chrono>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace filesystem
+{
+#if _GLIBCXX_USE_CXX11_ABI
+inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+#endif
+
+ /**
+ * @defgroup filesystem Filesystem
+ *
+ * Utilities for performing operations on file systems and their components,
+ * such as paths, regular files, and directories.
+ *
+ * @{
+ */
+
+ class file_status;
+_GLIBCXX_BEGIN_NAMESPACE_CXX11
+ class path;
+ class filesystem_error;
+ class directory_entry;
+ class directory_iterator;
+ class recursive_directory_iterator;
+_GLIBCXX_END_NAMESPACE_CXX11
+
+ struct space_info
+ {
+ uintmax_t capacity;
+ uintmax_t free;
+ uintmax_t available;
+ };
+
+ enum class file_type : signed char {
+ none = 0, not_found = -1, regular = 1, directory = 2, symlink = 3,
+ block = 4, character = 5, fifo = 6, socket = 7, unknown = 8
+ };
+
+ /// Bitmask type
+ enum class copy_options : unsigned short {
+ none = 0,
+ skip_existing = 1, overwrite_existing = 2, update_existing = 4,
+ recursive = 8,
+ copy_symlinks = 16, skip_symlinks = 32,
+ directories_only = 64, create_symlinks = 128, create_hard_links = 256
+ };
+
+ constexpr copy_options
+ operator&(copy_options __x, copy_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<copy_options>::type;
+ return static_cast<copy_options>(
+ static_cast<__utype>(__x) & static_cast<__utype>(__y));
+ }
+
+ constexpr copy_options
+ operator|(copy_options __x, copy_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<copy_options>::type;
+ return static_cast<copy_options>(
+ static_cast<__utype>(__x) | static_cast<__utype>(__y));
+ }
+
+ constexpr copy_options
+ operator^(copy_options __x, copy_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<copy_options>::type;
+ return static_cast<copy_options>(
+ static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
+ }
+
+ constexpr copy_options
+ operator~(copy_options __x) noexcept
+ {
+ using __utype = typename std::underlying_type<copy_options>::type;
+ return static_cast<copy_options>(~static_cast<__utype>(__x));
+ }
+
+ inline copy_options&
+ operator&=(copy_options& __x, copy_options __y) noexcept
+ { return __x = __x & __y; }
+
+ inline copy_options&
+ operator|=(copy_options& __x, copy_options __y) noexcept
+ { return __x = __x | __y; }
+
+ inline copy_options&
+ operator^=(copy_options& __x, copy_options __y) noexcept
+ { return __x = __x ^ __y; }
+
+
+ /// Bitmask type
+ enum class perms : unsigned {
+ none = 0,
+ owner_read = 0400,
+ owner_write = 0200,
+ owner_exec = 0100,
+ owner_all = 0700,
+ group_read = 040,
+ group_write = 020,
+ group_exec = 010,
+ group_all = 070,
+ others_read = 04,
+ others_write = 02,
+ others_exec = 01,
+ others_all = 07,
+ all = 0777,
+ set_uid = 04000,
+ set_gid = 02000,
+ sticky_bit = 01000,
+ mask = 07777,
+ unknown = 0xFFFF,
+ };
+
+ constexpr perms
+ operator&(perms __x, perms __y) noexcept
+ {
+ using __utype = typename std::underlying_type<perms>::type;
+ return static_cast<perms>(
+ static_cast<__utype>(__x) & static_cast<__utype>(__y));
+ }
+
+ constexpr perms
+ operator|(perms __x, perms __y) noexcept
+ {
+ using __utype = typename std::underlying_type<perms>::type;
+ return static_cast<perms>(
+ static_cast<__utype>(__x) | static_cast<__utype>(__y));
+ }
+
+ constexpr perms
+ operator^(perms __x, perms __y) noexcept
+ {
+ using __utype = typename std::underlying_type<perms>::type;
+ return static_cast<perms>(
+ static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
+ }
+
+ constexpr perms
+ operator~(perms __x) noexcept
+ {
+ using __utype = typename std::underlying_type<perms>::type;
+ return static_cast<perms>(~static_cast<__utype>(__x));
+ }
+
+ inline perms&
+ operator&=(perms& __x, perms __y) noexcept
+ { return __x = __x & __y; }
+
+ inline perms&
+ operator|=(perms& __x, perms __y) noexcept
+ { return __x = __x | __y; }
+
+ inline perms&
+ operator^=(perms& __x, perms __y) noexcept
+ { return __x = __x ^ __y; }
+
+ /// Bitmask type
+ enum class perm_options : unsigned {
+ replace = 0x1,
+ add = 0x2,
+ remove = 0x4,
+ nofollow = 0x8
+ };
+
+ constexpr perm_options
+ operator&(perm_options __x, perm_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<perm_options>::type;
+ return static_cast<perm_options>(
+ static_cast<__utype>(__x) & static_cast<__utype>(__y));
+ }
+
+ constexpr perm_options
+ operator|(perm_options __x, perm_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<perm_options>::type;
+ return static_cast<perm_options>(
+ static_cast<__utype>(__x) | static_cast<__utype>(__y));
+ }
+
+ constexpr perm_options
+ operator^(perm_options __x, perm_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<perm_options>::type;
+ return static_cast<perm_options>(
+ static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
+ }
+
+ constexpr perm_options
+ operator~(perm_options __x) noexcept
+ {
+ using __utype = typename std::underlying_type<perm_options>::type;
+ return static_cast<perm_options>(~static_cast<__utype>(__x));
+ }
+
+ inline perm_options&
+ operator&=(perm_options& __x, perm_options __y) noexcept
+ { return __x = __x & __y; }
+
+ inline perm_options&
+ operator|=(perm_options& __x, perm_options __y) noexcept
+ { return __x = __x | __y; }
+
+ inline perm_options&
+ operator^=(perm_options& __x, perm_options __y) noexcept
+ { return __x = __x ^ __y; }
+
+ // Bitmask type
+ enum class directory_options : unsigned char {
+ none = 0, follow_directory_symlink = 1, skip_permission_denied = 2
+ };
+
+ constexpr directory_options
+ operator&(directory_options __x, directory_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<directory_options>::type;
+ return static_cast<directory_options>(
+ static_cast<__utype>(__x) & static_cast<__utype>(__y));
+ }
+
+ constexpr directory_options
+ operator|(directory_options __x, directory_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<directory_options>::type;
+ return static_cast<directory_options>(
+ static_cast<__utype>(__x) | static_cast<__utype>(__y));
+ }
+
+ constexpr directory_options
+ operator^(directory_options __x, directory_options __y) noexcept
+ {
+ using __utype = typename std::underlying_type<directory_options>::type;
+ return static_cast<directory_options>(
+ static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
+ }
+
+ constexpr directory_options
+ operator~(directory_options __x) noexcept
+ {
+ using __utype = typename std::underlying_type<directory_options>::type;
+ return static_cast<directory_options>(~static_cast<__utype>(__x));
+ }
+
+ inline directory_options&
+ operator&=(directory_options& __x, directory_options __y) noexcept
+ { return __x = __x & __y; }
+
+ inline directory_options&
+ operator|=(directory_options& __x, directory_options __y) noexcept
+ { return __x = __x | __y; }
+
+ inline directory_options&
+ operator^=(directory_options& __x, directory_options __y) noexcept
+ { return __x = __x ^ __y; }
+
+ using file_time_type = std::chrono::system_clock::time_point;
+
+ // operational functions
+
+ void copy(const path& __from, const path& __to, copy_options __options);
+ void copy(const path& __from, const path& __to, copy_options __options,
+ error_code&) noexcept;
+
+ bool copy_file(const path& __from, const path& __to, copy_options __option);
+ bool copy_file(const path& __from, const path& __to, copy_options __option,
+ error_code&) noexcept;
+
+ path current_path();
+
+ bool exists(file_status) noexcept;
+
+ bool is_other(file_status) noexcept;
+
+ uintmax_t file_size(const path&);
+ uintmax_t file_size(const path&, error_code&) noexcept;
+ uintmax_t hard_link_count(const path&);
+ uintmax_t hard_link_count(const path&, error_code&) noexcept;
+ file_time_type last_write_time(const path&);
+ file_time_type last_write_time(const path&, error_code&) noexcept;
+
+ void permissions(const path&, perms, perm_options, error_code&);
+
+ path proximate(const path& __p, const path& __base, error_code& __ec);
+ path proximate(const path& __p, const path& __base, error_code& __ec);
+
+ path relative(const path& __p, const path& __base, error_code& __ec);
+
+ file_status status(const path&);
+ file_status status(const path&, error_code&) noexcept;
+
+ bool status_known(file_status) noexcept;
+
+ file_status symlink_status(const path&);
+ file_status symlink_status(const path&, error_code&) noexcept;
+
+ bool is_regular_file(file_status) noexcept;
+ bool is_symlink(file_status) noexcept;
+
+ // @} group filesystem
+} // namespace filesystem
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++17
+
+#endif // _GLIBCXX_FS_FWD_H
diff --git a/libstdc++-v3/include/bits/fs_ops.h b/libstdc++-v3/include/bits/fs_ops.h
new file mode 100644
index 00000000000..075d61e2a63
--- /dev/null
+++ b/libstdc++-v3/include/bits/fs_ops.h
@@ -0,0 +1,311 @@
+// Filesystem operational functions -*- C++ -*-
+
+// Copyright (C) 2014-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your __option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/fs_fwd.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{filesystem}
+ */
+
+#ifndef _GLIBCXX_FS_OPS_H
+#define _GLIBCXX_FS_OPS_H 1
+
+#if __cplusplus >= 201703L
+
+#include <cstdint>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace filesystem
+{
+ /**
+ * @ingroup filesystem
+ * @{
+ */
+
+ path absolute(const path& __p);
+ path absolute(const path& __p, error_code& __ec);
+
+ path canonical(const path& __p);
+ path canonical(const path& __p, error_code& __ec);
+
+ inline void
+ copy(const path& __from, const path& __to)
+ { copy(__from, __to, copy_options::none); }
+
+ inline void
+ copy(const path& __from, const path& __to, error_code& __ec)
+ { copy(__from, __to, copy_options::none, __ec); }
+
+ void copy(const path& __from, const path& __to, copy_options __options);
+ void copy(const path& __from, const path& __to, copy_options __options,
+ error_code& __ec);
+
+ inline bool
+ copy_file(const path& __from, const path& __to)
+ { return copy_file(__from, __to, copy_options::none); }
+
+ inline bool
+ copy_file(const path& __from, const path& __to, error_code& __ec)
+ { return copy_file(__from, __to, copy_options::none, __ec); }
+
+ bool copy_file(const path& __from, const path& __to, copy_options __option);
+ bool copy_file(const path& __from, const path& __to, copy_options __option,
+ error_code& __ec);
+
+ void copy_symlink(const path& __existing_symlink, const path& __new_symlink);
+ void copy_symlink(const path& __existing_symlink, const path& __new_symlink,
+ error_code& __ec) noexcept;
+
+ bool create_directories(const path& __p);
+ bool create_directories(const path& __p, error_code& __ec);
+
+ bool create_directory(const path& __p);
+ bool create_directory(const path& __p, error_code& __ec) noexcept;
+
+ bool create_directory(const path& __p, const path& attributes);
+ bool create_directory(const path& __p, const path& attributes,
+ error_code& __ec) noexcept;
+
+ void create_directory_symlink(const path& __to, const path& __new_symlink);
+ void create_directory_symlink(const path& __to, const path& __new_symlink,
+ error_code& __ec) noexcept;
+
+ void create_hard_link(const path& __to, const path& __new_hard_link);
+ void create_hard_link(const path& __to, const path& __new_hard_link,
+ error_code& __ec) noexcept;
+
+ void create_symlink(const path& __to, const path& __new_symlink);
+ void create_symlink(const path& __to, const path& __new_symlink,
+ error_code& __ec) noexcept;
+
+ path current_path();
+ path current_path(error_code& __ec);
+ void current_path(const path& __p);
+ void current_path(const path& __p, error_code& __ec) noexcept;
+
+ bool
+ equivalent(const path& __p1, const path& __p2);
+
+ bool
+ equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept;
+
+ inline bool
+ exists(file_status __s) noexcept
+ { return status_known(__s) && __s.type() != file_type::not_found; }
+
+ inline bool
+ exists(const path& __p)
+ { return exists(status(__p)); }
+
+ inline bool
+ exists(const path& __p, error_code& __ec) noexcept
+ {
+ auto __s = status(__p, __ec);
+ if (status_known(__s))
+ __ec.clear();
+ return exists(__s);
+ }
+
+ uintmax_t file_size(const path& __p);
+ uintmax_t file_size(const path& __p, error_code& __ec) noexcept;
+
+ uintmax_t hard_link_count(const path& __p);
+ uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept;
+
+ inline bool
+ is_block_file(file_status __s) noexcept
+ { return __s.type() == file_type::block; }
+
+ inline bool
+ is_block_file(const path& __p)
+ { return is_block_file(status(__p)); }
+
+ inline bool
+ is_block_file(const path& __p, error_code& __ec) noexcept
+ { return is_block_file(status(__p, __ec)); }
+
+ inline bool
+ is_character_file(file_status __s) noexcept
+ { return __s.type() == file_type::character; }
+
+ inline bool
+ is_character_file(const path& __p)
+ { return is_character_file(status(__p)); }
+
+ inline bool
+ is_character_file(const path& __p, error_code& __ec) noexcept
+ { return is_character_file(status(__p, __ec)); }
+
+ inline bool
+ is_directory(file_status __s) noexcept
+ { return __s.type() == file_type::directory; }
+
+ inline bool
+ is_directory(const path& __p)
+ { return is_directory(status(__p)); }
+
+ inline bool
+ is_directory(const path& __p, error_code& __ec) noexcept
+ { return is_directory(status(__p, __ec)); }
+
+ bool is_empty(const path& __p);
+ bool is_empty(const path& __p, error_code& __ec);
+
+ inline bool
+ is_fifo(file_status __s) noexcept
+ { return __s.type() == file_type::fifo; }
+
+ inline bool
+ is_fifo(const path& __p)
+ { return is_fifo(status(__p)); }
+
+ inline bool
+ is_fifo(const path& __p, error_code& __ec) noexcept
+ { return is_fifo(status(__p, __ec)); }
+
+ inline bool
+ is_other(file_status __s) noexcept
+ {
+ return exists(__s) && !is_regular_file(__s) && !is_directory(__s)
+ && !is_symlink(__s);
+ }
+
+ inline bool
+ is_other(const path& __p)
+ { return is_other(status(__p)); }
+
+ inline bool
+ is_other(const path& __p, error_code& __ec) noexcept
+ { return is_other(status(__p, __ec)); }
+
+ inline bool
+ is_regular_file(file_status __s) noexcept
+ { return __s.type() == file_type::regular; }
+
+ inline bool
+ is_regular_file(const path& __p)
+ { return is_regular_file(status(__p)); }
+
+ inline bool
+ is_regular_file(const path& __p, error_code& __ec) noexcept
+ { return is_regular_file(status(__p, __ec)); }
+
+ inline bool
+ is_socket(file_status __s) noexcept
+ { return __s.type() == file_type::socket; }
+
+ inline bool
+ is_socket(const path& __p)
+ { return is_socket(status(__p)); }
+
+ inline bool
+ is_socket(const path& __p, error_code& __ec) noexcept
+ { return is_socket(status(__p, __ec)); }
+
+ inline bool
+ is_symlink(file_status __s) noexcept
+ { return __s.type() == file_type::symlink; }
+
+ inline bool
+ is_symlink(const path& __p)
+ { return is_symlink(symlink_status(__p)); }
+
+ inline bool
+ is_symlink(const path& __p, error_code& __ec) noexcept
+ { return is_symlink(symlink_status(__p, __ec)); }
+
+ file_time_type last_write_time(const path& __p);
+ file_time_type last_write_time(const path& __p, error_code& __ec) noexcept;
+ void last_write_time(const path& __p, file_time_type __new_time);
+ void last_write_time(const path& __p, file_time_type __new_time,
+ error_code& __ec) noexcept;
+
+ void
+ permissions(const path& __p, perms __prms,
+ perm_options __opts = perm_options::replace);
+
+ inline void
+ permissions(const path& __p, perms __prms, error_code& __ec) noexcept
+ { permissions(__p, __prms, perm_options::replace, __ec); }
+
+ void
+ permissions(const path& __p, perms __prms, perm_options __opts,
+ error_code& __ec);
+
+ inline path proximate(const path& __p, error_code& __ec)
+ { return proximate(__p, current_path(), __ec); }
+
+ path proximate(const path& __p, const path& __base = current_path());
+ path proximate(const path& __p, const path& __base, error_code& __ec);
+
+ path read_symlink(const path& __p);
+ path read_symlink(const path& __p, error_code& __ec);
+
+ inline path relative(const path& __p, error_code& __ec)
+ { return relative(__p, current_path(), __ec); }
+
+ path relative(const path& __p, const path& __base = current_path());
+ path relative(const path& __p, const path& __base, error_code& __ec);
+
+ bool remove(const path& __p);
+ bool remove(const path& __p, error_code& __ec) noexcept;
+
+ uintmax_t remove_all(const path& __p);
+ uintmax_t remove_all(const path& __p, error_code& __ec);
+
+ void rename(const path& __from, const path& __to);
+ void rename(const path& __from, const path& __to, error_code& __ec) noexcept;
+
+ void resize_file(const path& __p, uintmax_t __size);
+ void resize_file(const path& __p, uintmax_t __size, error_code& __ec) noexcept;
+
+ space_info space(const path& __p);
+ space_info space(const path& __p, error_code& __ec) noexcept;
+
+ file_status status(const path& __p);
+ file_status status(const path& __p, error_code& __ec) noexcept;
+
+ inline bool status_known(file_status __s) noexcept
+ { return __s.type() != file_type::none; }
+
+ file_status symlink_status(const path& __p);
+ file_status symlink_status(const path& __p, error_code& __ec) noexcept;
+
+ path temp_directory_path();
+ path temp_directory_path(error_code& __ec);
+
+ path weakly_canonical(const path& __p);
+ path weakly_canonical(const path& __p, error_code& __ec);
+
+ // @} group filesystem
+} // namespace filesystem
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++17
+
+#endif // _GLIBCXX_FS_OPS_H
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
new file mode 100644
index 00000000000..7d97cdfbb81
--- /dev/null
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -0,0 +1,1166 @@
+// Class filesystem::path -*- C++ -*-
+
+// Copyright (C) 2014-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/fs_path.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{filesystem}
+ */
+
+#ifndef _GLIBCXX_FS_PATH_H
+#define _GLIBCXX_FS_PATH_H 1
+
+#if __cplusplus >= 201703L
+
+#include <utility>
+#include <type_traits>
+#include <vector>
+#include <locale>
+#include <iosfwd>
+#include <codecvt>
+#include <string_view>
+#include <system_error>
+#include <bits/stl_algobase.h>
+#include <bits/quoted_string.h>
+#include <bits/locale_conv.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# define _GLIBCXX_FILESYSTEM_IS_WINDOWS 1
+# include <algorithm>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace filesystem
+{
+_GLIBCXX_BEGIN_NAMESPACE_CXX11
+
+ /**
+ * @ingroup filesystem
+ * @{
+ */
+
+ /// A filesystem path.
+ class path
+ {
+ template<typename _CharT>
+ struct __is_encoded_char : std::false_type { };
+
+ template<typename _Iter,
+ typename _Iter_traits = std::iterator_traits<_Iter>>
+ using __is_path_iter_src
+ = __and_<__is_encoded_char<typename _Iter_traits::value_type>,
+ std::is_base_of<std::input_iterator_tag,
+ typename _Iter_traits::iterator_category>>;
+
+ template<typename _Iter>
+ static __is_path_iter_src<_Iter>
+ __is_path_src(_Iter, int);
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ static __is_encoded_char<_CharT>
+ __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int);
+
+ template<typename _CharT, typename _Traits>
+ static __is_encoded_char<_CharT>
+ __is_path_src(const basic_string_view<_CharT, _Traits>&, int);
+
+ template<typename _Unknown>
+ static std::false_type
+ __is_path_src(const _Unknown&, ...);
+
+ template<typename _Tp1, typename _Tp2>
+ struct __constructible_from;
+
+ template<typename _Iter>
+ struct __constructible_from<_Iter, _Iter>
+ : __is_path_iter_src<_Iter>
+ { };
+
+ template<typename _Source>
+ struct __constructible_from<_Source, void>
+ : decltype(__is_path_src(std::declval<_Source>(), 0))
+ { };
+
+ template<typename _Tp1, typename _Tp2 = void>
+ using _Path = typename
+ std::enable_if<__and_<__not_<is_same<_Tp1, path>>,
+ __constructible_from<_Tp1, _Tp2>>::value,
+ path>::type;
+
+ template<typename _Source>
+ static _Source
+ _S_range_begin(_Source __begin) { return __begin; }
+
+ struct __null_terminated { };
+
+ template<typename _Source>
+ static __null_terminated
+ _S_range_end(_Source) { return {}; }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ static const _CharT*
+ _S_range_begin(const basic_string<_CharT, _Traits, _Alloc>& __str)
+ { return __str.data(); }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ static const _CharT*
+ _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str)
+ { return __str.data() + __str.size(); }
+
+ template<typename _CharT, typename _Traits>
+ static const _CharT*
+ _S_range_begin(const basic_string_view<_CharT, _Traits>& __str)
+ { return __str.data(); }
+
+ template<typename _CharT, typename _Traits>
+ static const _CharT*
+ _S_range_end(const basic_string_view<_CharT, _Traits>& __str)
+ { return __str.data() + __str.size(); }
+
+ template<typename _Tp,
+ typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
+ typename _Val = typename std::iterator_traits<_Iter>::value_type>
+ using __value_type_is_char
+ = typename std::enable_if<std::is_same<_Val, char>::value>::type;
+
+ public:
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ typedef wchar_t value_type;
+ static constexpr value_type preferred_separator = L'\\';
+#else
+ typedef char value_type;
+ static constexpr value_type preferred_separator = '/';
+#endif
+ typedef std::basic_string<value_type> string_type;
+
+ enum format { native_format, generic_format, auto_format };
+
+ // constructors and destructor
+
+ path() noexcept { }
+
+ path(const path& __p) = default;
+
+ path(path&& __p) noexcept
+ : _M_pathname(std::move(__p._M_pathname)), _M_type(__p._M_type)
+ {
+ _M_split_cmpts();
+ __p.clear();
+ }
+
+ path(string_type&& __source, format = auto_format)
+ : _M_pathname(std::move(__source))
+ { _M_split_cmpts(); }
+
+ template<typename _Source,
+ typename _Require = _Path<_Source>>
+ path(_Source const& __source, format = auto_format)
+ : _M_pathname(_S_convert(_S_range_begin(__source),
+ _S_range_end(__source)))
+ { _M_split_cmpts(); }
+
+ template<typename _InputIterator,
+ typename _Require = _Path<_InputIterator, _InputIterator>>
+ path(_InputIterator __first, _InputIterator __last, format = auto_format)
+ : _M_pathname(_S_convert(__first, __last))
+ { _M_split_cmpts(); }
+
+ template<typename _Source,
+ typename _Require = _Path<_Source>,
+ typename _Require2 = __value_type_is_char<_Source>>
+ path(_Source const& __source, const locale& __loc, format = auto_format)
+ : _M_pathname(_S_convert_loc(_S_range_begin(__source),
+ _S_range_end(__source), __loc))
+ { _M_split_cmpts(); }
+
+ template<typename _InputIterator,
+ typename _Require = _Path<_InputIterator, _InputIterator>,
+ typename _Require2 = __value_type_is_char<_InputIterator>>
+ path(_InputIterator __first, _InputIterator __last, const locale& __loc,
+ format = auto_format)
+ : _M_pathname(_S_convert_loc(__first, __last, __loc))
+ { _M_split_cmpts(); }
+
+ ~path() = default;
+
+ // assignments
+
+ path& operator=(const path& __p) = default;
+ path& operator=(path&& __p) noexcept;
+ path& operator=(string_type&& __source);
+ path& assign(string_type&& __source);
+
+ template<typename _Source>
+ _Path<_Source>&
+ operator=(_Source const& __source)
+ { return *this = path(__source); }
+
+ template<typename _Source>
+ _Path<_Source>&
+ assign(_Source const& __source)
+ { return *this = path(__source); }
+
+ template<typename _InputIterator>
+ _Path<_InputIterator, _InputIterator>&
+ assign(_InputIterator __first, _InputIterator __last)
+ { return *this = path(__first, __last); }
+
+ // appends
+
+ path& operator/=(const path& __p)
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ if (__p.is_absolute()
+ || (__p.has_root_name() && __p.root_name() != root_name()))
+ operator=(__p);
+ else
+ {
+ string_type __pathname;
+ if (__p.has_root_directory())
+ __pathname = root_name().native();
+ else if (has_filename() || (!has_root_directory() && is_absolute()))
+ __pathname = _M_pathname + preferred_separator;
+ __pathname += __p.relative_path().native(); // XXX is this right?
+ _M_pathname.swap(__pathname);
+ _M_split_cmpts();
+ }
+#else
+ // Much simpler, as any path with root-name or root-dir is absolute.
+ if (__p.is_absolute())
+ operator=(__p);
+ else
+ {
+ if (has_filename() || (_M_type == _Type::_Root_name))
+ _M_pathname += preferred_separator;
+ _M_pathname += __p.native();
+ _M_split_cmpts();
+ }
+#endif
+ return *this;
+ }
+
+ template <class _Source>
+ _Path<_Source>&
+ operator/=(_Source const& __source)
+ { return append(__source); }
+
+ template<typename _Source>
+ _Path<_Source>&
+ append(_Source const& __source)
+ {
+ return _M_append(_S_convert(_S_range_begin(__source),
+ _S_range_end(__source)));
+ }
+
+ template<typename _InputIterator>
+ _Path<_InputIterator, _InputIterator>&
+ append(_InputIterator __first, _InputIterator __last)
+ { return _M_append(_S_convert(__first, __last)); }
+
+ // concatenation
+
+ path& operator+=(const path& __x);
+ path& operator+=(const string_type& __x);
+ path& operator+=(const value_type* __x);
+ path& operator+=(value_type __x);
+ path& operator+=(basic_string_view<value_type> __x);
+
+ template<typename _Source>
+ _Path<_Source>&
+ operator+=(_Source const& __x) { return concat(__x); }
+
+ template<typename _CharT>
+ _Path<_CharT*, _CharT*>&
+ operator+=(_CharT __x);
+
+ template<typename _Source>
+ _Path<_Source>&
+ concat(_Source const& __x)
+ { return *this += _S_convert(_S_range_begin(__x), _S_range_end(__x)); }
+
+ template<typename _InputIterator>
+ _Path<_InputIterator, _InputIterator>&
+ concat(_InputIterator __first, _InputIterator __last)
+ { return *this += _S_convert(__first, __last); }
+
+ // modifiers
+
+ void clear() noexcept { _M_pathname.clear(); _M_split_cmpts(); }
+
+ path& make_preferred();
+ path& remove_filename();
+ path& replace_filename(const path& __replacement);
+ path& replace_extension(const path& __replacement = path());
+
+ void swap(path& __rhs) noexcept;
+
+ // native format observers
+
+ const string_type& native() const noexcept { return _M_pathname; }
+ const value_type* c_str() const noexcept { return _M_pathname.c_str(); }
+ operator string_type() const { return _M_pathname; }
+
+ template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
+ typename _Allocator = std::allocator<_CharT>>
+ std::basic_string<_CharT, _Traits, _Allocator>
+ string(const _Allocator& __a = _Allocator()) const;
+
+ std::string string() const;
+#if _GLIBCXX_USE_WCHAR_T
+ std::wstring wstring() const;
+#endif
+ std::string u8string() const;
+ std::u16string u16string() const;
+ std::u32string u32string() const;
+
+ // generic format observers
+ template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
+ typename _Allocator = std::allocator<_CharT>>
+ std::basic_string<_CharT, _Traits, _Allocator>
+ generic_string(const _Allocator& __a = _Allocator()) const;
+
+ std::string generic_string() const;
+#if _GLIBCXX_USE_WCHAR_T
+ std::wstring generic_wstring() const;
+#endif
+ std::string generic_u8string() const;
+ std::u16string generic_u16string() const;
+ std::u32string generic_u32string() const;
+
+ // compare
+
+ int compare(const path& __p) const noexcept;
+ int compare(const string_type& __s) const;
+ int compare(const value_type* __s) const;
+ int compare(const basic_string_view<value_type> __s) const;
+
+ // decomposition
+
+ path root_name() const;
+ path root_directory() const;
+ path root_path() const;
+ path relative_path() const;
+ path parent_path() const;
+ path filename() const;
+ path stem() const;
+ path extension() const;
+
+ // query
+
+ bool empty() const noexcept { return _M_pathname.empty(); }
+ bool has_root_name() const;
+ bool has_root_directory() const;
+ bool has_root_path() const;
+ bool has_relative_path() const;
+ bool has_parent_path() const;
+ bool has_filename() const;
+ bool has_stem() const;
+ bool has_extension() const;
+ bool is_absolute() const;
+ bool is_relative() const { return !is_absolute(); }
+
+ // generation
+ path lexically_normal() const;
+ path lexically_relative(const path& base) const;
+ path lexically_proximate(const path& base) const;
+
+ // iterators
+ class iterator;
+ typedef iterator const_iterator;
+
+ iterator begin() const;
+ iterator end() const;
+
+ private:
+ enum class _Type : unsigned char {
+ _Multi, _Root_name, _Root_dir, _Filename
+ };
+
+ path(string_type __str, _Type __type) : _M_pathname(__str), _M_type(__type)
+ {
+ __glibcxx_assert(_M_type != _Type::_Multi);
+ }
+
+ enum class _Split { _Stem, _Extension };
+
+ path& _M_append(string_type&& __str)
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ operator/=(path(std::move(__str)));
+#else
+ if (!_M_pathname.empty() && !_S_is_dir_sep(_M_pathname.back())
+ && (__str.empty() || !_S_is_dir_sep(__str.front())))
+ _M_pathname += preferred_separator;
+ _M_pathname += __str;
+ _M_split_cmpts();
+#endif
+ return *this;
+ }
+
+ pair<const string_type*, size_t> _M_find_extension() const;
+
+ template<typename _CharT>
+ struct _Cvt;
+
+ static string_type
+ _S_convert(value_type* __src, __null_terminated)
+ { return string_type(__src); }
+
+ static string_type
+ _S_convert(const value_type* __src, __null_terminated)
+ { return string_type(__src); }
+
+ template<typename _Iter>
+ static string_type
+ _S_convert(_Iter __first, _Iter __last)
+ {
+ using __value_type = typename std::iterator_traits<_Iter>::value_type;
+ return _Cvt<typename remove_cv<__value_type>::type>::
+ _S_convert(__first, __last);
+ }
+
+ template<typename _InputIterator>
+ static string_type
+ _S_convert(_InputIterator __src, __null_terminated)
+ {
+ using _Tp = typename std::iterator_traits<_InputIterator>::value_type;
+ std::basic_string<typename remove_cv<_Tp>::type> __tmp;
+ for (; *__src != _Tp{}; ++__src)
+ __tmp.push_back(*__src);
+ return _S_convert(__tmp.c_str(), __tmp.c_str() + __tmp.size());
+ }
+
+ static string_type
+ _S_convert_loc(const char* __first, const char* __last,
+ const std::locale& __loc);
+
+ template<typename _Iter>
+ static string_type
+ _S_convert_loc(_Iter __first, _Iter __last, const std::locale& __loc)
+ {
+ const std::string __str(__first, __last);
+ return _S_convert_loc(__str.data(), __str.data()+__str.size(), __loc);
+ }
+
+ template<typename _InputIterator>
+ static string_type
+ _S_convert_loc(_InputIterator __src, __null_terminated,
+ const std::locale& __loc)
+ {
+ std::string __tmp;
+ while (*__src != '\0')
+ __tmp.push_back(*__src++);
+ return _S_convert_loc(__tmp.data(), __tmp.data()+__tmp.size(), __loc);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Allocator>
+ static basic_string<_CharT, _Traits, _Allocator>
+ _S_str_convert(const string_type&, const _Allocator& __a);
+
+ bool _S_is_dir_sep(value_type __ch)
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ return __ch == L'/' || __ch == preferred_separator;
+#else
+ return __ch == '/';
+#endif
+ }
+
+ void _M_split_cmpts();
+ void _M_trim();
+ void _M_add_root_name(size_t __n);
+ void _M_add_root_dir(size_t __pos);
+ void _M_add_filename(size_t __pos, size_t __n);
+
+ string_type _M_pathname;
+
+ struct _Cmpt;
+ using _List = _GLIBCXX_STD_C::vector<_Cmpt>;
+ _List _M_cmpts; // empty unless _M_type == _Type::_Multi
+ _Type _M_type = _Type::_Multi;
+ };
+
+ template<>
+ struct path::__is_encoded_char<char> : std::true_type
+ { using value_type = char; };
+
+ template<>
+ struct path::__is_encoded_char<wchar_t> : std::true_type
+ { using value_type = wchar_t; };
+
+ template<>
+ struct path::__is_encoded_char<char16_t> : std::true_type
+ { using value_type = char16_t; };
+
+ template<>
+ struct path::__is_encoded_char<char32_t> : std::true_type
+ { using value_type = char32_t; };
+
+ template<typename _Tp>
+ struct path::__is_encoded_char<const _Tp> : __is_encoded_char<_Tp> { };
+
+ inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); }
+
+ size_t hash_value(const path& __p) noexcept;
+
+ /// Compare paths
+ inline bool operator<(const path& __lhs, const path& __rhs) noexcept
+ { return __lhs.compare(__rhs) < 0; }
+
+ /// Compare paths
+ inline bool operator<=(const path& __lhs, const path& __rhs) noexcept
+ { return !(__rhs < __lhs); }
+
+ /// Compare paths
+ inline bool operator>(const path& __lhs, const path& __rhs) noexcept
+ { return __rhs < __lhs; }
+
+ /// Compare paths
+ inline bool operator>=(const path& __lhs, const path& __rhs) noexcept
+ { return !(__lhs < __rhs); }
+
+ /// Compare paths
+ inline bool operator==(const path& __lhs, const path& __rhs) noexcept
+ { return __lhs.compare(__rhs) == 0; }
+
+ /// Compare paths
+ inline bool operator!=(const path& __lhs, const path& __rhs) noexcept
+ { return !(__lhs == __rhs); }
+
+ /// Append one path to another
+ inline path operator/(const path& __lhs, const path& __rhs)
+ { return path(__lhs) /= __rhs; }
+
+ /// Write a path to a stream
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p)
+ {
+ auto __tmp = __p.string<_CharT, _Traits>();
+ using __quoted_string
+ = std::__detail::_Quoted_string<decltype(__tmp)&, _CharT>;
+ __os << __quoted_string{__tmp, '"', '\\'};
+ return __os;
+ }
+
+ /// Read a path from a stream
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
+ {
+ basic_string<_CharT, _Traits> __tmp;
+ using __quoted_string
+ = std::__detail::_Quoted_string<decltype(__tmp)&, _CharT>;
+ if (__is >> __quoted_string{ __tmp, '"', '\\' })
+ __p = std::move(__tmp);
+ return __is;
+ }
+
+ template<typename _Source>
+ inline auto
+ u8path(const _Source& __source)
+ -> decltype(filesystem::path(__source, std::locale::classic()))
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ const std::string __u8str{__source};
+ return std::filesystem::u8path(__u8str.begin(), __u8str.end());
+#else
+ return path{ __source };
+#endif
+ }
+
+ template<typename _InputIterator>
+ inline auto
+ u8path(_InputIterator __first, _InputIterator __last)
+ -> decltype(filesystem::path(__first, __last, std::locale::classic()))
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ codecvt_utf8<value_type> __cvt;
+ string_type __tmp;
+ if (__str_codecvt_in(__first, __last, __tmp, __cvt))
+ return path{ __tmp };
+ else
+ return {};
+#else
+ return path{ __first, __last };
+#endif
+ }
+
+ class filesystem_error : public std::system_error
+ {
+ public:
+ filesystem_error(const string& __what_arg, error_code __ec)
+ : system_error(__ec, __what_arg) { }
+
+ filesystem_error(const string& __what_arg, const path& __p1,
+ error_code __ec)
+ : system_error(__ec, __what_arg), _M_path1(__p1) { }
+
+ filesystem_error(const string& __what_arg, const path& __p1,
+ const path& __p2, error_code __ec)
+ : system_error(__ec, __what_arg), _M_path1(__p1), _M_path2(__p2)
+ { }
+
+ ~filesystem_error();
+
+ const path& path1() const noexcept { return _M_path1; }
+ const path& path2() const noexcept { return _M_path2; }
+ const char* what() const noexcept { return _M_what.c_str(); }
+
+ private:
+ std::string _M_gen_what();
+
+ path _M_path1;
+ path _M_path2;
+ std::string _M_what = _M_gen_what();
+ };
+
+ struct path::_Cmpt : path
+ {
+ _Cmpt(string_type __s, _Type __t, size_t __pos)
+ : path(std::move(__s), __t), _M_pos(__pos) { }
+
+ _Cmpt() : _M_pos(-1) { }
+
+ size_t _M_pos;
+ };
+
+ // specialize _Cvt for degenerate 'noconv' case
+ template<>
+ struct path::_Cvt<path::value_type>
+ {
+ template<typename _Iter>
+ static string_type
+ _S_convert(_Iter __first, _Iter __last)
+ { return string_type{__first, __last}; }
+ };
+
+ template<typename _CharT>
+ struct path::_Cvt
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ static string_type
+ _S_wconvert(const char* __f, const char* __l, true_type)
+ {
+ using _Cvt = std::codecvt<wchar_t, char, mbstate_t>;
+ const auto& __cvt = std::use_facet<_Cvt>(std::locale{});
+ std::wstring __wstr;
+ if (__str_codecvt_in(__f, __l, __wstr, __cvt))
+ return __wstr;
+ _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+ "Cannot convert character sequence",
+ std::make_error_code(errc::illegal_byte_sequence)));
+ }
+
+ static string_type
+ _S_wconvert(const _CharT* __f, const _CharT* __l, false_type)
+ {
+ std::codecvt_utf8<_CharT> __cvt;
+ std::string __str;
+ if (__str_codecvt_out(__f, __l, __str, __cvt))
+ {
+ const char* __f2 = __str.data();
+ const char* __l2 = __f2 + __str.size();
+ std::codecvt_utf8<wchar_t> __wcvt;
+ std::wstring __wstr;
+ if (__str_codecvt_in(__f2, __l2, __wstr, __wcvt))
+ return __wstr;
+ }
+ _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+ "Cannot convert character sequence",
+ std::make_error_code(errc::illegal_byte_sequence)));
+ }
+
+ static string_type
+ _S_convert(const _CharT* __f, const _CharT* __l)
+ {
+ return _S_wconvert(__f, __l, is_same<_CharT, char>{});
+ }
+#else
+ static string_type
+ _S_convert(const _CharT* __f, const _CharT* __l)
+ {
+ std::codecvt_utf8<_CharT> __cvt;
+ std::string __str;
+ if (__str_codecvt_out(__f, __l, __str, __cvt))
+ return __str;
+ _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+ "Cannot convert character sequence",
+ std::make_error_code(errc::illegal_byte_sequence)));
+ }
+#endif
+
+ static string_type
+ _S_convert(_CharT* __f, _CharT* __l)
+ {
+ return _S_convert(const_cast<const _CharT*>(__f),
+ const_cast<const _CharT*>(__l));
+ }
+
+ template<typename _Iter>
+ static string_type
+ _S_convert(_Iter __first, _Iter __last)
+ {
+ const std::basic_string<_CharT> __str(__first, __last);
+ return _S_convert(__str.data(), __str.data() + __str.size());
+ }
+
+ template<typename _Iter, typename _Cont>
+ static string_type
+ _S_convert(__gnu_cxx::__normal_iterator<_Iter, _Cont> __first,
+ __gnu_cxx::__normal_iterator<_Iter, _Cont> __last)
+ { return _S_convert(__first.base(), __last.base()); }
+ };
+
+ /// An iterator for the components of a path
+ class path::iterator
+ {
+ public:
+ using difference_type = std::ptrdiff_t;
+ using value_type = path;
+ using reference = const path&;
+ using pointer = const path*;
+ using iterator_category = std::bidirectional_iterator_tag;
+
+ iterator() : _M_path(nullptr), _M_cur(), _M_at_end() { }
+
+ iterator(const iterator&) = default;
+ iterator& operator=(const iterator&) = default;
+
+ reference operator*() const;
+ pointer operator->() const { return std::__addressof(**this); }
+
+ iterator& operator++();
+ iterator operator++(int) { auto __tmp = *this; ++*this; return __tmp; }
+
+ iterator& operator--();
+ iterator operator--(int) { auto __tmp = *this; --*this; return __tmp; }
+
+ friend bool operator==(const iterator& __lhs, const iterator& __rhs)
+ { return __lhs._M_equals(__rhs); }
+
+ friend bool operator!=(const iterator& __lhs, const iterator& __rhs)
+ { return !__lhs._M_equals(__rhs); }
+
+ private:
+ friend class path;
+
+ iterator(const path* __path, path::_List::const_iterator __iter)
+ : _M_path(__path), _M_cur(__iter), _M_at_end()
+ { }
+
+ iterator(const path* __path, bool __at_end)
+ : _M_path(__path), _M_cur(), _M_at_end(__at_end)
+ { }
+
+ bool _M_equals(iterator) const;
+
+ const path* _M_path;
+ path::_List::const_iterator _M_cur;
+ bool _M_at_end; // only used when type != _Multi
+ };
+
+
+ inline path&
+ path::operator=(path&& __p) noexcept
+ {
+ _M_pathname = std::move(__p._M_pathname);
+ _M_cmpts = std::move(__p._M_cmpts);
+ _M_type = __p._M_type;
+ __p.clear();
+ return *this;
+ }
+
+ inline path&
+ path::operator=(string_type&& __source)
+ { return *this = path(std::move(__source)); }
+
+ inline path&
+ path::assign(string_type&& __source)
+ { return *this = path(std::move(__source)); }
+
+ inline path&
+ path::operator+=(const path& __p)
+ {
+ return operator+=(__p.native());
+ }
+
+ inline path&
+ path::operator+=(const string_type& __x)
+ {
+ _M_pathname += __x;
+ _M_split_cmpts();
+ return *this;
+ }
+
+ inline path&
+ path::operator+=(const value_type* __x)
+ {
+ _M_pathname += __x;
+ _M_split_cmpts();
+ return *this;
+ }
+
+ inline path&
+ path::operator+=(value_type __x)
+ {
+ _M_pathname += __x;
+ _M_split_cmpts();
+ return *this;
+ }
+
+ inline path&
+ path::operator+=(basic_string_view<value_type> __x)
+ {
+ _M_pathname.append(__x.data(), __x.size());
+ _M_split_cmpts();
+ return *this;
+ }
+
+ template<typename _CharT>
+ inline path::_Path<_CharT*, _CharT*>&
+ path::operator+=(_CharT __x)
+ {
+ auto* __addr = std::__addressof(__x);
+ return concat(__addr, __addr + 1);
+ }
+
+ inline path&
+ path::make_preferred()
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ std::replace(_M_pathname.begin(), _M_pathname.end(), L'/',
+ preferred_separator);
+#endif
+ return *this;
+ }
+
+ inline void path::swap(path& __rhs) noexcept
+ {
+ _M_pathname.swap(__rhs._M_pathname);
+ _M_cmpts.swap(__rhs._M_cmpts);
+ std::swap(_M_type, __rhs._M_type);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Allocator>
+ std::basic_string<_CharT, _Traits, _Allocator>
+ path::_S_str_convert(const string_type& __str, const _Allocator& __a)
+ {
+ if (__str.size() == 0)
+ return std::basic_string<_CharT, _Traits, _Allocator>(__a);
+
+ const value_type* __first = __str.data();
+ const value_type* __last = __first + __str.size();
+
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ using _CharAlloc = __alloc_rebind<_Allocator, char>;
+ using _String = basic_string<char, char_traits<char>, _CharAlloc>;
+ using _WString = basic_string<_CharT, _Traits, _Allocator>;
+
+ // use codecvt_utf8<wchar_t> to convert native string to UTF-8
+ codecvt_utf8<value_type> __cvt;
+ _String __u8str{_CharAlloc{__a}};
+ if (__str_codecvt_out(__first, __last, __u8str, __cvt))
+ {
+ if constexpr (is_same_v<_CharT, char>)
+ return __u8str;
+ else
+ {
+ _WString __wstr;
+ // use codecvt_utf8<_CharT> to convert UTF-8 to wide string
+ codecvt_utf8<_CharT> __cvt;
+ const char* __f = __u8str.data();
+ const char* __l = __f + __u8str.size();
+ if (__str_codecvt_in(__f, __l, __wstr, __cvt))
+ return __wstr;
+ }
+ }
+#else
+ codecvt_utf8<_CharT> __cvt;
+ basic_string<_CharT, _Traits, _Allocator> __wstr{__a};
+ if (__str_codecvt_in(__first, __last, __wstr, __cvt))
+ return __wstr;
+#endif
+ _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+ "Cannot convert character sequence",
+ std::make_error_code(errc::illegal_byte_sequence)));
+ }
+
+ template<typename _CharT, typename _Traits, typename _Allocator>
+ inline basic_string<_CharT, _Traits, _Allocator>
+ path::string(const _Allocator& __a) const
+ {
+ if constexpr (is_same_v<_CharT, value_type>)
+#if _GLIBCXX_USE_CXX11_ABI
+ return { _M_pathname, __a };
+#else
+ return { _M_pathname, string_type::size_type(0), __a };
+#endif
+ else
+ return _S_str_convert<_CharT, _Traits>(_M_pathname, __a);
+ }
+
+ inline std::string
+ path::string() const { return string<char>(); }
+
+#if _GLIBCXX_USE_WCHAR_T
+ inline std::wstring
+ path::wstring() const { return string<wchar_t>(); }
+#endif
+
+ inline std::string
+ path::u8string() const
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ std::string __str;
+ // convert from native encoding to UTF-8
+ codecvt_utf8<value_type> __cvt;
+ const value_type* __first = _M_pathname.data();
+ const value_type* __last = __first + _M_pathname.size();
+ if (__str_codecvt_out(__first, __last, __str, __cvt))
+ return __str;
+ _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+ "Cannot convert character sequence",
+ std::make_error_code(errc::illegal_byte_sequence)));
+#else
+ return _M_pathname;
+#endif
+ }
+
+ inline std::u16string
+ path::u16string() const { return string<char16_t>(); }
+
+ inline std::u32string
+ path::u32string() const { return string<char32_t>(); }
+
+ template<typename _CharT, typename _Traits, typename _Allocator>
+ inline std::basic_string<_CharT, _Traits, _Allocator>
+ path::generic_string(const _Allocator& __a) const
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ const value_type __slash = L'/';
+#else
+ const value_type __slash = '/';
+#endif
+ string_type __str(__a);
+
+ if (_M_type == _Type::_Root_dir)
+ __str.assign(1, __slash);
+ else
+ {
+ __str.reserve(_M_pathname.size());
+ bool __add_slash = false;
+ for (auto& __elem : *this)
+ {
+ if (__add_slash)
+ __str += __slash;
+ __str += __elem._M_pathname;
+ __add_slash = __elem._M_type == _Type::_Filename;
+ }
+ }
+
+ if constexpr (is_same_v<_CharT, value_type>)
+ return __str;
+ else
+ return _S_str_convert<_CharT, _Traits>(__str, __a);
+ }
+
+ inline std::string
+ path::generic_string() const
+ { return generic_string<char>(); }
+
+#if _GLIBCXX_USE_WCHAR_T
+ inline std::wstring
+ path::generic_wstring() const
+ { return generic_string<wchar_t>(); }
+#endif
+
+ inline std::string
+ path::generic_u8string() const
+ { return generic_string(); }
+
+ inline std::u16string
+ path::generic_u16string() const
+ { return generic_string<char16_t>(); }
+
+ inline std::u32string
+ path::generic_u32string() const
+ { return generic_string<char32_t>(); }
+
+ inline int
+ path::compare(const string_type& __s) const { return compare(path(__s)); }
+
+ inline int
+ path::compare(const value_type* __s) const { return compare(path(__s)); }
+
+ inline int
+ path::compare(basic_string_view<value_type> __s) const
+ { return compare(path(__s)); }
+
+ inline path
+ path::filename() const
+ {
+ if (empty())
+ return {};
+ else if (_M_type == _Type::_Filename)
+ return *this;
+ else if (_M_type == _Type::_Multi)
+ {
+ if (_M_pathname.back() == preferred_separator)
+ return {};
+ auto& __last = *--end();
+ if (__last._M_type == _Type::_Filename)
+ return __last;
+ }
+ return {};
+ }
+
+ inline path
+ path::stem() const
+ {
+ auto ext = _M_find_extension();
+ if (ext.first && ext.second != 0)
+ return path{ext.first->substr(0, ext.second)};
+ return {};
+ }
+
+ inline path
+ path::extension() const
+ {
+ auto ext = _M_find_extension();
+ if (ext.first && ext.second != string_type::npos)
+ return path{ext.first->substr(ext.second)};
+ return {};
+ }
+
+ inline bool
+ path::has_stem() const
+ {
+ auto ext = _M_find_extension();
+ return ext.first && ext.second != 0;
+ }
+
+ inline bool
+ path::has_extension() const
+ {
+ auto ext = _M_find_extension();
+ return ext.first && ext.second != string_type::npos;
+ }
+
+ inline bool
+ path::is_absolute() const
+ {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ return has_root_name();
+#else
+ return has_root_directory();
+#endif
+ }
+
+ inline path::iterator
+ path::begin() const
+ {
+ if (_M_type == _Type::_Multi)
+ return iterator(this, _M_cmpts.begin());
+ return iterator(this, false);
+ }
+
+ inline path::iterator
+ path::end() const
+ {
+ if (_M_type == _Type::_Multi)
+ return iterator(this, _M_cmpts.end());
+ return iterator(this, true);
+ }
+
+ inline path::iterator&
+ path::iterator::operator++()
+ {
+ __glibcxx_assert(_M_path != nullptr);
+ if (_M_path->_M_type == _Type::_Multi)
+ {
+ __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
+ ++_M_cur;
+ }
+ else
+ {
+ __glibcxx_assert(!_M_at_end);
+ _M_at_end = true;
+ }
+ return *this;
+ }
+
+ inline path::iterator&
+ path::iterator::operator--()
+ {
+ __glibcxx_assert(_M_path != nullptr);
+ if (_M_path->_M_type == _Type::_Multi)
+ {
+ __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin());
+ --_M_cur;
+ }
+ else
+ {
+ __glibcxx_assert(_M_at_end);
+ _M_at_end = false;
+ }
+ return *this;
+ }
+
+ inline path::iterator::reference
+ path::iterator::operator*() const
+ {
+ __glibcxx_assert(_M_path != nullptr);
+ if (_M_path->_M_type == _Type::_Multi)
+ {
+ __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end());
+ return *_M_cur;
+ }
+ return *_M_path;
+ }
+
+ inline bool
+ path::iterator::_M_equals(iterator __rhs) const
+ {
+ if (_M_path != __rhs._M_path)
+ return false;
+ if (_M_path == nullptr)
+ return true;
+ if (_M_path->_M_type == path::_Type::_Multi)
+ return _M_cur == __rhs._M_cur;
+ return _M_at_end == __rhs._M_at_end;
+ }
+
+ // @} group filesystem
+_GLIBCXX_END_NAMESPACE_CXX11
+} // namespace filesystem
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++17
+
+#endif // _GLIBCXX_FS_PATH_H
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index da6d49c96c4..e19f92abd76 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -31,7 +31,9 @@
#ifndef _HASHTABLE_POLICY_H
#define _HASHTABLE_POLICY_H 1
-#include <bits/stl_algobase.h> // for std::min.
+#include <tuple> // for std::tuple, std::forward_as_tuple
+#include <cstdint> // for std::uint_fast64_t
+#include <bits/stl_algobase.h> // for std::min.
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/bits/node_handle.h b/libstdc++-v3/include/bits/node_handle.h
index c7694a1e0ef..4a830630c89 100644
--- a/libstdc++-v3/include/bits/node_handle.h
+++ b/libstdc++-v3/include/bits/node_handle.h
@@ -37,7 +37,6 @@
# define __cpp_lib_node_extract 201606
#include <optional>
-#include <tuple>
#include <bits/alloc_traits.h>
#include <bits/ptr_traits.h>
@@ -283,26 +282,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Iterator position = _Iterator();
bool inserted = false;
_NodeHandle node;
-
- template<size_t _Idx>
- decltype(auto) get() &
- { return std::get<_Idx>(std::tie(inserted, position, node)); }
-
- template<size_t _Idx>
- decltype(auto) get() const &
- { return std::get<_Idx>(std::tie(inserted, position, node)); }
-
- template<size_t _Idx>
- decltype(auto) get() &&
- {
- return std::move(std::get<_Idx>(std::tie(inserted, position, node)));
- }
-
- template<size_t _Idx>
- decltype(auto) get() const &&
- {
- return std::move(std::get<_Idx>(std::tie(inserted, position, node)));
- }
};
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/specfun.h b/libstdc++-v3/include/bits/specfun.h
index 0aaebeab7ac..6bb3ec09681 100644
--- a/libstdc++-v3/include/bits/specfun.h
+++ b/libstdc++-v3/include/bits/specfun.h
@@ -1201,6 +1201,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
+#ifndef __STRICT_ANSI__
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -1305,6 +1306,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx
+#endif // __STRICT_ANSI__
#pragma GCC visibility pop
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index ea413b1b155..b5facef55dd 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -180,7 +180,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_InputIterator
__find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred)
{
- for (; __len; --__len, ++__first)
+ for (; __len; --__len, (void) ++__first)
if (!__pred(__first))
break;
return __first;
@@ -4462,7 +4462,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__typeof__(__gen())>)
for (__decltype(__n + 0) __niter = __n;
- __niter > 0; --__niter, ++__first)
+ __niter > 0; --__niter, (void) ++__first)
*__first = __gen();
return __first;
}
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index a80934c4faa..bfdfc7ded5e 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -738,7 +738,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
{
for (__decltype(__n + 0) __niter = __n;
- __niter > 0; --__niter, ++__first)
+ __niter > 0; --__niter, (void) ++__first)
*__first = __value;
return __first;
}
@@ -750,7 +750,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
const _Tp __tmp = __value;
for (__decltype(__n + 0) __niter = __n;
- __niter > 0; --__niter, ++__first)
+ __niter > 0; --__niter, (void) ++__first)
*__first = __tmp;
return __first;
}
@@ -796,7 +796,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static bool
equal(_II1 __first1, _II1 __last1, _II2 __first2)
{
- for (; __first1 != __last1; ++__first1, (void)++__first2)
+ for (; __first1 != __last1; ++__first1, (void) ++__first2)
if (!(*__first1 == *__first2))
return false;
return true;
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index d24e760d01b..ac548846b0e 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -417,7 +417,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (__last._M_offset != 0)
__fill_bvector(__last._M_p, 0, __last._M_offset, __x);
}
- else
+ else if (__first._M_offset != __last._M_offset)
__fill_bvector(__first._M_p, __first._M_offset, __last._M_offset, __x);
}
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index 88667a568c3..74ef0d9bf88 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1244,6 +1244,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter)
#endif // C++11
+#if __cpp_deduction_guides >= 201606
+ // These helper traits are used for deduction guides
+ // of associative containers.
+ template<typename _InputIterator>
+ using __iter_key_t = remove_const_t<
+ typename iterator_traits<_InputIterator>::value_type::first_type>;
+
+ template<typename _InputIterator>
+ using __iter_val_t =
+ typename iterator_traits<_InputIterator>::value_type::second_type;
+
+ template<typename _T1, typename _T2>
+ struct pair;
+
+ template<typename _InputIterator>
+ using __iter_to_alloc_t =
+ pair<add_const_t<__iter_key_t<_InputIterator>>,
+ __iter_val_t<_InputIterator>>;
+
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index 0e8a98a96c1..8a9e6c9c329 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -778,7 +778,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief Attempts to insert a std::pair into the %map.
-
* @param __x Pair to be inserted (see std::make_pair for easy
* creation of pairs).
*
@@ -791,12 +790,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* first element (the key) is not already present in the %map.
*
* Insertion requires logarithmic time.
+ * @{
*/
std::pair<iterator, bool>
insert(const value_type& __x)
{ return _M_t._M_insert_unique(__x); }
#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2354. Unnecessary copying when inserting into maps with braced-init
+ std::pair<iterator, bool>
+ insert(value_type&& __x)
+ { return _M_t._M_insert_unique(std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -804,6 +810,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(_Pair&& __x)
{ return _M_t._M_insert_unique(std::forward<_Pair>(__x)); }
#endif
+ // @}
#if __cplusplus >= 201103L
/**
@@ -840,6 +847,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* for more on @a hinting.
*
* Insertion requires logarithmic time (if the hint is not taken).
+ * @{
*/
iterator
#if __cplusplus >= 201103L
@@ -850,6 +858,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return _M_t._M_insert_unique_(__position, __x); }
#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2354. Unnecessary copying when inserting into maps with braced-init
+ iterator
+ insert(const_iterator __position, value_type&& __x)
+ { return _M_t._M_insert_unique_(__position, std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -858,6 +872,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return _M_t._M_insert_unique_(__position,
std::forward<_Pair>(__x)); }
#endif
+ // @}
/**
* @brief Template function that attempts to insert a range of elements.
@@ -1366,6 +1381,40 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const map<_K1, _T1, _C1, _A1>&);
};
+
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare = less<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ map(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ _Compare, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ map(initializer_list<pair<_Key, _Tp>>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> map<_Key, _Tp, _Compare, _Allocator>;
+
+ template <typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ map(_InputIterator, _InputIterator, _Allocator)
+ -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ less<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ map(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> map<_Key, _Tp, less<_Key>, _Allocator>;
+
+#endif
+
/**
* @brief Map equality comparison.
* @param __x A %map.
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 7e3cea48a47..1a16bf982e3 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -526,12 +526,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* thus multiple pairs with the same key can be inserted.
*
* Insertion requires logarithmic time.
+ * @{
*/
iterator
insert(const value_type& __x)
{ return _M_t._M_insert_equal(__x); }
#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2354. Unnecessary copying when inserting into maps with braced-init
+ iterator
+ insert(value_type&& __x)
+ { return _M_t._M_insert_equal(std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -539,6 +546,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(_Pair&& __x)
{ return _M_t._M_insert_equal(std::forward<_Pair>(__x)); }
#endif
+ // @}
/**
* @brief Inserts a std::pair into the %multimap.
@@ -559,6 +567,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
*
* Insertion requires logarithmic time (if the hint is not taken).
+ * @{
*/
iterator
#if __cplusplus >= 201103L
@@ -569,6 +578,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return _M_t._M_insert_equal_(__position, __x); }
#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2354. Unnecessary copying when inserting into maps with braced-init
+ iterator
+ insert(const_iterator __position, value_type&& __x)
+ { return _M_t._M_insert_equal_(__position, std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -577,6 +592,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return _M_t._M_insert_equal_(__position,
std::forward<_Pair>(__x)); }
#endif
+ // @}
/**
* @brief A template function that attempts to insert a range
@@ -1031,6 +1047,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const multimap<_K1, _T1, _C1, _A1>&);
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare = less<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ _Compare, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(initializer_list<pair<_Key, _Tp>>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multimap<_Key, _Tp, _Compare, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(_InputIterator, _InputIterator, _Allocator)
+ -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ less<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> multimap<_Key, _Tp, less<_Key>, _Allocator>;
+
+#endif
+
/**
* @brief Multimap equality comparison.
* @param __x A %multimap.
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 517e77e9372..d34b6758e18 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -881,6 +881,43 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const multiset<_K1, _C1, _A1>&);
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare =
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multiset<typename iterator_traits<_InputIterator>::value_type,
+ _Compare, _Allocator>;
+
+ template<typename _Key,
+ typename _Compare = less<_Key>,
+ typename _Allocator = allocator<_Key>,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(initializer_list<_Key>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multiset<_Key, _Compare, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(_InputIterator, _InputIterator, _Allocator)
+ -> multiset<typename iterator_traits<_InputIterator>::value_type,
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Key, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(initializer_list<_Key>, _Allocator)
+ -> multiset<_Key, less<_Key>, _Allocator>;
+
+#endif
+
/**
* @brief Multiset equality comparison.
* @param __x A %multiset.
@@ -971,6 +1008,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
_S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set)
{ return __set._M_t; }
};
+
#endif // C++17
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index e804a7cae70..3a7992c4dab 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -898,6 +898,41 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare =
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ set(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> set<typename iterator_traits<_InputIterator>::value_type,
+ _Compare, _Allocator>;
+
+ template<typename _Key, typename _Compare = less<_Key>,
+ typename _Allocator = allocator<_Key>,
+ typename = _RequireAllocator<_Allocator>>
+ set(initializer_list<_Key>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> set<_Key, _Compare, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ set(_InputIterator, _InputIterator, _Allocator)
+ -> set<typename iterator_traits<_InputIterator>::value_type,
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Key, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ set(initializer_list<_Key>, _Allocator)
+ -> set<_Key, less<_Key>, _Allocator>;
+
+#endif
/**
* @brief Set equality comparison.
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index c2ba863ed98..bac3fd01f7a 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -206,7 +206,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ForwardIterator __cur = __first;
__try
{
- for (; __n > 0; --__n, ++__cur)
+ for (; __n > 0; --__n, (void) ++__cur)
std::_Construct(std::__addressof(*__cur), __x);
return __cur;
}
@@ -347,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__try
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
- for (; __n > 0; --__n, ++__cur)
+ for (; __n > 0; --__n, (void) ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur), __x);
return __cur;
}
@@ -523,7 +523,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ForwardIterator __cur = __first;
__try
{
- for (; __n > 0; --__n, ++__cur)
+ for (; __n > 0; --__n, (void) ++__cur)
std::_Construct(std::__addressof(*__cur));
return __cur;
}
@@ -627,7 +627,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__try
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
- for (; __n > 0; --__n, ++__cur)
+ for (; __n > 0; --__n, (void) ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur));
return __cur;
}
@@ -687,7 +687,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ForwardIterator __cur = __first;
__try
{
- for (; __n > 0; --__n, ++__cur)
+ for (; __n > 0; --__n, (void) ++__cur)
std::_Construct_novalue(std::__addressof(*__cur));
return __cur;
}
@@ -747,7 +747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ForwardIterator __cur = __result;
__try
{
- for (; __n > 0; --__n, ++__first, ++__cur)
+ for (; __n > 0; --__n, (void) ++__first, ++__cur)
std::_Construct(std::__addressof(*__cur), *__first);
return __cur;
}
@@ -775,7 +775,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ForwardIterator __cur = __result;
__try
{
- for (; __n > 0; --__n, ++__first, ++__cur)
+ for (; __n > 0; --__n, (void) ++__first, ++__cur)
std::_Construct(std::__addressof(*__cur), *__first);
return {__first, __cur};
}
diff --git a/libstdc++-v3/include/bits/string_view.tcc b/libstdc++-v3/include/bits/string_view.tcc
index 4d98f8668a0..5c53c584381 100644
--- a/libstdc++-v3/include/bits/string_view.tcc
+++ b/libstdc++-v3/include/bits/string_view.tcc
@@ -119,7 +119,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr 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
+ find_first_of(const _CharT* __str, size_type __pos,
+ size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
for (; __n && __pos < this->_M_len; ++__pos)
@@ -135,7 +136,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr 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
+ find_last_of(const _CharT* __str, size_type __pos,
+ size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
size_type __size = this->size();
@@ -156,7 +158,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr 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
+ find_first_not_of(const _CharT* __str, size_type __pos,
+ size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
for (; __pos < this->_M_len; ++__pos)
@@ -179,7 +182,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr 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
+ find_last_not_of(const _CharT* __str, size_type __pos,
+ size_type __n) const noexcept
{
__glibcxx_requires_string_len(__str, __n);
size_type __size = this->_M_len;
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index df1302c80c0..385e4bd4df4 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -579,6 +579,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(const value_type& __x)
{ return _M_h.insert(__x); }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2354. Unnecessary copying when inserting into maps with braced-init
+ std::pair<iterator, bool>
+ insert(value_type&& __x)
+ { return _M_h.insert(std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -613,6 +619,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(const_iterator __hint, const value_type& __x)
{ return _M_h.insert(__hint, __x); }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2354. Unnecessary copying when inserting into maps with braced-init
+ iterator
+ insert(const_iterator __hint, value_type&& __x)
+ { return _M_h.insert(__hint, std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -1118,6 +1130,82 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&);
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash = hash<__iter_key_t<_InputIterator>>,
+ typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator,
+ typename unordered_map<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ _Hash, _Pred, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
+ typename _Pred = equal_to<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>,
+ typename unordered_map<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator,
+ typename unordered_map<int, int>::size_type, _Allocator)
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator, _Allocator)
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator,
+ typename unordered_map<int, int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>, _Hash,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>,
+ typename unordered_map<int, int>::size_type,
+ _Allocator)
+ -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>,
+ typename unordered_map<int, int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
+
+#endif
+
/**
* @brief A standard container composed of equivalent keys
* (possibly containing multiple of each key value) that associates
@@ -1468,6 +1556,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(const value_type& __x)
{ return _M_h.insert(__x); }
+ iterator
+ insert(value_type&& __x)
+ { return _M_h.insert(std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -1500,6 +1592,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(const_iterator __hint, const value_type& __x)
{ return _M_h.insert(__hint, __x); }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2354. Unnecessary copying when inserting into maps with braced-init
+ iterator
+ insert(const_iterator __hint, value_type&& __x)
+ { return _M_h.insert(__hint, std::move(__x)); }
+
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
@@ -1871,6 +1969,82 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Hash1, _Pred1, _Alloc1>&);
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash = hash<__iter_key_t<_InputIterator>>,
+ typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator,
+ unordered_multimap<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>, _Hash, _Pred,
+ _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
+ typename _Pred = equal_to<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>,
+ unordered_multimap<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator,
+ unordered_multimap<int, int>::size_type, _Allocator)
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator, _Allocator)
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator,
+ unordered_multimap<int, int>::size_type, _Hash,
+ _Allocator)
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>, _Hash,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>,
+ unordered_multimap<int, int>::size_type,
+ _Allocator)
+ -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>,
+ unordered_multimap<int, int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
+
+#endif
+
template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
inline void
swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index df57915f31a..416dbbcfb96 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -805,6 +805,70 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&);
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash =
+ hash<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Pred =
+ equal_to<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(_InputIterator, _InputIterator,
+ unordered_set<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
+ _Hash, _Pred, _Allocator>;
+
+ template<typename _Tp, typename _Hash = hash<_Tp>,
+ typename _Pred = equal_to<_Tp>,
+ typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(initializer_list<_Tp>,
+ unordered_set<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(_InputIterator, _InputIterator,
+ unordered_set<int>::size_type, _Allocator)
+ -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
+ hash<
+ typename iterator_traits<_InputIterator>::value_type>,
+ equal_to<
+ typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(_InputIterator, _InputIterator,
+ unordered_set<int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
+ _Hash,
+ equal_to<
+ typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(initializer_list<_Tp>,
+ unordered_set<int>::size_type, _Allocator)
+ -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
+
+ template<typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(initializer_list<_Tp>,
+ unordered_set<int>::size_type, _Hash, _Allocator)
+ -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
+
+#endif
+
/**
* @brief A standard container composed of equivalent keys
* (possibly containing multiple of each key value) in which the
@@ -1517,6 +1581,75 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&);
};
+
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash =
+ hash<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Pred =
+ equal_to<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(_InputIterator, _InputIterator,
+ unordered_multiset<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
+ _Hash, _Pred, _Allocator>;
+
+ template<typename _Tp, typename _Hash = hash<_Tp>,
+ typename _Pred = equal_to<_Tp>,
+ typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(initializer_list<_Tp>,
+ unordered_multiset<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(_InputIterator, _InputIterator,
+ unordered_multiset<int>::size_type, _Allocator)
+ -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
+ hash<typename
+ iterator_traits<_InputIterator>::value_type>,
+ equal_to<typename
+ iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(_InputIterator, _InputIterator,
+ unordered_multiset<int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_multiset<typename
+ iterator_traits<_InputIterator>::value_type,
+ _Hash,
+ equal_to<
+ typename
+ iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(initializer_list<_Tp>,
+ unordered_multiset<int>::size_type, _Allocator)
+ -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
+
+ template<typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(initializer_list<_Tp>,
+ unordered_multiset<int>::size_type, _Hash, _Allocator)
+ -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
+
+#endif
+
template<class _Value, class _Hash, class _Pred, class _Alloc>
inline void
swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
diff --git a/libstdc++-v3/include/c_compatibility/math.h b/libstdc++-v3/include/c_compatibility/math.h
index 84755c8c35c..28c7c8368f0 100644
--- a/libstdc++-v3/include/c_compatibility/math.h
+++ b/libstdc++-v3/include/c_compatibility/math.h
@@ -111,7 +111,7 @@ using std::tgamma;
using std::trunc;
#endif // C++11 && _GLIBCXX_USE_C99_MATH_TR1
-#if __STDCPP_WANT_MATH_SPEC_FUNCS__ == 1
+#if _GLIBCXX_USE_STD_SPEC_FUNCS
using std::assoc_laguerref;
using std::assoc_laguerrel;
using std::assoc_laguerre;
@@ -175,7 +175,7 @@ using std::sph_legendre;
using std::sph_neumannf;
using std::sph_neumannl;
using std::sph_neumann;
-#endif // __STDCPP_WANT_MATH_SPEC_FUNCS__
+#endif // _GLIBCXX_USE_STD_SPEC_FUNCS
#endif // _GLIBCXX_MATH_H
#endif // __cplusplus
diff --git a/libstdc++-v3/include/c_global/cstddef b/libstdc++-v3/include/c_global/cstddef
index 09754ee45da..11d268b7f81 100644
--- a/libstdc++-v3/include/c_global/cstddef
+++ b/libstdc++-v3/include/c_global/cstddef
@@ -57,9 +57,11 @@ namespace std
}
#endif
-#if __cplusplus > 201402L
+#if __cplusplus >= 201703L
namespace std
{
+#define __cpp_lib_byte 201603
+
/// std::byte
enum class byte : unsigned char {};
diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array
index 9c279221040..95edc84f38b 100644
--- a/libstdc++-v3/include/debug/array
+++ b/libstdc++-v3/include/debug/array
@@ -306,6 +306,14 @@ namespace __debug
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
_S_ref(__arr._M_elems, _Int);
}
+
+ template<std::size_t _Int, typename _Tp, std::size_t _Nm>
+ constexpr const _Tp&&
+ get(const array<_Tp, _Nm>&& __arr) noexcept
+ {
+ static_assert(_Int < _Nm, "index is out of bounds");
+ return std::move(__debug::get<_Int>(__arr));
+ }
} // namespace __debug
_GLIBCXX_BEGIN_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index 7e3c193c103..5816b4b1624 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -624,6 +624,16 @@ namespace __debug
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
};
+#if __cpp_deduction_guides >= 201606
+ template<typename _InputIterator, typename _ValT
+ = typename iterator_traits<_InputIterator>::value_type,
+ typename _Allocator = allocator<_ValT>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ deque(_InputIterator, _InputIterator, _Allocator = _Allocator())
+ -> deque<_ValT, _Allocator>;
+#endif
+
template<typename _Tp, typename _Alloc>
inline bool
operator==(const deque<_Tp, _Alloc>& __lhs,
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index cd343302b00..20c7ebe4a8f 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -772,6 +772,16 @@ namespace __debug
_M_base() const noexcept { return *this; }
};
+#if __cpp_deduction_guides >= 201606
+ template<typename _InputIterator, typename _ValT
+ = typename iterator_traits<_InputIterator>::value_type,
+ typename _Allocator = allocator<_ValT>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ forward_list(_InputIterator, _InputIterator, _Allocator = _Allocator())
+ -> forward_list<_ValT, _Allocator>;
+#endif
+
template<typename _Tp, typename _Alloc>
bool
operator==(const forward_list<_Tp, _Alloc>& __lx,
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index a45ece244bd..94d325c6e6a 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -769,6 +769,16 @@ namespace __debug
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
};
+#if __cpp_deduction_guides >= 201606
+ template<typename _InputIterator, typename _ValT
+ = typename iterator_traits<_InputIterator>::value_type,
+ typename _Allocator = allocator<_ValT>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ list(_InputIterator, _InputIterator, _Allocator = _Allocator())
+ -> list<_ValT, _Allocator>;
+#endif
+
template<typename _Tp, typename _Alloc>
inline bool
operator==(const list<_Tp, _Alloc>& __lhs,
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index c275979052c..d5a2c9f6e6f 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -667,6 +667,39 @@ namespace __debug
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare = less<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ map(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ _Compare, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ map(initializer_list<pair<_Key, _Tp>>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> map<_Key, _Tp, _Compare, _Allocator>;
+
+ template <typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ map(_InputIterator, _InputIterator, _Allocator)
+ -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ less<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ map(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> map<_Key, _Tp, less<_Key>, _Allocator>;
+
+#endif
+
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index f971cfa41f0..6c7b2ab4f8d 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -555,6 +555,39 @@ namespace __debug
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare = less<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ _Compare, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(initializer_list<pair<_Key, _Tp>>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multimap<_Key, _Tp, _Compare, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(_InputIterator, _InputIterator, _Allocator)
+ -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
+ less<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> multimap<_Key, _Tp, less<_Key>, _Allocator>;
+
+#endif
+
template<typename _Key, typename _Tp,
typename _Compare, typename _Allocator>
inline bool
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index 97c7b843f27..59331b4bc6b 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -542,6 +542,43 @@ namespace __debug
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare =
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multiset<typename iterator_traits<_InputIterator>::value_type,
+ _Compare, _Allocator>;
+
+ template<typename _Key,
+ typename _Compare = less<_Key>,
+ typename _Allocator = allocator<_Key>,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(initializer_list<_Key>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> multiset<_Key, _Compare, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(_InputIterator, _InputIterator, _Allocator)
+ -> multiset<typename iterator_traits<_InputIterator>::value_type,
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Key, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ multiset(initializer_list<_Key>, _Allocator)
+ -> multiset<_Key, less<_Key>, _Allocator>;
+
+#endif
+
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator==(const multiset<_Key, _Compare, _Allocator>& __lhs,
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index 07032865bc9..5353cfe87b2 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -560,6 +560,42 @@ namespace __debug
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Compare =
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ set(_InputIterator, _InputIterator,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> set<typename iterator_traits<_InputIterator>::value_type,
+ _Compare, _Allocator>;
+
+ template<typename _Key, typename _Compare = less<_Key>,
+ typename _Allocator = allocator<_Key>,
+ typename = _RequireAllocator<_Allocator>>
+ set(initializer_list<_Key>,
+ _Compare = _Compare(), _Allocator = _Allocator())
+ -> set<_Key, _Compare, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ set(_InputIterator, _InputIterator, _Allocator)
+ -> set<typename iterator_traits<_InputIterator>::value_type,
+ less<typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Key, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ set(initializer_list<_Key>, _Allocator)
+ -> set<_Key, less<_Key>, _Allocator>;
+
+#endif
+
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
operator==(const set<_Key, _Compare, _Allocator>& __lhs,
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index 51a55ae21f3..c5734304846 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -616,6 +616,82 @@ namespace __debug
}
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash = hash<__iter_key_t<_InputIterator>>,
+ typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator,
+ typename unordered_map<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ _Hash, _Pred, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
+ typename _Pred = equal_to<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>,
+ typename unordered_map<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator,
+ typename unordered_map<int, int>::size_type, _Allocator)
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator, _Allocator)
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(_InputIterator, _InputIterator,
+ typename unordered_map<int, int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_map<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>, _Hash,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>,
+ typename unordered_map<int, int>::size_type,
+ _Allocator)
+ -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_map(initializer_list<pair<_Key, _Tp>>,
+ typename unordered_map<int, int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
+
+#endif
+
template<typename _Key, typename _Tp, typename _Hash,
typename _Pred, typename _Alloc>
inline void
@@ -1110,6 +1186,82 @@ namespace __debug
}
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash = hash<__iter_key_t<_InputIterator>>,
+ typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
+ typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator,
+ unordered_multimap<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>, _Hash, _Pred,
+ _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
+ typename _Pred = equal_to<_Key>,
+ typename _Allocator = allocator<pair<const _Key, _Tp>>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>,
+ unordered_multimap<int, int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator,
+ unordered_multimap<int, int>::size_type, _Allocator)
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator, _Allocator)
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>,
+ hash<__iter_key_t<_InputIterator>>,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(_InputIterator, _InputIterator,
+ unordered_multimap<int, int>::size_type, _Hash,
+ _Allocator)
+ -> unordered_multimap<__iter_key_t<_InputIterator>,
+ __iter_val_t<_InputIterator>, _Hash,
+ equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>,
+ unordered_multimap<int, int>::size_type,
+ _Allocator)
+ -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
+ -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
+
+ template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multimap(initializer_list<pair<_Key, _Tp>>,
+ unordered_multimap<int, int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
+
+#endif
+
template<typename _Key, typename _Tp, typename _Hash,
typename _Pred, typename _Alloc>
inline void
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index 923ff2bc4d8..1fe493fe52f 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -530,6 +530,70 @@ namespace __debug
}
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash =
+ hash<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Pred =
+ equal_to<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(_InputIterator, _InputIterator,
+ unordered_set<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
+ _Hash, _Pred, _Allocator>;
+
+ template<typename _Tp, typename _Hash = hash<_Tp>,
+ typename _Pred = equal_to<_Tp>,
+ typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(initializer_list<_Tp>,
+ unordered_set<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+ -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(_InputIterator, _InputIterator,
+ unordered_set<int>::size_type, _Allocator)
+ -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
+ hash<
+ typename iterator_traits<_InputIterator>::value_type>,
+ equal_to<
+ typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(_InputIterator, _InputIterator,
+ unordered_set<int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
+ _Hash,
+ equal_to<
+ typename iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(initializer_list<_Tp>,
+ unordered_set<int>::size_type, _Allocator)
+ -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
+
+ template<typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_set(initializer_list<_Tp>,
+ unordered_set<int>::size_type, _Hash, _Allocator)
+ -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
+
+#endif
+
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
inline void
swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
@@ -1012,6 +1076,74 @@ namespace __debug
}
};
+#if __cpp_deduction_guides >= 201606
+
+ template<typename _InputIterator,
+ typename _Hash =
+ hash<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Pred =
+ equal_to<typename iterator_traits<_InputIterator>::value_type>,
+ typename _Allocator =
+ allocator<typename iterator_traits<_InputIterator>::value_type>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(_InputIterator, _InputIterator,
+ unordered_multiset<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
+ _Hash, _Pred, _Allocator>;
+
+ template<typename _Tp, typename _Hash = hash<_Tp>,
+ typename _Pred = equal_to<_Tp>,
+ typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(initializer_list<_Tp>,
+ unordered_multiset<int>::size_type = {},
+ _Hash = _Hash(), _Pred = _Pred(),
+ _Allocator = _Allocator())
+ -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
+
+ template<typename _InputIterator, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(_InputIterator, _InputIterator,
+ unordered_multiset<int>::size_type, _Allocator)
+ -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
+ hash<typename
+ iterator_traits<_InputIterator>::value_type>,
+ equal_to<typename
+ iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _InputIterator, typename _Hash, typename _Allocator,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(_InputIterator, _InputIterator,
+ unordered_multiset<int>::size_type,
+ _Hash, _Allocator)
+ -> unordered_multiset<typename
+ iterator_traits<_InputIterator>::value_type,
+ _Hash,
+ equal_to<
+ typename
+ iterator_traits<_InputIterator>::value_type>,
+ _Allocator>;
+
+ template<typename _Tp, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(initializer_list<_Tp>,
+ unordered_multiset<int>::size_type, _Allocator)
+ -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
+
+ template<typename _Tp, typename _Hash, typename _Allocator,
+ typename = _RequireAllocator<_Allocator>>
+ unordered_multiset(initializer_list<_Tp>,
+ unordered_multiset<int>::size_type, _Hash, _Allocator)
+ -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
+
+#endif
+
template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
inline void
swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index a6d18d94508..c24c2f3d45f 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -757,6 +757,16 @@ namespace __debug
_GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
{ __lhs.swap(__rhs); }
+#if __cpp_deduction_guides >= 201606
+ template<typename _InputIterator, typename _ValT
+ = typename iterator_traits<_InputIterator>::value_type,
+ typename _Allocator = allocator<_ValT>,
+ typename = _RequireInputIter<_InputIterator>,
+ typename = _RequireAllocator<_Allocator>>
+ vector(_InputIterator, _InputIterator, _Allocator = _Allocator())
+ -> vector<_ValT, _Allocator>;
+#endif
+
} // namespace __debug
#if __cplusplus >= 201103L
diff --git a/libstdc++-v3/include/experimental/bits/fs_dir.h b/libstdc++-v3/include/experimental/bits/fs_dir.h
index 1ff0d9b6def..ecadf37a9cd 100644
--- a/libstdc++-v3/include/experimental/bits/fs_dir.h
+++ b/libstdc++-v3/include/experimental/bits/fs_dir.h
@@ -49,7 +49,7 @@ namespace filesystem
inline namespace v1
{
/**
- * @ingroup filesystem
+ * @ingroup filesystem-ts
* @{
*/
@@ -351,7 +351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_GLIBCXX_END_NAMESPACE_CXX11
- // @} group filesystem
+ // @} group filesystem-ts
} // namespace v1
} // namespace filesystem
} // namespace experimental
diff --git a/libstdc++-v3/include/experimental/bits/fs_fwd.h b/libstdc++-v3/include/experimental/bits/fs_fwd.h
index 7b851a3d4a8..ac43c5f44f5 100644
--- a/libstdc++-v3/include/experimental/bits/fs_fwd.h
+++ b/libstdc++-v3/include/experimental/bits/fs_fwd.h
@@ -53,7 +53,7 @@ inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
#endif
/**
- * @defgroup filesystem Filesystem
+ * @defgroup filesystem-ts Filesystem TS
* @ingroup experimental
*
* Utilities for performing operations on file systems and their components,
@@ -278,7 +278,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
bool is_regular_file(file_status) noexcept;
bool is_symlink(file_status) noexcept;
- // @} group filesystem
+ // @} group filesystem-ts
} // namespace v1
} // namespace filesystem
} // namespace experimental
diff --git a/libstdc++-v3/include/experimental/bits/fs_ops.h b/libstdc++-v3/include/experimental/bits/fs_ops.h
index 387537260e0..fa7f1de6bc4 100644
--- a/libstdc++-v3/include/experimental/bits/fs_ops.h
+++ b/libstdc++-v3/include/experimental/bits/fs_ops.h
@@ -47,7 +47,7 @@ namespace filesystem
inline namespace v1
{
/**
- * @ingroup filesystem
+ * @ingroup filesystem-ts
* @{
*/
@@ -285,7 +285,7 @@ inline namespace v1
path temp_directory_path();
path temp_directory_path(error_code& __ec);
- // @} group filesystem
+ // @} group filesystem-ts
} // namespace v1
} // namespace filesystem
} // namespace experimental
diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h
index cde3897b8e5..3e9bc6357af 100644
--- a/libstdc++-v3/include/experimental/bits/fs_path.h
+++ b/libstdc++-v3/include/experimental/bits/fs_path.h
@@ -72,7 +72,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
#endif
/**
- * @ingroup filesystem
+ * @ingroup filesystem-ts
* @{
*/
@@ -725,10 +725,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
pointer operator->() const { return std::__addressof(**this); }
iterator& operator++();
- iterator operator++(int) { auto __tmp = *this; ++_M_cur; return __tmp; }
+ iterator operator++(int) { auto __tmp = *this; ++*this; return __tmp; }
iterator& operator--();
- iterator operator--(int) { auto __tmp = *this; --_M_cur; return __tmp; }
+ iterator operator--(int) { auto __tmp = *this; --*this; return __tmp; }
friend bool operator==(const iterator& __lhs, const iterator& __rhs)
{ return __lhs._M_equals(__rhs); }
@@ -1079,7 +1079,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return _M_at_end == __rhs._M_at_end;
}
- // @} group filesystem
+ // @} group filesystem-ts
_GLIBCXX_END_NAMESPACE_CXX11
} // namespace v1
} // namespace filesystem
diff --git a/libstdc++-v3/include/experimental/filesystem b/libstdc++-v3/include/experimental/filesystem
index f0b19dd2910..90f6f9eabfe 100644
--- a/libstdc++-v3/include/experimental/filesystem
+++ b/libstdc++-v3/include/experimental/filesystem
@@ -40,36 +40,6 @@
#define __cpp_lib_experimental_filesystem 201406
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-namespace experimental
-{
-namespace filesystem
-{
-inline namespace v1
-{
- /**
- * @ingroup filesystem
- */
- inline std::string filesystem_error::_M_gen_what()
- {
- std::string __what = "filesystem error: ";
- __what += system_error::what();
- if (!_M_path1.empty())
- __what += " [" + _M_path1.string() + ']';
- if (!_M_path2.empty())
- __what += " [" + _M_path2.string() + ']';
- return __what;
- }
-} // namespace v1
-} // namespace filesystem
-} // namespace experimental
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace std
-
#endif // C++11
#endif // _GLIBCXX_EXPERIMENTAL_FILESYSTEM
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
index f05f152302a..8eaf9ec3d96 100644
--- a/libstdc++-v3/include/experimental/string_view
+++ b/libstdc++-v3/include/experimental/string_view
@@ -645,22 +645,22 @@ namespace experimental
inline namespace string_view_literals
{
inline constexpr basic_string_view<char>
- operator""sv(const char* __str, size_t __len)
+ operator""sv(const char* __str, size_t __len) noexcept
{ return basic_string_view<char>{__str, __len}; }
#ifdef _GLIBCXX_USE_WCHAR_T
inline constexpr basic_string_view<wchar_t>
- operator""sv(const wchar_t* __str, size_t __len)
+ operator""sv(const wchar_t* __str, size_t __len) noexcept
{ return basic_string_view<wchar_t>{__str, __len}; }
#endif
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
inline constexpr basic_string_view<char16_t>
- operator""sv(const char16_t* __str, size_t __len)
+ operator""sv(const char16_t* __str, size_t __len) noexcept
{ return basic_string_view<char16_t>{__str, __len}; }
inline constexpr basic_string_view<char32_t>
- operator""sv(const char32_t* __str, size_t __len)
+ operator""sv(const char32_t* __str, size_t __len) noexcept
{ return basic_string_view<char32_t>{__str, __len}; }
#endif
} // namespace string_literals
diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h
index b2993cd379f..4e1a71afeb0 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -122,6 +122,7 @@
#include <shared_mutex>
#endif
-#if __cplusplus > 201402L
+#if __cplusplus >= 201703L
#include <charconv>
+#include <filesystem>
#endif
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 1c7d6dc4ab1..01f7100bae0 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -328,6 +328,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_S_ref(__arr._M_elems, _Int);
}
+ template<std::size_t _Int, typename _Tp, std::size_t _Nm>
+ constexpr const _Tp&&
+ get(const array<_Tp, _Nm>&& __arr) noexcept
+ {
+ static_assert(_Int < _Nm, "array index is within bounds");
+ return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
+ }
+
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
@@ -339,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// tuple_size
template<typename _Tp>
- class tuple_size;
+ struct tuple_size;
/// Partial specialization for std::array
template<typename _Tp, std::size_t _Nm>
@@ -348,7 +356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// tuple_element
template<std::size_t _Int, typename _Tp>
- class tuple_element;
+ struct tuple_element;
/// Partial specialization for std::array
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index fc058fcd8d8..9491508e637 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -214,8 +214,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
treat_as_floating_point<_Rep>::value;
#endif // C++17
-#if __cplusplus > 201402L
-# define __cpp_lib_chrono 201510
+#if __cplusplus >= 201703L
+# define __cpp_lib_chrono 201611
template<typename _ToDur, typename _Rep, typename _Period>
constexpr __enable_if_is_duration<_ToDur>
diff --git a/libstdc++-v3/include/std/filesystem b/libstdc++-v3/include/std/filesystem
new file mode 100644
index 00000000000..b09997704c1
--- /dev/null
+++ b/libstdc++-v3/include/std/filesystem
@@ -0,0 +1,45 @@
+// <filesystem> -*- C++ -*-
+
+// Copyright (C) 2014-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// 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 filesystem
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_FILESYSTEM
+#define _GLIBCXX_FILESYSTEM 1
+
+#pragma GCC system_header
+
+#if __cplusplus >= 201703L
+
+#include <bits/fs_fwd.h>
+#include <bits/fs_path.h>
+#include <bits/fs_dir.h>
+#include <bits/fs_ops.h>
+
+#define __cpp_lib_filesystem 201703
+
+#endif // C++17
+
+#endif // _GLIBCXX_FILESYSTEM
diff --git a/libstdc++-v3/include/std/fstream b/libstdc++-v3/include/std/fstream
index 52830945fe2..a3324c004d7 100644
--- a/libstdc++-v3/include/std/fstream
+++ b/libstdc++-v3/include/std/fstream
@@ -216,6 +216,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+#if __cplusplus >= 201703L
+ template<typename _Path, typename _Result = _Path, typename _Path2
+ = decltype(std::declval<_Path&>().make_preferred().native())>
+ using _If_path = enable_if_t<is_same_v<_Path, _Path2>, _Result>;
+#endif // C++17
+
public:
// Constructors/destructor:
/**
@@ -306,7 +312,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__filebuf_type*
open(const std::string& __s, ios_base::openmode __mode)
{ return open(__s.c_str(), __mode); }
-#endif
+
+#if __cplusplus >= 201703L
+ /**
+ * @brief Opens an external file.
+ * @param __s The name of the file, as a filesystem::path.
+ * @param __mode The open mode flags.
+ * @return @c this on success, NULL on failure
+ */
+ template<typename _Path>
+ _If_path<_Path, __filebuf_type*>
+ open(const _Path& __s, ios_base::openmode __mode)
+ { return open(__s.c_str(), __mode); }
+#endif // C++17
+#endif // C++11
/**
* @brief Closes the currently associated file.
@@ -487,9 +506,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __mode Open file in specified mode (see std::ios_base).
*
* @c ios_base::in is automatically included in @a __mode.
- *
- * Tip: When using std::string to hold the filename, you must use
- * .c_str() before passing it to this constructor.
*/
explicit
basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
@@ -516,13 +532,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
this->open(__s, __mode);
}
+#if __cplusplus >= 201703L
+ /**
+ * @param Create an input file stream.
+ * @param __s filesystem::path specifying the filename.
+ * @param __mode Open file in specified mode (see std::ios_base).
+ *
+ * @c ios_base::in is automatically included in @a __mode.
+ */
+ template<typename _Path, typename = _Require<
+ is_constructible<__filebuf_type, const _Path&, ios_base::openmode>>>
+ basic_ifstream(const _Path& __s,
+ ios_base::openmode __mode = ios_base::in)
+ : basic_ifstream(__s.c_str(), __mode)
+ { }
+#endif // C++17
+
basic_ifstream(const basic_ifstream&) = delete;
basic_ifstream(basic_ifstream&& __rhs)
: __istream_type(std::move(__rhs)),
_M_filebuf(std::move(__rhs._M_filebuf))
{ __istream_type::set_rdbuf(&_M_filebuf); }
-#endif
+#endif // C++11
/**
* @brief The destructor does nothing.
@@ -587,9 +619,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Calls @c std::basic_filebuf::open(s,__mode|in). If that function
* fails, @c failbit is set in the stream's error state.
- *
- * Tip: When using std::string to hold the filename, you must use
- * .c_str() before passing it to this constructor.
*/
void
open(const char* __s, ios_base::openmode __mode = ios_base::in)
@@ -621,7 +650,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 409. Closing an fstream should clear error state
this->clear();
}
-#endif
+
+#if __cplusplus >= 201703L
+ /**
+ * @brief Opens an external file.
+ * @param __s The name of the file, as a filesystem::path.
+ * @param __mode The open mode flags.
+ *
+ * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function
+ * fails, @c failbit is set in the stream's error state.
+ */
+ template<typename _Path>
+ auto
+ open(const _Path& __s, ios_base::openmode __mode = ios_base::in)
+ -> decltype(_M_filebuf.open(__s, __mode))
+ { open(__s.c_str(), __mode); }
+#endif // C++17
+#endif // C++11
/**
* @brief Close the file.
@@ -687,15 +732,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __s Null terminated string specifying the filename.
* @param __mode Open file in specified mode (see std::ios_base).
*
- * @c ios_base::out | @c ios_base::trunc is automatically included in
- * @a __mode.
- *
- * Tip: When using std::string to hold the filename, you must use
- * .c_str() before passing it to this constructor.
+ * @c ios_base::out is automatically included in @a __mode.
*/
explicit
basic_ofstream(const char* __s,
- ios_base::openmode __mode = ios_base::out|ios_base::trunc)
+ ios_base::openmode __mode = ios_base::out)
: __ostream_type(), _M_filebuf()
{
this->init(&_M_filebuf);
@@ -708,18 +749,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __s std::string specifying the filename.
* @param __mode Open file in specified mode (see std::ios_base).
*
- * @c ios_base::out | @c ios_base::trunc is automatically included in
- * @a __mode.
+ * @c ios_base::out is automatically included in @a __mode.
*/
explicit
basic_ofstream(const std::string& __s,
- ios_base::openmode __mode = ios_base::out|ios_base::trunc)
+ ios_base::openmode __mode = ios_base::out)
: __ostream_type(), _M_filebuf()
{
this->init(&_M_filebuf);
this->open(__s, __mode);
}
+#if __cplusplus >= 201703L
+ /**
+ * @param Create an output file stream.
+ * @param __s filesystem::path specifying the filename.
+ * @param __mode Open file in specified mode (see std::ios_base).
+ *
+ * @c ios_base::out is automatically included in @a __mode.
+ */
+ template<typename _Path, typename = _Require<
+ is_constructible<__filebuf_type, const _Path&, ios_base::openmode>>>
+ basic_ofstream(const _Path& __s,
+ ios_base::openmode __mode = ios_base::out)
+ : basic_ofstream(__s.c_str(), __mode)
+ { }
+#endif // C++17
+
basic_ofstream(const basic_ofstream&) = delete;
basic_ofstream(basic_ofstream&& __rhs)
@@ -789,15 +845,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __s The name of the file.
* @param __mode The open mode flags.
*
- * Calls @c std::basic_filebuf::open(__s,__mode|out|trunc). If that
+ * Calls @c std::basic_filebuf::open(__s,__mode|out). If that
* function fails, @c failbit is set in the stream's error state.
- *
- * Tip: When using std::string to hold the filename, you must use
- * .c_str() before passing it to this constructor.
*/
void
- open(const char* __s,
- ios_base::openmode __mode = ios_base::out | ios_base::trunc)
+ open(const char* __s, ios_base::openmode __mode = ios_base::out)
{
if (!_M_filebuf.open(__s, __mode | ios_base::out))
this->setstate(ios_base::failbit);
@@ -813,12 +865,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __s The name of the file.
* @param __mode The open mode flags.
*
- * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that
+ * Calls @c std::basic_filebuf::open(s,mode|out). If that
* function fails, @c failbit is set in the stream's error state.
*/
void
- open(const std::string& __s,
- ios_base::openmode __mode = ios_base::out | ios_base::trunc)
+ open(const std::string& __s, ios_base::openmode __mode = ios_base::out)
{
if (!_M_filebuf.open(__s, __mode | ios_base::out))
this->setstate(ios_base::failbit);
@@ -827,7 +878,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 409. Closing an fstream should clear error state
this->clear();
}
-#endif
+
+#if __cplusplus >= 201703L
+ /**
+ * @brief Opens an external file.
+ * @param __s The name of the file, as a filesystem::path.
+ * @param __mode The open mode flags.
+ *
+ * Calls @c std::basic_filebuf::open(__s,__mode|out). If that
+ * function fails, @c failbit is set in the stream's error state.
+ */
+ template<typename _Path>
+ auto
+ open(const _Path& __s, ios_base::openmode __mode = ios_base::out)
+ -> decltype(_M_filebuf.open(__s, __mode))
+ { open(__s.c_str(), __mode); }
+#endif // C++17
+#endif // C++11
/**
* @brief Close the file.
@@ -894,9 +961,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @brief Create an input/output file stream.
* @param __s Null terminated string specifying the filename.
* @param __mode Open file in specified mode (see std::ios_base).
- *
- * Tip: When using std::string to hold the filename, you must use
- * .c_str() before passing it to this constructor.
*/
explicit
basic_fstream(const char* __s,
@@ -922,6 +986,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
this->open(__s, __mode);
}
+#if __cplusplus >= 201703L
+ /**
+ * @param Create an input/output file stream.
+ * @param __s filesystem::path specifying the filename.
+ * @param __mode Open file in specified mode (see std::ios_base).
+ */
+ template<typename _Path, typename = _Require<
+ is_constructible<__filebuf_type, const _Path&, ios_base::openmode>>>
+ basic_fstream(const _Path& __s,
+ ios_base::openmode __mode = ios_base::in | ios_base::out)
+ : basic_fstream(__s.c_str(), __mode)
+ { }
+#endif // C++17
+
basic_fstream(const basic_fstream&) = delete;
basic_fstream(basic_fstream&& __rhs)
@@ -993,9 +1071,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Calls @c std::basic_filebuf::open(__s,__mode). If that
* function fails, @c failbit is set in the stream's error state.
- *
- * Tip: When using std::string to hold the filename, you must use
- * .c_str() before passing it to this constructor.
*/
void
open(const char* __s,
@@ -1029,7 +1104,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 409. Closing an fstream should clear error state
this->clear();
}
-#endif
+
+#if __cplusplus >= 201703L
+ /**
+ * @brief Opens an external file.
+ * @param __s The name of the file, as a filesystem::path.
+ * @param __mode The open mode flags.
+ *
+ * Calls @c std::basic_filebuf::open(__s,__mode). If that
+ * function fails, @c failbit is set in the stream's error state.
+ */
+ template<typename _Path>
+ auto
+ open(const _Path& __s,
+ ios_base::openmode __mode = ios_base::in | ios_base::out)
+ -> decltype(_M_filebuf.open(__s, __mode))
+ { open(__s.c_str(), __mode); }
+#endif // C++17
+#endif // C++11
/**
* @brief Close the file.
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index 8c692a88ffd..50420ee22d4 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -688,6 +688,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__set_once_functor_lock_ptr(0);
#endif
+#ifdef __clang_analyzer__
+ // PR libstdc++/82481
+ __once_callable = nullptr;
+ __once_call = nullptr;
+#endif
+
if (__e)
__throw_system_error(__e);
}
diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index 97316ef49ab..1900b867841 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -96,14 +96,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr basic_string_view(const basic_string_view&) noexcept = default;
- constexpr basic_string_view(const _CharT* __str)
+ constexpr basic_string_view(const _CharT* __str) noexcept
: _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
_M_str{__str}
{ }
- constexpr basic_string_view(const _CharT* __str, size_type __len)
- : _M_len{__len},
- _M_str{__str}
+ constexpr
+ basic_string_view(const _CharT* __str, size_type __len) noexcept
+ : _M_len{__len}, _M_str{__str}
{ }
constexpr basic_string_view&
@@ -177,17 +177,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
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()),
- *this->_M_str);
+ if (__pos >= _M_len)
+ __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
+ "(which is %zu) >= this->size() "
+ "(which is %zu)"), __pos, this->size());
+ return *(this->_M_str + __pos);
}
constexpr const _CharT&
- front() const
+ front() const noexcept
{
// TODO: Assert to restore in a way compatible with the constexpr.
// __glibcxx_assert(this->_M_len > 0);
@@ -195,7 +193,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
constexpr const _CharT&
- back() const
+ back() const noexcept
{
// TODO: Assert to restore in a way compatible with the constexpr.
// __glibcxx_assert(this->_M_len > 0);
@@ -209,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [string.view.modifiers], modifiers:
constexpr void
- remove_prefix(size_type __n)
+ remove_prefix(size_type __n) noexcept
{
__glibcxx_assert(this->_M_len >= __n);
this->_M_str += __n;
@@ -217,7 +215,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
constexpr void
- remove_suffix(size_type __n)
+ remove_suffix(size_type __n) noexcept
{ this->_M_len -= __n; }
constexpr void
@@ -235,38 +233,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
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::copy: __pos "
- "(which is %zu) > this->size() "
- "(which is %zu)"),
- __pos, this->size());
- size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})};
+ __pos = _M_check(__pos, "basic_string_view::copy");
+ const size_type __rlen = std::min(__n, _M_len - __pos);
for (auto __begin = this->_M_str + __pos,
__end = __begin + __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
+ substr(size_type __pos, size_type __n = npos) const noexcept(false)
{
- 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::substr: __pos "
- "(which is %zu) > this->size() "
- "(which is %zu)"),
- __pos, this->size()), basic_string_view{});
+ __pos = _M_check(__pos, "basic_string_view::substr");
+ const size_type __rlen = std::min(__n, _M_len - __pos);
+ return basic_string_view{_M_str + __pos, __rlen};
}
constexpr 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));
+ const size_type __rlen = std::min(this->_M_len, __str._M_len);
+ int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen);
if (__ret == 0)
__ret = _S_compare(this->_M_len, __str._M_len);
return __ret;
@@ -279,7 +266,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr 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)); }
+ {
+ return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
+ }
constexpr int
compare(const _CharT* __str) const noexcept
@@ -291,7 +280,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr int
compare(size_type __pos1, size_type __n1,
- const _CharT* __str, size_type __n2) const
+ const _CharT* __str, size_type __n2) const noexcept(false)
{
return this->substr(__pos1, __n1)
.compare(basic_string_view(__str, __n2));
@@ -302,13 +291,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return this->find(__str._M_str, __pos, __str._M_len); }
constexpr size_type
- find(_CharT __c, size_type __pos=0) const noexcept;
+ find(_CharT __c, size_type __pos = 0) const noexcept;
constexpr size_type
find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
constexpr size_type
- find(const _CharT* __str, size_type __pos=0) const noexcept
+ find(const _CharT* __str, size_type __pos = 0) const noexcept
{ return this->find(__str, __pos, traits_type::length(__str)); }
constexpr size_type
@@ -350,7 +339,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return this->rfind(__c, __pos); }
constexpr size_type
- find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
+ find_last_of(const _CharT* __str, size_type __pos,
+ size_type __n) const noexcept;
constexpr size_type
find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
@@ -366,7 +356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr size_type
find_first_not_of(const _CharT* __str,
- size_type __pos, size_type __n) const;
+ size_type __pos, size_type __n) const noexcept;
constexpr size_type
find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
@@ -385,7 +375,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr size_type
find_last_not_of(const _CharT* __str,
- size_type __pos, size_type __n) const;
+ size_type __pos, size_type __n) const noexcept;
constexpr size_type
find_last_not_of(const _CharT* __str,
@@ -396,7 +386,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
constexpr size_type
- _M_check(size_type __pos, const char* __s) const
+ _M_check(size_type __pos, const char* __s) const noexcept(false)
{
if (__pos > this->size())
__throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
@@ -407,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// NB: _M_limit doesn't check for a bad __pos value.
constexpr size_type
- _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
+ _M_limit(size_type __pos, size_type __off) const noexcept
{
const bool __testoff = __off < this->size() - __pos;
return __testoff ? __off : this->size() - __pos;
@@ -418,11 +408,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr 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});
+ const difference_type __diff{__n1 - __n2};
+ if (__diff > std::numeric_limits<int>::max())
+ return std::numeric_limits<int>::max();
+ if (__diff < std::numeric_limits<int>::min())
+ return std::numeric_limits<int>::min();
+ return static_cast<int>(__diff);
}
size_t _M_len;
@@ -636,22 +627,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline namespace string_view_literals
{
inline constexpr basic_string_view<char>
- operator""sv(const char* __str, size_t __len)
+ operator""sv(const char* __str, size_t __len) noexcept
{ return basic_string_view<char>{__str, __len}; }
#ifdef _GLIBCXX_USE_WCHAR_T
inline constexpr basic_string_view<wchar_t>
- operator""sv(const wchar_t* __str, size_t __len)
+ operator""sv(const wchar_t* __str, size_t __len) noexcept
{ return basic_string_view<wchar_t>{__str, __len}; }
#endif
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
inline constexpr basic_string_view<char16_t>
- operator""sv(const char16_t* __str, size_t __len)
+ operator""sv(const char16_t* __str, size_t __len) noexcept
{ return basic_string_view<char16_t>{__str, __len}; }
inline constexpr basic_string_view<char32_t>
- operator""sv(const char32_t* __str, size_t __len)
+ operator""sv(const char32_t* __str, size_t __len) noexcept
{ return basic_string_view<char32_t>{__str, __len}; }
#endif
} // namespace string_literals
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 1f5365ad026..ac03c9ec402 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1329,6 +1329,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return std::forward<__element_type&&>(std::get<__i>(__t));
}
+ /// Return a const rvalue reference to the ith element of a const tuple rvalue.
+ template<std::size_t __i, typename... _Elements>
+ constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
+ get(const tuple<_Elements...>&& __t) noexcept
+ {
+ typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
+ return std::forward<const __element_type&&>(std::get<__i>(__t));
+ }
+
#if __cplusplus > 201103L
#define __cpp_lib_tuples_by_type 201304
@@ -1360,6 +1369,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const _Tp&
get(const tuple<_Types...>& __t) noexcept
{ return std::__get_helper2<_Tp>(__t); }
+
+ /// Return a const reference to the unique element of type _Tp of
+ /// a const tuple rvalue.
+ template <typename _Tp, typename... _Types>
+ constexpr const _Tp&&
+ get(const tuple<_Types...>&& __t) noexcept
+ { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); }
#endif
// This class performs the comparison operations on tuples
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 036f7667bd8..7eca08c1a50 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2664,7 +2664,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void operator=(__nonesuch const&) = delete;
};
-#if __cplusplus > 201402L
+#if __cplusplus >= 201703L
# define __cpp_lib_is_invocable 201703
/// std::invoke_result
@@ -2739,7 +2739,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= is_nothrow_invocable_r<_Fn, _Args...>::value;
#endif // C++17
-#if __cplusplus > 201402L
+#if __cplusplus >= 201703L
# define __cpp_lib_type_trait_variable_templates 201510L
template <typename _Tp>
inline constexpr bool is_void_v = is_void<_Tp>::value;
@@ -2943,6 +2943,16 @@ template <typename _From, typename _To>
#endif // C++17
+#if __cplusplus > 201703L
+ /// Byte order
+ enum class endian
+ {
+ little = __ORDER_LITTLE_ENDIAN__,
+ big = __ORDER_BIG_ENDIAN__,
+ native = __BYTE_ORDER__
+ };
+#endif // C++2a
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map
index 2cdcd377936..80773235b65 100644
--- a/libstdc++-v3/include/std/unordered_map
+++ b/libstdc++-v3/include/std/unordered_map
@@ -35,13 +35,12 @@
# include <bits/c++0x_warning.h>
#else
-#include <utility>
#include <type_traits>
#include <initializer_list>
-#include <tuple>
#include <bits/allocator.h>
#include <ext/alloc_traits.h>
#include <ext/aligned_buffer.h>
+#include <bits/stl_pair.h>
#include <bits/stl_function.h> // equal_to, _Identity, _Select1st
#include <bits/functional_hash.h>
#include <bits/hashtable.h>
diff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set
index 2646c0f2f00..faf7ebe23ae 100644
--- a/libstdc++-v3/include/std/unordered_set
+++ b/libstdc++-v3/include/std/unordered_set
@@ -35,13 +35,12 @@
# include <bits/c++0x_warning.h>
#else
-#include <utility>
#include <type_traits>
#include <initializer_list>
-#include <tuple>
#include <bits/allocator.h>
#include <ext/alloc_traits.h>
#include <ext/aligned_buffer.h>
+#include <bits/stl_pair.h>
#include <bits/stl_function.h> // equal_to, _Identity, _Select1st
#include <bits/functional_hash.h>
#include <bits/hashtable.h>
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 29a626004f9..e7386320e2a 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -184,6 +184,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr const _Tp1&
__const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept
{ return __pair.first; }
+
+ template<typename _Tp1, typename _Tp2>
+ static constexpr const _Tp1&&
+ __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept
+ { return std::forward<const _Tp1>(__pair.first); }
};
template<>
@@ -203,6 +208,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr const _Tp2&
__const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept
{ return __pair.second; }
+
+ template<typename _Tp1, typename _Tp2>
+ static constexpr const _Tp2&&
+ __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept
+ { return std::forward<const _Tp2>(__pair.second); }
};
template<std::size_t _Int, class _Tp1, class _Tp2>
@@ -220,6 +230,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(const std::pair<_Tp1, _Tp2>& __in) noexcept
{ return __pair_get<_Int>::__const_get(__in); }
+ template<std::size_t _Int, class _Tp1, class _Tp2>
+ constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&&
+ get(const std::pair<_Tp1, _Tp2>&& __in) noexcept
+ { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
+
#if __cplusplus > 201103L
#define __cpp_lib_tuples_by_type 201304
@@ -240,6 +255,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return std::move(__p.first); }
template <typename _Tp, typename _Up>
+ constexpr const _Tp&&
+ get(const pair<_Tp, _Up>&& __p) noexcept
+ { return std::move(__p.first); }
+
+ template <typename _Tp, typename _Up>
constexpr _Tp&
get(pair<_Up, _Tp>& __p) noexcept
{ return __p.second; }
@@ -254,6 +274,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(pair<_Up, _Tp>&& __p) noexcept
{ return std::move(__p.second); }
+ template <typename _Tp, typename _Up>
+ constexpr const _Tp&&
+ get(const pair<_Up, _Tp>&& __p) noexcept
+ { return std::move(__p.second); }
+
#define __cpp_lib_exchange_function 201304
/// Assign @p __new_val to @p __obj and return its previous value.