[libcxx-commits] [libcxx] [libc++] Don't claim strong emplace guarantee for vector/deque of throwing-move types (PR #229686)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Oct 17 11:07:06 PDT 2026


================
@@ -0,0 +1,136 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+
+// <flat_map>
+
+// Test that the invariants are restored when inserting an element in the middle of the
+// underlying containers throws from the element's assignment operator or, during
+// reallocation, from its copy constructor. Neither has a "no effects" guarantee for an
+// insertion in the middle of a vector or deque, even if the element type is
+// Cpp17CopyInsertable.
+
+#include <cassert>
+#include <deque>
+#include <flat_map>
+#include <functional>
+#include <type_traits>
+#include <vector>
+
+#include "test_macros.h"
+#include "../helpers.h"
+
+struct ThrowingAssign {
+  static inline bool throw_on_assign = false;
+
+  int value;
+
+  ThrowingAssign(int v) : value(v) {}
+  ThrowingAssign(const ThrowingAssign&)     = default;
+  ThrowingAssign(ThrowingAssign&&) noexcept = default;
+  ThrowingAssign& operator=(const ThrowingAssign& other) {
+    if (throw_on_assign)
+      throw 42;
+    value = other.value;
+    return *this;
+  }
+  ThrowingAssign& operator=(ThrowingAssign&& other) {
+    if (throw_on_assign)
+      throw 42;
+    value = other.value;
+    return *this;
+  }
+
+  friend bool operator==(const ThrowingAssign&, const ThrowingAssign&)  = default;
+  friend auto operator<=>(const ThrowingAssign&, const ThrowingAssign&) = default;
+};
+
+struct ThrowingCopy {
+  static inline int copies_until_throw = -1; // -1: never throw
----------------
huixie90 wrote:

i would suggest to use an enum to make the flag a bit more readable and you won't need the comment to explain what the number means

https://github.com/llvm/llvm-project/pull/229686


More information about the libcxx-commits mailing list