Skip to content

UltraEngine/tableplusplus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 

Repository files navigation

table++

By Josh Klint

https://www.ultraengine.com

About

This code is meant to bridge the gaps between dynamic data in C++, Lua, and JSON with an STL-like implementation of Lua tables.

This is useful for dynamic application settings and user-defined settings added by script.

Tables can be accessed by Lua using the sol library, but the tables themselves do not use Lua.

Tables can be saved in JSON format or loaded from JSON using the nlohmann::json library.

Only data types that can be written to JSON files are supported.

Programming Guide

Usage in C++ generally follows the same rules as STL containers, but tables have properties of both STL maps and vectors. The following STL-like methods are available:

  • begin
  • clear
  • empty
  • end
  • erase
  • find
  • operator[]
  • push_back
  • size

Additional methods are below:

  • copy
  • get_type
  • to_json

get_type will return one of the following:

  • table::type::object
  • table::type::null
  • table::type::string
  • table::type::boolean
  • table::type::number_float
  • table::type::number_integer

Note that size() will return the number of entries when the table is treated as a Lua array, which may be different from the number of entries that iterating through begin()...end() will provide.

Values can be retrieved using either a string or an integer for the key.

Usage in Lua is identical to Lua tables, with the following exceptions:

  • The only values that can be inserted into C++ tables are booleans, numbers, strings, nil, and other C++ tables.
  • If a Lua table is assigned to a C++ table, the contents of the Lua table will be copied to the C++ table, and additional changes to the Lua table will not affect the C++ table.
  • By default, there is no way to create a C++ table in Lua, because these usually are declared as a member of another class in C++. However, you can change the definition of TABLEPLUSPLUS_LUATABLEFUNCTION to 1 in the header file, and a creation function called "ctable" will be declared for use in Lua. This constructor will detect and handle infinite recursion.

Table to JSON conversion currently does not have any mechanism in place to prevent infinite recursion. The code below will produce a stack overflow error:

table t;
t["a"] = t;
t.to_json();

Lua Integration

When declaring C++ classes in sol that use a table as a member, it is necessary to use a sol::property and return a tablewrapper, the class that is actually declared to sol:

L->new_usertype<Entity> (
	"properties", sol::property(
		[](const Entity& e) { return tableplusplus::tablewrapper(e.properties); },
		[](Entity& e, sol::table t) { e.properties = t; }
	)
)

Examples

Here are some of the cool things you can do in C++ and Lua.

Key / value in C++

table t;
t["health"] = 100;
t["windowsettings"] = {};
t["windowsettings"]["position"] = 3;

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

Arrays 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"] = {};
t["windowsettings"]["position"] = 3;

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

//Insert an out-of-order index and it will get trimmed off in the resize call
t[12] = {};

t.resize(5);

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

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

C++ copy test

table t;
t["window"] = {};
t["window"]["position"] = 300;
auto b = t["window"];
t = nullptr;
std::string s = b["position"];
Print(s);

Key / value in Lua

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

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

Arrays in Lua

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

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

for k,v in ipairs(b) do
	Print(k ..": ".. tostring(v))
end

Convert to JSON

table t;

//Pure integer keys get output as a JSON array
for (int n = 0; n < 10; ++n)
{
    t[n] = n;
}
printf(t.to_json() + "\n");

//Mix string and integer keys
t["health"] = 100;
t["money"] = 0;
t["nullvalue"] = nullptr;
t["zvalue"] = true;

t["subtable"] = {};
t["subtable"]["position"] = 50;
t["subtable"]["size"] = 300;
t["subtable1"] = t["subtable"];

t["subarray"] = {};
t["subarray"][0] = 1;
t["subarray"][1] = 2;
t["subarray"][2] = 3;

printf(t.to_json());

License

This code may be used freely for any purpose unless it is stated otherwise below.

If you use this code you must include this unmodified README file somewhere in your application directory or subdirectory where it is accessible to the end user.

This unmodified readme file must be included in any source code distribution, or distribution of code derived from this code, or with any compiled binary that uses this code.

You may not misrepresent the origin of this code.

You may not use this code or any derivatives thereof in AI training models.

About

STL-like Lua tables in C++

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages