171 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 11// <flat_set>12 13// template <class... Args>14// iterator emplace_hint(const_iterator position, Args&&... args);15 16#include <flat_set>17#include <cassert>18#include <deque>19#include <functional>20#include <vector>21 22#include "MinSequenceContainer.h"23#include "test_macros.h"24#include "../../../Emplaceable.h"25#include "DefaultOnly.h"26#include "min_allocator.h"27#include "../helpers.h"28 29template <class KeyContainer>30constexpr void test_one() {31 using Key = typename KeyContainer::value_type;32 using M = std::flat_set<Key, std::less<Key>, KeyContainer>;33 using R = M::iterator;34 {35 // was empty36 M m;37 std::same_as<R> decltype(auto) r = m.emplace_hint(m.end(), typename M::value_type(2));38 assert(r == m.begin());39 assert(m.size() == 1);40 assert(*r == 2);41 }42 {43 // hints correct at the begin44 M m = {3, 4};45 auto hint = m.begin();46 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));47 assert(r == m.begin());48 assert(m.size() == 3);49 assert(*r == 2);50 }51 {52 // hints correct in the middle53 M m = {0, 1, 3, 4};54 auto hint = m.begin() + 2;55 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));56 assert(r == m.begin() + 2);57 assert(m.size() == 5);58 assert(*r == 2);59 }60 {61 // hints correct at the end62 M m = {0, 1};63 auto hint = m.end();64 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));65 assert(r == m.begin() + 2);66 assert(m.size() == 3);67 assert(*r == 2);68 }69 {70 // hints correct but key already exists71 M m = {0, 1, 2, 3, 4};72 auto hint = m.begin() + 2;73 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));74 assert(r == m.begin() + 2);75 assert(m.size() == 5);76 assert(*r == 2);77 }78 {79 // hints incorrectly at the begin80 M m = {1, 4};81 auto hint = m.begin();82 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));83 assert(r == m.begin() + 1);84 assert(m.size() == 3);85 assert(*r == 2);86 }87 {88 // hints incorrectly in the middle89 M m = {0, 1, 3, 4};90 auto hint = m.begin() + 1;91 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));92 assert(r == m.begin() + 2);93 assert(m.size() == 5);94 assert(*r == 2);95 }96 {97 // hints incorrectly at the end98 M m = {0, 3};99 auto hint = m.end();100 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));101 assert(r == m.begin() + 1);102 assert(m.size() == 3);103 assert(*r == 2);104 }105 {106 // hints incorrect and key already exists107 M m = {0, 1, 2, 3, 4};108 auto hint = m.begin();109 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));110 assert(r == m.begin() + 2);111 assert(m.size() == 5);112 assert(*r == 2);113 }114}115 116template <class KeyContainer>117constexpr void test_emplaceable() {118 using M = std::flat_set<Emplaceable, std::less<Emplaceable>, KeyContainer>;119 using R = M::iterator;120 121 M m;122 ASSERT_SAME_TYPE(decltype(m.emplace_hint(m.cbegin())), R);123 R r = m.emplace_hint(m.end(), 2, 0.0);124 assert(r == m.begin());125 assert(m.size() == 1);126 assert(*m.begin() == Emplaceable(2, 0.0));127 r = m.emplace_hint(m.end(), 1, 3.5);128 assert(r == m.begin());129 assert(m.size() == 2);130 assert(*m.begin() == Emplaceable(1, 3.5));131 r = m.emplace_hint(m.end(), 1, 3.5);132 assert(r == m.begin());133 assert(m.size() == 2);134 assert(*m.begin() == Emplaceable(1, 3.5));135}136 137constexpr bool test() {138 test_one<std::vector<int>>();139#ifndef __cpp_lib_constexpr_deque140 if (!TEST_IS_CONSTANT_EVALUATED)141#endif142 test_one<std::deque<int>>();143 test_one<MinSequenceContainer<int>>();144 test_one<std::vector<int, min_allocator<int>>>();145 146 test_emplaceable<std::vector<Emplaceable>>();147#ifndef __cpp_lib_constexpr_deque148 if (!TEST_IS_CONSTANT_EVALUATED)149#endif150 test_emplaceable<std::deque<Emplaceable>>();151 test_emplaceable<MinSequenceContainer<Emplaceable>>();152 test_emplaceable<std::vector<Emplaceable, min_allocator<Emplaceable>>>();153 154 return true;155}156 157void test_exception() {158 auto emplace_func = [](auto& m, auto key_arg) { m.emplace_hint(m.begin(), key_arg); };159 test_emplace_exception_guarantee(emplace_func);160}161 162int main(int, char**) {163 test();164 test_exception();165#if TEST_STD_VER >= 26166 static_assert(test());167#endif168 169 return 0;170}171