PR #2057: doc: clarify moved-from state for hash containers

Imported from GitHub PR https://github.com/abseil/abseil-cpp/pull/2057

Adds documentation to flat_hash_map, flat_hash_set, node_hash_map, and
node_hash_set clarifying the moved-from contract for Swiss table containers.

After a move, only destruction, assignment, and clear() are guaranteed
safe. Any other operation (e.g. size(), empty(), iteration) results in
undefined behavior.

Fixes #1928
Merge 64990acd7a7fb1fc017861c46bd8c31fb4b5acdf into c7269872a5565c86ab8fafc6d8a26097c4775050

Merging this change closes #2057

COPYBARA_INTEGRATE_REVIEW=https://github.com/abseil/abseil-cpp/pull/2057 from DrishtiTripathi2230:oc/moved-from-hash-container-state 64990acd7a7fb1fc017861c46bd8c31fb4b5acdf
PiperOrigin-RevId: 919140795
Change-Id: Ie755387c46907b0e5a78d4e21577173616c10f9f
diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h
index e6cea2e..af9018d 100644
--- a/absl/container/flat_hash_map.h
+++ b/absl/container/flat_hash_map.h
@@ -171,12 +171,19 @@
   //   // Move is guaranteed efficient
   //   absl::flat_hash_map<int, std::string> map5(std::move(map4));
   //
+  //   // After the move, map4 is in a valid but unspecified state. The only
+  //   // operations guaranteed to be safe on a moved-from map are destruction,
+  //   // assignment, and clear(). Any other operation (e.g. size(), empty(),
+  //   // iteration) results in undefined behavior.
+  //
   // * Move assignment operator
   //
   //   // May be efficient if allocators are compatible
   //   absl::flat_hash_map<int, std::string> map6;
   //   map6 = std::move(map5);
   //
+  //   // Same moved-from guarantees apply to map5 after this operation.
+  //
   // * Range constructor
   //
   //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h
index 6d37219..60f661b 100644
--- a/absl/container/flat_hash_set.h
+++ b/absl/container/flat_hash_set.h
@@ -167,12 +167,19 @@
   //   // Move is guaranteed efficient
   //   absl::flat_hash_set<std::string> set5(std::move(set4));
   //
+  //   // After the move, set4 is in a valid but unspecified state. The only
+  //   // operations guaranteed to be safe on a moved-from set are destruction,
+  //   // assignment, and clear(). Any other operation (e.g. size(), empty(),
+  //   // iteration) results in undefined behavior.
+  //
   // * Move assignment operator
   //
   //   // May be efficient if allocators are compatible
   //   absl::flat_hash_set<std::string> set6;
   //   set6 = std::move(set5);
   //
+  //   // Same moved-from guarantees apply to set5 after this operation.
+  //
   // * Range constructor
   //
   //   std::vector<std::string> v = {"a", "b"};
diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h
index a58680a..d58feed 100644
--- a/absl/container/node_hash_map.h
+++ b/absl/container/node_hash_map.h
@@ -167,12 +167,19 @@
   //   // Move is guaranteed efficient
   //   absl::node_hash_map<int, std::string> map5(std::move(map4));
   //
+  //   // After the move, map4 is in a valid but unspecified state. The only
+  //   // operations guaranteed to be safe on a moved-from map are destruction,
+  //   // assignment, and clear(). Any other operation (e.g. size(), empty(),
+  //   // iteration) results in undefined behavior.
+  //
   // * Move assignment operator
   //
   //   // May be efficient if allocators are compatible
   //   absl::node_hash_map<int, std::string> map6;
   //   map6 = std::move(map5);
   //
+  //   // Same moved-from guarantees apply to map5 after this operation.
+  //
   // * Range constructor
   //
   //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h
index 8fd326b..55568b7 100644
--- a/absl/container/node_hash_set.h
+++ b/absl/container/node_hash_set.h
@@ -161,12 +161,19 @@
   //   // Move is guaranteed efficient
   //   absl::node_hash_set<std::string> set5(std::move(set4));
   //
+  //   // After the move, set4 is in a valid but unspecified state. The only
+  //   // operations guaranteed to be safe on a moved-from set are destruction,
+  //   // assignment, and clear(). Any other operation (e.g. size(), empty(),
+  //   // iteration) results in undefined behavior.
+  //
   // * Move assignment operator
   //
   //   // May be efficient if allocators are compatible
   //   absl::node_hash_set<std::string> set6;
   //   set6 = std::move(set5);
   //
+  //   // Same moved-from guarantees apply to set5 after this operation.
+  //
   // * Range constructor
   //
   //   std::vector<std::string> v = {"a", "b"};