Spec-Zone.ru › C++

std::totally_ordered, std::totally_ordered_with

Определено в заголовочном файле <concepts>
template< class T >
concept totally_ordered =
    std::equality_comparable<T> && __PartiallyOrderedWith<T, T>;
(1) (начиная с C++20)
template< class T, class U >
concept totally_ordered_with =
    std::totally_ordered<T> &&
    std::totally_ordered<U> &&
    std::equality_comparable_with<T, U> &&
    std::totally_ordered<
        std::common_reference_t<
            const std::remove_reference_t<T>&,
            const std::remove_reference_t<U>&>> &&
    __PartiallyOrderedWith<T, U>;
(2) (начиная с C++20)
Вспомогательные концепты
template< class T, class U >
concept __PartiallyOrderedWith =
    requires(const std::remove_reference_t<T>& t,
             const std::remove_reference_t<U>& u) {
        { t <  u } -> boolean-testable;
        { t >  u } -> boolean-testable;
        { t <= u } -> boolean-testable;
        { t >= u } -> boolean-testable;
        { u <  t } -> boolean-testable;
        { u >  t } -> boolean-testable;
        { u <= t } -> boolean-testable;
        { u >= t } -> boolean-testable;
    };
(3) (только для пояснения*)
1) Концепт std::totally_ordered задаёт требование, согласно которому операторы сравнения ==,!=,<,>,<=,>= для типа дают результаты, соответствующие строгому линейному порядку на этом типе.
2) Концепт std::totally_ordered_with задаёт требование, согласно которому операторы сравнения ==,!=,<,>,<=,>= для операндов типов T и U (возможно, смешанных) дают результаты, соответствующие строгому линейному порядку. Сравнение операндов разных типов даёт результаты, эквивалентные сравнению операндов, преобразованных к их общему типу.
3) Концепт __PartiallyOrderedWith, предназначенный только для пояснения, задаёт требование, согласно которому значение типа T и значение типа U можно сравнивать друг с другом в частичном порядке (в любом порядке) с помощью <, >, <= и >=, причём результаты сравнений согласованы.

Семантические требования

Эти концепты считаются моделируемыми только в том случае, если они удовлетворяют требованиям и моделируются все включаемые ими концепты.

1) std::totally_ordered<T> считается моделируемым только в том случае, если для lvalue-выражений a, b и c типа const std::remove_reference_t<T> выполняются следующие условия:
  • Ровно одно из bool(a < b), bool(a > b) и bool(a == b) равно true;
  • Если bool(a < b) и bool(b < c) оба равны true, то bool(a < c) равно true;
  • bool(a > b) == bool(b < a)
  • bool(a >= b) == !bool(a < b)
  • bool(a <= b) == !bool(b < a)
2) std::totally_ordered_with<T, U> считается моделируемым только в том случае, если при заданных
  • t и t2 — lvalue-выражениях, обозначающих различные равные объекты типов const std::remove_reference_t<T> и std::remove_reference_t<T> соответственно, и
  • u и u2 — lvalue-выражениях, обозначающих различные равные объекты типов const std::remove_reference_t<U> и std::remove_reference_t<U> соответственно,

пусть C равно std::common_reference_t<const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>, а для заданного выражения E и типа C пусть CONVERT_TO<C>(E) равно:

  • static_cast<C>(std::as_const(E)).
(до C++23)
  • static_cast<const C&>(std::as_const(E)), если это допустимое выражение,
  • static_cast<const C&>(std::move(E)) в противном случае.
(начиная с C++23)

тогда выполняются следующие условия:

  • bool(t < u) == bool(CONVERT_TO<C>(t2) < CONVERT_TO<C>(u2))
  • bool(t > u) == bool(CONVERT_TO<C>(t2) > CONVERT_TO<C>(u2))
  • bool(t <= u) == bool(CONVERT_TO<C>(t2) <= CONVERT_TO<C>(u2))
  • bool(t >= u) == bool(CONVERT_TO<C>(t2) >= CONVERT_TO<C>(u2))
  • bool(u < t) == bool(CONVERT_TO<C>(u2) < CONVERT_TO<C>(t2))
  • bool(u > t) == bool(CONVERT_TO<C>(u2) > CONVERT_TO<C>(t2))
  • bool(u <= t) == bool(CONVERT_TO<C>(u2) <= CONVERT_TO<C>(t2))
  • bool(u >= t) == bool(CONVERT_TO<C>(u2) >= CONVERT_TO<C>(t2))
3) __PartiallyOrderedWith<T, U> считается моделируемым только в том случае, если для заданных
  • любого lvalue-выражения t типа const std::remove_reference_t<T> и
  • любого lvalue-выражения u типа const std::remove_reference_t<U>

выполняются следующие условия:

  • t < u, t <= u, t > u, t >= u, u < t, u <= t, u > t и u >= t имеют одну и ту же область определения;
  • bool(t < u) == bool(u > t);
  • bool(u < t) == bool(t > u);
  • bool(t <= u) == bool(u >= t); и
  • bool(u <= t) == bool(t >= u).

Сохранение равенства

Выражения, объявленные в requires-выражениях концептов стандартной библиотеки, должны сохранять равенство (кроме случаев, где указано иное).

Неявные варианты выражений

requires-выражение, использующее выражение, не изменяющее некоторый константный lvalue-операнд, также требует наличия неявных вариантов выражения.

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
    • 18.5.5 Концепт totally_ordered [concept.totallyordered]
  • Стандарт C++20 (ISO/IEC 14882:2020):
    • 18.5.4 Концепт totally_ordered [concept.totallyordered]

См. также

three_way_comparablethree_way_comparable_with
(C++20)(C++20)
задаёт требование, согласно которому оператор <=> даёт согласованный результат для заданных типов
(концепт)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/concepts/totally_ordered

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API