166 lines
4.4 KiB
C++
166 lines
4.4 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// This source file is part of the LuaPlus source distribution and is Copyright
|
|
// 2001-2011 by Joshua C. Jensen (jjensen@workspacewhiz.com).
|
|
//
|
|
// The latest version may be obtained from http://luaplus.org/.
|
|
//
|
|
// The code presented in this file may be used in any environment it is
|
|
// acceptable to use Lua.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#ifndef LUAPLUS__LUASTACKTABLEITERATOR_INL
|
|
#define LUAPLUS__LUASTACKTABLEITERATOR_INL
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// namespace LuaPlus
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace LuaPlus
|
|
{
|
|
|
|
/**
|
|
\param tableObj The table to iterate the contents of.
|
|
\param doReset If true, the Reset() function is called at constructor
|
|
initialization time, allowing the iterator to be used immediately.
|
|
If false, then Reset() must be called before iterating.
|
|
\param autoStackManagement If true, then for every Next() pass through
|
|
the iterator, the stack is cleared to the iteration position (as if
|
|
a LuaAutoBlock was run every single time).
|
|
**/
|
|
LUAPLUS_INLINE LuaStackTableIterator::LuaStackTableIterator(LuaStackObject& tableObj, bool doReset, bool _autoStackManagement)
|
|
: L(tableObj.GetCState())
|
|
, stackIndex(tableObj)
|
|
, startStackIndex(-1)
|
|
, autoStackManagement(_autoStackManagement) {
|
|
// If the user requested it, perform the automatic reset.
|
|
if (doReset)
|
|
Reset();
|
|
}
|
|
|
|
|
|
/**
|
|
The destructor does nothing.
|
|
**/
|
|
LUAPLUS_INLINE LuaStackTableIterator::~LuaStackTableIterator() {
|
|
}
|
|
|
|
|
|
/**
|
|
Start iteration at the beginning of the table.
|
|
**/
|
|
LUAPLUS_INLINE void LuaStackTableIterator::Reset() {
|
|
// Start afresh...
|
|
startStackIndex = lua_gettop(L);
|
|
|
|
// Push the head stack entry.
|
|
lua_pushnil(L);
|
|
|
|
// Start the iteration. If the return value is 0, then the iterator
|
|
// will be invalid.
|
|
if (lua_next(L, stackIndex) == 0)
|
|
startStackIndex = -1;
|
|
}
|
|
|
|
|
|
/**
|
|
Invalidates the iterator. Call this function if you early abort from
|
|
an iteration loop (such as before it hits the end).
|
|
**/
|
|
LUAPLUS_INLINE void LuaStackTableIterator::Invalidate() {
|
|
// See if the iterator is already invalid.
|
|
if (!IsValid())
|
|
return;
|
|
|
|
// This is a local helper variable so we don't waste space in the class
|
|
// definition.
|
|
if (!autoStackManagement) {
|
|
luaplus_assert(lua_gettop(L) <= startStackIndex + 1);
|
|
}
|
|
|
|
// Set the stack back.
|
|
lua_settop(L, startStackIndex);
|
|
|
|
// Invalidate the iterator.
|
|
startStackIndex = -1;
|
|
}
|
|
|
|
/**
|
|
Go to the next entry in the table.
|
|
|
|
\return Returns true if the iteration is done.
|
|
**/
|
|
LUAPLUS_INLINE bool LuaStackTableIterator::Next() {
|
|
// This function is only active if Reset() has been called head.
|
|
luaplus_assert(IsValid());
|
|
|
|
// Do any stack management operations.
|
|
if (autoStackManagement) {
|
|
lua_settop(L, startStackIndex + 1);
|
|
} else {
|
|
// If this luaplus_assert fires, then you left something on the stack.
|
|
luaplus_assert(lua_gettop(L) == startStackIndex + 1);
|
|
}
|
|
|
|
// Do the Lua table iteration.
|
|
if (lua_next(L, stackIndex) == 0 ) {
|
|
// Invalidate the iterator.
|
|
startStackIndex = -1;
|
|
return false;
|
|
}
|
|
|
|
// The iterator is still valid.
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
\return Returns true if the iterator is valid (there is a current element).
|
|
**/
|
|
LUAPLUS_INLINE bool LuaStackTableIterator::IsValid() const {
|
|
return startStackIndex != -1;
|
|
}
|
|
|
|
|
|
/**
|
|
We can easily allow a prefix operator++. Postfix would be a stack
|
|
management nightmare.
|
|
**/
|
|
LUAPLUS_INLINE LuaStackTableIterator& LuaStackTableIterator::operator++() {
|
|
Next();
|
|
return *this;
|
|
}
|
|
|
|
|
|
/**
|
|
\return Returns true if the iterator is valid (there is a current element).
|
|
**/
|
|
LUAPLUS_INLINE LuaStackTableIterator::operator bool() const {
|
|
// If the iterator is valid, then we're good.
|
|
return IsValid();
|
|
}
|
|
|
|
|
|
/**
|
|
\return Returns a LuaStackObject describing the current key.
|
|
**/
|
|
LUAPLUS_INLINE LuaStackObject LuaStackTableIterator::GetKey() {
|
|
// This function is only active if Reset() has been called head.
|
|
luaplus_assert(IsValid());
|
|
|
|
return LuaStackObject(L, startStackIndex + 1);
|
|
}
|
|
|
|
|
|
/**
|
|
\return Returns a LuaStackObject describing the current value.
|
|
**/
|
|
LUAPLUS_INLINE LuaStackObject LuaStackTableIterator::GetValue() {
|
|
// This function is only active if Reset() has been called head.
|
|
luaplus_assert( IsValid() );
|
|
|
|
return LuaStackObject(L, startStackIndex + 2);
|
|
}
|
|
|
|
|
|
} // namespace LuaPlus
|
|
|
|
#endif // LUAPLUS__LUASTACKTABLEITERATOR_INL
|