]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
include/denc: use pair<const K,V> in range-based for loop 38678/head
authorKefu Chai <kchai@redhat.com>
Mon, 21 Dec 2020 17:07:37 +0000 (01:07 +0800)
committerKefu Chai <kchai@redhat.com>
Mon, 21 Dec 2020 17:17:28 +0000 (01:17 +0800)
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>
src/include/denc.h

index 402c5a47169ba07a19a2af12559f79ae16f521e5..266121bd20cda2669fe67f94eca94ecea9af0636 100644 (file)
@@ -877,7 +877,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;
 
@@ -909,14 +909,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);
   }
 };
@@ -1217,8 +1217,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)...);