#include <iostream>
#include <algorithm> //For std::swap
#include <memory> //For std::unique_ptr
#include <vector>
//std::make_unique implementation (it was forgotten in the C++11 standard, and will be added later).
//Once it's added, I can just remove this from here.
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}
//Swaps and pops every element in 'container', for which the callback function 'predicate(element)' returns false.
//This is faster than std::remove_if(), but does not preserve the order of the elements like 'remove_if()' does.
template<typename ContainerType, typename FunctionType>
void SwapAndPop(ContainerType &container, FunctionType predicate)
{
for(typename ContainerType::iterator it = container.begin(); it != container.end();)
{
if(predicate(*it))
{
//Swap the value of the current element with the element at the back of the container.
std::swap(*it, container.back());
//Pop the back of the container.
container.pop_back();
if(container.empty())
{
break;
}
}
else
{
++it;
}
}
}
class Object
{
static unsigned nextID;
public:
Object() : timeToDelete(++nextID % 3), id(nextID) { }
bool timeToDelete = false;
size_t id = 0;
public:
typedef std::unique_ptr<Object> uPtr;
};
unsigned Object::nextID = 0;
int main()
{
const size_t NumObjectsForTest = 40;
std::vector<Object::uPtr> objects;
//Create all the objects.
for(size_t i = 0; i < NumObjectsForTest; ++i)
{
objects.push_back(make_unique<Object>());
}
//Print all the objects.
for(const auto &object : objects)
{
std::cout << "Object " << object->id << ": " << (object->timeToDelete? "[Time to delete]":"[Still alive]") << std::endl;
}
std::cout << "------------------------------------\n"
<< "Calling SwapAndPop...\n"
<< "------------------------------------\n";
SwapAndPop(objects, [](Object::uPtr &objectPtr) -> bool { return objectPtr->timeToDelete; });
//Print all the objects again.
for(const auto &object : objects)
{
std::cout << "Object " << object->id << ": " << (object->timeToDelete? "[Time to delete]":"[Still alive]") << std::endl;
}
return 0;
}