|
9332 | 9332 | template <class...>
|
9333 | 9333 | using void_t = void;
|
9334 | 9334 |
|
| 9335 | + // \ref{meta.logical}, logical operator traits: |
| 9336 | + template<class... B> struct conjunction; |
| 9337 | + template<class... B> struct disjunction; |
| 9338 | + template<class B> struct negation; |
| 9339 | + |
9335 | 9340 | // \ref{meta.unary.cat}, primary type categories
|
9336 | 9341 | template <class T> constexpr bool is_void_v
|
9337 | 9342 | = is_void<T>::value;
|
|
9471 | 9476 | = is_base_of<Base, Derived>::value;
|
9472 | 9477 | template <class From, class To> constexpr bool is_convertible_v
|
9473 | 9478 | = is_convertible<From, To>::value;
|
| 9479 | + |
| 9480 | + // \ref{meta.logical}, logical operator traits: |
| 9481 | + template<class... B> constexpr bool conjunction_v = conjunction<B...>::value; |
| 9482 | + template<class... B> constexpr bool disjunction_v = disjunction<B...>::value; |
| 9483 | + template<class B> constexpr bool negation_v = negation<B>::value; |
9474 | 9484 | } // namespace std
|
9475 | 9485 | \end{codeblock}
|
9476 | 9486 |
|
|
10543 | 10553 | \end{codeblock}
|
10544 | 10554 | \exitexample
|
10545 | 10555 |
|
| 10556 | +\rSec2[meta.logical]{Logical operator traits} |
| 10557 | + |
| 10558 | +\pnum |
| 10559 | +This subclause describes type traits for applying logical operators |
| 10560 | +to other type traits. |
| 10561 | + |
| 10562 | +\pnum |
| 10563 | +\begin{codeblock} |
| 10564 | + template<class... B> struct conjunction : @\seebelow@ { }; |
| 10565 | +\end{codeblock} |
| 10566 | + |
| 10567 | +\pnum |
| 10568 | +The class template \tcode{conjunction} |
| 10569 | +forms the logical conjunction of its template type arguments. |
| 10570 | +Every template type argument |
| 10571 | +shall be usable as a base class and |
| 10572 | +shall have a member \tcode{value} which |
| 10573 | +is convertible to \tcode{bool}, |
| 10574 | +is not hidden, and |
| 10575 | +is unambiguously available in the type. |
| 10576 | + |
| 10577 | +\pnum |
| 10578 | +The BaseCharacteristic of a specialization \tcode{conjunction<B1, ..., BN>} |
| 10579 | +is the first type \tcode{Bi} in the list \tcode{true_type, B1, ..., BN} |
| 10580 | +for which \tcode{Bi::value == false}, or |
| 10581 | +if every \tcode{Bi::value != false}, the BaseCharacteristic is \tcode{BN}. |
| 10582 | +\enternote This means a specialization of \tcode{conjunction} |
| 10583 | +does not necessarily have a BaseCharacteristic |
| 10584 | +of either \tcode{true_type} or \tcode{false_type}. |
| 10585 | +\exitnote |
| 10586 | + |
| 10587 | +\pnum |
| 10588 | +For a specialization \tcode{conjunction<B1, ..., BN>}, |
| 10589 | +if there is a template type argument \tcode{Bi} with \tcode{Bi::value == false}, |
| 10590 | +then instantiating \tcode{conjunction<B1, ..., BN>::value} |
| 10591 | +does not require the instantiation of \tcode{Bj::value} for \tcode{j > i}. |
| 10592 | +\enternote This is analogous to the short-circuiting behavior of \tcode{\&\&}. |
| 10593 | +\exitnote |
| 10594 | + |
| 10595 | +\pnum |
| 10596 | +\begin{codeblock} |
| 10597 | + template<class... B> struct disjunction : @\seebelow@ { }; |
| 10598 | +\end{codeblock} |
| 10599 | + |
| 10600 | +\pnum |
| 10601 | +The class template \tcode{disjunction} |
| 10602 | +forms the logical disjunction of its template type arguments. |
| 10603 | +Every template type argument shall be usable as a base class and |
| 10604 | +shall have a member \tcode{value} which |
| 10605 | +is convertible to \tcode{bool}, |
| 10606 | +is not hidden, and |
| 10607 | +is unambiguously available in the type. |
| 10608 | + |
| 10609 | +\pnum |
| 10610 | +The BaseCharacteristic of a specialization \tcode{disjunction<B1, ..., BN>} |
| 10611 | +is the first type \tcode{Bi} in the list \tcode{false_type, B1, ..., BN} |
| 10612 | +for which \tcode{Bi::value != false}, or |
| 10613 | +if every \tcode{Bi::value == false}, the BaseCharacteristic is \tcode{BN}. |
| 10614 | +\enternote This means a specialization of \tcode{disjunction} |
| 10615 | +does not necessarily have a BaseCharacteristic |
| 10616 | +of either \tcode{true_type} or \tcode{false_type}. |
| 10617 | +\exitnote |
| 10618 | + |
| 10619 | +\pnum |
| 10620 | +For a specialization \tcode{disjunction<B1, ..., BN>}, |
| 10621 | +if there is a template type argument \tcode{Bi} with \tcode{Bi::value != false}, |
| 10622 | +then instantiating \tcode{disjunction<B1, ..., BN>::value} |
| 10623 | +does not require the instantiation of \tcode{Bj::value} for \tcode{j > i}. |
| 10624 | +\enternote This is analogous to the short-circuiting behavior of \tcode{||}. |
| 10625 | +\exitnote |
| 10626 | + |
| 10627 | +\pnum |
| 10628 | +\begin{codeblock} |
| 10629 | + template<class B> struct negation : bool_constant<!B::value> { }; |
| 10630 | +\end{codeblock} |
| 10631 | + |
| 10632 | +\pnum |
| 10633 | +The class template \tcode{negation} |
| 10634 | +forms the logical negation of its template type argument. |
| 10635 | +The type \tcode{negation<B>} |
| 10636 | +is a UnaryTypeTrait with a BaseCharacteristic of \tcode{bool_constant<!B::value>}. |
| 10637 | + |
10546 | 10638 | \rSec1[ratio]{Compile-time rational arithmetic}
|
10547 | 10639 |
|
10548 | 10640 | \rSec2[ratio.general]{In general}
|
|
0 commit comments