{"action":"created","issue":{"url":"https://api.github.com/repos/fmtlib/fmt/issues/341","repository_url":"https://api.github.com/repos/fmtlib/fmt","labels_url":"https://api.github.com/repos/fmtlib/fmt/issues/341/labels{/name}","comments_url":"https://api.github.com/repos/fmtlib/fmt/issues/341/comments","events_url":"https://api.github.com/repos/fmtlib/fmt/issues/341/events","html_url":"https://github.com/fmtlib/fmt/issues/341","id":159112003,"number":341,"title":"Is `CustomValue::format` only for internal use?","user":{"login":"jamboree","id":690570,"avatar_url":"https://avatars.githubusercontent.com/u/690570?v=3","gravatar_id":"","url":"https://api.github.com/users/jamboree","html_url":"https://github.com/jamboree","followers_url":"https://api.github.com/users/jamboree/followers","following_url":"https://api.github.com/users/jamboree/following{/other_user}","gists_url":"https://api.github.com/users/jamboree/gists{/gist_id}","starred_url":"https://api.github.com/users/jamboree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamboree/subscriptions","organizations_url":"https://api.github.com/users/jamboree/orgs","repos_url":"https://api.github.com/users/jamboree/repos","events_url":"https://api.github.com/users/jamboree/events{/privacy}","received_events_url":"https://api.github.com/users/jamboree/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2016-06-08T08:55:35Z","updated_at":"2016-06-09T16:43:55Z","closed_at":null,"body":"It's assigned within `MakeValue<Formatter>`:\r\n```c++\r\n  template <typename T>\r\n  MakeValue(const T &value,\r\n            typename EnableIf<Not<\r\n              ConvertToInt<T>::value>::value, int>::type = 0) {\r\n    custom.value = &value;\r\n    custom.format = &format_custom_arg<T>;\r\n  }\r\n```\r\n\r\nand `format_custom_arg` is defined as:\r\n```c++\r\n  // Formats an argument of a custom type, such as a user-defined class.\r\n  template <typename T>\r\n  static void format_custom_arg(\r\n      void *formatter, const void *arg, void *format_str_ptr) {\r\n    format(*static_cast<Formatter*>(formatter),\r\n           *static_cast<const Char**>(format_str_ptr),\r\n           *static_cast<const T*>(arg));\r\n  }\r\n```\r\nwhere `format` is found by ADL, this seems like a customization point to me.\r\n\r\nHowever, in `FMT_VARIADIC_`, it's called this way:\r\n```\r\nArgArray::template make<fmt::BasicFormatter<Char> >(args)...\r\n```\r\n\r\nThat means, it assumes `BasicFormatter` always uses `ArgFormatter<CharType>`, that is, even you could supply your `CustomArgFormatter` as described [here](http://fmtlib.net/latest/api.html#argument-formatters), there's no way for the CustomValue to use the `CustomArgFormatter` that you supplied. (unless you avoid the FMT_VARIADIC_ hack and specify the Formatter manually)\r\n\r\nBesides, the format-ADL mechanism allows you to do custom parsing on the format string, but does anyone really need it?\r\n\r\nIf `CustomValue::format` is designed for extension (w/o custom parsing), I think there could be a better way. For example, a customization point that takes `FormatSpec`, the real UDT, and the writer.\r\n\r\nWhy do I care at all? Recently I try to implement a pre-parsed format object, which parses the format string into its internal data structure. And `CustomValue::format` is a big headache for that. It seems that the current CustomValue::format is tightly coupled with some internal details.\r\n"},"comment":{"url":"https://api.github.com/repos/fmtlib/fmt/issues/comments/224954687","html_url":"https://github.com/fmtlib/fmt/issues/341#issuecomment-224954687","issue_url":"https://api.github.com/repos/fmtlib/fmt/issues/341","id":224954687,"user":{"login":"jamboree","id":690570,"avatar_url":"https://avatars.githubusercontent.com/u/690570?v=3","gravatar_id":"","url":"https://api.github.com/users/jamboree","html_url":"https://github.com/jamboree","followers_url":"https://api.github.com/users/jamboree/followers","following_url":"https://api.github.com/users/jamboree/following{/other_user}","gists_url":"https://api.github.com/users/jamboree/gists{/gist_id}","starred_url":"https://api.github.com/users/jamboree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamboree/subscriptions","organizations_url":"https://api.github.com/users/jamboree/orgs","repos_url":"https://api.github.com/users/jamboree/repos","events_url":"https://api.github.com/users/jamboree/events{/privacy}","received_events_url":"https://api.github.com/users/jamboree/received_events","type":"User","site_admin":false},"created_at":"2016-06-09T16:43:55Z","updated_at":"2016-06-09T16:43:55Z","body":"The intent is indeed for performance, in case that the same format will be output many times so it might be beneficial to save the parsing every time.\r\nDynamic precision/width is not really a problem, it's already implemented in my experiment. What's missing is custom parsing which can be solved with a extended `FormatSpec` that stores the raw string."}}
{"actor":{"display_login":"jamboree"}}