diff --git a/docs/api_reference/src/quantities.tex b/docs/api_reference/src/quantities.tex index 2ee4305a4..5e77acf3a 100644 --- a/docs/api_reference/src/quantities.tex +++ b/docs/api_reference/src/quantities.tex @@ -48,8 +48,6 @@ export namespace mp_units { -enum class @\libglobal{text_encoding}@ : std::int8_t { utf8, portable, default_encoding = utf8 }; - enum class @\libglobal{quantity_character}@ { scalar, complex, vector, tensor }; // \ref{qty.helpers}, helpers @@ -95,7 +93,12 @@ namespace mp_units { -// \ref{qty.symbol.text}, class template \exposid{symbol-text} +// \ref{qty.sym.txt}, class template \exposid{symbol-text} + +enum class @\libglobal{text_encoding}@ : std::int8_t { utf8, portable, default_encoding = utf8 }; + +template +class @\exposidnc{symbol-text}@; // \expos // \ref{qty.expr.temp}, expression template @@ -120,7 +123,7 @@ // \ref{qty.dim.types}, types -template +template<@\exposidnc{symbol-text}@ Symbol> struct base_dimension; template @@ -227,7 +230,7 @@ // \ref{qty.mag.types}, types -template +template<@\exposidnc{symbol-text}@ Symbol, long double Value> requires(Value > 0) struct mag_constant; @@ -286,39 +289,39 @@ requires @\seebelownc@ struct scaled_unit; -template +template<@\exposidnc{symbol-text}@ Symbol, auto...> struct named_unit; // \notdef -template +template<@\exposidnc{symbol-text}@ Symbol, @\exposconceptnc{QuantityKindSpec}@ auto QS> requires @\seebelownc@ struct named_unit; -template +template<@\exposidnc{symbol-text}@ Symbol, @\exposconceptnc{QuantityKindSpec}@ auto QS, @\libconcept{PointOrigin}@ auto PO> requires @\seebelownc@ struct named_unit; -template +template<@\exposidnc{symbol-text}@ Symbol> requires @\seebelownc@ struct named_unit; -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{Unit}@ auto U> requires @\seebelownc@ struct named_unit; -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{Unit}@ auto U, @\libconcept{PointOrigin}@ auto PO> requires @\seebelownc@ struct named_unit; -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{AssociatedUnit}@ auto U, @\exposconceptnc{QuantityKindSpec}@ auto QS> requires @\seebelownc@ struct named_unit; -template requires @\seebelownc@ struct named_unit; -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{Magnitude}@ auto M, @\libconcept{PrefixableUnit}@ auto U> requires @\seebelownc@ struct prefixed_unit; @@ -335,7 +338,7 @@ } @\libglobal{percent}@; inline constexpr struct @\libglobal{per_mille}@ final : - named_unit * one> { } @\libglobal{per_mille}@; @@ -1050,7 +1053,141 @@ }; \end{codeblock} -\rSec2[qty.symbol.text]{Class template \exposid{symbol-text}} +\rSec2[qty.sym.txt]{Class template \exposid{symbol-text}} + +\indexlibraryglobal{\exposid{symbol-text}} +\begin{codeblock} +namespace mp_units { + +template +class @\exposidnc{symbol-text}@ { // \expos +public: + @\exposidnc{fixed-u8string}@ @\exposidnc{utf8}@; // \expos + @\exposidnc{fixed-string}@ @\exposidnc{portable}@; // \expos + + // constructors + constexpr explicit(false) @\exposidnc{symbol-text}@(char portable); + consteval explicit(false) @\exposidnc{symbol-text}@(const char (&portable)[N + 1]); + constexpr explicit(false) @\exposidnc{symbol-text}@(const fixed_string& portable); + consteval @\exposidnc{symbol-text}@(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); + constexpr @\exposidnc{symbol-text}@(const fixed_u8string& utf8, const fixed_string& portable); + + // observers + constexpr const auto& utf8() const { return @\exposidnc{utf8}@; } + constexpr const auto& portable() const { return @\exposidnc{portable}@; } + constexpr bool empty() const { return utf8().empty(); } + + // string operations + template + friend constexpr @\exposidnc{symbol-text}@ operator+(const @\exposidnc{symbol-text}@& lhs, + const @\exposidnc{symbol-text}@& rhs); + + // comparison + template + friend constexpr auto operator<=>(const @\exposidnc{symbol-text}@& lhs, + const @\exposidnc{symbol-text}@& rhs) noexcept; + template + friend constexpr bool operator==(const @\exposidnc{symbol-text}@& lhs, + const @\exposidnc{symbol-text}@& rhs) noexcept; +}; + +// deduction guides + +@\exposidnc{symbol-text}@(char) -> @\exposidnc{symbol-text}@<1, 1>; + +template +@\exposidnc{symbol-text}@(const char (&)[N]) -> @\exposidnc{symbol-text}@; + +template +@\exposidnc{symbol-text}@(const fixed_string&) -> @\exposidnc{symbol-text}@; + +template +@\exposidnc{symbol-text}@(const char8_t (&)[N], const char (&)[M]) -> @\exposidnc{symbol-text}@; + +template +@\exposidnc{symbol-text}@(const fixed_u8string&, const fixed_string&) -> @\exposidnc{symbol-text}@; + +} +\end{codeblock} + +\pnum +\exposid{symbol-text} describes a symbol text. +\exposid{utf8} stores its UTF-8 representation, and +\exposid{portable} stores its portable representation. +\tcode{\exposid{symbol-text}} is a structural type\irefcppx{temp.param}{term.structural.type}. + +\pnum +In the descriptions that follow, +it is a \Fundescx{Precondition} that +\begin{itemize} +\item +values of \tcode{char} are in the basic literal character set\irefcpp{lex.charset}, and +\item +for a parameter of the form \tcode{const \placeholdernc{CharT} (\&\placeholdernc{txt})[\placeholder{M}]}, +\tcode{(\placeholdernc{txt}[\placeholdernc{M} - 1] == \placeholdernc{CharT}())} is \tcode{true}. +\end{itemize} + +\begin{itemdecl} +constexpr explicit(false) @\exposidnc{symbol-text}@(char portable); +consteval explicit(false) @\exposidnc{symbol-text}@(const char (&portable)[N + 1]); +constexpr explicit(false) @\exposidnc{symbol-text}@(const fixed_string& portable); +consteval @\exposidnc{symbol-text}@(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); +constexpr @\exposidnc{symbol-text}@(const fixed_u8string& utf8, const fixed_string& portable); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{lhs} be \tcode{utf8} for the last two constructors, +and otherwise: +\begin{codeblock} +std::bit_cast<@\exposidnc{fixed-u8string}@>(@\exposidnc{basic-fixed-string}@(portable)) +\end{codeblock} + +\pnum +\effects +Equivalent to the \fakegrammarterm{mem-initializer-list}: +\begin{codeblock} +@\exposid{utf8}@{lhs}, @\exposidnc{portable}@{portable} +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template +friend constexpr @\exposidnc{symbol-text}@ operator+(const @\exposidnc{symbol-text}@& lhs, + const @\exposidnc{symbol-text}@& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return @\exposidnc{symbol-text}@(lhs.utf8() + rhs.utf8(), + lhs.portable() + rhs.portable()); +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template +friend constexpr auto operator<=>(const @\exposidnc{symbol-text}@& lhs, + const @\exposidnc{symbol-text}@& rhs) noexcept; +template +friend constexpr bool operator==(const @\exposidnc{symbol-text}@& lhs, + const @\exposidnc{symbol-text}@& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{@} be the \fakegrammarterm{operator}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return std::make_tuple(std::cref(lhs.utf8()), std::cref(lhs.portable())) @\atsign@ + std::make_tuple(std::cref(rhs.utf8()), std::cref(rhs.portable())); +\end{codeblock} +\end{itemdescr} \rSec1[qty.expr.temp]{Expression template} @@ -1384,7 +1521,7 @@ } }; -template +template<@\exposidnc{symbol-text}@ Symbol> struct @\libglobal{base_dimension}@ : @\exposidnc{dimension-interface}@ { static constexpr auto @\exposidnc{symbol}@ = Symbol; // \expos }; @@ -2057,7 +2194,7 @@ \begin{codeblock} namespace mp_units { -template +template<@\exposidnc{symbol-text}@ Symbol, long double Value> requires(Value > 0) struct @\libglobal{mag_constant}@ { static constexpr auto @\exposidnc{symbol}@ = Symbol; // \expos @@ -2410,7 +2547,7 @@ \begin{codeblock} namespace mp_units { -template +template<@\exposidnc{symbol-text}@ Symbol, @\exposconceptnc{QuantityKindSpec}@ auto QS> requires(!Symbol.empty()) && @\exposconceptnc{BaseDimension}@> struct @\libglobal{named_unit}@ : @\exposidnc{unit-interface}@ { using @\exposidnc{base-type}@ = named_unit; // \expos @@ -2418,7 +2555,7 @@ static constexpr auto @\exposidnc{quantity-spec}@ = QS; // \expos }; -template +template<@\exposidnc{symbol-text}@ Symbol, @\exposconceptnc{QuantityKindSpec}@ auto QS, @\libconcept{PointOrigin}@ auto PO> requires(!Symbol.empty()) && @\exposconceptnc{BaseDimension}@> struct named_unit : @\exposidnc{unit-interface}@ { using @\exposidnc{base-type}@ = named_unit; // \expos @@ -2427,21 +2564,21 @@ static constexpr auto @\exposidnc{point-origin}@ = PO; // \expos }; -template +template<@\exposidnc{symbol-text}@ Symbol> requires(!Symbol.empty()) struct named_unit : @\exposidnc{unit-interface}@ { using @\exposidnc{base-type}@ = named_unit; // \expos static constexpr auto @\exposidnc{symbol}@ = Symbol; // \expos }; -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{Unit}@ auto U> requires(!Symbol.empty()) struct named_unit : decltype(U)::@\exposidnc{base-type}@ { using @\exposidnc{base-type}@ = named_unit; // \expos static constexpr auto @\exposidnc{symbol}@ = Symbol; // \expos }; -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{Unit}@ auto U, @\libconcept{PointOrigin}@ auto PO> requires(!Symbol.empty()) struct named_unit : decltype(U)::@\exposidnc{base-type}@ { using @\exposidnc{base-type}@ = named_unit; // \expos @@ -2449,7 +2586,7 @@ static constexpr auto @\exposidnc{point-origin}@ = PO; // \expos }; -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{AssociatedUnit}@ auto U, @\exposconceptnc{QuantityKindSpec}@ auto QS> requires(!Symbol.empty()) && (QS.dimension == @\exposidnc{get-associated-quantity}@(U).dimension) struct named_unit : decltype(U)::@\exposidnc{base-type}@ { using @\exposidnc{base-type}@ = named_unit; // \expos @@ -2457,7 +2594,7 @@ static constexpr auto @\exposidnc{quantity-spec}@ = QS; // \expos }; -template requires(!Symbol.empty()) && (QS.dimension == @\exposidnc{get-associated-quantity}@(U).dimension) struct named_unit : decltype(U)::@\exposidnc{base-type}@ { @@ -2536,7 +2673,7 @@ \begin{codeblock} namespace mp_units { -template +template<@\exposidnc{symbol-text}@ Symbol, @\libconcept{Magnitude}@ auto M, @\libconcept{PrefixableUnit}@ auto U> requires(!Symbol.empty()) struct prefixed_unit : decltype(M * U)::@\exposidnc{base-type}@ { using @\exposidnc{base-type}@ = prefixed_unit; // \expos