brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.6 KiB · 53db5ba Raw
473 lines · c
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//  Utility functions to test comparisons on containers.9 10#ifndef TEST_CONTAINER_COMPARISONS11#define TEST_CONTAINER_COMPARISONS12 13#include <functional>14#include <set>15 16#include "test_allocator.h"17#include "test_comparisons.h"18 19// Implementation detail of `test_sequence_container_spaceship`20template <template <typename...> typename Container, typename Elem, typename Allocator, typename Order>21constexpr void test_sequence_container_spaceship_with_type() {22  // Empty containers23  {24    Container<Elem, Allocator> l1;25    Container<Elem, Allocator> l2;26    assert(testOrder(l1, l2, Order::equivalent));27  }28  // Identical contents29  {30    Container<Elem, Allocator> l1{1, 1};31    Container<Elem, Allocator> l2{1, 1};32    assert(testOrder(l1, l2, Order::equivalent));33  }34  // Less, due to contained values35  {36    Container<Elem, Allocator> l1{1, 1};37    Container<Elem, Allocator> l2{1, 2};38    assert(testOrder(l1, l2, Order::less));39  }40  // Greater, due to contained values41  {42    Container<Elem, Allocator> l1{1, 3};43    Container<Elem, Allocator> l2{1, 2};44    assert(testOrder(l1, l2, Order::greater));45  }46  // Shorter list47  {48    Container<Elem, Allocator> l1{1};49    Container<Elem, Allocator> l2{1, 2};50    assert(testOrder(l1, l2, Order::less));51  }52  // Longer list53  {54    Container<Elem, Allocator> l1{1, 2};55    Container<Elem, Allocator> l2{1};56    assert(testOrder(l1, l2, Order::greater));57  }58  // Unordered59  if constexpr (std::is_same_v<Elem, PartialOrder>) {60    Container<Elem, Allocator> l1{1, std::numeric_limits<int>::min()};61    Container<Elem, Allocator> l2{1, 2};62    assert(testOrder(l1, l2, Order::unordered));63  }64}65 66// Tests the `operator<=>` on sequence containers67template <template <typename...> typename Container>68constexpr bool test_sequence_container_spaceship() {69  // The container should fulfill `std::three_way_comparable`70  static_assert(std::three_way_comparable<Container<int>>);71 72  // Test different comparison categories73  test_sequence_container_spaceship_with_type<Container, int, std::allocator<int>, std::strong_ordering>();74  test_sequence_container_spaceship_with_type<Container,75                                              StrongOrder,76                                              test_allocator<StrongOrder>,77                                              std::strong_ordering>();78  test_sequence_container_spaceship_with_type<Container, WeakOrder, std::allocator<WeakOrder>, std::weak_ordering>();79  test_sequence_container_spaceship_with_type<Container,80                                              PartialOrder,81                                              test_allocator<PartialOrder>,82                                              std::partial_ordering>();83 84  // `LessAndEqComp` does not have `operator<=>`. Ordering is synthesized based on `operator<`85  test_sequence_container_spaceship_with_type<Container,86                                              LessAndEqComp,87                                              std::allocator<LessAndEqComp>,88                                              std::weak_ordering>();89 90  // Thanks to SFINAE, the following is not a compiler error but returns `false`91  static_assert(!std::three_way_comparable<Container<NonComparable>>);92 93  return true;94}95 96// Implementation detail of `test_sequence_container_adaptor_spaceship`97template <template <typename...> typename ContainerAdaptor,98          template <typename...>99          typename Container,100          typename Elem,101          typename Order>102constexpr void test_sequence_container_adaptor_spaceship_with_type() {103  // Empty containers104  {105    Container<Elem> l1;106    ContainerAdaptor<Elem, Container<Elem>> ca1{l1};107    Container<Elem> l2;108    ContainerAdaptor<Elem, Container<Elem>> ca2{l2};109    assert(testOrder(ca1, ca2, Order::equivalent));110  }111  // Identical contents112  {113    Container<Elem> l1{1, 1};114    ContainerAdaptor<Elem, Container<Elem>> ca1{l1};115    Container<Elem> l2{1, 1};116    ContainerAdaptor<Elem, Container<Elem>> ca2{l2};117    assert(testOrder(ca1, ca2, Order::equivalent));118  }119  // Less, due to contained values120  {121    Container<Elem> l1{1, 1};122    ContainerAdaptor<Elem, Container<Elem>> ca1{l1};123    Container<Elem> l2{1, 2};124    ContainerAdaptor<Elem, Container<Elem>> ca2{l2};125    assert(testOrder(ca1, ca2, Order::less));126  }127  // Greater, due to contained values128  {129    Container<Elem> l1{1, 3};130    ContainerAdaptor<Elem, Container<Elem>> ca1{l1};131    Container<Elem> l2{1, 2};132    ContainerAdaptor<Elem, Container<Elem>> ca2{l2};133    assert(testOrder(ca1, ca2, Order::greater));134  }135  // Shorter list136  {137    Container<Elem> l1{1};138    ContainerAdaptor<Elem, Container<Elem>> ca1{l1};139    Container<Elem> l2{1, 2};140    ContainerAdaptor<Elem, Container<Elem>> ca2{l2};141    assert(testOrder(ca1, ca2, Order::less));142  }143  // Longer list144  {145    Container<Elem> l1{1, 2};146    ContainerAdaptor<Elem, Container<Elem>> ca1{l1};147    Container<Elem> l2{1};148    ContainerAdaptor<Elem, Container<Elem>> ca2{l2};149    assert(testOrder(ca1, ca2, Order::greater));150  }151  // Unordered152  if constexpr (std::is_same_v<Elem, PartialOrder>) {153    Container<Elem> l1{1, std::numeric_limits<int>::min()};154    ContainerAdaptor<Elem, Container<Elem>> ca1{l1};155    Container<Elem> l2{1, 2};156    ContainerAdaptor<Elem, Container<Elem>> ca2{l2};157    assert(testOrder(ca1, ca2, Order::unordered));158  }159}160 161// Tests the `operator<=>` on sequence container adaptors162template <template <typename...> typename ContainerAdaptor, template <typename...> typename Container>163constexpr bool test_sequence_container_adaptor_spaceship() {164  // Thanks to SFINAE, the following is not a compiler error but returns `false`165  static_assert(!std::three_way_comparable<ContainerAdaptor<NonComparable>>);166 167  // The container should fulfill `std::three_way_comparable`168  static_assert(std::three_way_comparable<ContainerAdaptor<int, Container<int>>>);169 170  // Test different comparison categories171  test_sequence_container_adaptor_spaceship_with_type<ContainerAdaptor, Container, int, std::strong_ordering>();172  test_sequence_container_adaptor_spaceship_with_type<ContainerAdaptor, Container, StrongOrder, std::strong_ordering>();173  test_sequence_container_adaptor_spaceship_with_type<ContainerAdaptor, Container, WeakOrder, std::weak_ordering>();174  test_sequence_container_adaptor_spaceship_with_type<ContainerAdaptor,175                                                      Container,176                                                      PartialOrder,177                                                      std::partial_ordering>();178 179  // `LessAndEqComp` does not have `operator<=>`. Ordering is synthesized based on `operator<`180  test_sequence_container_adaptor_spaceship_with_type<ContainerAdaptor, Container, LessAndEqComp, std::weak_ordering>();181 182  return true;183}184 185// Implementation detail of `test_ordered_map_container_spaceship`186template <template <typename...> typename Container,187          typename Key,188          typename Val,189          typename Allocator,190          typename Order,191          typename Compare>192constexpr void test_ordered_map_container_spaceship_with_type(Compare comp) {193  // Empty containers194  {195    Container<Key, Val, Compare, Allocator> l1{{}, comp};196    Container<Key, Val, Compare, Allocator> l2{{}, comp};197    assert(testOrder(l1, l2, Order::equivalent));198  }199  // Identical contents200  {201    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, 1}}, comp};202    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 1}}, comp};203    assert(testOrder(l1, l2, Order::equivalent));204  }205  // Less, due to contained values206  {207    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, 1}}, comp};208    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}}, comp};209    assert(testOrder(l1, l2, Order::less));210  }211  // Greater, due to contained values212  {213    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, 3}}, comp};214    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}}, comp};215    assert(testOrder(l1, l2, Order::greater));216  }217  // Shorter list218  {219    Container<Key, Val, Compare, Allocator> l1{{{1, 1}}, comp};220    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}}, comp};221    assert(testOrder(l1, l2, Order::less));222  }223  // Longer list224  {225    Container<Key, Val, Compare, Allocator> l1{{{1, 2}, {2, 2}}, comp};226    Container<Key, Val, Compare, Allocator> l2{{{1, 1}}, comp};227    assert(testOrder(l1, l2, Order::greater));228  }229  // Unordered230  if constexpr (std::is_same_v<Val, PartialOrder>) {231    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, std::numeric_limits<int>::min()}}, comp};232    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}}, comp};233    assert(testOrder(l1, l2, Order::unordered));234  }235 236  // Identical contents237  {238    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, 1}, {2, 2}}, comp};239    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 1}, {2, 2}}, comp};240    assert(testOrder(l1, l2, Order::equivalent));241 242    Container<Key, Val, Compare, Allocator> l3{{{1, 1}, {2, 1}, {2, 2}}, comp};243    Container<Key, Val, Compare, Allocator> l4{{{2, 1}, {2, 2}, {1, 1}}, comp};244    assert(testOrder(l3, l4, Order::equivalent));245  }246  // Less, due to contained values247  {248    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, 1}, {2, 1}}, comp};249    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}, {2, 2}}, comp};250    assert(testOrder(l1, l2, Order::less));251 252    Container<Key, Val, Compare, Allocator> l3{{{1, 1}, {2, 1}, {2, 1}}, comp};253    Container<Key, Val, Compare, Allocator> l4{{{2, 2}, {2, 2}, {1, 1}}, comp};254    assert(testOrder(l3, l4, Order::less));255  }256  // Greater, due to contained values257  {258    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, 3}, {2, 3}}, comp};259    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}, {2, 2}}, comp};260    assert(testOrder(l1, l2, Order::greater));261 262    Container<Key, Val, Compare, Allocator> l3{{{1, 1}, {2, 3}, {2, 3}}, comp};263    Container<Key, Val, Compare, Allocator> l4{{{2, 2}, {2, 2}, {1, 1}}, comp};264    assert(testOrder(l3, l4, Order::greater));265  }266  // Shorter list267  {268    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, 2}}, comp};269    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}, {2, 2}, {3, 1}}, comp};270    assert(testOrder(l1, l2, Order::less));271 272    Container<Key, Val, Compare, Allocator> l3{{{1, 1}, {2, 2}}, comp};273    Container<Key, Val, Compare, Allocator> l4{{{3, 1}, {2, 2}, {2, 2}, {1, 1}}, comp};274    assert(testOrder(l3, l4, Order::less));275  }276  // Longer list277  {278    Container<Key, Val, Compare, Allocator> l1{{{1, 2}, {2, 2}, {2, 2}, {3, 1}}, comp};279    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}}, comp};280    assert(testOrder(l1, l2, Order::greater));281 282    Container<Key, Val, Compare, Allocator> l3{{{1, 2}, {2, 2}, {2, 2}, {3, 1}}, comp};283    Container<Key, Val, Compare, Allocator> l4{{{2, 2}, {1, 1}}, comp};284    assert(testOrder(l3, l4, Order::greater));285  }286  // Unordered287  if constexpr (std::is_same_v<Val, PartialOrder>) {288    Container<Key, Val, Compare, Allocator> l1{{{1, 1}, {2, std::numeric_limits<int>::min()}, {2, 3}}, comp};289    Container<Key, Val, Compare, Allocator> l2{{{1, 1}, {2, 2}, {2, 3}}, comp};290    assert(testOrder(l1, l2, Order::unordered));291 292    Container<Key, Val, Compare, Allocator> l3{{{1, 1}, {2, std::numeric_limits<int>::min()}, {2, 3}}, comp};293    Container<Key, Val, Compare, Allocator> l4{{{2, 3}, {2, 2}, {1, 1}}, comp};294    assert(testOrder(l3, l4, Order::unordered));295  }296}297 298// Tests the `operator<=>` on ordered map containers299template <template <typename...> typename Container>300constexpr bool test_ordered_map_container_spaceship() {301  // Thanks to SFINAE, the following is not a compiler error but returns `false`302  static_assert(!std::three_way_comparable<Container<int, NonComparable>>);303 304  // The container should fulfill `std::three_way_comparable`305  static_assert(std::three_way_comparable<Container<int, int>>);306 307  // Test different comparison categories308  test_ordered_map_container_spaceship_with_type<Container,309                                                 int,310                                                 int,311                                                 std::allocator<std::pair<const int, int>>,312                                                 std::strong_ordering>(std::less{});313  test_ordered_map_container_spaceship_with_type<Container,314                                                 int,315                                                 int,316                                                 test_allocator<std::pair<const int, int>>,317                                                 std::strong_ordering>(std::greater{});318  test_ordered_map_container_spaceship_with_type<Container,319                                                 int,320                                                 StrongOrder,321                                                 std::allocator<std::pair<const int, StrongOrder>>,322                                                 std::strong_ordering>(std::less{});323  test_ordered_map_container_spaceship_with_type<Container,324                                                 int,325                                                 StrongOrder,326                                                 test_allocator<std::pair<const int, StrongOrder>>,327                                                 std::strong_ordering>(std::greater{});328  test_ordered_map_container_spaceship_with_type<Container,329                                                 int,330                                                 WeakOrder,331                                                 std::allocator<std::pair<const int, WeakOrder>>,332                                                 std::weak_ordering>(std::less{});333  test_ordered_map_container_spaceship_with_type<Container,334                                                 int,335                                                 WeakOrder,336                                                 test_allocator<std::pair<const int, WeakOrder>>,337                                                 std::weak_ordering>(std::greater{});338  test_ordered_map_container_spaceship_with_type<Container,339                                                 int,340                                                 PartialOrder,341                                                 std::allocator<std::pair<const int, PartialOrder>>,342                                                 std::partial_ordering>(std ::less{});343  test_ordered_map_container_spaceship_with_type<Container,344                                                 int,345                                                 PartialOrder,346                                                 test_allocator<std::pair<const int, PartialOrder>>,347                                                 std::partial_ordering>(std ::greater{});348 349  // `LessAndEqComp` does not have `operator<=>`. Ordering is synthesized based on `operator<`350  test_ordered_map_container_spaceship_with_type<Container,351                                                 int,352                                                 LessAndEqComp,353                                                 std::allocator<std::pair<const int, LessAndEqComp>>,354                                                 std::weak_ordering>(std::less{});355 356  return true;357}358 359// Implementation detail of `test_ordered_set_container_spaceship`360template <template <typename...> typename Container,361          typename Elem,362          typename Allocator,363          typename Order,364          typename Compare>365constexpr void test_ordered_set_spaceship_with_type(Compare comp) {366  // Empty containers367  {368    Container<Elem, Compare, Allocator> l1{{}, comp};369    Container<Elem, Compare, Allocator> l2{{}, comp};370    assert(testOrder(l1, l2, Order::equivalent));371  }372  // Identical contents373  {374    Container<Elem, Compare, Allocator> l1{{1, 1, 2}, comp};375    Container<Elem, Compare, Allocator> l2{{1, 1, 2}, comp};376    assert(testOrder(l1, l2, Order::equivalent));377  }378  // Less, due to contained values379  {380    Container<Elem, Compare, Allocator> l1{{1, 1, 2, 3}, comp};381    Container<Elem, Compare, Allocator> l2{{1, 2, 2, 4}, comp};382    assert(testOrder(l1, l2, Order::less));383  }384  // Greater, due to contained values385  {386    Container<Elem, Compare, Allocator> l1{{1, 2, 2, 4}, comp};387    Container<Elem, Compare, Allocator> l2{{1, 1, 2, 3}, comp};388    assert(testOrder(l1, l2, Order::greater));389  }390  // Shorter list391  {392    Container<Elem, Compare, Allocator> l1{{1, 1, 2, 2}, comp};393    Container<Elem, Compare, Allocator> l2{{1, 1, 2, 2, 3}, comp};394    assert(testOrder(l1, l2, Order::less));395  }396  // Longer list397  {398    Container<Elem, Compare, Allocator> l1{{1, 1, 2, 2, 3}, comp};399    Container<Elem, Compare, Allocator> l2{{1, 1, 2, 2}, comp};400    assert(testOrder(l1, l2, Order::greater));401  }402  // Unordered403  if constexpr (std::is_same_v< Container<Elem>, std::multiset<PartialOrder>>) {404    if constexpr (std::is_same_v<Elem, PartialOrder> && std::is_same_v<Compare, decltype(std::less{})>) {405      Container<Elem, Compare, Allocator> l1{{1, std::numeric_limits<int>::min()}, comp};406      Container<Elem, Compare, Allocator> l2{{1, 2}, comp};407      assert(testOrder(l1, l2, Order::unordered));408    }409    if constexpr (std::is_same_v<Elem, PartialOrder> && std::is_same_v<Compare, decltype(std::less{})>) {410      Container<Elem, Compare, Allocator> l1{{1, std::numeric_limits<int>::max()}, comp};411      Container<Elem, Compare, Allocator> l2{{1, 2}, comp};412      assert(testOrder(l1, l2, Order::unordered));413    }414  }415  if constexpr (std::is_same_v< Container<Elem>, std::set<PartialOrder>>) {416    // Unordered values are not supported for `set`417    if constexpr (std::is_same_v<Elem, PartialOrder> && std::is_same_v<Compare, decltype(std::less{})>) {418      Container<Elem, Compare, Allocator> l1{{1, std::numeric_limits<int>::min()}, comp};419      Container<Elem, Compare, Allocator> l2{{1, 2}, comp};420      assert(testOrder(l1, l2, Order::less));421    }422    if constexpr (std::is_same_v<Elem, PartialOrder> && std::is_same_v<Compare, decltype(std::less{})>) {423      Container<Elem, Compare, Allocator> l1{{1, std::numeric_limits<int>::max()}, comp};424      Container<Elem, Compare, Allocator> l2{{1, 2}, comp};425      assert(testOrder(l1, l2, Order::less));426    }427  }428  if constexpr (std::is_same_v<Elem, PartialOrder> && std::is_same_v<Compare, decltype(std::greater{})>) {429    Container<Elem, Compare, Allocator> l1{{1, std::numeric_limits<int>::min()}, comp};430    Container<Elem, Compare, Allocator> l2{{1, 2}, comp};431    assert(testOrder(l1, l2, Order::less));432  }433  if constexpr (std::is_same_v<Elem, PartialOrder> && std::is_same_v<Compare, decltype(std::greater{})>) {434    Container<Elem, Compare, Allocator> l1{{1, std::numeric_limits<int>::max()}, comp};435    Container<Elem, Compare, Allocator> l2{{1, 2}, comp};436    assert(testOrder(l1, l2, Order::less));437  }438}439 440// Tests the `operator<=>` on ordered set containers441template <template <typename...> typename Container>442constexpr bool test_ordered_set_container_spaceship() {443  // Thanks to SFINAE, the following is not a compiler error but returns `false`444  static_assert(!std::three_way_comparable<Container<NonComparable>>);445 446  // The container should fulfill `std::three_way_comparable`447  static_assert(std::three_way_comparable<Container<int>>);448 449  // Test different comparison categories450  test_ordered_set_spaceship_with_type<Container, int, std::allocator<int>, std::strong_ordering>(std::less{});451  test_ordered_set_spaceship_with_type<Container, int, test_allocator<int>, std::strong_ordering>(std::greater{});452  test_ordered_set_spaceship_with_type<Container, StrongOrder, std::allocator<StrongOrder>, std::strong_ordering>(453      std::less{});454  test_ordered_set_spaceship_with_type<Container, StrongOrder, test_allocator<StrongOrder>, std::strong_ordering>(455      std::greater{});456  test_ordered_set_spaceship_with_type<Container, WeakOrder, std::allocator<WeakOrder>, std::weak_ordering>(457      std::less{});458  test_ordered_set_spaceship_with_type<Container, WeakOrder, test_allocator<WeakOrder>, std::weak_ordering>(459      std::greater{});460  test_ordered_set_spaceship_with_type<Container, PartialOrder, std::allocator<PartialOrder>, std::partial_ordering>(461      std::less{});462  test_ordered_set_spaceship_with_type<Container, PartialOrder, test_allocator<PartialOrder>, std::partial_ordering>(463      std::greater{});464 465  // `LessAndEqComp` does not have `operator<=>`. Ordering is synthesized based on `operator<`466  test_ordered_set_spaceship_with_type<Container, LessAndEqComp, std::allocator<LessAndEqComp>, std::weak_ordering>(467      std::less{});468 469  return true;470}471 472#endif473