ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.12k stars 500 forks source link

Multimap seems to be converted to just regular map using just first key value pairs #1462

Open maxdemarzi opened 1 year ago

maxdemarzi commented 1 year ago

I have a 5 pair multimap but when I try to pass it back from C++ to lua, it swallows the duplicate key pairs and gives me a map with just 3 values. See https://godbolt.org/z/6zcbM5znj to try it.

#include <limits>
#include <sol/sol.hpp>
#include <iostream>
#include <vector>
#include <unordered_set>

int main()
{
    sol::state lua;
    lua.set("mmtest", sol::as_table_t<std::unordered_multimap<uint64_t, uint64_t>>(std::unordered_multimap<uint64_t, uint64_t>{{1,10}, {1,11}, {2,20}, {3,30}, {3,31} } ));

    sol::table result = lua.script("return mmtest ");
    sol::object first_key = result.get<sol::object>(1);
    if (first_key.is<sol::table>()) {
         std::cout <<  "I am a table\n"; 
    }
    sol::type what_am_i = first_key.get_type();
    std::cout << type_name(lua, what_am_i) << "\n";

     std::cout << result.get<uint64_t>(1) << "\n"; 
     std::cout << result.get<uint64_t>(2) << "\n"; 
     std::cout << result.get<uint64_t>(3) << "\n"; 
     std::cout << result.size() << "\n"; 
}

Program output is:

number
10
20
30
3

I was expecting the values of a multimap to be a table or vector

ThePhD commented 1 year ago

This is probably because we recognize this is some kind of map, but don't acknowledge things that overwrite previous inserts. (Tables in Lua get built up by just inserting one value after the next.) I'll need to add a new-ish category of detection for multimap types, then perform the insertions....

ThePhD commented 1 year ago

One problem we're going to have here is how we make a multimap in Lua, and what the API for the table looks like. The conversion between and map and a multimap is going to be pretty brutal, and the performance metrics will drop heavily if we do something like e.g. make every pushed value a table even if there's only 1 value to that key. We might have to have a mix of single values and table values, but this will definitely complicate people's usage of the API.