Ch26.1: Modules and the Four Concept Categories

中文(简体)

1. The Module Is the API Contract

fast_io ships headers and C++20 module interfaces. The headers expose almost the whole implementation. The modules expose a curated subset: the names listed in share/fast_io/fast_io_inc/*.inc. That subset is the API surface an importer should treat as public.

This is the distinction the rest of this reference follows. A name is documented as a module API only when the module exports it. A useful header-only helper that is not in the export list is marked as such; it is not silently presented as part of the module contract.

The header interface remains valid. #include <fast_io.h> is still how the tutorial builds, and it is the escape hatch when a module is incomplete. But when both exist, the module export list is the smaller and more stable surface.

2. Module Inventory

Module Interface file What it adds Imports
fast_io fast_io.cppm Umbrella: core vocabulary, I/O operations, devices, buffers, containers, freestanding helpers, network and time types. none
fast_io.floating fast_io_floating.cppm Shortest round-trip floating-point conversion for binary16, bfloat16, binary32, binary64, binary80 and binary128. Build separately; requires #embed. core fast_io headers
fast_io.i18n fast_io_i18n.cppm Locale blobs, lc_locale, lc_ctx, imbue, locale-aware concat and lc_dump. The loader is compiled into the module. fast_io
fast_io_crypto fast_io_crypto.cppm CRC32/CRC32C, AES-128/192/256, Ed25519, X25519, NIST elliptic curves and signing/verification helpers. fast_io
fast_io.tls fast_io_tls.cppm TLS clients, TLS socket files, root stores, peer certificates, platform TLS backends and async TLS customization points. fast_io, fast_io_crypto
fast_io_legacy fast_io_legacy.cppm FILE* interoperation and std::basic_filebuf interoperation. Read-only for new code. fast_io
fast_io.json fast_io_json.cppm Streaming JSON handler interface and a DOM document over the same parser. fast_io containers and core types

The naming is not uniform: fast_io.floating, fast_io.i18n, fast_io.tls and fast_io.json use dotted names, while fast_io_crypto and fast_io_legacy use underscores. Treat the spelling in the table as part of the current interface, not as a style you should extrapolate from.

3. The Four Concept Categories

fast_io is easier to learn when its types are sorted by the concept they satisfy rather than by the header they live in. Four categories carry almost everything:

Category What it means Typical names
Device A thing that can provide input bytes, accept output bytes, seek, or participate in transmit. A device is the endpoint, not the formatter. native_file, ibuf_file, obuf_file, iobuf_file, native_pipe, iobuf_pipe, iobuf_socket_file, c_file, basic_iobuf
I/O type The vocabulary that connects values to operations: scatter arrays, aliases, reserve types, status values, observers and the customization points used by print and scan. basic_io_scatter_t, io_type_t, io_reserve_type_t, io_alias_t, io_scatter_status_t, stream observers and references
Manipulator A small value that changes how one argument is formatted. It carries a manip_tag; it does not mutate the stream and does not persist after the call. hex, fixed, left, boolalpha, code_cvt, os_c_str, lc_dump
Strlike A string-like output sink: contiguous character storage with strlike_begin/strlike_curr/strlike_end, reserve and append customization. This is what concat, locale formatting and print into memory use. fast_io::string, basic_string_view, basic_ostring_ref_fast_io, io_strlike_reference_wrapper

They compose in one direction: a device receives the result, a strlike can be the destination when the result is text in memory, an I/O type carries the intermediate representation, and a manipulator changes one argument on its way through.


::fast_io::println(device, ::fast_io::mnp::hex(value));
//                ^device  ^manipulator

What about transcoders?

transcoder is an older category. It described a stateful conversion pipeline between encodings. Most of what it was for is now expressed by the code_cvt manipulator and the code_cvt_os_c_str alias, which convert one value inside a print call without a separate object. Treat the transcoder family as legacy and under review: do not design a new API around it, and check whether code_cvt already does the job.

4. What the Umbrella Module Exports

The export list is the best table of contents for the library. The main groups are:

Group Exported examples
I/O functions print, println, perr, perrln, panic, panicln, scan, scan_some, debug_print, debug_perr (unless disabled)
Devices and buffers ibuf_file, obuf_file, iobuf_file, iobuf_pipe, iobuf_socket_file, lockable variants, basic_ibuf, basic_obuf, basic_iobuf
Containers string, vector, array, span, string_view, list, deque, queue, stack, B-tree and Swiss-table string containers
Core vocabulary basic_io_scatter_t, io_type_t, io_reserve_type_t, io_alias_t, print_reserve_define, scan_context_define, parse_by_scan
Operations read_some, read_all, write_some, write_all, pread_*, pwrite_*, scatter variants, print_freestanding
Freestanding and utilities allocation adapters, freestanding algorithms, bit operations, endian/byte swap, SIMD intrinsics, posix_timespec64, iso8601_timestamp
Herbceptions When __HERBCEPTIONS__ is defined, the module re-exports std::error, std::errc, std::parse_errc and the query manipulators.

5. The Exported Manipulator Surface

These are the manipulators the fast_io module exports today, grouped by what they do. All of them are in ::fast_io::mnp (the alias for ::fast_io::manipulators).

Group Names
Integer base base<N>, baseupper<N>, bin, oct, dec, hex, hexupper, hex0x, hex0xupper
Floating format decimal, general, fixed, scientific, hexfloat, and the comma-grouped forms comma_decimal, comma_general, comma_fixed, comma_scientific, comma_hexfloat
Boolean boolalpha (with an optional uppercase template argument)
Width and alignment width, left, middle, right, internal
Pointer and handle views pointervw, handlevw, methodvw, addrvw, dfvw, bitfieldvw
String and range views os_c_str, os_c_str_carr, os_c_str_null_terminated, os_c_str_null_terminated_carr, os_c_str_or_nullptr, os_c_str_with_known_size, rgvw, strvw
Encoding code_cvt, code_cvt_os_c_str
Binary leb128_get, leb128_put
Network ip_generic, ip_scan_generic
Source and errors cur_src_loc, name, message, name_message, posix_equivalent_name, posix_equivalent_message, posix_equivalent_name_message, herbceptions_query_information
Locale lc_dump (from fast_io.i18n)
Line skippers lf, crlf, cr, line_skipper_platform (from fast_io.tls)

The module also exports the types behind these values: scalar_flags, scalar_manip_t, scalar_placement, floating_format, percentage_flag, lc_time_flag, ip_flags, ip_manip_t, ip_scan_manip_t, member_function_pointer_holder_t and whole_get_t.

Not currently exported by the module: ordinal, percentage_conventional, percentage_sex_ratio and their comma/base variants, host, url, url_path, token, header_value, sql_string, funcvw, itervw, fieldptrvw, chvw, enum_int_view, small_scatter and mtvw. They exist in the headers; use the header interface if you need them today.

6. The Locale Module

fast_io.i18n is a separate module because locale data is bulky and optional. It exports fast_io and adds the locale layer on top:


import fast_io.i18n;

int main()
{
    using namespace ::fast_io::io;

    auto const *loc{::fast_io::l10n::load_l10n(u8"de_DE.UTF-8")};

    // Grouping and separators come from LC_NUMERIC.
    println(::fast_io::imbue(loc, ::fast_io::out()), 1234567);

    // The whole locale as text, for inspection.
    println(::fast_io::imbue(loc, ::fast_io::out()), ::fast_io::mnp::lc_dump(loc));
}

The locale categories available through basic_lc_all are identification, monetary, numeric, time, messages, paper, telephone, name, address, measurement and keyboard. The numeric layer carries the thousands separator and grouping; the time layer carries the POSIX format strings and alternate digits. A locale with no grouping takes the plain formatting path and never builds an lc_ctx.

The header interface is #include <fast_io_i18n.h>. The module compiles the loader into itself, so importing fast_io.i18n does not require a separate fast_io_i18n library.

7. Importing and Building

The module files live in {fast_io}/share/fast_io. Build fast_io first, then the module that imports it. The dependency order is:


fast_io
  ├── fast_io.i18n
  ├── fast_io_crypto
  │     └── fast_io.tls
  ├── fast_io_legacy
  ├── fast_io.json
  └── fast_io.floating   (separately compiled conversion support)

import fast_io;

int main()
{
    ::fast_io::io::println("Hello from the module");
    ::fast_io::vector<int> v{1, 2, 3};
    for (auto x : v)
    {
        ::fast_io::io::print(x, " ");
    }
}

Clang is the supported path for modules today; GCC module support is experimental and the herbceptions GCC build is known to ICE on some fast_io module units. MSVC is not supported because it has no herbceptions. The exact precompile and link commands are in Ch1.8.

Key Takeaways