printf.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #include <boost/hana/adjust_if.hpp>
  5. #include <boost/hana/at_key.hpp>
  6. #include <boost/hana/core/is_a.hpp>
  7. #include <boost/hana/core/to.hpp>
  8. #include <boost/hana/filter.hpp>
  9. #include <boost/hana/functional/compose.hpp>
  10. #include <boost/hana/functional/partial.hpp>
  11. #include <boost/hana/map.hpp>
  12. #include <boost/hana/not.hpp>
  13. #include <boost/hana/pair.hpp>
  14. #include <boost/hana/prepend.hpp>
  15. #include <boost/hana/string.hpp>
  16. #include <boost/hana/sum.hpp>
  17. #include <boost/hana/tuple.hpp>
  18. #include <boost/hana/type.hpp>
  19. #include <boost/hana/unpack.hpp>
  20. #include <cstdio>
  21. namespace hana = boost::hana;
  22. constexpr auto formats = hana::make_map(
  23. hana::make_pair(hana::type_c<int>, hana::string_c<'%', 'd'>),
  24. hana::make_pair(hana::type_c<float>, hana::string_c<'%', 'f'>),
  25. hana::make_pair(hana::type_c<char const*>, hana::string_c<'%', 's'>)
  26. );
  27. template <typename ...Tokens>
  28. constexpr auto format(Tokens ...tokens_) {
  29. auto tokens = hana::make_tuple(tokens_...);
  30. // If you don't care about constexpr-ness of `format`, you can use
  31. // this lambda instead of `compose(partial(...), typeid_)`:
  32. //
  33. // [](auto token) {
  34. // return formats[typeid_(token)];
  35. // }
  36. auto format_string_tokens = hana::adjust_if(tokens,
  37. hana::compose(hana::not_, hana::is_a<hana::string_tag>),
  38. hana::compose(hana::partial(hana::at_key, formats), hana::typeid_)
  39. );
  40. auto format_string = hana::sum<hana::string_tag>(format_string_tokens);
  41. auto variables = hana::filter(tokens, hana::compose(hana::not_, hana::is_a<hana::string_tag>));
  42. return hana::prepend(variables, format_string);
  43. }
  44. int main() {
  45. int a = 1;
  46. float b = 1.3;
  47. char const* c = "abcdef";
  48. auto args = format(
  49. BOOST_HANA_STRING("first="), a
  50. , BOOST_HANA_STRING(" second="), b
  51. , BOOST_HANA_STRING(" third="), c
  52. );
  53. hana::unpack(args, [](auto fmt, auto ...args) {
  54. std::printf(hana::to<char const*>(fmt), args...);
  55. });
  56. }