Primitive Types
Like raw C++, Pion has a number of primitives that are used to build up aggregate structures.
Integral Numerics
C++ has a variety of integral types, such as int
, short
, unsigned long long
, etc. Many developers will use
width-specific aliases defined in the cstdint
header, such as int32_t
.
All these types are valid in Pion, but their use is discouraged and considered non-"Pionic". Instead, Pion defines two
type templates, Integer<N>
and Natural<N>
. These two templates take a number N as a non-type template parameter,
which indicates the width of the integer type. For example, Integer<32>
is a 32-bit integer. The value of N can be
arbitrary. Integer<1024>
defines a 1024-bit integer, just as Integer<19>
defines a 19-bit integer. The Integer
template is used for signed integral numbers, while Natural
is used for unsigned ones. An import distinction between
these types and the core C++ integer types is that there is no arbitrary integer promotion. When two Pion integers are
operated on together, the result will be the maximum of the two bit-widths (and unsigned if either integer was
unsigned).
In implementation, Integer
and Natural
rely on the compiler's support for the C type _BitInt
, and has all of the
same limitations thereof. The maximum width of a Pion integer is therefore limited to the value
of __BITINT_MAXWIDTH__
, but this is guaranteed to always be at least 128 in any supported compiler.
A number of convenience type aliases are provided:
Integer2
Integer8
Integer16
Integer24
Integer32
Integer48
Integer64
Integer128
Natural1
Natural8
Natural16
Natural24
Natural32
Natural48
Natural64
Natural128
When the compiler supports widths above 128-bit, aliases are also provided for widths of 256, 512, 1024, and 2048 if such sizes are available.
Integral Literals
Undecorated integer literals are still int
by default as in raw C++, but can be assigned transparently, without
warning, to Pion integers provided the value fits within the range of the type to which it is assigned. Explicit
literals can be expressed by giving a suffix of n
or i
for the default word sized integer. The suffix followed by
any width listed above in the width-specific aliases can also be used, e.g. n32
expresses a Natural32
.
Arbitrary widths can also be expressed by adding a decimal point to the integer, followed by the width, and then the
suffix 'n' or 'i'. For example, 123.32i
expresses the Integer<32>
value 123
, and 456.192n
expresses the
Natural<192>
value 456
.
Booleans
Pion defines the type Boolean
as indicating the binary values of true
or false
. This type is an alias
for Natural<1>
, the single-bit integer.
Binary Floating Point
Pion defines the Float
template for IEEE binary floating point values. The template takes 3 non-type template
parameters: the width of the value, in bits; the number of bits used for the exponent; and the exponent bias value. The
later two template parameters can be defaulted based on the IEEE formula for standard floating point types. The most
common types used are Float<32>
a.k.a. Float32
and Float<64>
a.k.a. Float64
.
Floating point values are implemented by hardware when possible, but any arbitrary floating point type can be defined
and will be implemented in software when the architecture lacks hardware support. Some other common floating point types
are Float<16>
a.k.a. Float16
, Float<128>
a.k.a. Float128
, and BFloat16
.
Decimal Floating Point
Pion likewise supports IEEE decimal floating point values. These are implemented in hardware when possible but otherwise
use software implementations. Common types/aliases are Decimal<32>
/Decimal32
, Decimal<64>
/Decimal64
, and
Decimal<128>
/Decimal128
.
Bytes
The type Byte
represents a single octet. Because the C++ specification defines a number of behaviors in terms of
std::byte
, Byte
is in fact an alias for std::byte
. However, Pion also allows for the b
suffix on an integer
literal to define a byte of a specific value, e.g. 0xF0b
. It is a compile-time error for a byte literal to have a
value above 0xFF
, or negative.