]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: add generate_test_instances() for std::variant 54488/head
authorCasey Bodley <cbodley@redhat.com>
Tue, 14 Nov 2023 19:43:25 +0000 (14:43 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 1 Dec 2023 13:52:31 +0000 (08:52 -0500)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/common/versioned_variant.h
src/test/common/test_versioned_variant.cc

index 9c9c5ada9b0133dc1a451bb6669feda75fc95874..f7e46b7296e7f2dc3b21cf3a2585130271db3de0 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <concepts>
 #include <limits>
+#include <list>
 #include <variant>
 
 #include <boost/mp11/algorithm.hpp> // for mp_with_index
@@ -212,4 +213,22 @@ void decode(std::variant<Ts...>& v, bufferlist::const_iterator& p)
 
 } // namespace converted_variant
 
+
+/// \brief Generate a list with a default-constructed variant of each type.
+///
+/// This can be used in generate_test_instances() for types that contain
+/// variants to ensure that an encoding of each type is present in the
+/// ceph-object-corpus. This allows the ceph-dencoder tests to catch any
+/// breaking changes to the variant types that are present in encodings.
+template <typename ...Ts>
+void generate_test_instances(std::list<std::variant<Ts...>>& instances)
+{
+  // use an immediately-invoked lambda to get a parameter pack of variant indices
+  [&instances] <std::size_t ...I> (std::index_sequence<I...>) {
+    // use a fold expression to call emplace_back() for each index in the pack
+    // use in_place_index to default-construct a variant of the type at index I
+    (instances.emplace_back(std::in_place_index<I>), ...);
+  } (std::make_index_sequence<sizeof...(Ts)>{});
+}
+
 } // namespace ceph
index b91e24b6f13fede2d536ba003932c5524754dbfb..81f12c23c2b4f65bf98d5ffb8d7000710c2cd54b 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "common/versioned_variant.h"
+#include <bitset>
 #include <string>
 #include <gtest/gtest.h>
 
@@ -320,4 +321,21 @@ TEST(ConvertedVariant, EncodeNew)
   }
 }
 
+TEST(Variant, GenerateTestInstances)
+{
+  using Variant = std::variant<int, bool, double>;
+
+  std::bitset<std::variant_size_v<Variant>> bits;
+  ASSERT_TRUE(bits.none());
+
+  std::list<Variant> instances;
+  generate_test_instances(instances);
+
+  for (const auto& v : instances) {
+    bits.set(v.index());
+  }
+
+  EXPECT_TRUE(bits.all());
+}
+
 } // namespace ceph