18 Concepts library [concepts]

18.5 Comparison concepts [concepts.compare]

18.5.2 Boolean testability [concept.booleantestable]

The exposition-only boolean-testable concept specifies the requirements on expressions that are convertible to bool and for which the logical operators ([expr.log.and], [expr.log.or], [expr.unary.op]) have the conventional semantics.
template<class T> concept boolean-testable-impl = convertible_­to<T, bool>; // exposition only
Let e be an expression such that decltype((e)) is T.
T models boolean-testable-impl only if:
  • either remove_­cvref_­t<T> is not a class type, or name lookup for the names operator&& and operator|| within the scope of remove_­cvref_­t<T> as if by class member access lookup ([class.member.lookup]) results in an empty declaration set; and
  • name lookup for the names operator&& and operator|| in the associated namespaces and entities of T ([basic.lookup.argdep]) finds no disqualifying declaration (defined below).
A disqualifying parameter is a function parameter whose declared type P
  • is not dependent on a template parameter, and there exists an implicit conversion sequence ([over.best.ics]) from e to P; or
  • is dependent on one or more template parameters, and either
    • P contains no template parameter that participates in template argument deduction ([temp.deduct.type]), or
    • template argument deduction using the rules for deducing template arguments in a function call ([temp.deduct.call]) and e as the argument succeeds.
A key parameter of a function template D is a function parameter of type cv X or reference thereto, where X names a specialization of a class template that is a member of the same namespace as D, and X contains at least one template parameter that participates in template argument deduction.
[Example
:
In
namespace Z {
  template<class> struct C {};
  template<class T>
    void operator&&(C<T> x, T y);
  template<class T>
    void operator||(C<type_identity_t<T>> x, T y);
}
the declaration of Z​::​operator&& contains one key parameter, C<T> x, and the declaration of Z​::​operator|| contains no key parameters.
— end example
]
A disqualifying declaration is
  • a (non-template) function declaration that contains at least one disqualifying parameter; or
  • a function template declaration that contains at least one disqualifying parameter, where
    • at least one disqualifying parameter is a key parameter; or
    • the declaration contains no key parameters; or
    • the declaration declares a function template that is not visible in its namespace ([namespace.memdef]).
[Note
:
The intention is to ensure that given two types T1 and T2 that each model boolean-testable-impl, the && and || operators within the expressions declval<T1>() && declval<T2>() and declval<T1>() || declval<T2>() resolve to the corresponding built-in operators.
— end note
]
template<class T> concept boolean-testable = // exposition only boolean-testable-impl<T> && requires (T&& t) { { !std::forward<T>(t) } -> boolean-testable-impl; };
Let e be an expression such that decltype((e)) is T.
T models boolean-testable only if bool(e) == !bool(!e).
[Example
:
The types bool, true_­type ([meta.type.synop]), int*, and bitset<N>​::​reference ([template.bitset]) model boolean-testable.
— end example
]