{"id":13629947,"url":"https://github.com/p-ranav/pprint","last_synced_at":"2025-10-04T07:30:37.447Z","repository":{"id":52753647,"uuid":"183324785","full_name":"p-ranav/pprint","owner":"p-ranav","description":"Pretty Printer for Modern C++","archived":true,"fork":false,"pushed_at":"2020-02-20T20:55:47.000Z","size":241,"stargazers_count":910,"open_issues_count":1,"forks_count":76,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-09-29T23:42:28.523Z","etag":null,"topics":["cpp17","mit-license","pretty-printer","single-header-lib"],"latest_commit_sha":null,"homepage":null,"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/p-ranav.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}},"created_at":"2019-04-25T00:16:58.000Z","updated_at":"2024-09-24T02:09:15.000Z","dependencies_parsed_at":"2022-08-13T02:10:11.104Z","dependency_job_id":null,"html_url":"https://github.com/p-ranav/pprint","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-ranav%2Fpprint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-ranav%2Fpprint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-ranav%2Fpprint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-ranav%2Fpprint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p-ranav","download_url":"https://codeload.github.com/p-ranav/pprint/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235227462,"owners_count":18956137,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cpp17","mit-license","pretty-printer","single-header-lib"],"created_at":"2024-08-01T22:01:25.138Z","updated_at":"2025-10-04T07:30:32.090Z","avatar_url":"https://github.com/p-ranav.png","language":"C++","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg height=\"60\" src=\"https://i.imgur.com/QT98aqi.png\" alt=\"pprint\"/\u003e\n\u003c/p\u003e\n\n## Highlights\n\n* Single header file\n* Requires C++17\n* MIT License\n\n## Quick Start\n\nSimply include pprint.hpp and you're good to go.\n\n```cpp\n#include \u003cpprint.hpp\u003e\n```\n\nTo start printing, create a ```PrettyPrinter```\n\n```cpp\npprint::PrettyPrinter printer;\n```\n\nYou can construct a ```PrettyPrinter``` with any stream that inherits from ```std::ostream``` , e.g, ```std::stringstream```\n\n```cpp\nstd::stringstream stream;\npprint::PrettyPrinter printer(stream);\n```\n\n\n## Fundamental Types\n\n```cpp\nprinter.print(5);\nprinter.print(3.14f);\nprinter.print(2.718);\nprinter.print(true);\nprinter.print('x');\nprinter.print(\"Hello, 世界\");\nprinter.print(nullptr);\n```\n\n```bash\n5\n3.14f\n2.718\ntrue\nx\nHello, 世界\nnullptr\n```\n\n## Strings\n\nMaybe you want your strings to be quoted? Simply set ```printer.quotes(true)```\n\n```cpp\nprinter.quotes(true);\nprinter.print(\"A\", \"B\", \"C\");\n```\n\n```bash\n\"A\" \"B\" \"C\"\n```\n\n## Complex Numbers\n\n```cpp\nusing namespace std::complex_literals;\nstd::complex\u003cdouble\u003e foo = 1. + 2.5i;\nstd::complex\u003cdouble\u003e bar = 9. + 4i;\nprinter.print(foo, \"*\", bar, \"=\", (foo * bar));   // parameter packing\n```\n\n```bash\n(1 + 2.5i) * (9 + 4i) = (-1 + 26.5i)\n```\n## Enumeration Types\n\n```cpp\nenum Color { RED = 2, BLUE = 4, GREEN = 8 };\nColor color = BLUE;\nprinter.print(color);\n```\n\n```bash\n4\n```\n\nIf you compile with\n* Clang/LLVM \u003e= 5\n* Visual C++ \u003e= 15.3 / Visual Studio \u003e= 2017\n* Xcode \u003e= 10.2\n* GCC \u003e= 9\n\nthen pprint will print the name of the enum for you (thanks to [magic_enum](https://github.com/Neargye/magic_enum))\n\n```cpp\nenum Level { LOW, MEDIUM, HIGH };\nLevel current_level = MEDIUM;\nstd::cout \u003c\u003c \"Current level: \";\nprinter.print(current_level);\n```\n\n```bash\nCurrent level: MEDIUM\n```\n\n## STL Sequence Containers\n\npprint supports a variety of STL sequence containers including ```std::vector```, ```std::list```, ```std::deque```, and ```std::array```. \n\nHere's an example pretty print of a simple 3x3 matrix:\n\n```cpp\ntypedef std::array\u003cstd::array\u003cint, 3\u003e, 3\u003e Mat3x3;\nMat3x3 matrix;\nmatrix[0] = {1, 2, 3};\nmatrix[1] = {4, 5, 6};\nmatrix[2] = {7, 8, 9};\nprinter.print(\"Matrix =\", matrix);\n```\n\n```bash\nMatrix = [\n  [1, 2, 3], \n  [4, 5, 6], \n  [7, 8, 9]\n]\n```\n\n### Compact Printing\n\npprint also supports compact printing of containers. Simply call ```printer.compact(true)``` to enable this:\n\n```cpp\nstd::vector\u003cstd::map\u003cstd::string, int\u003e\u003e foo {{{\"a\", 1}, {\"b\", 2}}, {{\"c\", 3}, {\"d\", 4}}};\nprinter.compact(true);\nprinter.print(\"Foo =\", foo);\n```\n\n```bash\nFoo = [{a : 1, b : 2}, {c : 3, d : 4}]\n```\n\n## STL Associative Containers\n\nSupport for associative containers includes pretty printing of ```std::map```, ```std::multimap```, ```std::unordered_map```, ```std::unordered_multimap```, ```std::set```, ```std::multiset```, ```std::unordered_set``` and , ```std::unordered_multiset``` \n\n```cpp\nprinter.print(std::map\u003cstd::string, std::set\u003cint\u003e\u003e{ \n    {\"foo\", {1, 2, 3, 3, 2, 1}}, {\"bar\", {7, 6, 5, 4}}});\n```\n\n```bash\n{\n  \"bar\" : {4, 5, 6, 7}, \n  \"foo\" : {1, 2, 3}\n}\n```\n\n## STL Container Adaptors\n\npprint can print container adaptors including ```std::queue```, ```std::priority_queue``` and ```std::stack```. Here's an example print of a priority queue:\n\n```cpp\nstd::priority_queue\u003cint\u003e queue;\nfor(int n : {1,8,5,6,3,4,0,9,7,2}) queue.push(n);\nprinter.print(queue);\n```\n\n```bash\n[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]\n```\n\n## Fixed-size Heterogeneous Tuples\n\n```cpp\nauto get_student = [](int id) {\n  if (id == 0) return std::make_tuple(3.8, 'A', \"Lisa Simpson\");\n  if (id == 1) return std::make_tuple(2.9, 'C', \"Milhouse Van Houten\");\n  if (id == 2) return std::make_tuple(1.7, 'D', \"Ralph Wiggum\");\n  throw std::invalid_argument(\"id\");\n};\nprinter.print({ get_student(0), get_student(1), get_student(2) });\n```\n\n```bash\n{(1.7, 'D', \"Ralph Wiggum\"), (2.9, 'C', \"Milhouse Van Houten\"), (3.8, 'A', \"Lisa Simpson\")}\n```\n\n## Type-safe Unions\n\n```cpp\n// Construct a vector of values\nstd::vector\u003cstd::variant\u003cbool, int, int *, float, std::string, std::vector\u003cint\u003e,\t\t      \n       std::map\u003cstd::string, std::map\u003cstd::string, int\u003e\u003e, \n       std::pair\u003cdouble, double\u003e\u003e\u003e var;\nvar.push_back(5);\nvar.push_back(nullptr);\nvar.push_back(3.14f);\nvar.push_back(std::string{\"Hello World\"});\nvar.push_back(std::vector\u003cint\u003e{1, 2, 3, 4});\nvar.push_back(std::map\u003cstd::string, std::map\u003cstd::string, int\u003e\u003e{{\"a\",{{\"b\",1}}}, {\"c\",{{\"d\",2}, {\"e\",3}}}});\nvar.push_back(true);\nvar.push_back(std::pair\u003cdouble, double\u003e{1.1, 2.2});\n\n// Print the vector\npprint::PrettyPrinter printer;\nprinter.indent(2);\nprinter.quotes(true);\nprinter.print(var);\n```\n\n```bash\n[\n  5, \n  nullptr,\n  3.14f, \n  \"Hello World\", \n  [1, 2, 3, 4], \n  {\"a\" : {\"b\" : 1}, \"c\" : {\"d\" : 2, \"e\" : 3}}, \n  true, \n  (1.1, 2.2)\n]\n```\n\n## Optional Values\n\n```cpp\nstd::optional\u003cint\u003e opt = 5;\nstd::optional\u003cint\u003e opt2;\n\nprinter.print(opt);\nprinter.print(opt2);\n```\n\n```bash\n5\nnullopt\n```\n\n## Class Objects\n\npprint print class objects with or without an overloaded ```\u003c\u003c``` operator \n\n```cpp\nclass Foo {};\nFoo foo;\nprinter.print(foo);\n```\n\n```\n\u003cObject main::Foo\u003e\n```\n\nIf an ```\u003c\u003c``` operator is available, pprint will use it to print your object:\n\n```cpp\nclass Date {\n  unsigned int month, day, year;\npublic:\n  Date(unsigned int m, unsigned int d, unsigned int y) : month(m), day(d), year(y) {}\n  friend std::ostream\u0026 operator\u003c\u003c(std::ostream\u0026 os, const Date\u0026 dt);\n};\n\n    \nstd::ostream\u0026 operator\u003c\u003c(std::ostream\u0026 os, const Date\u0026 dt) {\n  os \u003c\u003c dt.month \u003c\u003c '/' \u003c\u003c dt.day \u003c\u003c '/' \u003c\u003c dt.year;\n  return os;\n}\n```\n\n```cpp\nDate date(04, 07, 2019);\nprinter.print(\"Today's date is\", date);\n```\n\n```bash\nToday's date is 4/7/2019\n```\n\n## User-defined types\n\nHere's an example to print user-defined types. Let's say you want to print Mesh objects\n\n```cpp\nstruct Vector3 {\n  float x, y, z;\n};\n\nstruct Mesh {\n  std::vector\u003cVector3\u003e vertices;\n};\n```\n\nFirst, overload the ```\u003c\u003c``` operator for these structs:\n\n```cpp\nstd::ostream\u0026 operator\u003c\u003c(std::ostream\u0026 os, const Vector3\u0026 v) {\n  pprint::PrettyPrinter printer(os);\n  printer.print_inline(std::make_tuple(v.x, v.y, v.z));\n  return os;\n}\n\nstd::ostream\u0026 operator\u003c\u003c(std::ostream\u0026 os, const Mesh\u0026 mesh) {\n  pprint::PrettyPrinter printer(os);\n  printer.print(\"Mesh {\");\n  printer.indent(2);\n  printer.print_inline(\"vertices:\", mesh.vertices);\n  printer.print(\"}\");\n  return os;\n}\n```\n\nthen simply call ```printer.print(Mesh)```\n\n```cpp\nMesh quads = {{\n  {0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {0, 1, 0},\n  {0, 0, 1}, {1, 0, 1}, {1, 1, 1}, {0, 0, 1}, {1, 1, 1}, {0, 1, 1},\n  }};\n\npprint::PrettyPrinter printer;\nprinter.print(quads);\n```\n\n```bash\nMesh {\n  vertices: [\n      (0, 0, 0), \n      (1, 0, 0), \n      (1, 1, 0), \n      (0, 0, 0), \n      (1, 1, 0), \n      (0, 1, 0), \n      (0, 0, 1), \n      (1, 0, 1), \n      (1, 1, 1), \n      (0, 0, 1), \n      (1, 1, 1), \n      (0, 1, 1)\n  ]\n}\n```\n## License\nThe project is available under the [MIT](https://opensource.org/licenses/MIT) license.\n","funding_links":[],"categories":["Miscellaneous","C++","排序","Data Formatting and Presentation","Libraries"],"sub_categories":["多项混杂","String formatting \u0026 templating"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-ranav%2Fpprint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp-ranav%2Fpprint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-ranav%2Fpprint/lists"}