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

Reply via email to