Implement the standard formatting library and extensions
- Dominant language
- C++
- Stars
- 2.5k
- Forks
- 486
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 295
Description
In #4939, I've already started porting libc++'s implementation of `std::format` to libcu++. This issue is intended to track the progress and discuss the changes.
The current design consists of several papers introduced in C++20 onwards. Here is the list of the features and whether they are implemented in libc++ or not:
Feature-test macro
libc++
Std
Feature
__cpp_lib_format
✔
(C++20)
Text formatting
✔
(C++23)
(DR20)
Compile-time format string checks;
Reducing parameterization of std::vformat_to
❌
✔
(C++23)
(DR20)
Fixing locale handling in chrono formatters;
Supporting non-const-formattable types
✔
❌
(C++23)
(DR20)
Exposing std::basic_format_string;
Clarify handling of encodings in localized formatting of chrono types
✔
(C++26)
Formatting pointers
❌
(C++26)
Type-checking format args
✔
(C++26)
Member std::basic_format_arg::visit
✔
(C++26)
Runtime format string
✔
(C++26)
Printing Blank Lines with std::println
❌
(C++26)
(DR23)
Permit an efficient implementation of std::print This section is incomplete
Reason: the value should be >= 202406L, i.e. be different from the previous one
__cpp_lib_format_ranges
✔
(C++23)
Formatting ranges
__cpp_lib_format_path
❌
(C++26)
Formatting of std::filesystem::path
__cpp_lib_format_uchar
✔
(C++26)
Fix formatting of code units as integers
__cpp_lib_formatters
✔
(C++23)
Formatting std::thread::id and std::stacktrace
From what I've seen, we should be able to adopt all of the standard features except for the `std::format` function - it returns a `std::string` object which is not currently implemented in libcu++. I would also omit the support for locale for now.
### Prerequisites
I've already implemented `cuda::std::to_chars` for integers, but the implementation uses `cuda::std::to_chars` for floats, too. We can add support for floating point types formatting later.
### Extensions
I've been thinking how could we improve the user experience using the formatting functions in device code. I think it would be nice to provide:
1. Formatters for *vector types*, so the user could do:
```cpp
auto result = cuda::std::format_to(buff, "[thread {}, block {}]: {}", threadIdx, blockIdx, msg);
```
2. Block/warp collective formatting funtions. If a user wants to format a string to a single buffer by multiple threads, the simple `cuda::std::format_to` functions is not enough. That's why I would like to have something like `cuda::device::block_format_to` and `cuda::device::warp_format_to` (and `_n` variants) that would do all find out the size of the result string, do a prefix sum to find out the position a thread would be writting to and do the formatting. The buffer address (and size) must be the same for all threads. Example:
```cpp
__global__ void kernel(char* output, cuda::std::size_t size, cuda::std::size_t* block_offset)
{
__shared__ char buffer[1024];
auto result = cuda::block_format_to_n(buffer, size, "Hello from thread {} in block {}\n", threadIdx.x, blockIdx.x);
cuda::std::size_t offset;
if (threadIdx.x == 0)
{
offset = cuda::std::atomic_ref(block_offset).fetch_add(result.size);
}
// copy buffer -> output + offset
}
```
### Progress
#4939 - `format_parse_context`, `format_error`
#5217 - `format_arg`, `format_args`, `visit_format_arg`, `make_format_args`, `format_context`, `formatter`
#5368 - `formatter` specializations for standard types
#5569 - `format_string`
Contributor guide
Assessment
This issue has not been assessed yet.