Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,14 @@ jobs:
cxxstd: "14,17,20,latest"
addrmd: "64"
os: windows-latest
- toolset: msvc-14.5
cxxstd: "14,17,20,latest"
addrmd: "32"
os: windows-latest
- toolset: msvc-14.5
cxxstd: "14,17,20,latest"
addrmd: "64"
os: windows-latest
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: "32"
Expand Down
15 changes: 13 additions & 2 deletions doc/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
* xref:overview.adoc[]
* xref:getting_started.adoc[]
* xref:printer.adoc[]
* xref:examples.adoc[]
** xref:examples.adoc#examples_construction[Basic Construction]
** xref:examples.adoc#examples_arithmetic[Basic Arithmetic]
Expand All @@ -9,9 +11,10 @@
** xref:examples.adoc#examples_numeric_algorithms[`<numeric>` support (Numeric Algorithms)]
** xref:examples.adoc#examples_checked[Checked Arithmetic]
** xref:examples.adoc#examples_mixed_sign[Mixed Signedness Arithmetic]
** xref:examples.adoc#examples_to_string[String Conversion (to_string)]
** xref:examples.adoc#examples_boost_math_random[Boost Math and Random Integration]
** xref:examples.adoc#examples_boost_charconv[Boost.Charconv Integration]
** xref:examples.adoc#examples_to_string[String Conversion (to_string)]
** xref:examples.adoc#examples_fmt_format[pass:[{fmt}] Integration]
** xref:examples.adoc#examples_cstdlib[`<cstdlib>` support (Combined div and mod)]
** xref:examples.adoc#examples_cuda[Use of the library in a CUDA kernel]
* xref:api_reference.adoc[]
Expand All @@ -21,10 +24,11 @@
** xref:api_reference.adoc#api_structs[Structs]
** xref:api_reference.adoc#api_functions[Functions]
*** xref:api_reference.adoc#api_bit[`<bit>`]
*** xref:api_reference.adoc#api_cstdlib[`<cstdlib>`]
*** xref:api_reference.adoc#api_charconv[`<charconv>`]
*** xref:api_reference.adoc#api_cmath[`<cmath>`]
*** xref:api_reference.adoc#api_cstdlib[`<cstdlib>`]
*** xref:api_reference.adoc#api_functional[`<functional>`]
*** xref:api_reference.adoc#api_formatting[Formatting]
*** xref:api_reference.adoc#api_iostream[`<iostream>`]
*** xref:api_reference.adoc#api_ios[`<ios>`]
*** xref:api_reference.adoc#api_numeric[`<numeric>`]
Expand All @@ -34,6 +38,7 @@
*** xref:api_reference.adoc#api_macro_literals[Literals]
*** xref:api_reference.adoc#api_macro_configuration[Configuration]
** xref:api_reference.adoc#api_headers[Headers]
* xref:file_structure.adoc[]
* xref:uint128_t.adoc[]
** xref:uint128_t.adoc#u128_alignment[Alignment]
** xref:uint128_t.adoc#u128_operator_behavior[Operator Behavior]
Expand All @@ -59,11 +64,16 @@
* xref:hash.adoc[]
* xref:numeric.adoc[]
* xref:string.adoc[]
* xref:format.adoc[]
** xref:format.adoc#std_format[`<format>`]
** xref:format.adoc#fmt_format[pass:[{fmt}]]
* xref:utilities.adoc[]
** xref:utilities.adoc#powm[Modular Exponentiation]
** xref:utilities.adoc#ipow[Integer Power]
** xref:utilities.adoc#isqrt[Integer Square Root]
** xref:utilities.adoc#checked[Checked Arithmetic]
* xref:random.adoc[]
* xref:config.adoc[]
* Benchmarks
** xref:u128_benchmarks.adoc[]
*** xref:u128_benchmarks.adoc#u128_linux[Linux]
Expand All @@ -74,5 +84,6 @@
*** xref:i128_benchmarks.adoc#i128_windows[Windows]
*** xref:i128_benchmarks.adoc#i128_mac[macOS]
* xref:comp_to_multiprecision.adoc[]
* xref:design.adoc[]
* xref:reference.adoc[]
* xref:copyright.adoc[]
24 changes: 24 additions & 0 deletions doc/modules/ROOT/pages/api_reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ https://www.boost.org/LICENSE_1_0.txt

| xref:charconv.adoc[`boost::charconv`]
| `to_chars` and `from_chars` overloads for 128-bit integers (requires Boost.Charconv)

| `boost::random::traits`
| Trait specializations enabling use with Boost.Random (requires Boost.Random)
|===

[#api_types]
Expand Down Expand Up @@ -233,6 +236,12 @@ Listed by analogous STL header.

| xref:stream.adoc#ios[`std::nouppercase`]
| Lowercase hex digits

| xref:stream.adoc#ios[`std::showbase`]
| Adds a leading base prefix on output

| xref:stream.adoc#ios[`std::noshowbase`]
| Omits the leading base prefix on output
|===

[#api_numeric]
Expand Down Expand Up @@ -353,6 +362,9 @@ Listed by analogous STL header.

| xref:config.adoc#enable_cuda[`BOOST_INT128_ENABLE_CUDA`]
| Enables CUDA support allowing the library types and functions to be run on both host and device

| xref:config.adoc#build_module[`BOOST_INT128_BUILD_MODULE`]
| Builds the library as a pass:[C++20] named module (`import boost.int128`)
|===

==== Automatic Configuration
Expand All @@ -370,6 +382,18 @@ Listed by analogous STL header.
| xref:config.adoc#automatic_config[`BOOST_INT128_ENDIAN_BIG_BYTE`]
| Defined on big-endian systems

| xref:config.adoc#automatic_config[`BOOST_INT128_HAS_MSVC_INT128`]
| Defined when the MSVC simulated 128-bit integer types are available

| xref:config.adoc#automatic_config[`BOOST_INT128_HAS_SPACESHIP_OPERATOR`]
| Defined when pass:[C++20] three-way comparison is available

| xref:config.adoc#automatic_config[`BOOST_INT128_HAS_FORMAT`]
| Defined when pass:[C++20] `<format>` is available

| xref:config.adoc#automatic_config[`BOOST_INT128_HAS_FMT_FORMAT`]
| Defined when the pass:[{fmt}] library is available

| xref:config.adoc#host_device[`BOOST_INT128_HOST_DEVICE`]
| Expands to `pass:[__host__ __device__]` under NVCC for CUDA support
|===
Expand Down
20 changes: 15 additions & 5 deletions doc/modules/ROOT/pages/config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ https://www.boost.org/LICENSE_1_0.txt
= Configuration Macros
:idprefix: config_

[source,c++]
----
#include <boost/int128/config.hpp>
----
The configuration macros below are defined automatically once any library header (for example `<boost/int128.hpp>`) is included; there is no separate configuration header to include directly.

== User Configurable Macros

Expand All @@ -28,6 +25,11 @@ Allowed functions have `BOOST_INT128_HOST_DEVICE` as part of their function sign
- `BOOST_INT128_DISABLE_EXCEPTIONS`: Allows exceptions to be disabled.
This macro will automatically be defined in the presence of `-fno-exceptions` or similar MSVC flags.

[#build_module]
- `BOOST_INT128_BUILD_MODULE`: Define this when building the library as a pass:[C++20] named module (consumed via `import boost.int128`).
It switches the headers into module mode by exporting the public interface and suppressing the includes that the module unit itself provides.
See xref:getting_started.adoc[Getting Started].

[#automatic_config]
== Automatic Configuration Macros

Expand All @@ -37,6 +39,14 @@ This macro will automatically be defined in the presence of `-fno-exceptions` or

- `BOOST_INT128_ENDIAN_BIG_BYTE`: This is defined to `1` when compiling on a big endian architecture, otherwise `0`.

- `BOOST_INT128_HAS_MSVC_INT128`: This is defined when the MSVC standard library provides the simulated 128-bit integer types in `pass:[<__msvc_int128.hpp>]` (MSVC in pass:[C++20] mode). When defined, the library uses those types as its native 128-bit backing.

- `BOOST_INT128_HAS_SPACESHIP_OPERATOR`: This is defined when the compiler and standard library provide pass:[C++20] three-way comparison (`operator<=>` and `<compare>`). When defined, both types provide `operator<=>`.

- `BOOST_INT128_HAS_FORMAT`: This is defined by `<boost/int128/format.hpp>` when pass:[C++20] `<format>` is available. When defined, that header provides `std::formatter` specializations for both types.

- `BOOST_INT128_HAS_FMT_FORMAT`: This is defined by `<boost/int128/fmt_format.hpp>` when the pass:[{fmt}] library is available. When defined, that header provides `fmt::formatter` specializations for both types.

[#host_device]
- `BOOST_INT128_HOST_DEVICE`: This is defined to `pass:[__host__ __device__]` when compiling with NVCC (`pass:[__NVCC__]` is defined), and to nothing otherwise.
All public functions, constructors, operators, and conversion operators in the library are annotated with this macro, allowing `int128_t` and `uint128_t` to be used in CUDA device code without modification.
The core type operations (constructors, conversion operators, and the comparison, bitwise, arithmetic, and shift operators) and most free functions are annotated with this macro, allowing `int128_t` and `uint128_t` to be used in CUDA device code. Host-only integrations that depend on host facilities are not annotated: `std::hash`, the iostream operators, the `std::formatter` / pass:[{fmt}] support, and the `core::string_view` overloads of `from_chars`.
48 changes: 48 additions & 0 deletions doc/modules/ROOT/pages/design.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
////
Copyright 2025 Matt Borland
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////

[#design]
= Design Decisions
:idprefix: design_

== Exactly 128 Bits on Every Platform

The central design goal is that `sizeof(uint128_t)` and `sizeof(int128_t)` are exactly 16 bytes on every supported platform.
The compiler's `pass:[__int128]` extension is only available on some 64-bit targets and is absent on MSVC, while multiprecision types typically carry an additional word of bookkeeping.
By fixing the layout at two 64-bit words, the library provides a drop-in 128-bit integer whose size and alignment match a built-in type where one exists.
See xref:comp_to_multiprecision.adoc[Comparison to Boost.Multiprecision] for the tradeoffs relative to a multiprecision `number`.

== Intrinsics with a Portable Fallback

Where the compiler provides a native 128-bit integer or a suitable intrinsic, the operators forward to it for native performance.
Elsewhere (including MSVC and 32-bit targets) the library uses optimized software implementations over the two 64-bit words.
This keeps behavior and results identical across platforms while still taking advantage of hardware support when it is present.

== pass:[C++14] and constexpr

The library targets pass:[C++14] as its minimum standard.
Relaxed pass:[C++14] `constexpr` allows nearly all functionality to be evaluated at compile time, so the types can be used in constant expressions much like a built-in integer.
Meeting the pass:[C++14] bar also satisfies the conceptual requirements of libraries such as Boost.Math and Boost.Random, which this library integrates with directly.

== Emulating a Built-in Integer

To behave like a built-in integer in generic code, the types provide implicit conversions to and from the built-in integer and floating-point types, and implicit conversion between `int128_t` and `uint128_t`.
The single exception is `operator bool`, which is `explicit` to match the standard library convention and to avoid unintended participation in arithmetic and overload resolution.

Mixed-sign and mixed-width operations follow the usual arithmetic conversions of the language.
In particular, an operation mixing a signed and an unsigned 128-bit operand produces a `uint128_t`, identical to the value the equivalent built-in `pass:[unsigned __int128]` operation would produce, with two's-complement wrap-around.
See xref:mixed_type_ops.adoc[Mixed Type Operations] for the complete result-type rules.

== Layout and Alignment

Each type is a struct of two 64-bit words, `low` and `high`, whose declaration order depends on the endianness of the target so that the in-memory representation matches a native 128-bit integer.
For `int128_t` the `high` word is signed.
When a native 128-bit type is available the struct is over-aligned to match it, except on 32-bit x86 where the native alignment is not forced.

== GPU Support

The types and many of the free functions are annotated with `BOOST_INT128_HOST_DEVICE` so they can be used unchanged in CUDA device code when the library is compiled with `BOOST_INT128_ENABLE_CUDA`.
See xref:config.adoc[Configuration Macros].
12 changes: 8 additions & 4 deletions doc/modules/ROOT/pages/examples.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ include::example$stream.cpp[]
=== Basic Streaming ===
Signed value: -42
Unsigned value (dec): 36893488147419103231
Unsigned value (hex): 0x1ffffffffffffffff
Unsigned value (oct): 03777777777777777777777
Upper unsigned value: 0X1FFFFFFFFFFFFFFFF
Unsigned value (hex): 1ffffffffffffffff
Unsigned value (oct): 3777777777777777777777
Upper unsigned value: 1FFFFFFFFFFFFFFFF
Lower unsigned value: 36893488147419103231

=== Large Values (Beyond 64-bit) ===
Expand Down Expand Up @@ -427,11 +427,15 @@ int128_t to_string(INT64_MAX): 9223372036854775807
std::to_string(INT64_MAX): 9223372036854775807
Match: true

int128_t min: -170141183460469231731687303715884105728
int128_t min with string literal: 0

int128_t min with INT128_C macro: -170141183460469231731687303715884105728
int128_t max: 170141183460469231731687303715884105727
----
====

NOTE: The line `int128_t min with string literal: 0` is expected. The positive magnitude of the minimum `int128_t` value (2^127) is larger than the maximum `int128_t` value, so it cannot be written as a negated `_i128` literal. Construct it with `BOOST_INT128_INT128_C` or `(std::numeric_limits<int128_t>::min)()`, as the example shows.

[#examples_fmt_format]
== \{fmt} Library Integration

Expand Down
6 changes: 3 additions & 3 deletions doc/modules/ROOT/pages/file_structure.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ The entire library can be consumed via `<boost/int128.hpp>`, or by independently
| xref:api_reference.adoc#api_macro_literals[`<boost/int128/climits.hpp>`]
| C-style limit macros (`BOOST_INT128_INT128_MAX`, etc.)

| xref:config.adoc[`<boost/int128/config.hpp>`]
| Configuration macros

| xref:cstdlib.adoc[`<boost/int128/cstdlib.hpp>`]
| Division with quotient and remainder (`div`)

Expand Down Expand Up @@ -62,4 +59,7 @@ The entire library can be consumed via `<boost/int128.hpp>`, or by independently

| xref:string.adoc[`<boost/int128/string.hpp>`]
| `to_string` overloads

| xref:utilities.adoc[`<boost/int128/utilities.hpp>`]
| Modular exponentiation, integer power, integer square root, and checked arithmetic
|===
10 changes: 5 additions & 5 deletions doc/modules/ROOT/pages/format.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ There are three allowable signs first in the format string:
| pass:[` `] (Space) | Adds a ` ` to positive values, and a `-` to negative values. Preserves alignment
|===

== Padding

You can then add any number of padding characters to make sure that a formatted value takes up a specified width (5 means minimum width of 5 characters and so on).
Any integer value is accepted here.

== Prepend Prefix

If you want to prepend the prefix to your number (if applicable) add `#`
Expand All @@ -69,6 +64,11 @@ If you want to prepend the prefix to your number (if applicable) add `#`
| Hex | `0x` or `0X`
|===

== Padding

You can then add any number of padding characters to make sure that a formatted value takes up a specified width (5 means minimum width of 5 characters and so on).
Any integer value is accepted here.

== Output Base Modifiers

The following type modifiers are the same as those used by built-in integer values.
Expand Down
92 changes: 92 additions & 0 deletions doc/modules/ROOT/pages/getting_started.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
////
Copyright 2025 Matt Borland
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////

[#getting_started]
= Getting Started
:idprefix: gs_

Boost.Int128 is header-only. The core types and functions have no required dependencies, so in most cases it is enough to add the library's `include` directory to your compiler's search path and include the umbrella header:

[source, c++]
----
#include <boost/int128.hpp>
----

The umbrella header pulls in the two types and every feature that has no external dependency. The optional integration headers (xref:charconv.adoc[`charconv.hpp`], `random.hpp`, and the pass:[{fmt}] support in xref:format.adoc[`fmt_format.hpp`]) are not included by the umbrella and must be included explicitly. See xref:file_structure.adoc[File Structure] for the full header list.

== B2

Run the following commands to clone the latest version of Boost, prepare the Boost.Build system, and build with pass:[C++14] as the default standard:

[source, bash]
----
git clone https://github.com/boostorg/boost
cd boost
git submodule update --init
./bootstrap
./b2 cxxstd=14
----

To install the headers system-wide, run:

[source, bash]
----
sudo ./b2 install cxxstd=14
----

The value of `cxxstd` must be at least 14. https://www.boost.org/doc/libs/release/tools/build/doc/html/index.html[See the b2 documentation] under `cxxstd` for all valid values.

== CMake

Boost.Int128 ships a CMake package and the `Boost::int128` target. When building against a Boost tree that contains this library, request it and link the interface target:

[source, cmake]
----
cmake .. -DBOOST_INCLUDE_LIBRARIES="int128"
----

[source, cmake]
----
target_link_libraries(my_target PRIVATE Boost::int128)
----

The library can also be consumed on its own with `FetchContent`:

[source, cmake]
----
include(FetchContent)
FetchContent_Declare(
int128
GIT_REPOSITORY https://github.com/boostorg/int128
GIT_TAG develop
)
FetchContent_MakeAvailable(int128)

target_link_libraries(my_target PRIVATE Boost::int128)
----

== pass:[C++20] Module

When compiling with pass:[C++20] or newer, the library can be consumed as a named module instead of via header inclusion:

[source, c++]
----
import boost.int128;
----

Building the module requires defining `BOOST_INT128_BUILD_MODULE` and compiling `module/int128.cxx` with your toolchain's module support. See xref:config.adoc[Configuration Macros] for details.

== CUDA Support

The library types and many of the functions can run on both host and device under CUDA. Compile with a CUDA-aware toolchain and define `BOOST_INT128_ENABLE_CUDA`. Functions carrying `BOOST_INT128_HOST_DEVICE` in their signature run on both host and device; all others run on host only. See xref:config.adoc[Configuration Macros].

== Dependencies

The core library (everything included by `<boost/int128.hpp>`) has no required dependencies and needs only a conforming pass:[C++14] compiler. The optional integration headers depend on the following, and are only usable when those components are available:

* xref:charconv.adoc[`<boost/int128/charconv.hpp>`] requires Boost.Charconv.
* `<boost/int128/random.hpp>` requires Boost.Random.
* xref:format.adoc[`<boost/int128/fmt_format.hpp>`] requires the https://github.com/fmtlib/fmt[pass:[{fmt}]] library.
Loading
Loading