Search code examples
c++templatesc++17boost-hana

Combine 2 functions (templated) in only one


I am trying to get a boost::hana::string by order as inserted in tuple looking by std::string_view name in an array (please check code, it is easier to understand there than in my words).

I have got it, but the syntax really gets messy and lost its self-explanatory meaning, because it is necessary to call two functions (1 fn for getting the index, and 1 templ. fn por getting the string) instead of only one direct call.

Please, be aware that the problem is harder than it looks, due to the fact that boost::hana::string returns a different type even if you change a single char in the string, regardless their lengths.

The source code is also available in coliru: http://coliru.stacked-crooked.com/a/45ea8db0d6b4dbad

#include <array>
#include <tuple>
#include <iostream>
#include <string_view>
#include <boost/hana/string.hpp>

using namespace std::string_view_literals;

constexpr std::array images = { "USERS.PNG"sv, "LESSONS.PNG"sv, "COURSES.PNG"sv, "ALUMNS.PNG"sv };
constexpr std::tuple sources = { BOOST_HANA_STRING("1"), BOOST_HANA_STRING("2"), BOOST_HANA_STRING("3"), BOOST_HANA_STRING("4") };

constexpr size_t image(const std::string_view& name)
{
    size_t i = 0;
    for (auto& image : images)
        if (image == name || !++i) break;

    return i;
}

template <size_t I>
constexpr auto source()
{
    return std::get<I>(sources);
}

//constexpr auto combined(const std::string_view& name)
//{
//    constexpr auto index = image(name);
//    return source<index>();
//}

int main()
{
    //constexpr auto hana_str = combined("LESSONS.PNG"sv);
    
    constexpr auto index = image("LESSONS.PNG"sv);
    constexpr auto hana_string = source<index>();

    static_assert(std::string_view(hana_string.c_str()) == "2"sv);
}

The function I would like to have is the commented as "combined" in above code.


Solution

  • You can pass boost::hana::string to combined() instead in order to invoke image() at compile-time with std::string_view:

    template <class CharT, CharT... s>
    constexpr auto combined(const boost::hana::string<s...>& name)
    {
       constexpr auto index = image(name.c_str());
       return source<index>();
    }
    

    And here's how to use it:

    using boost::hana::literals::operator""_s;
    constexpr auto hana_str = combined("LESSONS.PNG"_s);
    static_assert(hana_str.c_str() == "2"sv);
    

    But in order to enable boost::hana::literals::operator""_s you need to define BOOST_HANA_CONFIG_ENABLE_STRING_UDL before including <boost/hana/string.hpp>:

    #define BOOST_HANA_CONFIG_ENABLE_STRING_UDL
    #include <boost/hana/string.hpp>