Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps 16?
I'm not sure if it's worth avoiding dereferencing *__first twice in this
special case, but I figured we might as well?
-- >8 --
When inserting a range of pair-like elements we can avoid constructing a
value_type temporary and instead obtain the corresponding key and value
to insert directly from *__first.
libstdc++-v3/ChangeLog:
* include/std/flat_map (flat_map::_M_insert): Avoid constructing
value_type temporary when the iterator already has pair-like
elements.
---
libstdc++-v3/include/std/flat_map | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/libstdc++-v3/include/std/flat_map
b/libstdc++-v3/include/std/flat_map
index b82d41b4f5e1..1815ced51225 100644
--- a/libstdc++-v3/include/std/flat_map
+++ b/libstdc++-v3/include/std/flat_map
@@ -637,9 +637,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto __n = size();
for (; __first != __last; ++__first)
{
- value_type __value = *__first;
- _M_cont.keys.emplace_back(std::move(__value.first));
- _M_cont.values.emplace_back(std::move(__value.second));
+ if constexpr (__pair_like<iter_reference_t<_Iter>>)
+ {
+ auto&& __value = *__first;
+ _M_cont.keys.emplace_back
+ (std::get<0>(std::forward<decltype(__value)>(__value)));
+ _M_cont.values.emplace_back
+ (std::get<1>(std::forward<decltype(__value)>(__value)));
+ }
+ else
+ {
+ value_type __value = *__first;
+ _M_cont.keys.emplace_back(std::move(__value.first));
+ _M_cont.values.emplace_back(std::move(__value.second));
+ }
}
auto __zv = views::zip(_M_cont.keys, _M_cont.values);
if (__is_sorted)
--
2.55.0.122.gf85a7e6620