Created
July 20, 2019 02:16
-
-
Save notfoundry/835b4f3db275a54262dbf8d29bb64933 to your computer and use it in GitHub Desktop.
cpp_constexpr_string_interpolation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <boost/mp11/map.hpp> | |
| #include <boost/mp11/list.hpp> | |
| namespace ct { | |
| using namespace boost::mp11; | |
| template <class C, C... Cs> | |
| struct nttp_string { | |
| constexpr static C data[sizeof...(Cs)] = {Cs...}; | |
| constexpr static auto value = []{ return data; }; | |
| constexpr static char const* c_str() noexcept { | |
| return data; | |
| } | |
| }; | |
| template <class S1, class S2> | |
| struct nttp_string_concat; | |
| template <class C, C... S1Cs, C... S2Cs> | |
| struct nttp_string_concat<nttp_string<C, S1Cs...>, nttp_string<C, S2Cs...>> { | |
| using type = nttp_string<C, S1Cs..., S2Cs...>; | |
| }; | |
| enum class state { | |
| waiting_for_opener, | |
| waiting_for_closer | |
| }; | |
| template <class Format, class Table, class Result, class Key, state State = state::waiting_for_opener> | |
| struct nttp_string_formatter_impl; | |
| template <class C, class Table, C... ResultCs, class Key> | |
| struct nttp_string_formatter_impl<nttp_string<C>, Table, nttp_string<C, ResultCs...>, Key, state::waiting_for_opener> { | |
| constexpr static auto value = nttp_string<C, ResultCs...>(); | |
| }; | |
| template <class C, C Front, C... FormatCs, class Table, C... ResultCs, class Key> | |
| struct nttp_string_formatter_impl<nttp_string<C, Front, FormatCs...>, Table, nttp_string<C, ResultCs...>, Key, state::waiting_for_opener> { | |
| constexpr static auto value = nttp_string_formatter_impl< | |
| nttp_string<C, FormatCs...>, Table, nttp_string<C, ResultCs..., Front>, Key, state::waiting_for_opener | |
| >::value; | |
| }; | |
| template <class C, C... FormatCs, class Table, C... ResultCs, class Key> | |
| struct nttp_string_formatter_impl<nttp_string<C, C('{'), FormatCs...>, Table, nttp_string<C, ResultCs...>, Key, state::waiting_for_opener> { | |
| constexpr static auto value = nttp_string_formatter_impl< | |
| nttp_string<C, FormatCs...>, Table, nttp_string<C, ResultCs...>, nttp_string<C>, state::waiting_for_closer | |
| >::value; | |
| }; | |
| template <class C, C Front, C... FormatCs, class Table, class Result, C... KeyCs> | |
| struct nttp_string_formatter_impl<nttp_string<C, Front, FormatCs...>, Table, Result, nttp_string<C, KeyCs...>, state::waiting_for_closer> { | |
| constexpr static auto value = nttp_string_formatter_impl< | |
| nttp_string<C, FormatCs...>, Table, Result, nttp_string<C, KeyCs..., Front>, state::waiting_for_closer | |
| >::value; | |
| }; | |
| template <class C, C... FormatCs, class Table, class Result, C... KeyCs> | |
| struct nttp_string_formatter_impl<nttp_string<C, C('}'), FormatCs...>, Table, Result, nttp_string<C, KeyCs...>, state::waiting_for_closer> { | |
| using substitution = mp_second<mp_map_find<Table, nttp_string<C, KeyCs...>>>; | |
| constexpr static auto value = nttp_string_formatter_impl< | |
| nttp_string<C, FormatCs...>, Table, typename nttp_string_concat<Result, substitution>::type, nttp_string<C, KeyCs...>, state::waiting_for_opener | |
| >::value; | |
| }; | |
| template <class Format, class Table> | |
| struct nttp_string_formatter; | |
| template <class C, C... Cs, class Table> | |
| struct nttp_string_formatter<nttp_string<C, Cs...>, Table> { | |
| constexpr static auto value = nttp_string_formatter_impl<nttp_string<C, Cs...>, Table, nttp_string<C>, nttp_string<C>>::value; | |
| }; | |
| template <class Format, class Table = mp_list<>> | |
| struct formatted_nttp_string_builder { | |
| template <class Key, class Value> | |
| constexpr auto operator()(Key, Value) { | |
| return formatted_nttp_string_builder<Format, mp_map_insert<Table, mp_list<Key, Value>>>(); | |
| } | |
| constexpr auto operator()() { | |
| return nttp_string_formatter<Format, Table>::value; | |
| } | |
| }; | |
| namespace string_literals { | |
| template <class C, C... Cs> | |
| constexpr auto operator""_s() noexcept { | |
| return nttp_string<C, Cs...>(); | |
| } | |
| template <class C, C... Cs> | |
| constexpr auto operator""_f() noexcept { | |
| return formatted_nttp_string_builder<nttp_string<C, Cs...>>(); | |
| } | |
| } | |
| } | |
| using namespace ct::string_literals; | |
| constexpr auto s = "Hello {name}, today is {date}!"_f("name"_s, "Foo"_s)("date"_s, "Friday"_s)(); | |
| char const* cs = s.c_str(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment