//===----------------------------------------------------------------------===// // // 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 // // template pair insert(K&& x); // template iterator insert(const_iterator hint, K&& x); #include #include #include #include #include #include #include #include "MinSequenceContainer.h" #include "../helpers.h" #include "test_macros.h" #include "test_iterators.h" #include "min_allocator.h" // Constraints: The qualified-id Compare::is_transparent is valid and denotes a type. is_constructible_v is true. template concept CanInsert = requires(M m, Args&&... args) { m.insert(std::forward(args)...); }; using TransparentSet = std::flat_set; using TransparentSetIter = typename TransparentSet::iterator; static_assert(CanInsert>); static_assert(CanInsert>); static_assert(!CanInsert>); static_assert(!CanInsert>); using NonTransparentSet = std::flat_set; using NonTransparentSetIter = typename NonTransparentSet::iterator; static_assert(!CanInsert>); static_assert(!CanInsert>); static_assert(!CanInsert>); static_assert(!CanInsert>); template constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_set; { const int expected[] = {1, 2, 3, 4, 5}; { // insert(K&&) bool transparent_used = false; M m{{1, 2, 4, 5}, TransparentComparator{transparent_used}}; assert(!transparent_used); std::same_as> decltype(auto) r = m.insert(ExplicitlyConvertibleTransparent{3}); assert(transparent_used); assert(r.first == m.begin() + 2); assert(r.second); assert(std::ranges::equal(m, expected)); } { // insert(const_iterator, K&&) bool transparent_used = false; M m{{1, 2, 4, 5}, TransparentComparator{transparent_used}}; assert(!transparent_used); std::same_as auto it = m.insert(m.begin(), ExplicitlyConvertibleTransparent{3}); assert(transparent_used); assert(it == m.begin() + 2); assert(std::ranges::equal(m, expected)); } } { // was empty const int expected[] = {3}; { // insert(K&&) bool transparent_used = false; M m{{}, TransparentComparator{transparent_used}}; assert(!transparent_used); std::same_as> decltype(auto) r = m.insert(ExplicitlyConvertibleTransparent{3}); assert(!transparent_used); // no elements to compare against assert(r.first == m.begin()); assert(r.second); assert(std::ranges::equal(m, expected)); } { // insert(const_iterator, K&&) bool transparent_used = false; M m{{}, TransparentComparator{transparent_used}}; assert(!transparent_used); std::same_as auto it = m.insert(m.begin(), ExplicitlyConvertibleTransparent{3}); assert(!transparent_used); // no elements to compare against assert(it == m.begin()); assert(std::ranges::equal(m, expected)); } } } constexpr bool test() { test_one>(); #ifndef __cpp_lib_constexpr_deque if (!TEST_IS_CONSTANT_EVALUATED) #endif test_one>(); test_one>(); test_one>>(); { // no ambiguity between insert(pos, P&&) and insert(first, last) using M = std::flat_set; struct Evil { operator M::value_type() const; operator M::const_iterator() const; }; std::flat_set m; ASSERT_SAME_TYPE(decltype(m.insert(Evil())), std::pair); ASSERT_SAME_TYPE(decltype(m.insert(m.begin(), Evil())), M::iterator); ASSERT_SAME_TYPE(decltype(m.insert(m.begin(), m.end())), void); } { // LWG4239 std::string and C string literal using M = std::flat_set>; M m{"alpha", "beta", "epsilon", "eta", "gamma"}; auto [iter, inserted] = m.insert("beta"); assert(!inserted); assert(iter == m.begin() + 1); } return true; } void test_exception() { { auto insert_func = [](auto& m, auto key_arg) { using FlatSet = std::decay_t; m.insert(ExplicitlyConvertibleTransparent{key_arg}); }; test_emplace_exception_guarantee(insert_func); } { auto insert_func_iter = [](auto& m, auto key_arg) { using FlatSet = std::decay_t; m.insert(m.begin(), ExplicitlyConvertibleTransparent{key_arg}); }; test_emplace_exception_guarantee(insert_func_iter); } } int main(int, char**) { test(); test_exception(); #if TEST_STD_VER >= 26 static_assert(test()); #endif return 0; }