File: comparison.pass.cpp

package info (click to toggle)
llvm-toolchain-16 1%3A16.0.6-15~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,634,792 kB
  • sloc: cpp: 6,179,261; ansic: 1,216,205; asm: 741,319; python: 196,614; objc: 75,325; f90: 49,640; lisp: 32,396; pascal: 12,286; sh: 9,394; perl: 7,442; ml: 5,494; awk: 3,523; makefile: 2,723; javascript: 1,206; xml: 886; fortran: 581; cs: 573
file content (149 lines) | stat: -rw-r--r-- 5,373 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// Starting with C++20 the spaceship operator was included. This tests
// comparison in that context, thus doesn't support older language versions.
// These are tested per operator.

// UNSUPPORTED: c++03, c++11, c++14, c++17

// <string_view>

// template<class charT, class traits>
//   constexpr bool operator==(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs);
// template<class charT, class traits>
//   constexpr auto operator<=>(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs);
// (plus "sufficient additional overloads" to make implicit conversions work as intended)

#include <string_view>

#include <array>
#include <cassert>
#include <string>

#include "constexpr_char_traits.h"
#include "make_string.h"
#include "test_comparisons.h"
#include "test_macros.h"

#define SV(S) MAKE_STRING_VIEW(CharT, S)

// Copied from constexpr_char_traits, but it doesn't have a full implementation.
// It has a comparison_category used in the tests.
template <class CharT, class Ordering>
struct char_traits {
  using char_type           = CharT;
  using int_type            = int;
  using off_type            = std::streamoff;
  using pos_type            = std::streampos;
  using state_type          = std::mbstate_t;
  using comparison_category = Ordering;

  static constexpr void assign(char_type& __c1, const char_type& __c2) noexcept { __c1 = __c2; }
  static constexpr bool eq(char_type __c1, char_type __c2) noexcept { return __c1 == __c2; }
  static constexpr bool lt(char_type __c1, char_type __c2) noexcept { return __c1 < __c2; }
  static constexpr int compare(const char_type* __s1, const char_type* __s2, size_t __n) {
    for (; __n; --__n, ++__s1, ++__s2) {
      if (lt(*__s1, *__s2))
        return -1;
      if (lt(*__s2, *__s1))
        return 1;
    }
    return 0;
  }

  static constexpr size_t length(const char_type* __s);
  static constexpr const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
  static constexpr char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
  static constexpr char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
  static constexpr char_type* assign(char_type* __s, size_t __n, char_type __a);
  static constexpr int_type not_eof(int_type __c) noexcept { return eq_int_type(__c, eof()) ? ~eof() : __c; }
  static constexpr char_type to_char_type(int_type __c) noexcept { return char_type(__c); }
  static constexpr int_type to_int_type(char_type __c) noexcept { return int_type(__c); }
  static constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept { return __c1 == __c2; }
  static constexpr int_type eof() noexcept { return int_type(EOF); }
};

template <class T, class Ordering = std::strong_ordering>
constexpr void test() {
  AssertOrderAreNoexcept<T>();
  AssertOrderReturn<Ordering, T>();

  using CharT = typename T::value_type;

  // sorted values
  std::array v{
      SV(""),
      SV("abc"),
      SV("abcdef"),
  };

  // sorted values with embedded NUL character
  std::array vn{
      SV("abc"),
      SV("abc\0"),
      SV("abc\0def"),
  };
  static_assert(v.size() == vn.size());

  for (size_t i = 0; i < v.size(); ++i) {
    for (size_t j = 0; j < v.size(); ++j) {
      assert(testOrder(v[i], v[j], i == j ? Ordering::equivalent : i < j ? Ordering::less : Ordering::greater));
      assert(testOrder(
          v[i],
          std::basic_string<CharT>{v[j]},
          i == j  ? Ordering::equivalent
          : i < j ? Ordering::less
                  : Ordering::greater));

      assert(testOrder(
          v[i],
          std::basic_string<CharT>{v[j]}.c_str(),
          i == j  ? Ordering::equivalent
          : i < j ? Ordering::less
                  : Ordering::greater));

      // NUL test omitted for c-strings since it will fail.
      assert(testOrder(vn[i], vn[j], i == j ? Ordering::equivalent : i < j ? Ordering::less : Ordering::greater));
      assert(testOrder(
          vn[i],
          std::basic_string<CharT>{vn[j]},
          i == j  ? Ordering::equivalent
          : i < j ? Ordering::less
                  : Ordering::greater));
    }
  }
}

template <class CharT>
constexpr void test_all_orderings() {
  test<std::basic_string_view<CharT>>(); // Strong ordering in its char_traits
  test<std::basic_string_view<CharT, constexpr_char_traits<CharT>>,
       std::weak_ordering>(); // No ordering in its char_traits
  test<std::basic_string_view<CharT, char_traits<CharT, std::weak_ordering>>, std::weak_ordering>();
  test<std::basic_string_view<CharT, char_traits<CharT, std::partial_ordering>>, std::partial_ordering>();
}

constexpr bool test_all_types() {
  test_all_orderings<char>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
  test_all_orderings<wchar_t>();
#endif
  test_all_orderings<char8_t>();
  test_all_orderings<char16_t>();
  test_all_orderings<char32_t>();

  return true;
}

int main(int, char**) {
  test_all_types();
  static_assert(test_all_types());

  return 0;
}