
The changes come from the `functions` branch, where I'm using these structures a lot. This also includes a new `BLI::Optional<T>` type, which is similar to `std::Optional<T>` which can be used when Blender starts using C++17.
151 lines
2.9 KiB
C++
151 lines
2.9 KiB
C++
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef __BLI_STACK_CXX_H__
|
|
#define __BLI_STACK_CXX_H__
|
|
|
|
/** \file
|
|
* \ingroup bli
|
|
*
|
|
* Basic stack implementation with support for small object optimization.
|
|
*/
|
|
|
|
#include "BLI_vector.h"
|
|
|
|
namespace BLI {
|
|
|
|
template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Stack {
|
|
private:
|
|
Vector<T, N, Allocator> m_elements;
|
|
|
|
public:
|
|
Stack() = default;
|
|
|
|
/**
|
|
* Construct a stack from an array ref. The elements will be pushed in the same order they are in
|
|
* the array.
|
|
*/
|
|
Stack(ArrayRef<T> values) : m_elements(values)
|
|
{
|
|
}
|
|
|
|
operator ArrayRef<T>()
|
|
{
|
|
return m_elements;
|
|
}
|
|
|
|
/**
|
|
* Return the number of elements in the stack.
|
|
*/
|
|
uint size() const
|
|
{
|
|
return m_elements.size();
|
|
}
|
|
|
|
/**
|
|
* Return true when the stack is empty, otherwise false.
|
|
*/
|
|
bool is_empty() const
|
|
{
|
|
return this->size() == 0;
|
|
}
|
|
|
|
/**
|
|
* Add a new element to the top of the stack.
|
|
*/
|
|
void push(const T &value)
|
|
{
|
|
m_elements.append(value);
|
|
}
|
|
|
|
void push(T &&value)
|
|
{
|
|
m_elements.append(std::move(value));
|
|
}
|
|
|
|
void push_multiple(ArrayRef<T> values)
|
|
{
|
|
m_elements.extend(values);
|
|
}
|
|
|
|
/**
|
|
* Remove the element from the top of the stack and return it.
|
|
* This will assert when the stack is empty.
|
|
*/
|
|
T pop()
|
|
{
|
|
return m_elements.pop_last();
|
|
}
|
|
|
|
/**
|
|
* Return a reference to the value a the top of the stack.
|
|
* This will assert when the stack is empty.
|
|
*/
|
|
T &peek()
|
|
{
|
|
BLI_assert(!this->is_empty());
|
|
return m_elements[this->size() - 1];
|
|
}
|
|
|
|
T *begin()
|
|
{
|
|
return m_elements.begin();
|
|
}
|
|
|
|
T *end()
|
|
{
|
|
return m_elements.end();
|
|
}
|
|
|
|
const T *begin() const
|
|
{
|
|
return m_elements.begin();
|
|
}
|
|
|
|
const T *end() const
|
|
{
|
|
return m_elements.end();
|
|
}
|
|
|
|
/**
|
|
* Remove all elements from the stack but keep the memory.
|
|
*/
|
|
void clear()
|
|
{
|
|
m_elements.clear();
|
|
}
|
|
|
|
/**
|
|
* Remove all elements and free any allocated memory.
|
|
*/
|
|
void clear_and_make_small()
|
|
{
|
|
m_elements.clear_and_make_small();
|
|
}
|
|
|
|
/**
|
|
* Does a linear search to check if the value is in the stack.
|
|
*/
|
|
bool contains(const T &value)
|
|
{
|
|
return m_elements.contains(value);
|
|
}
|
|
};
|
|
|
|
} /* namespace BLI */
|
|
|
|
#endif /* __BLI_STACK_CXX_H__ */
|