std::experi...Comparable,(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

okay bestie, this is the std::experi...Comparable,(3) page from the C++ Standard Libary (yes, that spelling is in the header, and honestly? iconic) β€” we're about to make equality concepts make sense πŸ’…βœ¨

πŸ’– NAME πŸ’–

the page name is literally this: std::experimental::ranges::EqualityComparable, - std::experimental::ranges::EqualityComparable,

✨ Synopsis ✨

Defined in header <experimental/ranges/concepts>, and the synopsis goes a little like this:

template< class T >
concept bool EqualityComparable = WeaklyEqualityComparableWith<T, T>;

template< class T, class U >
concept bool EqualityComparableWith =
    EqualityComparable<T> &&
    EqualityComparable<U> &&
    CommonReference<
        const std::remove_reference_t<T>&,
        const std::remove_reference_t<U>&> &&
    EqualityComparable<
        ranges::common_reference_t<
            const std::remove_reference_t<T>&,
            const std::remove_reference_t<U>&>> &&
    WeaklyEqualityComparableWith<T, U>;

The source has two little markers in there: (1) (ranges TS) and (2) (ranges TS) β€” those point at the two explanations below, bestie 🫢

  1. The concept EqualityComparable<T> says the comparison operators == and != on T actually reflect equality: == gives true if and only if the operands are equal. EqualityComparable<T> is satisfied only if, given objects a and b of type T, bool(a == b) is true if and only if a and b are equal. And because a == b also has to be equality preserving, that means == is symmetric and transitive, plus it's reflexive for every object a that's equal to at least one other object. periodt πŸ’…
  2. The concept EqualityComparableWith<T, U> says the comparison operators == and != on (possibly mixed) T and U operands give results that are consistent with equality. Comparing mixed operands gives results equivalent to comparing the operands converted to their common type. Formally, EqualityComparableWith<T, U> is satisfied only if, given any lvalue t of type const std::remove_reference_t<T> and any lvalue u of type const std::remove_reference_t<U>, and letting C be ranges::common_reference_t<const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>, this holds: bool(t == u) == bool(C(t) == C(u)). no cap 🧚

πŸŽ€ Equality preservation πŸŽ€

An expression is equality preserving if it gives equal outputs when given equal inputs.

  • The inputs to an expression are its operands.
  • The outputs of an expression are its result and all operands that the expression modifies (if any).

Every expression that has to be equality preserving is also required to be stable: two evaluations of that expression with the same input objects must have equal outputs, unless something explicitly modifies those input objects in between. literally the bare minimum 😭

πŸ¦‹ Implicit expression variations πŸ¦‹

A requires-expression that uses an expression that is non-modifying for some constant lvalue operand also implicitly requires extra variations of that expression. Those variations accept a non-constant lvalue or a (possibly constant) rvalue for the given operand β€” unless such an expression variation is explicitly required with differing semantics. These implicit expression variations have to meet the same semantic requirements as the declared expression. The extent to which an implementation validates the syntax of the variations is unspecified. slay but make it unspecified πŸ’€


and that's the tea β˜• source: http://cppreference.com, version/date: 2024.06.10, page: std::experi...Comparable,(3) β€” byeee bestie πŸŽ€βœ¨

πŸ“¦ where this page comes from