Search code examples
c++boostmetaprogrammingboost-hana

How to join two Boost Hana maps?


I have two boost::hana::maps to join together.

constexpr auto m1 = hana::make_map( 
    hana::make_pair("key1"_s, hana::type_c<std::string>), 
    hana::make_pair("key2"_s, hana::type_c<std::string>) 
); 

constexpr auto m2 = hana::make_map( 
    hana::make_pair("key3"_s, hana::type_c<std::string>), 
    hana::make_pair("key4"_s, hana::type_c<std::string>), 
    hana::make_pair("key5"_s, hana::type_c<std::string>) 
); 

How to get map containing both of it, as below?

constexpr auto result = hana::make_map( 
    hana::make_pair("key1"_s, hana::type_c<std::string>), 
    hana::make_pair("key2"_s, hana::type_c<std::string>), 
    hana::make_pair("key3"_s, hana::type_c<std::string>), 
    hana::make_pair("key4"_s, hana::type_c<std::string>), 
    hana::make_pair("key5"_s, hana::type_c<std::string>) 
); 

Solution

  • Newer version

    (Boost.Hana > 1.2, Boost >= 1.65)

    There is boost::hana::union_ function for joining boost::hana::maps.

    Returns the union of two maps.

    Given two maps xs and ys, hana::union_(xs, ys) is a new map containing all the elements of xs and all the elements of ys, without duplicates. If both xs and ys contain an element with the same key, the one in ys is taken.

    Cite from Boost.Hana docs

    There is also example:

    // Simple example
    constexpr auto m1 = hana::make_map(
        hana::make_pair("key1"_s, hana::type_c<std::string>),
        hana::make_pair("key2"_s, hana::type_c<std::string>)
    );
    constexpr auto m2 = hana::make_map(
        hana::make_pair("key3"_s, hana::type_c<std::string>),
        hana::make_pair("key4"_s, hana::type_c<std::string>),
        hana::make_pair("key5"_s, hana::type_c<std::string>)
    );
    BOOST_HANA_CONSTANT_CHECK(hana::union_(m1, m2) == hana::make_map(
           hana::make_pair("key1"_s, hana::type_c<std::string>),
           hana::make_pair("key2"_s, hana::type_c<std::string>),
           hana::make_pair("key3"_s, hana::type_c<std::string>),
           hana::make_pair("key4"_s, hana::type_c<std::string>),
           hana::make_pair("key5"_s, hana::type_c<std::string>)
    ));
    
    // Example with overwriting pair (the same key)
    constexpr auto m3 = hana::make_map(
        hana::make_pair(hana::type_c<int>, hana::int_c<1>),
        hana::make_pair(hana::type_c<bool>, hana::bool_c<true>)
    );
    constexpr auto m4 = hana::make_map(
           hana::make_pair(hana::type_c<char>, hana::char_c<'c'>),
           hana::make_pair(hana::type_c<bool>, hana::bool_c<false>)
    );
    BOOST_HANA_CONSTANT_CHECK(hana::union_(m3, m4) == hana::make_map(
           hana::make_pair(hana::type_c<int>, hana::int_c<1>),
           hana::make_pair(hana::type_c<bool>, hana::bool_c<false>),
           hana::make_pair(hana::type_c<char>, hana::char_c<'c'>)
    ));
    

    Full working interactive example here on Godbolt online compiler.


    Older versions

    (Boost.Hana <= 1.1, Boost <= 1.64)

    Based on modified example from some Boost forums topic.

    constexpr auto map1 = hana::make_map( 
        hana::make_pair(hana::type_c<TwoOtherKeys1>,      hana::type_c<SomeValue>),
        hana::make_pair(hana::type_c<SameKey_SameType>,   hana::type_c<SomeValue>),
        hana::make_pair(hana::type_c<SameKey_DifferType>, hana::type_c<SomeValue>)
    );
    constexpr auto map2 = hana::make_map( 
        hana::make_pair(hana::type_c<TwoOtherKeys2>,      hana::type_c<SomeValue>), 
        hana::make_pair(hana::type_c<SameKey_SameType>,   hana::type_c<SomeValue>), 
        hana::make_pair(hana::type_c<SameKey_DifferType>, hana::type_c<OtherValue>) 
    ); 
    
    // Creates result sequence by inserting all of (source) `map1` sequence into (initial) `map1` sequence. 
    // Since both sequences are maps with unique keys, keys that exist in both source and initial map got overwrited.
    constexpr auto result = hana::fold(map1, map2, hana::insert);
    
    // Excepted result
    constexpr auto expected = hana::make_map(
        // Diffrent keys pairs are copied.
        hana::make_pair(hana::type_c<TwoOtherKeys1>, hana::type_c<SomeValue>),
        hana::make_pair(hana::type_c<TwoOtherKeys2>, hana::type_c<SomeValue>),
    
        // The same key and type pairs are just passed.
        hana::make_pair(hana::type_c<SameKey_SameType>, hana::type_c<SomeValue>),   
    
        // The same key, differ type - overwrited.
        hana::make_pair(hana::type_c<SameKey_DifferType>, hana::type_c<OtherValue>)
    );
    
    // Assertion to confirm exceptation
    static_assert(result == expected, ""); // OK
    

    Full working interactive example here on Godbolt online compiler.

    The solution works exacly the same as the one in newest version of Boost.Hana.


    All credits for the soulution to Louis Dionne.