# What Are the range_format Types in fmtlib? A Complete Guide to C++ Range Formatting

> Explore fmtlib's range_format types: disabled, map, set, sequence, string, and debug_string. Learn how to format C++ ranges, containers, and tuples effectively.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: deep-dive
- Published: 2026-09-10

---

**The fmtlib library defines six `range_format` enumerations—`disabled`, `map`, `set`, `sequence`, `string`, and `debug_string`—in [`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h) that control how C++ ranges, containers, and tuples are serialized during formatting operations.**

The fmtlib/fmt library provides comprehensive support for formatting C++ ranges through the `range_format` enum class. Understanding these `range_format` types in fmtlib is essential when you need to customize how containers like `std::vector`, `std::map`, or character arrays appear in output. Each enumerator instructs the library whether to treat a type as a bracketed sequence, a braced set, a key-value map, or a literal string.

## The range_format Enum Declaration

The core range formatting interface is declared in **[`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h)** at line 31. The `enum class range_format` provides six distinct formatting strategies that the library uses when encountering iterable types. These enumerations are not manually selected by end users in typical usage; instead, the library's internal trait system determines the appropriate format based on the container's interface.

## The Six range_format Types Explained

Each enumerator in `range_format` determines delimiter choice, element separation, and character escaping behavior.

### disabled

Range formatting is turned **off**. The container is treated as a single opaque object, causing the library to fall back to standard `operator<<` formatting or custom formatter specializations. Use this mode when you want fmtlib to ignore a container's iterable nature and rely on bespoke output logic.

### map

The range is treated as a **dictionary-like map** containing distinct `key_type` and `mapped_type` members. Elements format as `key: value` pairs wrapped in `{}` braces. This applies automatically to `std::map`, `std::unordered_map`, and user-defined types exposing both type aliases.

### set

The range is interpreted as a **set-like collection** exposing `key_type` but lacking `mapped_type`. Elements render as a comma-separated list enclosed in `{}` braces. `std::set` and `std::unordered_set` trigger this mode automatically.

### sequence

The generic **sequence** mode handles any container providing `begin()` and `end()` iterators that do not qualify as maps or sets. Elements appear in order within `[]` brackets. `std::vector`, `std::list`, `std::deque`, and C-style arrays default to this format.

### string

Character ranges format as **literal strings** without surrounding brackets or quotes. `std::string`, `std::vector<char>`, and similar character containers print their contents directly using this mode.

### debug_string

Similar to `string`, but each character undergoes **debug escaping** where non-printable characters convert to `\xNN` hexadecimal notation. This mode helps visualize hidden bytes in raw buffers or non-ASCII data.

## How fmtlib Selects the Format Type

The library determines which `range_format` enumerator applies by inspecting the type at compile-time through the **`range_format_kind_`** trait, starting at line 253 in [`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h). This trait checks for map-like interfaces (presence of `key_type` and `mapped_type`), then set-like interfaces (`key_type` only), before falling back to sequence, string, or debug-string rules based on the value type.

Once determined, the **`range_formatter`** class defined around line 391 in the same header uses this compile-time constant to emit the appropriate opening delimiter, element separator, and closing delimiter.

## Practical Code Examples

The following example demonstrates automatic selection of each `range_format` type:

```cpp
#include <fmt/ranges.h>
#include <map>
#include <set>
#include <vector>
#include <string>

int main() {
    std::vector<int> seq   = {1, 2, 3};
    std::set<int> s        = {4, 5, 6};
    std::map<int, char> m  = {{7, 'a'}, {8, 'b'}};
    std::string str        = "hello";

    fmt::print("Sequence : {}\n", seq);        // → [1, 2, 3]
    fmt::print("Set      : {}\n", s);          // → {4, 5, 6}
    fmt::print("Map      : {}\n", m);          // → {7: a, 8: b}
    fmt::print("String   : {}\n", str);        // → hello

    // Debug string (use fmt::debug_string for explicit request)
    fmt::print("Debug    : {}\n", fmt::debug_string(str));
}

```

Output:

```

Sequence : [1, 2, 3]
Set      : {4, 5, 6}
Map      : {7: a, 8: b}
String   : hello
Debug    : hello

```

To explicitly disable range formatting for a specific type, specialize the formatter or provide a custom `operator<<` implementation that the library will prefer, effectively selecting the `disabled` mode.

## Summary

- The `range_format` enum in [`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h) defines six formatting strategies for C++ ranges.
- **`map`** and **`set`** use `{}` delimiters; **`sequence`** uses `[]`; **`string`** and **`debug_string`** omit brackets.
- The **`range_format_kind_`** trait automatically selects the appropriate format at compile-time based on container interface detection.
- **`disabled`** forces fallback to `operator<<` or custom formatters.
- The **`range_formatter`** class implements the actual output logic using the selected enumeration.

## Frequently Asked Questions

### How do I disable range formatting for a specific type in fmtlib?

Provide a custom formatter specialization or an `operator<<` overload for your type. When the library detects a valid `operator<<` or custom formatter, it automatically selects the `range_format::disabled` enumerator, bypassing the generic range formatting logic in [`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h).

### What is the difference between string and debug_string in range_format?

`range_format::string` prints character ranges literally without escaping, making it ideal for human-readable text. `range_format::debug_string` escapes non-printable characters as `\xNN` hexadecimal sequences, which is essential for debugging raw byte buffers or inspecting hidden control characters.

### How does fmtlib determine which range_format to use automatically?

The library uses the `range_format_kind_` trait defined at line 253 of [`include/fmt/ranges.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/ranges.h) to inspect the type at compile-time. It checks for `key_type` and `mapped_type` to identify maps, `key_type` alone to identify sets, and value type characteristics to distinguish between generic sequences and strings.

### Can I force a container to use a specific range_format type?

While the library automatically selects the format via traits, you can influence the behavior by wrapping containers in view types or specializing formatting traits. For explicit debug output, use `fmt::debug_string()` to force the `debug_string` format regardless of the automatic selection.