179179#include < iterator>
180180#include < limits>
181181#include < memory>
182+ #include < string>
182183#include < tuple>
183184#include < type_traits>
184185#include < utility>
@@ -1038,35 +1039,75 @@ size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
10381039 return 0 ;
10391040}
10401041
1041- #define ABSL_INTERNAL_ASSERT_IS_FULL (ctrl, generation, generation_ptr, \
1042- operation) \
1043- do { \
1044- ABSL_HARDENING_ASSERT ((ctrl != nullptr ) && operation \
1045- " called on end() iterator." ); \
1046- ABSL_HARDENING_ASSERT ((ctrl != EmptyGroup ()) && operation \
1047- " called on default-constructed iterator." ); \
1048- if (SwisstableGenerationsEnabled () && generation != *generation_ptr) \
1049- ABSL_INTERNAL_LOG (FATAL, operation \
1050- " called on invalidated iterator. The table could " \
1051- " have rehashed since this iterator was initialized." ); \
1052- ABSL_HARDENING_ASSERT ( \
1053- (IsFull (*ctrl)) && operation \
1054- " called on invalid iterator. The element might have been erased or " \
1055- " the table might have rehashed." ); \
1056- } while (0 )
1042+ constexpr bool SwisstableDebugEnabled () {
1043+ #if defined(ABSL_SWISSTABLE_ENABLE_GENERATIONS) || \
1044+ ABSL_OPTION_HARDENED == 1 || !defined (NDEBUG)
1045+ return true ;
1046+ #else
1047+ return false ;
1048+ #endif
1049+ }
1050+
1051+ inline void AssertIsFull (const ctrl_t * ctrl, GenerationType generation,
1052+ const GenerationType* generation_ptr,
1053+ const char * operation) {
1054+ if (!SwisstableDebugEnabled ()) return ;
1055+ if (ctrl == nullptr ) {
1056+ ABSL_INTERNAL_LOG (FATAL,
1057+ std::string (operation) + " called on end() iterator." );
1058+ }
1059+ if (ctrl == EmptyGroup ()) {
1060+ ABSL_INTERNAL_LOG (FATAL, std::string (operation) +
1061+ " called on default-constructed iterator." );
1062+ }
1063+ if (SwisstableGenerationsEnabled ()) {
1064+ if (generation != *generation_ptr) {
1065+ ABSL_INTERNAL_LOG (FATAL,
1066+ std::string (operation) +
1067+ " called on invalid iterator. The table could have "
1068+ " rehashed since this iterator was initialized." );
1069+ }
1070+ if (!IsFull (*ctrl)) {
1071+ ABSL_INTERNAL_LOG (
1072+ FATAL,
1073+ std::string (operation) +
1074+ " called on invalid iterator. The element was likely erased." );
1075+ }
1076+ } else {
1077+ if (!IsFull (*ctrl)) {
1078+ ABSL_INTERNAL_LOG (
1079+ FATAL,
1080+ std::string (operation) +
1081+ " called on invalid iterator. The element might have been erased "
1082+ " or the table might have rehashed. Consider running with "
1083+ " --config=asan to diagnose rehashing issues." );
1084+ }
1085+ }
1086+ }
10571087
10581088// Note that for comparisons, null/end iterators are valid.
10591089inline void AssertIsValidForComparison (const ctrl_t * ctrl,
10601090 GenerationType generation,
10611091 const GenerationType* generation_ptr) {
1062- ABSL_HARDENING_ASSERT (
1063- (ctrl == nullptr || ctrl == EmptyGroup () || IsFull (*ctrl)) &&
1064- " Invalid iterator comparison. The element might have "
1065- " been erased or the table might have rehashed." );
1066- if (SwisstableGenerationsEnabled () && generation != *generation_ptr) {
1067- ABSL_INTERNAL_LOG (FATAL,
1068- " Invalid iterator comparison. The table could have "
1069- " rehashed since this iterator was initialized." );
1092+ if (!SwisstableDebugEnabled ()) return ;
1093+ const bool ctrl_is_valid_for_comparison =
1094+ ctrl == nullptr || ctrl == EmptyGroup () || IsFull (*ctrl);
1095+ if (SwisstableGenerationsEnabled ()) {
1096+ if (generation != *generation_ptr) {
1097+ ABSL_INTERNAL_LOG (FATAL,
1098+ " Invalid iterator comparison. The table could have "
1099+ " rehashed since this iterator was initialized." );
1100+ }
1101+ if (!ctrl_is_valid_for_comparison) {
1102+ ABSL_INTERNAL_LOG (
1103+ FATAL, " Invalid iterator comparison. The element was likely erased." );
1104+ }
1105+ } else {
1106+ ABSL_HARDENING_ASSERT (
1107+ ctrl_is_valid_for_comparison &&
1108+ " Invalid iterator comparison. The element might have been erased or "
1109+ " the table might have rehashed. Consider running with --config=asan to "
1110+ " diagnose rehashing issues." );
10701111 }
10711112}
10721113
@@ -1097,8 +1138,7 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
10971138 const void * const & slot_b,
10981139 const GenerationType* generation_ptr_a,
10991140 const GenerationType* generation_ptr_b) {
1100- #if defined(ABSL_SWISSTABLE_ENABLE_GENERATIONS) || \
1101- ABSL_OPTION_HARDENED == 1 || !defined (NDEBUG)
1141+ if (!SwisstableDebugEnabled ()) return ;
11021142 const bool a_is_default = ctrl_a == EmptyGroup ();
11031143 const bool b_is_default = ctrl_b == EmptyGroup ();
11041144 if (a_is_default != b_is_default) {
@@ -1108,9 +1148,9 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
11081148 " with non-default-constructed iterator." );
11091149 }
11101150 if (a_is_default && b_is_default) return ;
1111- #endif
11121151
1113- if (SwisstableGenerationsEnabled () && generation_ptr_a != generation_ptr_b) {
1152+ if (SwisstableGenerationsEnabled ()) {
1153+ if (generation_ptr_a == generation_ptr_b) return ;
11141154 const bool a_is_empty = generation_ptr_a == EmptyGeneration ();
11151155 const bool b_is_empty = generation_ptr_b == EmptyGeneration ();
11161156 if (a_is_empty != b_is_empty) {
@@ -1129,11 +1169,13 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
11291169 ABSL_INTERNAL_LOG (FATAL,
11301170 " Invalid iterator comparison. Comparing non-end() "
11311171 " iterators from different hashtables." );
1172+ } else {
1173+ ABSL_HARDENING_ASSERT (
1174+ AreItersFromSameContainer (ctrl_a, ctrl_b, slot_a, slot_b) &&
1175+ " Invalid iterator comparison. The iterators may be from different "
1176+ " containers or the container might have rehashed. Consider running "
1177+ " with --config=asan to diagnose rehashing issues." );
11321178 }
1133- ABSL_HARDENING_ASSERT (
1134- AreItersFromSameContainer (ctrl_a, ctrl_b, slot_a, slot_b) &&
1135- " Invalid iterator comparison. The iterators may be from different "
1136- " containers or the container might have rehashed." );
11371179}
11381180
11391181struct FindInfo {
@@ -1471,22 +1513,19 @@ class raw_hash_set {
14711513
14721514 // PRECONDITION: not an end() iterator.
14731515 reference operator *() const {
1474- ABSL_INTERNAL_ASSERT_IS_FULL (ctrl_, generation (), generation_ptr (),
1475- " operator*()" );
1516+ AssertIsFull (ctrl_, generation (), generation_ptr (), " operator*()" );
14761517 return PolicyTraits::element (slot_);
14771518 }
14781519
14791520 // PRECONDITION: not an end() iterator.
14801521 pointer operator ->() const {
1481- ABSL_INTERNAL_ASSERT_IS_FULL (ctrl_, generation (), generation_ptr (),
1482- " operator->" );
1522+ AssertIsFull (ctrl_, generation (), generation_ptr (), " operator->" );
14831523 return &operator *();
14841524 }
14851525
14861526 // PRECONDITION: not an end() iterator.
14871527 iterator& operator ++() {
1488- ABSL_INTERNAL_ASSERT_IS_FULL (ctrl_, generation (), generation_ptr (),
1489- " operator++" );
1528+ AssertIsFull (ctrl_, generation (), generation_ptr (), " operator++" );
14901529 ++ctrl_;
14911530 ++slot_;
14921531 skip_empty_or_deleted ();
@@ -2052,8 +2091,7 @@ class raw_hash_set {
20522091 // This overload is necessary because otherwise erase<K>(const K&) would be
20532092 // a better match if non-const iterator is passed as an argument.
20542093 void erase (iterator it) {
2055- ABSL_INTERNAL_ASSERT_IS_FULL (it.ctrl_ , it.generation (), it.generation_ptr (),
2056- " erase()" );
2094+ AssertIsFull (it.ctrl_ , it.generation (), it.generation_ptr (), " erase()" );
20572095 PolicyTraits::destroy (&alloc_ref (), it.slot_ );
20582096 erase_meta_only (it);
20592097 }
@@ -2087,9 +2125,8 @@ class raw_hash_set {
20872125 }
20882126
20892127 node_type extract (const_iterator position) {
2090- ABSL_INTERNAL_ASSERT_IS_FULL (position.inner_ .ctrl_ ,
2091- position.inner_ .generation (),
2092- position.inner_ .generation_ptr (), " extract()" );
2128+ AssertIsFull (position.inner_ .ctrl_ , position.inner_ .generation (),
2129+ position.inner_ .generation_ptr (), " extract()" );
20932130 auto node =
20942131 CommonAccess::Transfer<node_type>(alloc_ref (), position.inner_ .slot_ );
20952132 erase_meta_only (position);
@@ -2739,6 +2776,5 @@ ABSL_NAMESPACE_END
27392776} // namespace absl
27402777
27412778#undef ABSL_SWISSTABLE_ENABLE_GENERATIONS
2742- #undef ABSL_INTERNAL_ASSERT_IS_FULL
27432779
27442780#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
0 commit comments