The concepts in this subclause describe the requirements on function
objects ([function.objects]) and their arguments.

The invocable concept specifies a relationship between a callable
type ([func.def]) F and a set of argument types Args... which
can be evaluated by the library function invoke ([func.invoke]).

```
template<class F, class... Args>
concept invocable = requires(F&& f, Args&&... args) {
invoke(std::forward<F>(f), std::forward<Args>(args)...); // not required to be equality-preserving
};
```

[ Example

: *end example*

]A function that generates random numbers can model invocable,
since the invoke function call expression is not required to be
equality-preserving ([concepts.equality]).

â€” ```
template<class F, class... Args>
concept regular_invocable = invocable<F, Args...>;
```

The invoke function call expression shall be equality-preserving and
shall not modify the function object or the
arguments ([concepts.equality]).

```
template<class F, class... Args>
concept predicate = regular_invocable<F, Args...> && boolean<invoke_result_t<F, Args...>>;
```

```
template<class R, class T, class U>
concept relation =
predicate<R, T, T> && predicate<R, U, U> &&
predicate<R, T, U> && predicate<R, U, T>;
```

```
template<class R, class T, class U>
concept strict_weak_order = relation<R, T, U>;
```

The term
*strict*
refers to the
requirement of an irreflexive relation (!comp(x, x) for all x),
and the term
*weak*
to requirements that are not as strong as
those for a total ordering,
but stronger than those for a partial
ordering.

If we define
equiv(a, b)
as
!comp(a, b) && !comp(b, a),
then the requirements are that
comp
and
equiv
both be transitive relations:

- comp(a, b) && comp(b, c) implies comp(a, c)
- equiv(a, b) && equiv(b, c) implies equiv(a, c)