Commit 954019983d

Andrew Kelley <andrew@ziglang.org>
2022-12-03 07:05:12
std: add move() functions to hash maps
1 parent 2a0efbe
Changed files (2)
lib/std/array_hash_map.zig
@@ -399,6 +399,14 @@ pub fn ArrayHashMap(
             return other.promoteContext(allocator, ctx);
         }
 
+        /// Set the map to an empty state, making deinitialization a no-op, and
+        /// returning a copy of the original.
+        pub fn move(self: *Self) Self {
+            const result = self.*;
+            self.unmanaged = .{};
+            return result;
+        }
+
         /// Rebuilds the key indexes. If the underlying entries has been modified directly, users
         /// can call `reIndex` to update the indexes to account for these new entries.
         pub fn reIndex(self: *Self) !void {
@@ -1149,6 +1157,8 @@ pub fn ArrayHashMapUnmanaged(
             errdefer other.entries.deinit(allocator);
 
             if (self.index_header) |header| {
+                // TODO: I'm pretty sure this could be memcpy'd instead of
+                // doing all this work.
                 const new_header = try IndexHeader.alloc(allocator, header.bit_index);
                 other.insertAllEntriesIntoNewHeader(if (store_hash) {} else ctx, new_header);
                 other.index_header = new_header;
@@ -1156,6 +1166,14 @@ pub fn ArrayHashMapUnmanaged(
             return other;
         }
 
+        /// Set the map to an empty state, making deinitialization a no-op, and
+        /// returning a copy of the original.
+        pub fn move(self: *Self) Self {
+            const result = self.*;
+            self.* = .{};
+            return result;
+        }
+
         /// Rebuilds the key indexes. If the underlying entries has been modified directly, users
         /// can call `reIndex` to update the indexes to account for these new entries.
         pub fn reIndex(self: *Self, allocator: Allocator) !void {
@@ -1163,6 +1181,7 @@ pub fn ArrayHashMapUnmanaged(
                 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call reIndexContext instead.");
             return self.reIndexContext(allocator, undefined);
         }
+
         pub fn reIndexContext(self: *Self, allocator: Allocator, ctx: Context) !void {
             if (self.entries.capacity <= linear_scan_max) return;
             // We're going to rebuild the index header and replace the existing one (if any). The
lib/std/hash_map.zig
@@ -673,6 +673,14 @@ pub fn HashMap(
             var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);
             return other.promoteContext(new_allocator, new_ctx);
         }
+
+        /// Set the map to an empty state, making deinitialization a no-op, and
+        /// returning a copy of the original.
+        pub fn move(self: *Self) Self {
+            const result = self.*;
+            self.unmanaged = .{};
+            return result;
+        }
     };
 }
 
@@ -1488,6 +1496,14 @@ pub fn HashMapUnmanaged(
             return other;
         }
 
+        /// Set the map to an empty state, making deinitialization a no-op, and
+        /// returning a copy of the original.
+        pub fn move(self: *Self) Self {
+            const result = self.*;
+            self.* = .{};
+            return result;
+        }
+
         fn grow(self: *Self, allocator: Allocator, new_capacity: Size, ctx: Context) Allocator.Error!void {
             @setCold(true);
             const new_cap = std.math.max(new_capacity, minimal_capacity);