[meta.logical]

# 21 Metaprogramming library [[meta]](./#meta)

## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.logical)

### 21.3.10 Logical operator traits [meta.logical]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2616)

This subclause describes type traits for applying logical operators
to other type traits[.](#1.sentence-1)

[ð](#lib:conjunction)

`template<class... B> struct conjunction : see below { };
`

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2626)

The class template conjunction forms the logical conjunction of its template type arguments[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2630)

For a specialization conjunction<B1, …, BN>,
if there is a template type argument Bi for which bool(Bi​::​value) is false,
then instantiating conjunction<B1, …, BN>​::​value does not require the instantiation of Bj​::​value for j>i[.](#3.sentence-1)

[*Note [1](#note-1)*:

This is analogous to the short-circuiting behavior of
the built-in operator &&[.](#3.sentence-2)

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2641)

Every template type argument
for which Bi​::​value is instantiated
shall be usable as a base class and
shall have a member value which
is convertible to bool,
is not hidden, and
is unambiguously available in the type[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2650)

The specialization conjunction<B1, …, BN> has a public and unambiguous base that is either

- [(5.1)](#5.1)

the first type Bi in the list true_type, B1, …, BN for which bool(Bi​::​value) is false, or

- [(5.2)](#5.2)

if there is no such Bi, the last type in the list[.](#5.sentence-1)

[*Note [2](#note-2)*:

This means a specialization of conjunction does not necessarily inherit from
either true_type or false_type[.](#5.sentence-2)

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2666)

The member names of the base class, other than conjunction andoperator=, shall not be hidden and shall be unambiguously available
in conjunction[.](#6.sentence-1)

[ð](#lib:disjunction)

`template<class... B> struct disjunction : see below { };
`

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2678)

The class template disjunction forms the logical disjunction of its template type arguments[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2682)

For a specialization disjunction<B1, …, BN>,
if there is a template type argument Bi for which bool(Bi​::​value) is true,
then instantiating disjunction<B1, …, BN>​::​value does not require the instantiation of Bj​::​value for j>i[.](#8.sentence-1)

[*Note [3](#note-3)*:

This is analogous to the short-circuiting behavior of
the built-in operator ||[.](#8.sentence-2)

â *end note*]

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2693)

Every template type argument
for which Bi​::​value is instantiated
shall be usable as a base class and
shall have a member value which
is convertible to bool,
is not hidden, and
is unambiguously available in the type[.](#9.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2702)

The specialization disjunction<B1, …, BN> has a public and unambiguous base that is either

- [(10.1)](#10.1)

the first type Bi in the list false_type, B1, …, BN for which bool(Bi​::​value) is true, or

- [(10.2)](#10.2)

if there is no such Bi, the last type in the list[.](#10.sentence-1)

[*Note [4](#note-4)*:

This means a specialization of disjunction does not necessarily inherit from
either true_type or false_type[.](#10.sentence-2)

â *end note*]

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2716)

The member names of the base class,
other than disjunction and operator=,
shall not be hidden and shall be unambiguously available in disjunction[.](#11.sentence-1)

[ð](#lib:negation)

`template<class B> struct negation : see below { };
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2728)

The class template negation forms the logical negation of its template type argument[.](#12.sentence-1)

The type negation<B> is a [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") with a base characteristic of bool_constant<!bool(B​::​​value)>[.](#12.sentence-2)
