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.18k stars 515 forks source link

Adding custom ipairs function #1483

Closed UltraEngine closed 1 year ago

UltraEngine commented 1 year ago

I'm developing an STL-like table class for C++

https://github.com/UltraEngine/tableplusplus

Features

This is for user settings and other dynamic data that may be set in an application's C++ code or by a script extension.

All the following examples currently work.

Key / value in C++

table t;
t["health"] = 100;
t["windowsettings"] = table();
t["windowsettings"]["position"] = 3;

for (auto a : t)
{
    std::string s = a.first;
    Print(s);
    s = a.second;
    Print(s);
}

Array in C++

table arr;
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
arr.push_back(4);
arr.push_back(5);

for (int n = 0; n < arr.size(); ++n)
{
    Print(std::string(arr[n]));
}

Mixing Key / value and array-style keys

table t;

t["health"] = 100;
t["windowsettings"] = table();
t["windowsettings"]["position"] = 3;

t.resize(10);
for (int n = 0; n < t.size(); ++n)
{
    t[n] = n;
}
t.resize(5);

Print("Size: " + String(t.size()));

for (auto a : t)
{
  std::string s = a.first;
  Print(s);
  s = a.second;
  Print(s);
}

Key / value in Lua

local a = Table()
a["health"] = 100
a["color"] = "blue"

for k,v in pairs(a) do
    Print(k ..": ".. tostring(v))
end

Arrays in Lua

b = Table()
b[1] = 1
b[2] = 2
b[3] = 3
b[4] = 4

for n = 1, #b do
    Print(b[n])
end

The only thing missing is support for ipairs:

b = Table()
b[1] = 1
b[2] = 2
b[3] = 3
b[4] = 4

--  "Error: No matching function call takes this number of arguments and the specified types"
for k,v in ipairs(b) do
    Print(b[n])
end

I based my pairs() implementation off the code here: https://github.com/ThePhD/sol2/blob/7aae1aaaaa1bbcc03fd059fe38075cfe3f4b2e90/examples/source/pairs.cpp

Can we get a similar example for implementing ipairs?

Rochet2 commented 1 year ago

Can we get a similar example for implementing ipairs?

Pairs and ipairs probably are implemented the same way. Originally totally looked at the wrong things here.

The issue is that in your lua code you do this:

b = Table()
b[1] = 1
b[2] = 2
b[3] = 3
b[4] = 4

--  "Error: No matching function call takes this number of arguments and the specified types"
for k,v in ipairs(b) do
    Print(b[n])
end

but n in b[n] is not defined. If you use the same code for printing inside the for loop as you use in pairs then it should work.

UltraEngine commented 1 year ago

Oh man, how did I miss that? It seems that sol uses size() to construct ipairs, so you don't even need a special iterator. This works as expected:

b = ctable()
b[1] = 1
b[2] = 2
b[3] = 3
b[4] = 4
b[5] = 5

b[4] = nil

b["key"] = "value"
b[7] = 7

for k,v in ipairs(b) do
    Print(v)
end