175 lines
6.2 KiB
C++
Raw Normal View History

2024-03-19 17:45:12 +08:00
/**************************************************************************************/
/* */
/* Visualization Library */
/* http://visualizationlibrary.org */
/* */
/* Copyright (c) 2005-2020, Michele Bosi */
/* All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without modification, */
/* are permitted provided that the following conditions are met: */
/* */
/* - Redistributions of source code must retain the above copyright notice, this */
/* list of conditions and the following disclaimer. */
/* */
/* - Redistributions in binary form must reproduce the above copyright notice, this */
/* list of conditions and the following disclaimer in the documentation and/or */
/* other materials provided with the distribution. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/**************************************************************************************/
#ifndef Collection_INCLUDE_ONCE
#define Collection_INCLUDE_ONCE
#include <vlCore/Object.hpp>
#include <vector>
#include <algorithm>
namespace vl
{
//------------------------------------------------------------------------------
// Collection
//------------------------------------------------------------------------------
/** It's basically an std::vector for Objects that is itself an Object so it can be reference
* counted and passed around with ease. It has also handy utility functions like sort(), find(), etc.
* Handy alternative to std::vector< ref< Object > > which becomes Collection<Object>.
*/
template <typename T>
class Collection: public Object
{
VL_INSTRUMENT_CLASS(vl::Collection<T>, Object)
public:
Collection(const std::vector< ref<T> >& vector)
{
VL_DEBUG_SET_OBJECT_NAME()
mVector = vector;
}
Collection()
{
VL_DEBUG_SET_OBJECT_NAME()
}
Collection& operator=(const std::vector< ref<T> >& vector)
{
mVector = vector;
return *this;
}
operator std::vector< ref<T> >() const
{
return mVector;
}
void push_back( T* data ) { mVector.push_back(data); }
void pop_back() { mVector.pop_back(); }
void resize(int size) { mVector.resize(size); }
int size() const { return (int)mVector.size(); }
bool empty() const { return mVector.empty(); }
void clear() { mVector.clear(); }
const T* back() const { return mVector.back().get(); }
T* back() { return mVector.back().get(); }
void reserve(int capacity) { mVector.reserve(capacity); }
int capacity() const { return (int)mVector.capacity(); }
const ref<T>& operator[](int i) const { return mVector[i]; }
ref<T>& operator[](int i) { return mVector[i]; }
const T* at(int i) const { return mVector[i].get(); }
T* at(int i) { return mVector[i].get(); }
void swap(Collection& other) { mVector.swap(other.mVector); }
// added functionalities
void sort()
{
std::sort(mVector.begin(), mVector.end(), less);
}
int find(T* obj) const
{
typename std::vector< ref<T> >::const_iterator pos = std::find(mVector.begin(), mVector.end(), obj);
if (pos == mVector.end())
return -1;
else
return (int)(pos - mVector.begin());
}
void shrink()
{
Collection<T>(mVector).swap(mVector);
}
void push_back(const Collection<T>& objs )
{
mVector.insert(mVector.end(), objs.mVector.begin(), objs.mVector.end());
}
void insert(int start, const Collection<T>& objs )
{
mVector.insert(mVector.begin()+start, objs.mVector.begin(), objs.mVector.end());
}
void set(const Collection<T>& objs)
{
mVector = objs.mVector;
}
void erase(int start, int count)
{
mVector.erase(mVector.begin()+start, mVector.begin()+start+count);
}
void set(int index, T* obj) { mVector[index] = obj; }
void insert(int index, T* obj) { mVector.insert(mVector.begin() + index, obj); }
void erase(const T* data)
{
typename std::vector< ref<T> >::iterator it = std::find(mVector.begin(), mVector.end(), data);
if (it != mVector.end())
mVector.erase(it);
}
void eraseAt(int index) { mVector.erase(mVector.begin()+index); }
const std::vector< ref<T> >& vector() const { return mVector; }
std::vector< ref<T> >& vector() { return mVector; }
protected:
bool static less(const ref<T>& a, const ref<T>& b) { return *a < *b; }
protected:
std::vector< ref<T> > mVector;
};
//-----------------------------------------------------------------------------
}
#endif