]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
include/denc: use pair<const K,V> in range-based for loop 46230/head
authorKefu Chai <kchai@redhat.com>
Mon, 21 Dec 2020 17:07:37 +0000 (01:07 +0800)
committerCasey Bodley <cbodley@redhat.com>
Wed, 11 May 2022 17:33:38 +0000 (13:33 -0400)
map<K,V>::value_type is pair<const K, V>, so if we use range-based for
loop when iterating through a map, we should use pair<const K,V> instead
of pair<K,V>, the latter also compiles, but it might create a temporary
object of pair<K,V> from pair<const K,V>. GCC-11 complains at seeing
this:

../src/include/denc.h:1002:21: warning: loop variable ‘e’ of type ‘const T&’ {aka ‘const std::pair<OSDPerfMetricQuery, OSDPerfMetricReport>&’} binds to a tem\
porary constructed from type ‘const std::pair<const OSDPerfMetricQuery, OSDPerfMetricReport>’ [-Wrange-loop-constru
ct]
 1002 |       for (const T& e : s) {
      |                     ^

this change

* use the value_type of container in `maplike_details<Container>`,
  so we can avoid the overhead of creating temporay objects when
  encoding a map
* define denc_traits for std::pair<const A, B> as well, so the elements
  of a map can be encoded using denc facility

Signed-off-by: Kefu Chai <kchai@redhat.com>
(cherry picked from commit c828ce29400a1eea4b223229b36b3a092eda6139)

src/include/denc.h

index dfd5e923d388132aba3013790e24c6841f6819cb..acbca1464b1a5211e7d6cc1878197fe0a6ecc7ee 100644 (file)
@@ -876,7 +876,7 @@ struct denc_traits<ceph::buffer::list> {
 template<typename A, typename B>
 struct denc_traits<
   std::pair<A, B>,
-  std::enable_if_t<denc_supported<A> && denc_supported<B>>> {
+  std::enable_if_t<denc_supported<std::remove_const_t<A>> && denc_supported<B>>> {
   typedef denc_traits<A> a_traits;
   typedef denc_traits<B> b_traits;
 
@@ -908,14 +908,14 @@ struct denc_traits<
   }
 
   static void decode(std::pair<A,B>& v, ceph::buffer::ptr::const_iterator& p, uint64_t f=0) {
-    denc(v.first, p, f);
+    denc(const_cast<std::remove_const_t<A>&>(v.first), p, f);
     denc(v.second, p, f);
   }
   template<typename AA=A>
   static std::enable_if_t<!!sizeof(AA) && !need_contiguous>
   decode(std::pair<A,B>& v, ceph::buffer::list::const_iterator& p,
         uint64_t f = 0) {
-    denc(v.first, p);
+    denc(const_cast<std::remove_const_t<AA>&>(v.first), p);
     denc(v.second, p);
   }
 };
@@ -1116,8 +1116,7 @@ struct denc_traits<
 namespace _denc {
   template<typename Container>
   struct maplike_details : public container_details_base<Container> {
-    using T = std::pair<typename Container::key_type,
-                       typename Container::mapped_type>;
+    using T = typename Container::value_type;
     template<typename ...Args>
     static void insert(Container& c, Args&& ...args) {
       c.emplace_hint(c.cend(), std::forward<Args>(args)...);