{"id":13431074,"url":"https://github.com/philip82148/cpp-dump","last_synced_at":"2026-01-12T00:38:57.486Z","repository":{"id":188025649,"uuid":"677935568","full_name":"philip82148/cpp-dump","owner":"philip82148","description":"A C++ library for debugging purposes that can print any variable, even user-defined types.","archived":false,"fork":false,"pushed_at":"2025-04-10T06:33:52.000Z","size":5482,"stargazers_count":338,"open_issues_count":3,"forks_count":10,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-10T07:26:58.558Z","etag":null,"topics":["competitive-programming","cpp","debugging"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/philip82148.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-13T06:11:44.000Z","updated_at":"2025-04-10T06:33:54.000Z","dependencies_parsed_at":"2023-09-23T18:49:22.432Z","dependency_job_id":"886be1af-644f-4f85-974f-23deaecb27f4","html_url":"https://github.com/philip82148/cpp-dump","commit_stats":null,"previous_names":["philip82148/cpp-dump"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/philip82148/cpp-dump","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philip82148%2Fcpp-dump","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philip82148%2Fcpp-dump/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philip82148%2Fcpp-dump/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philip82148%2Fcpp-dump/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/philip82148","download_url":"https://codeload.github.com/philip82148/cpp-dump/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philip82148%2Fcpp-dump/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28329806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"ssl_error","status_checked_at":"2026-01-12T00:36:15.229Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["competitive-programming","cpp","debugging"],"created_at":"2024-07-31T02:01:00.293Z","updated_at":"2026-01-12T00:38:57.471Z","avatar_url":"https://github.com/philip82148.png","language":"C++","readme":"# cpp-dump \u003c!-- omit in toc --\u003e\n\n![cpp-dump.gif](./readme/cpp-dump.gif)  \n_This is an animated GIF._\n\n**cpp-dump is a C++ library for printing variables of any type for debugging.**\n\nPython has `print()`, JavaScript has `console.log()`, and PHP has `var_dump()` — functions that print variables of any type and are useful for debugging when you want a quick way to inspect variables. But what about C++? Enter `cpp_dump(...)`. cpp-dump is a library that automatically formats and prints variables of any type. With features like auto-indentation, colored output, string representations similar to JavaScript, Python, and C++, and over 20 manipulators, cpp-dump is equipped with everything you need to effortlessly and clearly print variables.\n\nKey points:\n\n- cpp-dump can print a wide variety of types, including multi-D vectors, (multi)maps, (multi)sets, and tuples.\n- cpp-dump has an auto-indentation feature. The output fits into the maximum line width, and nested containers are formatted for readability.\n- The string representation of variables is similar to JavaScript, Python, and C++ syntax. The output is readable without being overloaded with information. (You can add more details using manipulators if you want.)\n- Customizable colored output is available. You can achieve syntax highlighting similar to that of IDEs.\n- With over 20 manipulators, you can easily change the format or add information to the output.\n- By using macros, cpp-dump supports user-defined types as well. There is no need to write new functions for printing.\n- cpp-dump is a header-only library. No build or dependencies are required!\n\n[日本語記事はこちら！](https://zenn.dev/sassan/articles/19db660e4da0a4)\n\n## Table of Contents \u003c!-- omit in toc --\u003e\n\n- [Introduction](#introduction)\n- [Features](#features)\n  - [A wide variety of supported types](#a-wide-variety-of-supported-types)\n  - [Auto indent](#auto-indent)\n  - [Filename and line can be printed instead of `[dump]`](#filename-and-line-can-be-printed-instead-of-dump)\n  - [Customizable output color](#customizable-output-color)\n  - [Can print even user-defined types](#can-print-even-user-defined-types)\n- [Advanced Feature](#advanced-feature)\n  - [20+ Manipulators to change the display style](#20-manipulators-to-change-the-display-style)\n- [Requirement](#requirement)\n- [Installation](#installation)\n  - [Simplest solution](#simplest-solution)\n  - [With CMake](#with-cmake)\n    - [Run `cmake --install` to copy the headers to `/usr/local/include/` or equivalent](#run-cmake---install-to-copy-the-headers-to-usrlocalinclude-or-equivalent)\n    - [Use `FetchContent`](#use-fetchcontent)\n- [Configuration (as needed)](#configuration-as-needed)\n  - [Configuration options](#configuration-options)\n    - [`max_line_width`](#max_line_width)\n    - [`max_depth`](#max_depth)\n    - [`max_iteration_count`](#max_iteration_count)\n    - [`cont_indent_style`](#cont_indent_style)\n    - [`enable_asterisk`](#enable_asterisk)\n    - [`print_expr`](#print_expr)\n    - [`log_label_func`](#log_label_func)\n    - [`es_style`](#es_style)\n    - [`es_value`](#es_value)\n    - [`detailed_class_es`](#detailed_class_es)\n    - [`detailed_member_es`](#detailed_member_es)\n    - [`detailed_number_es`](#detailed_number_es)\n- [Detailed usage](#detailed-usage)\n  - [Macros](#macros)\n  - [Types](#types)\n  - [Variables](#variables)\n  - [Functions](#functions)\n  - [How to print a user-defined type with cpp-dump](#how-to-print-a-user-defined-type-with-cpp-dump)\n    - [Method 1. Use `CPP_DUMP_DEFINE_EXPORT_OBJECT()` macro](#method-1-use-cpp_dump_define_export_object-macro)\n    - [Method 2. Use `CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC()` macro](#method-2-use-cpp_dump_define_export_object_generic-macro)\n    - [Method 3. Define `std::ostream\u0026 operator\u003c\u003c(std::ostream\u0026, const T \u0026)` operator](#method-3-define-stdostream-operatorstdostream-const-t--operator)\n  - [Customize `[dump]`](#customize-dump)\n  - [Formatting with manipulators](#formatting-with-manipulators)\n    - [How to use manipulators](#how-to-use-manipulators)\n    - [`front()`, `middle()`, `back()`, `both_ends()` manipulators](#front-middle-back-both_ends-manipulators)\n    - [`index()` manipulator](#index-manipulator)\n    - [`int_style()` and its alias manipulators](#int_style-and-its-alias-manipulators)\n    - [`format()` manipulator](#format-manipulator)\n    - [`bw()`, `boolnum()` manipulators](#bw-boolnum-manipulators)\n    - [`stresc()` manipulator](#stresc-manipulator)\n    - [`charhex()` manipulator](#charhex-manipulator)\n    - [`addr()` manipulator](#addr-manipulator)\n    - [`map_*()` manipulators](#map_-manipulators)\n  - [Change the output destination from the standard error output](#change-the-output-destination-from-the-standard-error-output)\n  - [How to pass complex expressions to `cpp_dump(...)`](#how-to-pass-complex-expressions-to-cpp_dump)\n    - [Expressions with commas](#expressions-with-commas)\n    - [Variadic template arguments](#variadic-template-arguments)\n  - [For competitive programming use](#for-competitive-programming-use)\n- [Supported types](#supported-types)\n  - [Display example](#display-example)\n\n## Introduction\n\nYou can print variables of a wide variety of types by passing them to the `cpp_dump(expressions...)` macro.  \n[See Full Example Code](./readme/introduction.cpp)\n\n```cpp\nstd::vector\u003cstd::vector\u003cint\u003e\u003e my_vector{{3, 5, 8, 9, 7}, {9, 3, 2, 3, 8}};\ncpp_dump(my_vector);\n```\n\n![introduction.png](./readme/introduction.png)\n\n## Features\n\n### A wide variety of supported types\n\ncpp-dump supports a wide variety of types, including multi-D vectors, (multi)maps, (multi)sets, and tuples.  \nTheir string representation is similar to JavaScript, Python, and C++ syntax, which is easy to read.  \n[See All Supported Types](#supported-types)  \n[See Full Example Code](./readme/supports-various-types.cpp)\n\n```cpp\nbool my_bool = true; double my_double = 3.141592; int my_int = 65;\nchar my_char = 'a', LF_char = '\\n'; std::string my_string = \"This is a string.\";\nint *int_ptr = \u0026my_int; void *void_ptr = \u0026my_int;\nstd::vector\u003cstd::vector\u003cint\u003e\u003e my_vector{{3, 5, 8, 9, 7}, {9, 3, 2, 3, 8}};\nstd::set\u003cchar\u003e my_set{'A', 'p', 'p', 'l', 'e'};\nstd::map\u003cint, int\u003e my_map{{2, 6}, {4, 6}, {5, 3}};\nstd::multiset\u003cchar\u003e my_multiset{'A', 'p', 'p', 'l', 'e'};\nstd::multimap\u003cint, int\u003e my_multimap{{2, 4}, {4, 6}, {5, 3}, {4, 7}};\nstd::pair\u003cint, char\u003e my_pair{8, 'a'};\nstd::tuple\u003cint, double, std::string\u003e my_tuple{7, 4.5, \"This is a string.\"};\nstd::queue\u003cint\u003e my_queue;\nstd::priority_queue\u003cint\u003e my_priority_queue;\nstd::stack\u003cint\u003e my_stack;\nfor (auto v : {1, 2, 3, 4, 5}) my_queue.push(v), my_priority_queue.push(v), my_stack.push(v);\nstd::bitset\u003c8\u003e my_bitset(0x3a);\nstd::complex\u003cdouble\u003e my_complex{1.0, -1.0};\nstd::optional\u003cint\u003e my_optional{15};\nstd::variant\u003cint, std::string\u003e my_variant{\"This is a string.\"};\nstd::vector\u003cstd::pair\u003cint, std::string\u003e\u003e vector_of_pairs{{1, \"apple\"}, {3, \"banana\"}};\n\nstd::clog \u003c\u003c \"\\n// Basic Type\" \u003c\u003c std::endl;\ncpp_dump(my_bool, my_double, my_int); cpp_dump(my_string, my_char, LF_char);\ncpp_dump(int_ptr, void_ptr, nullptr);\n\nstd::clog \u003c\u003c \"\\n// Container\" \u003c\u003c std::endl;\ncpp_dump(my_vector);\n\nstd::clog \u003c\u003c \"\\n// Set/Map\" \u003c\u003c std::endl;\ncpp_dump(my_set); cpp_dump(my_map);\n\nstd::clog \u003c\u003c \"\\n// Multiset/Multimap\" \u003c\u003c std::endl;\ncpp_dump(my_multiset); cpp_dump(my_multimap);\n\nstd::clog \u003c\u003c \"\\n// Tuple\" \u003c\u003c std::endl;\ncpp_dump(my_tuple); cpp_dump(my_pair);\n\nstd::clog \u003c\u003c \"\\n// FIFO/LIFO\" \u003c\u003c std::endl;\ncpp_dump(my_queue); cpp_dump(my_priority_queue); cpp_dump(my_stack);\n\nstd::clog \u003c\u003c \"\\n// Other\" \u003c\u003c std::endl;\ncpp_dump(my_bitset); cpp_dump(my_complex);\ncpp_dump(my_optional, std::nullopt); cpp_dump(my_variant);\n\nstd::clog \u003c\u003c \"\\n// Combination\" \u003c\u003c std::endl;\ncpp_dump(vector_of_pairs);\n```\n\n![supports-various-types.png](./readme/supports-various-types.png)\n\n### Auto indent\n\ncpp-dump automatically indents so that the output does not exceed the maximum width.  \nAdditionally, nested containers are indented by default (This behavior can be changed through [the settings](#cont_indent_style)).  \n[See Full Example Code](./readme/auto-indent.cpp)\n\n```cpp\ncpp_dump(my_vector);\nmy_vector.push_back(\"This is a test string.\");\ncpp_dump(my_vector);\n```\n\n![Auto indent](./readme/auto-indent.png)\n\n### Filename and line can be printed instead of `[dump]`\n\nIf you want to print the filename and line instead of `[dump]`, use the following code. The `cpp_dump()` macro will automatically detect and print the filename and the line. You can attach the function name, too. See [Customize `[dump]`](#customize-dump) for details.  \n[See Full Example Code](./readme/customize-dump.cpp)\n\n```cpp\n// Print the filename and line instead of [dump]\nCPP_DUMP_SET_OPTION(log_label_func, cp::log_label::filename());\n// Print along with the function name\nCPP_DUMP_SET_OPTION(log_label_func, cp::log_label::filename(true));\n```\n\n![customize-dump.png](./readme/customize-dump.png)\n\n### Customizable output color\n\nYou can modify the escape sequences to change the colors of the output using the following code.  \n[See Full Example Code](./readme/customizable-colors.cpp)\n\n```cpp\n// Use more colors\nCPP_DUMP_SET_OPTION(es_value.log, \"\\x1b[02m\");                 // log: dark\nCPP_DUMP_SET_OPTION(es_value.expression, \"\\x1b[34m\");          // expression: blue\nCPP_DUMP_SET_OPTION(es_value.reserved, \"\\x1b[38;5;39m\");       // reserved: light blue\nCPP_DUMP_SET_OPTION(es_value.number, \"\\x1b[38;5;150m\");        // number: light green\nCPP_DUMP_SET_OPTION(es_value.character, \"\\x1b[38;5;172m\");     // character: orange\nCPP_DUMP_SET_OPTION(es_value.escaped_char, \"\\x1b[38;5;220m\");  // escaped_char: light orange\nCPP_DUMP_SET_OPTION(es_value.op, \"\\x1b[02m\");                  // op: dark\nCPP_DUMP_SET_OPTION(es_value.identifier, \"\\x1b[32m\");          // identifier:  green\nCPP_DUMP_SET_OPTION(es_value.member, \"\\x1b[96m\");              // member: light cyan\nCPP_DUMP_SET_OPTION(es_value.unsupported, \"\\x1b[31m\");         // unsupported: red\nCPP_DUMP_SET_OPTION(es_value.bracket_by_depth, (std::vector\u003cstd::string\u003e{\n    \"\\x1b[33m\",  // bracket_by_depth[0]: yellow\n    \"\\x1b[35m\",  // bracket_by_depth[1]: magenta\n    \"\\x1b[36m\",  // bracket_by_depth[2]: cyan\n}));\nCPP_DUMP_SET_OPTION(es_value.class_op, \"\\x1b[02m\");   // class_op: dark\nCPP_DUMP_SET_OPTION(es_value.member_op, \"\\x1b[02m\");  // member_op: dark\nCPP_DUMP_SET_OPTION(es_value.number_op, \"\");          // number_op: default\n\n// Use the 'class_op'/'member_op'/'number_op' color for operators\n// in class names, members, and numbers (::, \u003c\u003e, (), -, +, etc...).\nCPP_DUMP_SET_OPTION(detailed_class_es, true);\nCPP_DUMP_SET_OPTION(detailed_member_es, true);\nCPP_DUMP_SET_OPTION(detailed_number_es, true);\n\n// Use a color scheme closer to standard syntax highlighting.\n// CPP_DUMP_SET_OPTION(es_style, cp::types::es_style_t::by_syntax);\n```\n\n![customizable-colors.png](./readme/customizable-colors.png)\n\nFor [the light theme](https://gist.github.com/philip82148/9684321c37ba6ae18fb101b586a7bd00), the output will be like this.\n\n![customizable-colors-light-plus](./readme/customizable-colors-light-plus.png)\n\nTo turn off output coloring, use the following code.  \n[See Full Example Code](./readme/no-es.cpp)\n\n```cpp\n// Turn off output coloring\nCPP_DUMP_SET_OPTION(es_style, cp::types::es_style_t::no_es);\n```\n\n### Can print even user-defined types\n\nIf you want to print a user-defined type, you can enable the library to print it by using macros or defining an operator. The following is an example of the use of macros. See [How to print a user-defined type with cpp-dump](#how-to-print-a-user-defined-type-with-cpp-dump) for details.  \n[See Full Example Code](./readme/user-defined-class-generic.cpp)\n\n```cpp\nCPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(i, str());\n```\n\n![user-defined-class-generic.png](./readme/user-defined-class-generic.png)\n\n## Advanced Feature\n\n### 20+ Manipulators to change the display style\n\nThis library has over 20 manipulators to change the display style.  \nSee [Formatting with manipulators](#formatting-with-manipulators) for details.\n\n**[Manipulator to omit part of a container](#front-middle-back-both_ends-manipulators)**\n\n![manipulator-front-etc.png](./readme/manipulator-front-etc.png)\n\n**[Manipulator to show indexes of an array](#index-manipulator)**\n\n![manipulator-index.png](./readme/manipulator-index.png)\n\n**[Manipulator to change the numerical base](#int_style-and-its-alias-manipulators)**\n\n![manipulator-int-style2.png](./readme/manipulator-int-style2.png)\n\n**[Manipulator to escape strings](#stresc-manipulator)**\n\n![manipulator-stresc.png](./readme/manipulator-stresc.png)\n\n## Requirement\n\n- C++17 or higher.\n- No build or dependencies are required since cpp-dump is a header-only library.\n\n## Installation\n\n### Simplest solution\n\n```shell\ngit clone https://github.com/philip82148/cpp-dump\n```\n\nThen\n\n```cpp\n#include \"path/to/cpp-dump/cpp-dump.hpp\"\n```\n\n[Copy this code to test the library](./readme/test-code.cpp)\n\n### With CMake\n\n#### Run `cmake --install` to copy the headers to `/usr/local/include/` or equivalent\n\n```shell\ngit clone https://github.com/philip82148/cpp-dump\ncd cpp-dump\ncmake -S . -B build # No configuration is needed because the library is header-only.\nsudo cmake --install build\n# (The 'cpp-dump' folder can be removed after this.)\n```\n\nThen\n\n```cpp\n#include \u003ccpp-dump.hpp\u003e\n```\n\n#### Use `FetchContent`\n\n`CMakeLists.txt`\n\n```cmake\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Generate compile_commands.json (optional)\n\ninclude(FetchContent)\n\n# Fetch cpp-dump\nFetchContent_Declare(cpp-dump\n    GIT_REPOSITORY https://github.com/philip82148/cpp-dump\n    GIT_TAG main\n)\nFetchContent_MakeAvailable(cpp-dump)\n```\n\nThen\n\n```cpp\n#include \u003ccpp-dump.hpp\u003e\n```\n\n## Configuration (as needed)\n\nIf you want to customize the library, you can write the configuration code as follows:\n\n`custom-cpp-dump.hpp`\n\n```cpp\n#ifdef DEBUGGING\n#include \"path/to/cpp-dump/cpp-dump.hpp\"\nnamespace cp = cpp_dump;\n// You can use this in both a header file and a source file,\n// but make sure not to use it more than once for the same option.\nCPP_DUMP_SET_OPTION_GLOBAL(max_line_width, 100);\n\n// To ensure proper instantiation of templates,\n// include these in at least one translation unit where cpp_dump(...) prints each type.\n// One way is to write them in a header file and then include it wherever needed.\nCPP_DUMP_DEFINE_EXPORT_OBJECT(my_class, member1, member2());\nCPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(member3, member4());\nCPP_DUMP_DEFINE_EXPORT_ENUM(my_enum, my_enum::a, my_enum::b, my_enum::c);\nCPP_DUMP_DEFINE_EXPORT_ENUM_GENERIC(member_a, member_b, member_c);\n#else\n#define cpp_dump(...)\n#define CPP_DUMP_SET_OPTION(...)\n#endif\n```\n\n`main.cpp`\n\n```cpp\n#include \"path/to/custom-cpp-dump.hpp\"\n\nint main() {\n  cpp_dump(vec | cp::back());\n}\n```\n\nIf you want to configure the library within a function, use `CPP_DUMP_SET_OPTION()` instead.\n\n`main.cpp`\n\n```cpp\n#include \"path/to/custom-cpp-dump.hpp\"\n\nvoid func() {\n  CPP_DUMP_SET_OPTION(print_expr, false);\n  cpp_dump(vec | cp::back());\n  CPP_DUMP_SET_OPTION(print_expr, true);\n}\n```\n\n### Configuration options\n\nSee also [Variables](#variables).\n\n#### `max_line_width`\n\nType: `std::size_t` Default: `160`  \nThe maximum line width of the strings returned by `cpp_dump()` and `cpp_dump::export_var()`, which `cpp_dump()` internally uses to convert a variable into a string.\n\n#### `max_depth`\n\nType: `std::size_t` Default: `4`  \nThe maximum number of times `cpp_dump::export_var()` is called recursively.\n\n#### `max_iteration_count`\n\nType: `std::size_t` Default: `16`  \nThe maximum number of iterations of `cpp_dump::export_var()` over an iterator.  \nNote that in a single call, `cpp_dump::export_var()` calls itself at most `(max_iteration_count^(max_depth+1)-1)/(max_iteration_count-1)` times.\n\n#### `cont_indent_style`\n\nType: `enum class cpp_dump::types::cont_indent_style_t` Default: `cpp_dump::types::cont_indent_style_t::when_nested`  \nThe style of indents of the Container, Set and Map categories (See [Supported types](#supported-types)).\n\n| Name                     | Description                                                                                                                               |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| `minimal`                | Don't indent unless the `max_line_width` is exceeded.                                                                                     |\n| `when_nested`            | Default. Always indent when the element/key/value type also falls into the Container/Set/Map/Tuple category.                              |\n| `when_non_tuples_nested` | Always indent when the element/key/value type falls into the Container/Set/Map category, but don't when it falls into the Tuple category. |\n| `always`                 | Always indent even if the Container/Set/Map is not nested.                                                                                |\n\n#### `enable_asterisk`\n\nType: `bool` Default: `false`  \nWhether `cpp_dump::export_var()` prints types of the Asterisk category (See [Supported types](#supported-types)).\n\n#### `print_expr`\n\nType: `bool` Default: `true`  \nWhether `cpp_dump()` prints the expressions.\n\n#### `log_label_func`\n\nType: `cpp_dump::types::log_label_func_t` Default: `cpp_dump::log_label::default_func`  \nThe function that returns the label that `cpp_dump()` prints at the beginning of the output.\n\n#### `es_style`\n\nType: `enum class cpp_dump::types::es_style_t` Default `cpp_dump::types::es_style_t::original`  \nThe style of the escape sequences (the output coloring).\n\n| Name        | Description                                                                                                                                |\n| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ |\n| `original`  | Default.                                                                                                                                   |\n| `by_syntax` | Use a color scheme closer to standard syntax highlighting. Pointers, bitsets, complexes, and etc. are colored differently from `original`. |\n| `no_es`     | Turn off output coloring.                                                                                                                  |\n\n#### `es_value`\n\nType: `cpp_dump::types::es_value_t` Default: (Default constructor, see [Types](#types))  \nThe values of the escape sequences.\n\n#### `detailed_class_es`\n\nType: `bool` Default: `false`  \nIf true, the `es_value.class_op` color is used for operators in class names (`::`, `\u003c\u003e`, etc...).\n\n#### `detailed_member_es`\n\nType: `bool` Default: `false`  \nIf true, the `es_value.member_op` color is used for operators in members (`()`, etc...).\n\n#### `detailed_number_es`\n\nType: `bool` Default: `false`  \nIf true, the `es_value.number_op` color is used for operators in numbers (`-`, `+`, etc...).\n\n## Detailed usage\n\n### Macros\n\n```cpp\n/**\n * Print string representations of expressions and results to std::clog or other configurable outputs.\n * If you want to change the output, define an explicit specialization of cpp_dump::write_log().\n * This macro uses cpp_dump::export_var() internally.\n */\n#define cpp_dump(expressions...)\n\n/**\n * Make cpp_dump::export_var() support type T.\n * Member functions to be displayed must be const.\n */\n#define CPP_DUMP_DEFINE_EXPORT_OBJECT(T, members...)\n\n/**\n * Make cpp_dump::export_var() support every type that has the specified members.\n * Member functions to be displayed must be const.\n * Compile errors in this macro, such as ambiguous function calls, are never reported due to SFINAE.\n */\n#define CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(members...)\n\n/**\n * Make cpp_dump::export_var() support enum T.\n */\n#define CPP_DUMP_DEFINE_EXPORT_ENUM(T, members...)\n\n/**\n * Make cpp_dump::export_var() support every enum type that has the specified members.\n * Compile errors in this macro, such as ambiguous function calls, are never reported due to SFINAE.\n */\n#define CPP_DUMP_DEFINE_EXPORT_ENUM_GENERIC(members...)\n\n/**\n * Set a value to a variable in cpp_dump::options namespace.\n */\n#define CPP_DUMP_SET_OPTION(variable, value)\n\n/**\n * Set a value to a variable in cpp_dump::options namespace.\n * Use this if you want to run it in the global namespace, meaning before the main starts.\n */\n#define CPP_DUMP_SET_OPTION_GLOBAL(variable, value)\n```\n\n### Types\n\n```cpp\nnamespace cpp_dump::types {\n\n/**\n * Type of cpp_dump::options::cont_indent_style.\n * cpp_dump::export_var() supports this type.\n */\nenum class cont_indent_style_t { minimal, when_nested, when_non_tuples_nested, always };\n\n/**\n * Type of cpp_dump::options::es_style.\n * cpp_dump::export_var() supports this type.\n */\nenum class es_style_t { no_es, original, by_syntax };\n\n/**\n * Type of cpp_dump::options::es_value.\n * cpp_dump::export_var() supports this type.\n */\nstruct es_value_t {\n  std::string log = \"\\x1b[02m\";                           // dark\n  std::string expression = \"\\x1b[36m\";                    // cyan\n  std::string reserved{};                                 // default\n  std::string number{};                                   // default\n  std::string character{};                                // default\n  std::string escaped_char = \"\\x1b[02m\";                  // dark\n  std::string op = \"\\x1b[02m\";                            // dark\n  std::string identifier = \"\\x1b[32m\";                    // green\n  std::string member = \"\\x1b[36m\";                        // cyan\n  std::string unsupported = \"\\x1b[31m\";                   // red\n  std::vector\u003cstd::string\u003e bracket_by_depth{\"\\x1b[02m\"};  // dark\n  std::string class_op = \"\\x1b[02m\";                      // dark\n  std::string member_op = \"\\x1b[02m\";                     // dark\n  std::string number_op{};                                // default\n};\n\nusing log_label_func_t = std::function\u003cstd::string(std::string_view, std::size_t, std::string_view)\u003e;\n\n}  // namespace cpp_dump::types\n```\n\n### Variables\n\n```cpp\nnamespace cpp_dump::options {\n\n/**\n * Maximum line width of the strings returned by cpp_dump() and cpp_dump::export_var().\n */\ninline std::size_t max_line_width = 160;\n\n/**\n * Maximum number of times cpp_dump::export_var() is called recursively.\n */\ninline std::size_t max_depth = 4;\n\n/**\n * Maximum number of iterations of cpp_dump::export_var() over an iterator.\n * Note that in a single call, cpp_dump::export_var() calls itself at most\n * (max_iteration_count^(max_depth+1)-1)/(max_iteration_count-1) times.\n */\ninline std::size_t max_iteration_count = 16;\n\n/**\n * Style of indents of the Container, Set and Map categories (See 'Supported types')\n */\ninline types::cont_indent_style_t cont_indent_style = types::cont_indent_style_t::when_nested;\n\n/**\n * Whether cpp_dump() prints types of the Asterisk category (See 'Supported types').\n */\ninline bool enable_asterisk = false;\n\n/**\n * Whether cpp_dump() prints the expressions.\n */\ninline bool print_expr = true;\n\n/**\n * Function that returns the label that cpp_dump() prints at the beginning of the output.\n */\ninline types::log_label_func_t log_label_func = log_label::default_func;\n\n/**\n * Style of the escape sequences (output coloring).\n */\ninline types::es_style_t es_style = types::es_style_t::original;\n\n/**\n * Values of the escape sequences (output coloring).\n */\ninline types::es_value_t es_value;\n\n/**\n * If true, the 'es_value.class_op' color is used for operators in class names (::, \u003c\u003e, etc...).\n */\ninline bool detailed_class_es = false;\n\n/**\n * If true, the 'es_value.member_op' color is used for operators in members ((), etc...).\n */\ninline bool detailed_member_es = false;\n\n/**\n * If true, the 'es_value.number_op' color is used for operators in numbers (-, +, etc...).\n */\ninline bool detailed_number_es = false;\n\n\n}  // namespace cpp_dump::options\n```\n\n### Functions\n\n```cpp\nnamespace cpp_dump {\n\n/**\n * Return a string representation of a variable.\n * cpp_dump() uses this function internally.\n */\ntemplate \u003ctypename T\u003e\nstd::string export_var(const T \u0026value);\n\n/**\n * cpp_dump() uses this function to print logs.\n * Define an explicit specialization with 'void' to customize this function.\n */\ntemplate \u003ctypename = void\u003e\nvoid write_log(std::string_view output) {\n  std::clog \u003c\u003c output \u003c\u003c std::endl;\n}\n\n// Manipulators (See 'Formatting with manipulators' for details.)\nfront(std::size_t iteration_count = options::max_iteration_count);\nmiddle(std::size_t iteration_count = options::max_iteration_count);\nback(std::size_t iteration_count = options::max_iteration_count);\nboth_ends(std::size_t half_iteration_count = options::max_iteration_count / 2);\nindex();\nint_style(int base, int digits = -1, int chunk = 0,\n    bool space_fill = false, bool make_unsigned_or_no_space_for_minus = false);\nbin(int digits = -1, int chunk = 0, bool space_fill = false);\noct(int digits = -1, int chunk = 0, bool space_fill = false);\nhex(int digits = -1, int chunk = 0, bool space_fill = false);\ndec(int digits = -1, int chunk = 0, bool space_fill = true);\nubin(int digits = -1, int chunk = 0, bool space_fill = false);\nuoct(int digits = -1, int chunk = 0, bool space_fill = false);\nuhex(int digits = -1, int chunk = 0, bool space_fill = false);\nudec(int digits = -1, int chunk = 0, bool space_fill = true);\nmap_k(return_value_of_manipulator);\nmap_v(return_value_of_manipulator);\nmap_kv(return_value_of_manipulator_for_key, return_value_of_manipulator_for_value);\nformat(const char *f);\nbw(bool left = false);\nboolnum();\nstresc();\ncharhex();\naddr(std::size_t depth = 0);\n\n}  // namespace cpp_dump\n\n// See 'Customize \"[dump]\"'.\nnamespace cpp_dump::log_label {\n\nstd::string default_func(std::string_view, std::size_t, std::string_view);\ntypes::log_label_func_t line(bool show_func = false, int min_width = 0);\ntypes::log_label_func_t basename(bool show_func = false, int min_width = 0);\ntypes::log_label_func_t filename(bool show_func = false, int min_width = 0);\ntypes::log_label_func_t fullpath(int substr_start, bool show_func = false, int min_width = 0);\ntypes::log_label_func_t fixed_length(int min_width, int max_width,\n    int substr_start, bool show_func = false);\n\n}  // namespace cpp_dump::log_label\n```\n\n### How to print a user-defined type with cpp-dump\n\nThere are three ways to enable the library to print a user type.\n\n#### Method 1. Use `CPP_DUMP_DEFINE_EXPORT_OBJECT()` macro\n\nThis macro requires the user type to be accessible from the global scope, but it is the safest and easiest way to enable `cpp_dump()` to print a user type.  \n[See Full Example Code](./readme/user-defined-class.cpp)\n\n```cpp\n// Somewhere accessible from the global scope (not private or defined in a function)\nstruct class_A {\n  int i;\n  std::string str() const { return std::to_string(i); }\n};\n\n// In the global scope\n// CPP_DUMP_DEFINE_EXPORT_OBJECT(type_name, members...)\nCPP_DUMP_DEFINE_EXPORT_OBJECT(class_A, i, str());\n\n// In a function\nclass_A my_class_A{10};\ncpp_dump(my_class_A);\n```\n\n![user-defined-class.png](./readme/user-defined-class.png)\n\nFor enums, use `CPP_DUMP_DEFINE_EXPORT_ENUM()` macro.  \n[See Full Example Code](./readme/user-defined-enum.cpp)\n\n```cpp\n// Somewhere accessible from the global scope (not private or defined in a function)\nenum class enum_A { member_a, member_b, member_c };\n\n// In the global scope\n// CPP_DUMP_DEFINE_EXPORT_ENUM(enum_name, members...)\nCPP_DUMP_DEFINE_EXPORT_ENUM(enum_A, enum_A::member_a, enum_A::member_b, enum_A::member_c);\n\n// In a function\nenum_A my_enum_A = enum_A::member_c;\ncpp_dump(my_enum_A);\n```\n\n![user-defined-enum.png](./readme/user-defined-enum.png)\n\n#### Method 2. Use `CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC()` macro\n\nThis macro enables `cpp_dump()` to print any type with specified members.  \nThis macro doesn't require the user type to be accessible from the global scope (or need even the type name).\n\nIf you use this macro two or more times, you need to be careful of ambiguous function call compile errors.  \nIf such an error occurs, it won't be reported due to SFINAE, and the user-defined type will remain unsupported.  \n[See Full Example Code](./readme/user-defined-class-generic.cpp)\n\n```cpp\n// In the global scope\n// CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(members...)\nCPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(i, str());\n\n// Anywhere\nstruct class_A {\n  int i;\n  std::string str() const { return std::to_string(i); }\n};\n\n// In a function\nclass_A my_class_A{10};\ncpp_dump(my_class_A);\n```\n\n![user-defined-class-generic.png](./readme/user-defined-class-generic.png)\n\nFor enums, use `CPP_DUMP_DEFINE_EXPORT_ENUM_GENERIC()` macro.  \n[See Full Example Code](./readme/user-defined-enum-generic.cpp)\n\n```cpp\n// In the global scope\n// CPP_DUMP_DEFINE_EXPORT_ENUM_GENERIC(members...)\nCPP_DUMP_DEFINE_EXPORT_ENUM(member_a, member_b, member_c);\n\n// Anywhere\nenum class enum_A { member_a, member_b, member_c };\n\n// In a function\nenum_A my_enum_A = enum_A::member_c;\ncpp_dump(my_enum_A);\n```\n\n![user-defined-enum-generic.png](./readme/user-defined-enum-generic.png)\n\n#### Method 3. Define `std::ostream\u0026 operator\u003c\u003c(std::ostream\u0026, const T \u0026)` operator\n\nThe last way is to define the operator `std::ostream\u0026 operator\u003c\u003c(std::ostream\u0026, const T \u0026)`.  \n[See Full Example Code](./readme/user-defined-class-ostream.cpp)\n\n```cpp\n// Somewhere accessible from the global scope (not private or defined in a function)\nstruct class_A {\n  int i;\n  std::string str() const { return std::to_string(i); }\n};\n\n// In the global scope\nstd::ostream \u0026operator\u003c\u003c(std::ostream \u0026os, const class_A \u0026a) {\n  os \u003c\u003c \"class_A{ i= \" \u003c\u003c a.i \u003c\u003c \", str()= \\\"\" \u003c\u003c a.str() \u003c\u003c \"\\\" }\";\n  return os;\n}\n\n// In a function\nclass_A my_class_A{10};\ncpp_dump(my_class_A);\n```\n\n![user-defined-class-ostream.png](./readme/user-defined-class-ostream.png)\n\n### Customize `[dump]`\n\nAssigning a function to `cpp_dump::options::log_label_func`, you can customize `[dump]`.  \ncpp-dump has some functions that create a function to assign to `cpp_dump::options::log_label_func`, so you don't have to make your own function.\n\n```cpp\nnamespace cpp_dump::types {\n\nusing log_label_func_t =\n  std::function\u003cstd::string(std::string_view fullpath, std::size_t line, std::string_view func_name)\u003e;\n\n}  // namespace cpp_dump::types\n\nnamespace cpp_dump::log_label {\n\n// Default function assigned to cpp_dump::options::log_label_func.\nstd::string default_func(std::string_view, std::size_t, std::string_view) {\n  return \"[dump] \";\n}\n\n// Functions that create a function that can be assigned to cpp_dump::options::log_label_func.\ntypes::log_label_func_t line(bool show_func = false, int min_width = 0);\ntypes::log_label_func_t basename(bool show_func = false, int min_width = 0);\ntypes::log_label_func_t filename(bool show_func = false, int min_width = 0);\ntypes::log_label_func_t fullpath(int substr_start, bool show_func = false, int min_width = 0);\ntypes::log_label_func_t fixed_length(int min_width, int max_width,\n    int substr_start, bool show_func = false);\n\n}  // namespace cpp_dump::log_label\n\nnamespace cpp_dump::options {\n\ninline types::log_label_func_t log_label_func = log_label::default_func;\n\n}  // namespace cpp_dump::options\n```\n\n### Formatting with manipulators\n\nUsing manipulators, you can easily change the format or add information to the output.  \nFor example, you can select which elements and how many elements of an array, map, or set will be displayed using [the front, middle, back, and both_ends manipulators](#front-middle-back-both_ends-manipulators).  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\n// Show the last 10 elements for the 1st dimension, the first 5 and the last 5 for the 2nd dimension.\ncpp_dump(some_huge_vector | cp::back(10) | cp::both_ends(5) | cp::dec(2));\n```\n\n![manipulator-front-etc.png](./readme/manipulator-front-etc.png)\n\nAnd you can display the indexes of an array by using [the index manipulator](#index-manipulator).  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\nCPP_DUMP_SET_OPTION(max_iteration_count, 5);\n\n// Show the indexes of the vector.\ncpp_dump(some_huge_vector | cp::dec(2) | cp::index());\n```\n\n![manipulator-index.png](./readme/manipulator-index.png)\n\nThere are also many other manipulators, such as [the int_style manipulators](#int_style-and-its-alias-manipulators).  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\n// Show integers in binary, minimum 16 digits, separated by every 4 characters.\ncpp_dump(0x3e8u | cp::bin(16, 4));\n// Show integers in octal, minimum 6 digits, separated by every 3 characters.\ncpp_dump(0x3e8u | cp::oct(6, 3));\n// Show integers in hexadecimal, minimum 4 digits, separated by every 2 characters.\ncpp_dump(0x3e8u | cp::hex(4, 2));\n// Show integers in minimum 4 digits.\ncpp_dump(0x3e8u | cp::dec(4));\n```\n\n![manipulator-int-style.png](./readme/manipulator-int-style.png)\n\n#### How to use manipulators\n\nYou can use the manipulators by applying the '|' operator or the '\u003c\u003c' operator.  \nThe order of manipulators matters for some, but not for others.\n\n```cpp\ncpp_dump(variable | manipulatorA() | manipulatorB());\ncpp_dump(manipulatorA() \u003c\u003c manipulatorB() \u003c\u003c variable);\n```\n\n#### `front()`, `middle()`, `back()`, `both_ends()` manipulators\n\n```cpp\nnamespace cpp_dump {\n\nfront(std::size_t iteration_count = options::max_iteration_count);\nmiddle(std::size_t iteration_count = options::max_iteration_count);\nback(std::size_t iteration_count = options::max_iteration_count);\nboth_ends(std::size_t half_iteration_count = options::max_iteration_count / 2);\n\n}  // namespace cpp_dump\n```\n\nThese manipulators are **order-sensitive**.\n\nThe further left manipulator will act on the more outside dimensions of the array/map/set.  \n**Caution:**  \n**These manipulators other than `front()` calculate the container's size. Containers whose size cannot be calculated with `std::size()` will cost O(N) in computation. In particular, passing an infinite sequence to these manipulators will result in an infinite loop.**  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\n// Show the last 10 elements for the 1st dimension, the first 5 and the last 5 for the 2nd dimension.\ncpp_dump(some_huge_vector | cp::back(10) | cp::both_ends(5) | cp::dec(2));\n```\n\n![manipulator-front-etc.png](./readme/manipulator-front-etc.png)\n\n#### `index()` manipulator\n\n```cpp\ncpp_dump::index();\n```\n\nUnlike the `front()` and other manipulators, the `index()` manipulator acts on all sequence containers in the variable. (The order is irrelevant.)  \nIt does not affect maps/sets.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\ncpp_dump(some_huge_vector | cp::dec(2) | cp::index());\n```\n\n![manipulator-index.png](./readme/manipulator-index.png)\n\n#### `int_style()` and its alias manipulators\n\n```cpp\nnamespace cpp_dump {\n\nint_style(int base, int digits = -1, int chunk = 0,\n    bool space_fill = false, bool make_unsigned_or_no_space_for_minus = false);\n\nbin(int digits = -1, int chunk = 0, bool space_fill = false) {\n  return int_style(2, digits, chunk, space_fill, false);\n}\noct(int digits = -1, int chunk = 0, bool space_fill = false) {\n  return int_style(8, digits, chunk, space_fill, false);\n}\nhex(int digits = -1, int chunk = 0, bool space_fill = false) {\n  return int_style(16, digits, chunk, space_fill, false);\n}\ndec(int digits = -1, int chunk = 0, bool space_fill = true) {\n  return int_style(10, digits, chunk, space_fill, false);\n}\n\nubin(int digits = -1, int chunk = 0, bool space_fill = false) {\n  return int_style(2, digits, chunk, space_fill, true);\n}\nuoct(int digits = -1, int chunk = 0, bool space_fill = false) {\n  return int_style(8, digits, chunk, space_fill, true);\n}\nuhex(int digits = -1, int chunk = 0, bool space_fill = false) {\n  return int_style(16, digits, chunk, space_fill, true);\n}\nudec(int digits = -1, int chunk = 0, bool space_fill = true) {\n  return int_style(10, digits, chunk, space_fill, true);\n}\n\n}  // namespace cpp_dump\n```\n\nThe parameter `base` of `int_style()` supports values of 2, 8, 10, 16. For other values, this manipulator does nothing.  \n`digits` supports values of `digits` \u003e= 0 and `digits` \u003c= 'the maximum digits', where 'the maximum digits' is the maximum number of digits that can be represented by the integer type for the given `base`. For other values, it is treated as `digits` = 'the maximum digits'.  \n`chunk` supports values of `chunk` \u003e= 0. For other values, it is treated as `chunk` = 0.\n\nLike the `index()` manipulators, the `int_style()` manipulator acts on all integers in the variable. (The order is irrelevant.)  \nThe `bin(...)`, `oct(...)`, `hex(...)`, `ubin(...)`, `uoct(...)`, `uhex(...)`, `dec(...)`, `udec(...)`, are aliases of `int_style(...)`.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\n// Show integers in binary, minimum 16 digits, separated by every 4 characters.\ncpp_dump(0x3e8u | cp::bin(16, 4));\n// Show integers in octal, minimum 6 digits, separated by every 3 characters.\ncpp_dump(0x3e8u | cp::oct(6, 3));\n// Show integers in hexadecimal, minimum 4 digits, separated by every 2 characters.\ncpp_dump(0x3e8u | cp::hex(4, 2));\n// Show integers in minimum 4 digits.\ncpp_dump(0x3e8u | cp::dec(4));\n```\n\n![manipulator-int-style.png](./readme/manipulator-int-style.png)\n\nFor signed integer types, the `bin()`, `oct()`, `hex()`, and `dec()` manipulators will add an extra space for positive values and a minus sign for negative values.  \nFor unsigned integer types, these manipulators will not add any extra space or minus sign.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\ncpp_dump(signed_int_vector | cp::front(2) | cp::hex(2));\ncpp_dump(unsigned_int_vector | cp::front(2) | cp::hex(2));\ncpp_dump(signed_int_vector | cp::front(2) | cp::dec(2));\ncpp_dump(unsigned_int_vector | cp::front(2) | cp::dec(2));\n```\n\n![manipulator-bin-etc.png](./readme/manipulator-bin-etc.png)\n\nThe `ubin()`, `uoct()`, and `uhex()` manipulators interpret all integer types as unsigned.  \nIf the original type is not unsigned, the suffix `u` is shown.  \nHowever, the `udec()` manipulator acts differently from these.  \nThe `udec()` manipulator interprets signed types as signed type, but it does not add an extra space for positive values.  \nThis is suitable for showing a container of a signed integers when all values are positive.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\ncpp_dump(signed_int_vector | cp::front(2) | cp::uhex());\ncpp_dump(unsigned_int_vector | cp::front(2) | cp::uhex(2));\ncpp_dump(signed_int_vector | cp::front(2) | cp::udec(2));\ncpp_dump(unsigned_int_vector | cp::front(2) | cp::udec(2));\n```\n\n![manipulator-ubin-etc.png](./readme/manipulator-ubin-etc.png)\n\n#### `format()` manipulator\n\n```cpp\ncpp_dump::format(const char *f);\n```\n\nThis manipulator uses `snprintf()` to format numbers (integers and floating points).  \nMake sure that the types specified by format specifiers match the actual types.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\ncpp_dump(pi | cp::format(\"%.10f\"));\n```\n\n![manipulator-format.png](./readme/manipulator-format.png)\n\n#### `bw()`, `boolnum()` manipulators\n\n```cpp\ncpp_dump::bw(bool left = false);\ncpp_dump::boolnum();\n```\n\nThese manipulators are for formatting bool.  \nThe `bw()` manipulator adds a space when a bool value is `true` to match the width of `false`.  \nbw stands for \"bool width\".  \nThe `boolnum()` manipulator shows bool values as `1` or `0`.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\ncpp_dump(bool_vector | cp::bw());\ncpp_dump(bool_vector | cp::bw(true));\ncpp_dump(bool_vector | cp::boolnum());\n```\n\n![manipulator-bw-boolnum.png](./readme/manipulator-bw-boolnum.png)\n\n#### `stresc()` manipulator\n\n```cpp\ncpp_dump::stresc();\n```\n\nThis manipulator escapes strings.  \nFor escaped characters, the `es_value.escaped_char` color is used.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\ncpp_dump(\"\\a\\t\\\\\\\"\\n\\x7f need to be escaped.\");\ncpp_dump(\"\\a\\t\\\\\\\"\\n\\x7f need to be escaped.\" | cp::stresc());\n```\n\n![manipulator-stresc.png](./readme/manipulator-stresc.png)\n\n#### `charhex()` manipulator\n\n```cpp\ncpp_dump::charhex();\n```\n\nThis manipulator shows chars with their hex.  \nThe width of their string representation is fixed.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\nfor (auto c : \"\\a\\t\\\\\\\"\\n\\x7f ABC\") cpp_dump(c | cp::charhex());\n```\n\n![manipulator-charhex.png](./readme/manipulator-charhex.png)\n\n#### `addr()` manipulator\n\n```cpp\ncpp_dump::addr(std::size_t depth = 0);\n```\n\nThis manipulator shows pointers by their address.  \nUse the `depth` parameter to specify the depth of pointers for displaying addresses.  \n[See Full Example Code](./readme/formatting-with-manipulators.cpp)\n\n```cpp\nint my_int = 15;\nint *int_ptr = \u0026my_int;\nint **int_ptr_ptr = \u0026int_ptr;\n\ncpp_dump(int_ptr_ptr);\ncpp_dump(int_ptr_ptr | cp::addr());\ncpp_dump(int_ptr_ptr | cp::addr(1));\n```\n\n![manipulator-addr.png](./readme/manipulator-addr.png)\n\n#### `map_*()` manipulators\n\n```cpp\nnamespace cpp_dump {\n\nmap_k(return_value_of_manipulator);\nmap_v(return_value_of_manipulator);\nmap_kv(return_value_of_manipulator_for_key, return_value_of_manipulator_for_value);\n\n}  // namespace cpp_dump\n```\n\nThese manipulators are **order-sensitive**.\n\nThese manipulators act on (multi)maps.  \nIn the following example, the keys are displayed in hexadecimal, and if the values are iterable, the front part of the values is omitted.\n\n```cpp\ncpp_dump(cp::front() \u003c\u003c cp::map_kv(cp::hex(), cp::back()) \u003c\u003c map);\ncpp_dump(map | cp::front() | cp::map_kv(cp::hex(), cp::back()));\n```\n\n### Change the output destination from the standard error output\n\nTo change the output destination, define an explicit specialization of `cpp_dump::write_log()` with `void`.\n\n```cpp\n// You can write this in a header file.\n// If you write it in a source file, you can remove the inline keyword.\ntemplate \u003c\u003e\ninline void cpp_dump::write_log(std::string_view output) {\n  elsewhere \u003c\u003c output \u003c\u003c std::endl;\n}\n```\n\n### How to pass complex expressions to `cpp_dump(...)`\n\n#### Expressions with commas\n\nEnclose expressions that contain commas in parentheses.\n\n```cpp\ncpp_dump(std::is_same_v\u003cT, U\u003e); // Compile error!\ncpp_dump((std::is_same_v\u003cT, U\u003e)); // Correct\n```\n\n#### Variadic template arguments\n\nWhen passing variadic template arguments, do not pass any additional arguments.\n\n```cpp\ntemplate \u003ctypename... Args\u003e\nvoid variadic_template_func(Args \u0026\u0026...args) {\n  int i = 0;\n  cpp_dump(args..., i); // Compile error!\n  cpp_dump(args...), cpp_dump(i); // Correct\n}\n```\n\n### For competitive programming use\n\n```cpp\n#ifdef DEFINED_ONLY_IN_LOCAL\n#include \"./cpp-dump/cpp-dump.hpp\"\n#define dump(...) cpp_dump(__VA_ARGS__)\nnamespace cp = cpp_dump;\nCPP_DUMP_SET_OPTION_GLOBAL(max_line_width, 80);\nCPP_DUMP_SET_OPTION_GLOBAL(log_label_func, cp::log_label::filename());\nCPP_DUMP_SET_OPTION_GLOBAL(enable_asterisk, true);\n#else\n#define dump(...)\n#define CPP_DUMP_SET_OPTION(...)\n#define CPP_DUMP_DEFINE_EXPORT_OBJECT(...)\n#define CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(...)\n#define CPP_DUMP_DEFINE_EXPORT_ENUM(...)\n#define CPP_DUMP_DEFINE_EXPORT_ENUM_GENERIC(...)\n#endif\n\n#include \u003cbits/stdc++.h\u003e\n\n#define rep(i, n) for (int i = 0; i \u003c (int)(n); ++i)\n\nusing namespace std;\n\nint main() {\n  int N;\n  cin \u003e\u003e N;\n\n  vector\u003cint\u003e X(N);\n  rep(i, N) { cin \u003e\u003e X[i]; }\n  dump(X);\n\n  // To be continued...\n}\n```\n\nThen\n\n```shell\ng++ ./main.cpp -D DEFINED_ONLY_IN_LOCAL\n```\n\nor\n\n```shell\nclang++ ./main.cpp -D DEFINED_ONLY_IN_LOCAL\n```\n\n## Supported types\n\n`cpp_dump()` and `cpp_dump::export_var()` print variables recursively, so they can dump nested variables of any combination of types in the table below.\n\n| Category      | Type T is supported if ...                                                                                                                                                                                                                                                                            | Example                                            |\n| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |\n| Arithmetic    | `std::is_arithmetic_v\u003cT\u003e == true`                                                                                                                                                                                                                                                                     | `bool`, `char`, `int`, `long`, `float`, `double`   |\n| String        | T is convertible to `std::string_view`                                                                                                                                                                                                                                                                | `std::string`, `const char *`, `std::string_view`  |\n| Container     | T is compatible with the range-based for loop                                                                                                                                                                                                                                                         | `std::vector`, `std::forward_list`, C-style arrays |\n| Map           | T is either `std::map`, `std::unordered_map`, `std::multimap`, or `std::unordered_multimap`                                                                                                                                                                                                           |                                                    |\n| Set           | T is either `std::set`, `std::unordered_set`, `std::multiset`, or `std::unordered_multiset`                                                                                                                                                                                                           |                                                    |\n| Tuple         | T is compatible with `std::tuple_size_v\u003cT\u003e`                                                                                                                                                                                                                                                           | `std::tuple`, `std::pair`, User-defined tuples     |\n| FIFO/LIFO     | T is either `std::queue`, `std::priority_queue`, or `std::stack`                                                                                                                                                                                                                                      |                                                    |\n| Pointer       | T is a pointer or smart pointer                                                                                                                                                                                                                                                                       | `int *`, `std::shared_ptr`, `std::unique_ptr`      |\n| Reference     | T is `std::reference_wrapper`                                                                                                                                                                                                                                                                         |                                                    |\n| Exception     | T is convertible to `std::exception`                                                                                                                                                                                                                                                                  |                                                    |\n| Other         | T is either `std::bitset`, `std::complex`, `std::optional`, `std::variant`, `std::type_info`, `std::type_index` or `std::source_location`(C++20 or higher and g++ and MSVC only)                                                                                                                      |                                                    |\n| User-defined  | `CPP_DUMP_DEFINE_EXPORT_OBJECT(T, members...);` is in the global scope and the member functions to be displayed is const.                                                                                                                                                                             |                                                    |\n| Enum          | `CPP_DUMP_DEFINE_EXPORT_ENUM(T, members...);` is in the global scope.                                                                                                                                                                                                                                 |                                                    |\n| User-defined2 | All of the above are not satisfied, T has all members specified by just one `CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(members...);` at top level, and the member functions to be displayed is const.                                                                                                     |                                                    |\n| Enum2         | All of the above are not satisfied, and T has all members specified by just one `CPP_DUMP_DEFINE_EXPORT_ENUM_GENERIC(members...);` at top level.                                                                                                                                                      |                                                    |\n| Ostream       | All of the above are not satisfied, `std::is_function_v\u003cT\u003e == false \u0026\u0026 std::is_member_pointer_v\u003cT\u003e == false`, and the function `std::ostream\u0026 operator\u003c\u003c(std::ostream\u0026, const T \u0026)` is defined. **The string representation of T must not be an empty string** (This makes manipulators unsupported). |                                                    |\n| Asterisk      | All of the above are not satisfied, `cpp_dump::options::enable_asterisk == true` and the function `TypeExceptT operator*(const T \u0026)` or the const member function `TypeExceptT T::operator*() const` is defined.                                                                                      | Iterators                                          |\n\n### Display example\n\nSee also the image in the section [A wide variety of supported types](#a-wide-variety-of-supported-types).\n\n```console\n# Arithmetic\ntrue, 'c', 1, 3.140000\n\n# String\n\"A normal string\"\n`A string with '\"' or newline(s)`\n\n# Container\n[ value1, value2, ... ]\n\n# Map\n{ key1: value1, key2: value2, ... },\n{ key1 (multiplicity1): [ value1a, value1b, ... ], key2 (multiplicity2): [ ... ], ... }\n\n# Set\n{ value1, value2, ... },\n{ value1 (multiplicity1), value2 (multiplicity2), ... }\n\n# Tuple\n( value1, value2, ... )\n\n# FIFO/LIFO\nstd::queue{ size()= integer, front()= value, back()= value }\n\n# Pointer\n*value\nnullptr\n0x7fff2246c4d8\n# (The address will be displayed when the pointer type is void *\n#  or the type the pointer points to is not supported.)\n\n# Reference\ntrue, 'c', 1, 3.140000\n# (No change)\n\n# Exception\nstd::logic_error{ what()= \"Error Message\" }\n\n# Asterisk\n*value\n```\n\nFor other categories, see the image(s) in the section...\n\nOther -\u003e [A wide variety of supported types](#a-wide-variety-of-supported-types)  \nUser-defined, Enum -\u003e [How to print a user-defined type with cpp-dump](#how-to-print-a-user-defined-type-with-cpp-dump)\n","funding_links":[],"categories":["C++","Debug"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilip82148%2Fcpp-dump","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphilip82148%2Fcpp-dump","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilip82148%2Fcpp-dump/lists"}