• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 #include <boost/hana/adjust_if.hpp>
6 #include <boost/hana/at_key.hpp>
7 #include <boost/hana/core/is_a.hpp>
8 #include <boost/hana/core/to.hpp>
9 #include <boost/hana/filter.hpp>
10 #include <boost/hana/functional/compose.hpp>
11 #include <boost/hana/functional/partial.hpp>
12 #include <boost/hana/map.hpp>
13 #include <boost/hana/not.hpp>
14 #include <boost/hana/pair.hpp>
15 #include <boost/hana/prepend.hpp>
16 #include <boost/hana/string.hpp>
17 #include <boost/hana/sum.hpp>
18 #include <boost/hana/tuple.hpp>
19 #include <boost/hana/type.hpp>
20 #include <boost/hana/unpack.hpp>
21 
22 #include <cstdio>
23 namespace hana = boost::hana;
24 
25 
26 constexpr auto formats = hana::make_map(
27     hana::make_pair(hana::type_c<int>, hana::string_c<'%', 'd'>),
28     hana::make_pair(hana::type_c<float>, hana::string_c<'%', 'f'>),
29     hana::make_pair(hana::type_c<char const*>, hana::string_c<'%', 's'>)
30 );
31 
32 template <typename ...Tokens>
format(Tokens...tokens_)33 constexpr auto format(Tokens ...tokens_) {
34     auto tokens = hana::make_tuple(tokens_...);
35 
36     // If you don't care about constexpr-ness of `format`, you can use
37     // this lambda instead of `compose(partial(...), typeid_)`:
38     //
39     // [](auto token) {
40     //     return formats[typeid_(token)];
41     // }
42     auto format_string_tokens = hana::adjust_if(tokens,
43         hana::compose(hana::not_, hana::is_a<hana::string_tag>),
44         hana::compose(hana::partial(hana::at_key, formats), hana::typeid_)
45     );
46 
47     auto format_string = hana::sum<hana::string_tag>(format_string_tokens);
48     auto variables = hana::filter(tokens, hana::compose(hana::not_, hana::is_a<hana::string_tag>));
49     return hana::prepend(variables, format_string);
50 }
51 
main()52 int main() {
53     int a = 1;
54     float b = 1.3;
55     char const* c = "abcdef";
56 
57     auto args = format(
58           BOOST_HANA_STRING("first="), a
59         , BOOST_HANA_STRING(" second="), b
60         , BOOST_HANA_STRING(" third="), c
61     );
62 
63     hana::unpack(args, [](auto fmt, auto ...args) {
64         std::printf(hana::to<char const*>(fmt), args...);
65     });
66 }
67