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
76 changes: 65 additions & 11 deletions doc/modules/ROOT/pages/examples.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ All the following examples can be found in the examples/ folder of the library.
[#examples_construction]
== Basic Construction

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/construction.cpp[example] demonstrates the various ways to construct uint128_t and int128_t values
====
[source, c++]
----
include::example$construction.cpp[]
----
Expand Down Expand Up @@ -42,11 +44,14 @@ From BOOST_INT128_INT128_C(min): -170141183460469231731687303715884105728
Default constructed: 0
Copy constructed: 36893488147419103232
----
====

[#examples_arithmetic]
== Basic Arithmetic

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/basic_arithmetic.cpp[example] demonstrates arithmetic operations with 128-bit integers
====
[source, c++]
----
include::example$basic_arithmetic.cpp[]
----
Expand Down Expand Up @@ -98,11 +103,14 @@ counter++ = 11
counter = 12
--counter = 11
----
====

[#examples_io]
== IO Streaming

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/stream.cpp[example] demonstrates iostream support and string conversions
====
[source, c++]
----
include::example$stream.cpp[]
----
Expand Down Expand Up @@ -135,19 +143,25 @@ As string: "68915718020162848918556923512"
Round-tripped: 68915718020162848918556923512
Match: true
----
====

[#examples_bit]
== Bitwise Functions (<bit>)

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/bit.cpp[example] demonstrates bitwise operations from the <bit> header
====
[source, c++]
----
include::example$bit.cpp[]
----
====

[#examples_numeric]
== Saturating Arithmetic (<numeric>)

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/saturating_arithmetic.cpp[example] demonstrates saturating arithmetic operations that clamp to min/max instead of overflowing
====
[source, c++]
----
include::example$saturating_arithmetic.cpp[]
----
Expand Down Expand Up @@ -176,11 +190,14 @@ saturate_cast<int128_t>(uint_max) = 170141183460469231731687303715884105727 (sat
saturate_cast<int64_t>(int_max) = 9223372036854775807 (saturates to INT64_MAX)
saturate_cast<int32_t>(uint_max) = 2147483647 (saturates to INT32_MAX)
----
====

[#examples_mixed_sign]
== Mixed Signedness Arithmetic

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/mixed_type_arithmetic.cpp[example] demonstrates arithmetic between 128-bit and built-in integer types
====
[source, c++]
----
include::example$mixed_type_arithmetic.cpp[]
----
Expand All @@ -204,19 +221,25 @@ signed_value - 4U = -7
signed_value * 2 = -6
signed_value / 4U = 0
----
====

[#examples_boost_math_random]
== Boost.Math and Boost.Random Integration

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/math_and_random.cpp[example] demonstrates integration with Boost.Math and Boost.Random libraries
====
[source, c++]
----
include::example$math_and_random.cpp[]
----
====

[#examples_boost_charconv]
== Boost.Charconv Integration

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/charconv.cpp[example] demonstrates fast string-to-number and number-to-string conversions using Boost.Charconv
====
[source, c++]
----
include::example$charconv.cpp[]
----
Expand All @@ -240,11 +263,14 @@ Parsed "-170141183460469231731687303715884105728"
Parsed hex "DEADBEEFCAFEBABE12345678"
Result: 68915718020162848918556923512
----
====

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

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/fmt_format.cpp[example] demonstrates formatting with the \{fmt} library including alignment specifiers
====
[source, c++]
----
include::example$fmt_format.cpp[]
----
Expand Down Expand Up @@ -278,6 +304,27 @@ Space sign: 42 and -42
8-digit padding: 00000255
16-digit padding: 0000000000000255

=== Alignment ===
Left align: '42 '
Right align: ' 42'
Center align: ' 42 '

=== Alignment with Fill Characters ===
Left with *: '42********'
Right with 0: '0000000042'
Center with -: '----42----'

=== Alignment with Sign ===
Right align +: ' +42'
Left align +: '+42 '
Center align +: ' +42 '
Right align -: '*******-42'

=== Alignment with Hex and Prefix ===
Right align hex: ' ff'
Left align hex: 'ff '
Center with prefix: '****0xff****'

=== Large Values ===
uint128_t max: 340282366920938463463374607431768211455
uint128_t max (hex): 0xffffffffffffffffffffffffffffffff
Expand All @@ -287,11 +334,14 @@ int128_t min: -170141183460469231731687303715884105728
Hex with prefix, uppercase, padded: 0XDEADBEEFCAFEBABE12345678
Signed with plus, padded: -00123456789012345678
----
====

[#examples_cstdlib]
== Division with Remainder (<cstdlib>)

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/cstdlib.cpp[example] demonstrates the div() function that returns both quotient and remainder
====
[source, c++]
----
include::example$cstdlib.cpp[]
----
Expand Down Expand Up @@ -321,11 +371,14 @@ Verification: 142857142857142857 * 7 + 1 = 1000000000000000000
--- Edge Cases ---
3 / 10 = 0 remainder 3
----
====

[#examples_numeric_algorithms]
== Numeric Algorithms (<numeric>)

[source,c++]
.This https://github.com/cppalliance/int128/blob/develop/examples/numeric_algorithms.cpp[example] demonstrates gcd, lcm, and midpoint algorithms
====
[source, c++]
----
include::example$numeric_algorithms.cpp[]
----
Expand Down Expand Up @@ -360,3 +413,4 @@ midpoint(uint128_max, uint128_max - 10) = 34028236692093846346337460743176821145
midpoint(-100, 100) = 0
midpoint(-100, -50) = -75
----
====
80 changes: 66 additions & 14 deletions doc/modules/ROOT/pages/format.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,32 @@ https://www.boost.org/LICENSE_1_0.txt
Boost.int128 support formatting with both `<format>` (when pass:[C++20] and the header are both available), and `<fmt/format.h>`
The following modifiers are listed in order of how they should be specified in the format string to be valid, and all information applies for both `<format>` and `<fmt/format.h>`

== Fill and Alignment

You can specify alignment with an optional fill character. The format is `[[fill]align]` where:

|===
| Alignment | Effect
| `<` | Left-aligns the value within the available space
| `>` | Right-aligns the value within the available space
| `^` | Centers the value within the available space
|===

The optional fill character (default is space) appears before the alignment character.

Examples:
|===
| Format | Output for 42
| `{:<6d}` | `"42 "` (left-aligned with spaces)
| `{:>6d}` | `" 42"` (right-aligned with spaces)
| `{:^6d}` | `" 42 "` (centered with spaces)
| `{:*<6d}` | `"42****"` (left-aligned with asterisks)
| `{:0>6d}` | `"000042"` (right-aligned with zeros)
| `{:*^6d}` | `"**42**"` (centered with asterisks)
|===

NOTE: When no alignment is specified but a width is given (e.g., `{:6d}`), zero-padding is applied from the left.

== Sign

There are three allowable sings first in the format string:
Expand Down Expand Up @@ -70,26 +96,39 @@ Examples using all of the above modifiers in some permutation:

int main()
{
constexpr boost::decimal::deciaml32_t value {42};
constexpr boost::int128::int128_t value {42};

// Default format
std::cout << std::format("{}", value) << '\n'; // Outputs: 42

// Sign modifier
std::cout << std::format("{:+d}", value) << '\n'; // Outputs +42
std::cout << std::format("{:+d}", -value) << '\n'; // Outputs -42

// Alignment with fill characters
std::cout << std::format("{:<10d}", value) << '\n'; // Outputs "42 " (left-aligned)
std::cout << std::format("{:>10d}", value) << '\n'; // Outputs " 42" (right-aligned)
std::cout << std::format("{:^10d}", value) << '\n'; // Outputs " 42 " (centered)
std::cout << std::format("{:*<10d}", value) << '\n'; // Outputs "42********" (left, fill with *)
std::cout << std::format("{:0>10d}", value) << '\n'; // Outputs "0000000042" (right, fill with 0)
std::cout << std::format("{:*^10d}", value) << '\n'; // Outputs "****42****" (centered, fill with *)

// Alignment with sign
std::cout << std::format("{:>+10d}", value) << '\n'; // Outputs " +42"
std::cout << std::format("{:<+10d}", value) << '\n'; // Outputs "+42 "

// Output base modifier and Prefix
std::cout << std::format("{:x}", value) << '\n'; // Outputs 2a
std::cout << std::format("{:X}", value) << '\n'; // Outputs 2A
std::cout << std::format("{:#X}", value) << '\n'; // Outputs 0X2A

// Padding
// Notice there are a total of 5 charaters to the right of the prefix
std::cout << std::format("{:#5X}", value) << '\n'; // Outputs 0X0002A
// Alignment with hex and prefix
std::cout << std::format("{:>#10x}", value) << '\n'; // Outputs " 0x2a"
std::cout << std::format("{:<#10x}", value) << '\n'; // Outputs "0x2a "
std::cout << std::format("{:*^#10x}", value) << '\n'; // Outputs "***0x2a***"

// All together
// Notice theres a space before the first character - quoted for clarity
std::cout << std::format("{: #5X}", value) << '\n'; // Outputs " 0X0002A"
// Zero-padding (no alignment specified)
std::cout << std::format("{:#10X}", value) << '\n'; // Outputs 0X00000002A

return 0;
}
Expand All @@ -108,26 +147,39 @@ This is nearly the same as above but with `fmt::format` in place of `std::format

int main()
{
constexpr boost::decimal::deciaml32_t value {42};
constexpr boost::int128::int128_t value {42};

// Default format
std::cout << fmt::format("{}", value) << '\n'; // Outputs: 42

// Sign modifier
std::cout << fmt::format("{:+d}", value) << '\n'; // Outputs +42
std::cout << fmt::format("{:+d}", -value) << '\n'; // Outputs -42

// Alignment with fill characters
std::cout << fmt::format("{:<10d}", value) << '\n'; // Outputs "42 " (left-aligned)
std::cout << fmt::format("{:>10d}", value) << '\n'; // Outputs " 42" (right-aligned)
std::cout << fmt::format("{:^10d}", value) << '\n'; // Outputs " 42 " (centered)
std::cout << fmt::format("{:*<10d}", value) << '\n'; // Outputs "42********" (left, fill with *)
std::cout << fmt::format("{:0>10d}", value) << '\n'; // Outputs "0000000042" (right, fill with 0)
std::cout << fmt::format("{:*^10d}", value) << '\n'; // Outputs "****42****" (centered, fill with *)

// Alignment with sign
std::cout << fmt::format("{:>+10d}", value) << '\n'; // Outputs " +42"
std::cout << fmt::format("{:<+10d}", value) << '\n'; // Outputs "+42 "

// Output base modifier and Prefix
std::cout << fmt::format("{:x}", value) << '\n'; // Outputs 2a
std::cout << fmt::format("{:X}", value) << '\n'; // Outputs 2A
std::cout << fmt::format("{:#X}", value) << '\n'; // Outputs 0X2A

// Padding
// Notice there are a total of 5 charaters to the right of the prefix
std::cout << fmt::format("{:#5X}", value) << '\n'; // Outputs 0X0002A
// Alignment with hex and prefix
std::cout << fmt::format("{:>#10x}", value) << '\n'; // Outputs " 0x2a"
std::cout << fmt::format("{:<#10x}", value) << '\n'; // Outputs "0x2a "
std::cout << fmt::format("{:*^#10x}", value) << '\n'; // Outputs "***0x2a***"

// All together
// Notice theres a space before the first character - quoted for clarity
std::cout << fmt::format("{: #5X}", value) << '\n'; // Outputs " 0X0002A"
// Zero-padding (no alignment specified)
std::cout << fmt::format("{:#10X}", value) << '\n'; // Outputs 0X00000002A

return 0;
}
Expand Down
31 changes: 30 additions & 1 deletion examples/fmt_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,39 @@ int main()

std::cout << "\n=== Zero Padding ===" << std::endl;

// Padding with zeros
// Padding with zeros (no alignment specifier)
std::cout << fmt::format("8-digit padding: {:08}", value) << std::endl;
std::cout << fmt::format("16-digit padding: {:016}", value) << std::endl;

std::cout << "\n=== Alignment ===" << std::endl;

// Left, right, and center alignment with default fill (space)
std::cout << fmt::format("Left align: '{:<10}'", positive) << std::endl;
std::cout << fmt::format("Right align: '{:>10}'", positive) << std::endl;
std::cout << fmt::format("Center align: '{:^10}'", positive) << std::endl;

std::cout << "\n=== Alignment with Fill Characters ===" << std::endl;

// Custom fill characters
std::cout << fmt::format("Left with *: '{:*<10}'", positive) << std::endl;
std::cout << fmt::format("Right with 0: '{:0>10}'", positive) << std::endl;
std::cout << fmt::format("Center with -: '{:-^10}'", positive) << std::endl;

std::cout << "\n=== Alignment with Sign ===" << std::endl;

// Alignment combined with sign specifiers
std::cout << fmt::format("Right align +: '{:>+10}'", positive) << std::endl;
std::cout << fmt::format("Left align +: '{:<+10}'", positive) << std::endl;
std::cout << fmt::format("Center align +: '{:^+11}'", positive) << std::endl;
std::cout << fmt::format("Right align -: '{:*>10}'", negative) << std::endl;

std::cout << "\n=== Alignment with Hex and Prefix ===" << std::endl;

// Alignment with base specifiers and prefixes
std::cout << fmt::format("Right align hex: '{:>10x}'", value) << std::endl;
std::cout << fmt::format("Left align hex: '{:<10x}'", value) << std::endl;
std::cout << fmt::format("Center with prefix: '{:*^#12x}'", value) << std::endl;

std::cout << "\n=== Large Values ===" << std::endl;

// Demonstrate with values beyond 64-bit range
Expand Down
Loading
Loading