134 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_map>12 13// friend bool operator==(const flat_map& x, const flat_map& y);14// friend synth-three-way-result<value_type>15// operator<=>(const flat_map& x, const flat_map& y);16 17#include <algorithm>18#include <cassert>19#include <deque>20#include <compare>21#include <flat_map>22#include <functional>23#include <limits>24#include <vector>25 26#include "MinSequenceContainer.h"27#include "test_macros.h"28#include "min_allocator.h"29#include "test_allocator.h"30#include "test_comparisons.h"31#include "test_container_comparisons.h"32 33template <class KeyContainer, class ValueContainer>34constexpr void test() {35 using Key = typename KeyContainer::value_type;36 using Value = typename ValueContainer::value_type;37 38 {39 using C = std::flat_map<Key, Value>;40 C s1 = {{1, 1}};41 C s2 = {{2, 0}}; // {{1,1}} versus {{2,0}}42 ASSERT_SAME_TYPE(decltype(s1 <=> s2), std::strong_ordering);43 AssertComparisonsReturnBool<C>();44 assert(testComparisons(s1, s2, false, true));45 s2 = {{1, 1}}; // {{1,1}} versus {{1,1}}46 assert(testComparisons(s1, s2, true, false));47 s2 = {{1, 1}, {2, 0}}; // {{1,1}} versus {{1,1},{2,0}}48 assert(testComparisons(s1, s2, false, true));49 s1 = {{0, 0}, {1, 1}, {2, 2}}; // {{0,0},{1,1},{2,2}} versus {{1,1},{2,0}}50 assert(testComparisons(s1, s2, false, true));51 s2 = {{0, 0}, {1, 1}, {2, 3}}; // {{0,0},{1,1},{2,2}} versus {{0,0},{1,1},{2,3}}52 assert(testComparisons(s1, s2, false, true));53 }54 {55 // Comparisons use value_type's native operators, not the comparator56 using C = std::flat_map<Key, Value, std::greater<Key>>;57 C s1 = {{1, 1}};58 C s2 = {{2, 0}}; // {{1,1}} versus {{2,0}}59 ASSERT_SAME_TYPE(decltype(s1 <=> s2), std::strong_ordering);60 AssertComparisonsReturnBool<C>();61 assert(testComparisons(s1, s2, false, true));62 s2 = {{1, 1}}; // {{1,1}} versus {{1,1}}63 assert(testComparisons(s1, s2, true, false));64 s2 = {{1, 1}, {2, 0}}; // {{1,1}} versus {{2,0},{1,1}}65 assert(testComparisons(s1, s2, false, true));66 s1 = {{0, 0}, {1, 1}, {2, 2}}; // {{2,2},{1,1},{0,0}} versus {2,0},{1,1}}67 assert(testComparisons(s1, s2, false, false));68 s2 = {{0, 0}, {1, 1}, {2, 3}}; // {{2,2},{1,1},{0,0}} versus {{2,3},{1,1},{0,0}}69 assert(testComparisons(s1, s2, false, true));70 }71}72 73constexpr bool test() {74 test<std::vector<int>, std::vector<int>>();75#ifndef __cpp_lib_constexpr_deque76 if (!TEST_IS_CONSTANT_EVALUATED)77#endif78 {79 test<std::deque<int>, std::deque<int>>();80 }81 test<MinSequenceContainer<int>, MinSequenceContainer<int>>();82 test<std::vector<int, min_allocator<int>>, std::vector<int, min_allocator<int>>>();83 test<std::vector<int, min_allocator<int>>, std::vector<int, min_allocator<int>>>();84 85 {86 using C = std::flat_map<double, int>;87 C s1 = {{1, 1}};88 C s2 = C(std::sorted_unique, {{std::numeric_limits<double>::quiet_NaN(), 2}});89 ASSERT_SAME_TYPE(decltype(s1 <=> s2), std::partial_ordering);90 AssertComparisonsReturnBool<C>();91 assert(testComparisonsComplete(s1, s2, false, false, false));92 }93 {94 using C = std::flat_map<int, double>;95 C s1 = {{1, 1}};96 C s2 = C(std::sorted_unique, {{2, std::numeric_limits<double>::quiet_NaN()}});97 ASSERT_SAME_TYPE(decltype(s1 <=> s2), std::partial_ordering);98 AssertComparisonsReturnBool<C>();99 assert(testComparisonsComplete(s1, s2, false, true, false));100 s2 = C(std::sorted_unique, {{1, std::numeric_limits<double>::quiet_NaN()}});101 assert(testComparisonsComplete(s1, s2, false, false, false));102 }103 {104 // Comparisons use value_type's native operators, not the comparator105 struct StrongComp {106 constexpr bool operator()(double a, double b) const { return std::strong_order(a, b) < 0; }107 };108 using C = std::flat_map<double, double, StrongComp>;109 C s1 = {{1, 1}};110 C s2 = {{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()}};111 ASSERT_SAME_TYPE(decltype(s1 <=> s2), std::partial_ordering);112 AssertComparisonsReturnBool<C>();113 assert(testComparisonsComplete(s1, s2, false, false, false));114 s1 = {{{1, 1}, {std::numeric_limits<double>::quiet_NaN(), 1}}};115 s2 = {{{std::numeric_limits<double>::quiet_NaN(), 1}, {1, 1}}};116 assert(std::lexicographical_compare_three_way(117 s1.keys().begin(), s1.keys().end(), s2.keys().begin(), s2.keys().end(), std::strong_order) ==118 std::strong_ordering::equal);119 assert(s1 != s2);120 assert((s1 <=> s2) == std::partial_ordering::unordered);121 }122 123 return true;124}125 126int main(int, char**) {127 test();128#if TEST_STD_VER >= 26129 static_assert(test());130#endif131 132 return 0;133}134