[meta.reflection.layout] # 21 Metaprogramming library [[meta]](./#meta) ## 21.4 Reflection [[meta.reflection]](meta.reflection#layout) ### 21.4.11 Reflection layout queries [meta.reflection.layout] [🔗](#lib:member_offset) `struct member_offset { ptrdiff_t bytes; ptrdiff_t bits; constexpr ptrdiff_t total_bits() const; auto operator<=>(const member_offset&) const = default; }; constexpr ptrdiff_t member_offset::total_bits() const; ` [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5663) *Returns*: bytes * CHAR_BIT + bits[.](#1.sentence-1) [🔗](#lib:offset_of) `consteval member_offset offset_of(info r); ` [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5674) Let V be the offset in bits from the beginning of a complete object of the type represented by parent_of(r) to the subobject associated with the entity represented by r[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5679) *Returns*: {V / CHAR_BIT, V % CHAR_BIT}[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5683) *Throws*: meta​::​exception unlessr represents a non-static data member, unnamed bit-field, or direct base class relationship (D,B) for which either B is not a virtual base class or D is not an abstract class[.](#4.sentence-1) [🔗](#lib:size_of) `consteval size_t size_of(info r); ` [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5699) *Returns*: If r represents - [(5.1)](#5.1) a non-static data member of type T, - [(5.2)](#5.2) a data member description (T,N,A,W,NUA), or - [(5.3)](#5.3) dealias(r) represents a type T, then sizeof(T) if T is not a reference type and size_of(​add_pointer(​^^T)) otherwise[.](#5.sentence-1) Otherwise, size_of(type_of(r))[.](#5.sentence-2) [*Note [1](#note-1)*: It is possible that while sizeof(char)​ == size_of(^^char) is true, that sizeof(char&)​ == size_of(​^^char&) is false[.](#5.sentence-3) If b represents a direct base class relationship of an empty base class, then size_of(b) > 0 is true[.](#5.sentence-4) — *end note*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5719) *Throws*: meta​::​exception unless all of the following conditions are met: - [(6.1)](#6.1) dealias(r) is a reflection of a type, object, value, variable of non-reference type, non-static data member that is not a bit-field, direct base class relationship, or data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")) where W is not ⊥[.](#6.1.sentence-1) - [(6.2)](#6.2) If dealias(r) represents a type, then is_complete_type(r) is true[.](#6.2.sentence-1) [🔗](#lib:alignment_of) `consteval size_t alignment_of(info r); ` [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5746) *Returns*: - [(7.1)](#7.1) If dealias(r) represents a type T, then alignment_of(add_pointer(r)) if T is a reference type and the alignment requirement of T otherwise[.](#7.1.sentence-1) - [(7.2)](#7.2) Otherwise, if dealias(r) represents a variable or object, then the alignment requirement of the variable or object[.](#7.2.sentence-1) - [(7.3)](#7.3) Otherwise, if r represents a direct base class relationship, then alignment_of(type_of(r))[.](#7.3.sentence-1) - [(7.4)](#7.4) Otherwise, if r represents a non-static data member M of a class C, then the alignment of the direct member subobject corresponding to M of a complete object of type C[.](#7.4.sentence-1) - [(7.5)](#7.5) Otherwise, r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General"))[.](#7.5.sentence-1) If A is not ⊥, then the value A[.](#7.5.sentence-2) Otherwise, alignment_of(^^T)[.](#7.5.sentence-3) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5771) *Throws*: meta​::​exception unless all of the following conditions are met: - [(8.1)](#8.1) dealias(r) is a reflection of a type, object, variable of non-reference type, non-static data member that is not a bit-field, direct base class relationship, or data member description[.](#8.1.sentence-1) - [(8.2)](#8.2) If dealias(r) represents a type, then is_complete_type(r) is true[.](#8.2.sentence-1) [🔗](#lib:bit_size_of) `consteval size_t bit_size_of(info r); ` [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5796) *Returns*: - [(9.1)](#9.1) If r represents an unnamed bit-field or a non-static data member that is a bit-field with width W, then W[.](#9.1.sentence-1) - [(9.2)](#9.2) Otherwise, if r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")) and W is not ⊥, then W[.](#9.2.sentence-1) - [(9.3)](#9.3) Otherwise, CHAR_BIT * size_of(r)[.](#9.3.sentence-1) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5814) *Throws*: meta​::​exception unless all of the following conditions are met: - [(10.1)](#10.1) dealias(r) is a reflection of a type, object, value, variable of non-reference type, non-static data member, unnamed bit-field, direct base class relationship, or data member description[.](#10.1.sentence-1) - [(10.2)](#10.2) If dealias(r) represents a type T, there is a point within the evaluation context from which T is not incomplete[.](#10.2.sentence-1)