Split get_default() into two for deferred default construction
[folly.git] / folly / test / MapUtilTest.cpp
index 52e63e81f7a900360a54a6d3ccd5f0fc1cf2f4be..693f7235260c83bdac27e893d424198db93cea6a 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <folly/MapUtil.h>
 
+#include <cstddef>
 #include <map>
 #include <unordered_map>
 
@@ -238,6 +239,7 @@ struct GetRefDefaultPathCompiles<
         std::declval<int>(),
         std::declval<int>(),
         std::declval<T>()))>> : std::true_type {};
+
 } // namespace
 
 TEST(MapUtil, get_ref_default_path_temporary) {
@@ -246,3 +248,41 @@ TEST(MapUtil, get_ref_default_path_temporary) {
   EXPECT_FALSE(GetRefDefaultPathCompiles<const int&&>::value);
   EXPECT_FALSE(GetRefDefaultPathCompiles<int&&>::value);
 }
+
+namespace {
+
+class TestConstruction {
+ public:
+  static std::size_t numberDefaultConstructs;
+  TestConstruction() {
+    ++numberDefaultConstructs;
+  }
+  TestConstruction(TestConstruction&&) = default;
+  TestConstruction(const TestConstruction&) = default;
+
+  TestConstruction& operator=(const TestConstruction&) = delete;
+  TestConstruction& operator=(TestConstruction&&) = delete;
+};
+
+std::size_t TestConstruction::numberDefaultConstructs = 0;
+
+} // namespace
+
+TEST(MapUtil, test_get_default_deferred_construction) {
+  auto map = std::unordered_map<int, TestConstruction>{};
+  map.insert({1, TestConstruction{}});
+
+  EXPECT_EQ(TestConstruction::numberDefaultConstructs, 1);
+
+  {
+    auto val = get_default(map, 1);
+    EXPECT_EQ(TestConstruction::numberDefaultConstructs, 1);
+    static_cast<void>(val);
+  }
+
+  {
+    auto val = get_default(map, 1, TestConstruction{});
+    EXPECT_EQ(TestConstruction::numberDefaultConstructs, 2);
+    static_cast<void>(val);
+  }
+}