{"id":951,"date":"2015-02-01T22:48:15","date_gmt":"2015-02-02T06:48:15","guid":{"rendered":"http:\/\/www.elbeno.com\/blog\/?p=951"},"modified":"2015-06-30T21:17:44","modified_gmt":"2015-07-01T04:17:44","slug":"how-to-print-anything-in-c-part-1","status":"publish","type":"post","link":"https:\/\/www.elbeno.com\/blog\/?p=951","title":{"rendered":"How to print anything in C++ (part 1)"},"content":{"rendered":"<p><a href=\"https:\/\/www.elbeno.com\/blog\/?p=951\">Part 1<\/a> <a href=\"https:\/\/www.elbeno.com\/blog\/?p=958\">Part 2<\/a> <a href=\"https:\/\/www.elbeno.com\/blog\/?p=964\">Part 3<\/a> <a href=\"https:\/\/www.elbeno.com\/blog\/?p=967\">Part 4<\/a> <a href=\"https:\/\/www.elbeno.com\/blog\/?p=973\">Part 5<\/a> <a href=\"https:\/\/www.elbeno.com\/blog\/?p=993\">Postscript<\/a><\/p>\n<p>I thought I&#8217;d have a go at writing some code that could print things. A pretty-printer, if you like. What I want to be able to do is this:<\/p>\n<pre lang=\"cpp\">\r\n \/\/ Print x correctly, where x is ANY type.\r\ncout << prettyprint(x) << endl;\r\n<\/pre>\n<p>Obviously this is going to involve templates since the type of <code>x<\/code> may vary. <\/p>\n<p>There are a few things that immediately spring to mind:<\/p>\n<ul>\n<li>Maybe <code>x<\/code> is already printable, that is, <code>operator&lt;&lt;<\/code> might work \"out of the box\".<\/li>\n<li>If <code>x<\/code> is a container, we want to do something with that and print the elements.<\/li>\n<li>We probably want to print elements of <code>pair<\/code> and <code>tuple<\/code> also.<\/li>\n<li>The value of some things is not printable, or at least not sensible to print. For example, functions.<\/li>\n<\/ul>\n<p>The basic plan that came to mind is this: <code>prettyprint<\/code> is a function template, which returns an object that wraps the <code>x<\/code> and has <code>operator&lt;&lt;<\/code> defined. This class will itself be a template, and the template instantiation we choose will be determined by what sort of thing <code>x<\/code> is.<\/p>\n<p>This suggest that the very first thing we can write looks something like this:<\/p>\n<pre lang=\"cpp\">\r\ntemplate <typename T>\r\nstruct stringifier\r\n{\r\n  explicit stringifier(const T&) {}\r\n\r\n  std::ostream& output(std::ostream& s) const\r\n  {\r\n    return s << \"<unknown>\";\r\n  }\r\n};\r\n\r\ntemplate <typename T>\r\ninline std::ostream& operator<<(std::ostream&#038; s, \r\n                                const stringifier<T>& t)\r\n{\r\n  return t.output(s);\r\n}\r\n\r\ntemplate <typename T>\r\ninline stringifier<T> prettyprint(T&& t)\r\n{\r\n  return stringifier<T>(std::forward<T>(t));\r\n}\r\n<\/pre>\n<p>So far so good. Now we can print \"&lt;unknown&gt;\" for any type. We have a place to start specializing things.<\/p>\n<p>A quick poke around <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/types\">C++ type support<\/a> and some experiments soon fleshed out the plan:<\/p>\n<ol>\n<li>There are at least 6 types of callable things: functions, member functions, <code>std::function<\/code>s, bind expressions, lambdas, and objects that support <code>operator()<\/code> (function objects). All of these are \"unprintable\". Lambdas are a kind of function object; I don't know whether they can be meaningfully distinguished or whether that is desirable.<\/li>\n<li><code>nullptr<\/code> is its own type and unprintable.<\/li>\n<li><code>enum class<\/code> values are not printable out-of-the-box; they will require a cast to <code>std::underlying_type<\/code>.<\/li>\n<li><code>pair<\/code>s should be easy to deal with, but <code>tuple<\/code>s will require some effort. They are designed for static access, not iteration.<\/li>\n<\/ol>\n<p>So now I have 4 broad categories I want to represent for printing: already-outputtable, unprintable, callable, and containers\/<code>pair<\/code>s\/<code>tuple<\/code>s. I decided to make tag types for each specializable thing so as to be able to select on them.<\/p>\n<pre lang=\"cpp\">\r\nstruct is_iterable_tag {};\r\nstruct is_pair_tag {};\r\nstruct is_tuple_tag {};\r\nstruct is_callable_tag {};\r\nstruct is_outputtable_tag {};\r\nstruct is_enum_tag {};\r\nstruct is_unprintable_tag {};\r\n<\/pre>\n<p>As luck would have it, several of these already have built-in support for detecting:<\/p>\n<pre lang=\"cpp\">\r\ntemplate<typename T>\r\nusing is_unprintable = typename std::conditional<\r\n  std::is_union<T>::value ||\r\n  std::is_class<T>::value ||\r\n  std::is_null_pointer<T>::value,\r\n  std::true_type, std::false_type>::type;\r\n\r\n\/\/ similarly we can use: \r\n\/\/ std::is_enum<T>::value to detect enum or enum class\r\n<\/pre>\n<p>Detecting <code>pair<\/code>s and <code>tuple<\/code>s is also easy, using a standard specialization pattern:<\/p>\n<pre lang=\"cpp\">\r\ntemplate <typename T>\r\nstruct is_pair : public std::false_type {};\r\n\r\ntemplate <typename T, typename U>\r\nstruct is_pair<std::pair<T, U>> : public std::true_type {};\r\n\r\ntemplate <typename T>\r\nstruct is_tuple : public std::false_type {};\r\n\r\ntemplate <typename... Ts>\r\nstruct is_tuple<std::tuple<Ts...>> : public std::true_type {};\r\n<\/pre>\n<p>A good setup so far. We can detect concrete types. Next, how to detect whether something already supports <code>operator&lt;&lt;<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Part 1 Part 2 Part 3 Part 4 Part 5 Postscript I thought I&#8217;d have a go at writing some code that could print things. A pretty-printer, if you like. What I want to be able to do is this: \/\/ Print x correctly, where x is ANY type. cout<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,8],"tags":[],"class_list":["post-951","post","type-post","status-publish","format-standard","hentry","category-cpp","category-programming"],"_links":{"self":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/951","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=951"}],"version-history":[{"count":9,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/951\/revisions"}],"predecessor-version":[{"id":1001,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/951\/revisions\/1001"}],"wp:attachment":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=951"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=951"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=951"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}