Skip to content

Commit 0296fbc

Browse files
authored
Add append back to LuaRef (#206)
1 parent 7fdd44e commit 0296fbc

4 files changed

Lines changed: 106 additions & 4 deletions

File tree

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ on:
1010
- "**/ThirdParty/**"
1111
- "**/CMakeLists.txt"
1212
- "**/.gitmodules"
13+
- "!**/*.md"
14+
- "!**/*.txt"
1315

1416
concurrency:
1517
group: ${{ github.workflow }}-${{ github.ref }}
@@ -37,7 +39,7 @@ jobs:
3739
- name: Install Ninja
3840
run: |
3941
sudo apt-get update
40-
sudo apt-get -y install ninja-build
42+
sudo apt-get -y install ninja-build libreadline-dev
4143
4244
- name: Initialize CodeQL
4345
uses: github/codeql-action/init@v3

Manual.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,18 @@ v [3] = v [2]; // v[2] and v[3] reference the same table
14881488
v [2] = luabridge::LuaNil (); // Removes the value with key = 2. The table is still referenced by v[3].
14891489
```
14901490
1491+
To append one or more values to a sequence table, use `append`. It is equivalent to assigning to `#t + 1`, `#t + 2`, etc., and uses `lua_rawseti` internally:
1492+
1493+
```cpp
1494+
luabridge::LuaRef t = luabridge::newTable (L);
1495+
1496+
t.append (1); // t = {1}
1497+
t.append (2, 3); // t = {1, 2, 3}
1498+
t.append ("hello", true); // t = {1, 2, 3, "hello", true}
1499+
```
1500+
1501+
`append` returns `true` if all values were successfully pushed and stored, and stops early (returning `false`) if any value fails to push onto the Lua stack.
1502+
14911503
4.3 - Calling Lua
14921504
-----------------
14931505

@@ -1903,9 +1915,10 @@ bool operator>= (T rhs) const;
19031915
template <class T>
19041916
bool rawequal (T v) const;
19051917

1906-
/// Append a value to a referred table. If the table is a sequence this will add another element to it.
1907-
template <class T>
1908-
void append (T v) const;
1918+
/// Append one or more values to a referred table. If the table is a sequence this will add more elements to it.
1919+
/// Uses lua_rawseti internally. Returns true if all values were successfully appended.
1920+
template <class... Ts>
1921+
bool append (const Ts&... vs) const;
19091922

19101923
/// Return the length of a referred array. This is identical to applying the Lua # operator.
19111924
int length () const;

Source/LuaBridge/detail/LuaRef.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,39 @@ class LuaRefBase
584584
return get_length(m_L, -1);
585585
}
586586

587+
//=============================================================================================
588+
/**
589+
* @brief Append one or more values to a referred table.
590+
*
591+
* If the table is a sequence this will add more elements to it.
592+
*
593+
* @param vs Values to append.
594+
*
595+
* @returns True if all values were successfully appended.
596+
*/
597+
template <class... Ts>
598+
bool append(const Ts&... vs) const
599+
{
600+
static_assert(sizeof...(vs) > 0);
601+
602+
const StackRestore stackRestore(m_L);
603+
604+
impl().push(m_L);
605+
606+
int index = get_length(m_L, -1) + 1;
607+
608+
auto appendOne = [&](const auto& v) -> bool
609+
{
610+
if (! Stack<std::decay_t<decltype(v)>>::push(m_L, v))
611+
return false;
612+
613+
lua_rawseti(m_L, -2, index++);
614+
return true;
615+
};
616+
617+
return (appendOne(vs) && ...);
618+
}
619+
587620
//=============================================================================================
588621
/**
589622
* @brief Call Lua code.

Tests/Source/LuaRefTests.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,3 +766,57 @@ TEST_F(LuaRefTests, HookTesting)
766766
func.second(0, "x");
767767
}
768768
}
769+
770+
TEST_F(LuaRefTests, AppendSingleValue)
771+
{
772+
runLua("result = {}");
773+
774+
EXPECT_TRUE(result().append(1));
775+
EXPECT_TRUE(result().append(2));
776+
EXPECT_TRUE(result().append(3));
777+
778+
ASSERT_EQ(3, result().length());
779+
ASSERT_EQ(1, result()[1].unsafe_cast<int>());
780+
ASSERT_EQ(2, result()[2].unsafe_cast<int>());
781+
ASSERT_EQ(3, result()[3].unsafe_cast<int>());
782+
}
783+
784+
TEST_F(LuaRefTests, AppendMultipleValues)
785+
{
786+
runLua("result = {}");
787+
788+
EXPECT_TRUE(result().append(10, 20, 30));
789+
790+
ASSERT_EQ(3, result().length());
791+
ASSERT_EQ(10, result()[1].unsafe_cast<int>());
792+
ASSERT_EQ(20, result()[2].unsafe_cast<int>());
793+
ASSERT_EQ(30, result()[3].unsafe_cast<int>());
794+
}
795+
796+
TEST_F(LuaRefTests, AppendMixedTypes)
797+
{
798+
runLua("result = {}");
799+
800+
EXPECT_TRUE(result().append(42, std::string("hello"), true, 3.14));
801+
802+
ASSERT_EQ(4, result().length());
803+
ASSERT_EQ(42, result()[1].unsafe_cast<int>());
804+
ASSERT_EQ("hello", result()[2].unsafe_cast<std::string>());
805+
ASSERT_TRUE(result()[3].unsafe_cast<bool>());
806+
ASSERT_DOUBLE_EQ(3.14, result()[4].unsafe_cast<double>());
807+
}
808+
809+
TEST_F(LuaRefTests, AppendToExistingSequence)
810+
{
811+
runLua("result = {10, 20}");
812+
813+
ASSERT_EQ(2, result().length());
814+
815+
EXPECT_TRUE(result().append(30, 40));
816+
817+
ASSERT_EQ(4, result().length());
818+
ASSERT_EQ(10, result()[1].unsafe_cast<int>());
819+
ASSERT_EQ(20, result()[2].unsafe_cast<int>());
820+
ASSERT_EQ(30, result()[3].unsafe_cast<int>());
821+
ASSERT_EQ(40, result()[4].unsafe_cast<int>());
822+
}

0 commit comments

Comments
 (0)