A single-header C++ library for expressive and concise print debugging, replacing cout/printf with powerful formatting and lazy evaluation.
Icecream-cpp is a single-header C++ library that simplifies print debugging by replacing verbose `cout` or `printf` statements with concise macros. It automatically prints variable names and values, supports formatting, and can inspect data in range pipelines, making debugging faster and less error-prone. The library is designed for use during development and can be disabled for production builds.
C++ developers (C++11 and later) who frequently use print debugging and want a more expressive, less intrusive way to inspect variables, function flow, and range-based data transformations.
Developers choose Icecream-cpp because it drastically reduces boilerplate in debug code, provides rich formatting options, and integrates seamlessly with modern C++ features like ranges and third-party libraries. Its header-only nature and configurability make it easy to adopt and tailor to specific debugging needs.
🍦 Never use cout/printf to debug again
Open-Awesome is built by the community, for the community. Submit a project, suggest an awesome list, or help improve the catalog on GitHub.
IC() macros automatically print variable names and values, replacing verbose cout statements with minimal code, as shown in examples like IC(a, b, sum(a, b)).
IC_V() integrates lazily into C++20 or Range-v3 pipelines to print intermediate data without breaking the flow, supporting views like vws::split.
Format strings (e.g., IC_F('#x', i)) allow control over output for integers, floats, ranges, and tuples, including hex, decimal, and slicing.
Global and scoped IC_CONFIG objects enable customization of output destination, prefixes, string handling, and more, with thread-safe operations.
The IC macro can clash with other identifiers, requiring workarounds like defining ICECREAM_LONG_NAME, as admitted in the pitfalls section.
Handling wide and Unicode strings involves multiple transcoding layers (wide_string_transcoder, unicode_transcoder), which can be confusing and require custom implementations for edge cases.
For standards before C++20, separate nullary macros like IC0() are needed, adding boilerplate and complexity for cross-version compatibility.