4coder-non-source/test_data/lots_of_files/gjLookup.h

254 lines
7.3 KiB
C++

///////////////////////////////////////////////////////////////////
//*-------------------------------------------------------------*//
//| Part of the Game Jolt API C++ Library (http://gamejolt.com) |//
//*-------------------------------------------------------------*//
//| Released under the zlib License |//
//| More information available in the readme file |//
//*-------------------------------------------------------------*//
///////////////////////////////////////////////////////////////////
#pragma once
#ifndef _GJ_GUARD_LOOKUP_H_
#define _GJ_GUARD_LOOKUP_H_
typedef unsigned int gjUint;
#ifndef ASSERT
#define ASSERT(x)
#endif
// ****************************************************************
// lookup container class
template <typename T> class gjLookup final
{
public:
//! internal types
typedef std::pair<std::string, T> gjEntry;
typedef std::vector<gjEntry> gjList;
typedef typename gjList::iterator gjIterator;
typedef typename gjList::const_iterator gjConstIterator;
private:
gjList m_aList; //!< vector-list with pair-values
public:
gjLookup()noexcept;
gjLookup(const gjLookup<T>& c)noexcept;
gjLookup(gjLookup<T>&& m)noexcept;
~gjLookup();
//! assignment operator
//! @{
gjLookup<T>& operator = (gjLookup<T> o)noexcept;
template <typename S> friend void swap(gjLookup<S>& a, gjLookup<S>& b)noexcept;
//! @}
//! access specific entry
//! @{
const T& at(const char* pcKey)const noexcept;
T& operator [] (const char* pcKey)noexcept;
inline T& operator [] (const gjUint& iIndex)noexcept {return m_aList[iIndex].second;}
//! @}
//! check number of existing entries
//! @{
inline gjUint count(const char* pcKey)const noexcept {return this->__check(this->__retrieve(pcKey)) ? 1 : 0;}
inline gjUint size()const noexcept {return m_aList.size();}
inline bool empty()const noexcept {return m_aList.empty();}
//! @}
//! control memory consumption
//! @{
inline void reserve(const gjUint& iReserve)noexcept {m_aList.reserve(iReserve);}
inline gjUint capacity()const noexcept {return m_aList.capacity();}
//! @}
//! remove existing entries
//! @{
void erase(const T& Entry)noexcept;
void erase(const char* pcKey)noexcept;
inline void erase(const gjUint& iIndex)noexcept {ASSERT(iIndex < m_aList.size()) m_aList.erase(m_aList.begin()+iIndex);}
inline void erase(const gjConstIterator& Iterator)noexcept {m_aList.erase(Iterator);}
inline void clear()noexcept {m_aList.clear();}
//! @}
//! retrieve internal iterator
//! @{
inline gjIterator begin()noexcept {return m_aList.begin();}
inline gjConstIterator begin()const noexcept {return m_aList.begin();}
inline gjIterator end()noexcept {return m_aList.end();}
inline gjConstIterator end()const noexcept {return m_aList.end();}
//! @}
private:
//! retrieve iterator
//! @{
gjIterator __retrieve(const T& Entry)noexcept;
gjConstIterator __retrieve(const T& Entry)const noexcept;
gjIterator __retrieve(const char* pcKey)noexcept;
gjConstIterator __retrieve(const char* pcKey)const noexcept;
//! @}
//! check for valid iterator
//! @{
inline bool __check(const gjIterator& it)const noexcept {return (it != m_aList.end()) ? true : false;}
inline bool __check(const gjConstIterator& it)const noexcept {return (it != m_aList.end()) ? true : false;}
//! @}
};
// ****************************************************************
// constructor
template <typename T> gjLookup<T>::gjLookup()noexcept
{
// reserve variable sized memory
constexpr_var gjUint iSize = 1 + 64/sizeof(T);
m_aList.reserve(iSize);
}
template <typename T> gjLookup<T>::gjLookup(const gjLookup<T>& c)noexcept
: m_aList (c.m_aList)
{
}
template <typename T> gjLookup<T>::gjLookup(gjLookup<T>&& m)noexcept
: m_aList (std::move(m.m_aList))
{
}
// ****************************************************************
// destructor
template <typename T> gjLookup<T>::~gjLookup()
{
m_aList.clear();
}
// ****************************************************************
// assignment operator
template <typename T> gjLookup<T>& gjLookup<T>::operator = (gjLookup<T> o)noexcept
{
swap(*this, o);
return *this;
}
template <typename S> void swap(gjLookup<S>& a, gjLookup<S>& b)noexcept
{
using std::swap;
swap(a.m_aList, b.m_aList);
}
// ****************************************************************
// access specific entry
template <typename T> const T& gjLookup<T>::at(const char* pcKey)const noexcept
{
// retrieve and check iterator by specific key
auto it = this->__retrieve(pcKey);
ASSERT(this->__check(it))
return it->second;
}
// ****************************************************************
// access specific entry and create it if necessary
template <typename T> T& gjLookup<T>::operator [] (const char* pcKey)noexcept
{
// retrieve and check iterator by specific key
auto it = this->__retrieve(pcKey);
if(!this->__check(it))
{
// create new entry
m_aList.push_back(gjEntry(pcKey, T()));
it = m_aList.end()-1;
}
return it->second;
}
// ****************************************************************
// remove existing entry
template <typename T> void gjLookup<T>::erase(const T& Entry)noexcept
{
// retrieve and check iterator by specific value
auto it = this->__retrieve(Entry);
if(this->__check(it))
{
// remove existing entry
m_aList.erase(it);
}
}
template <typename T> void gjLookup<T>::erase(const char* pcKey)noexcept
{
// retrieve and check iterator by specific key
auto it = this->__retrieve(pcKey);
if(this->__check(it))
{
// remove existing entry
m_aList.erase(it);
}
}
// ****************************************************************
// retrieve iterator by specific value
template <typename T> typename gjLookup<T>::gjIterator gjLookup<T>::__retrieve(const T& Entry)noexcept
{
// loop through all entries
FOR_EACH(it, m_aList)
{
// compare values
if(it->second == Entry)
return it;
}
return m_aList.end();
}
template <typename T> typename gjLookup<T>::gjConstIterator gjLookup<T>::__retrieve(const T& Entry)const noexcept
{
// loop through all entries
FOR_EACH(it, m_aList)
{
// compare values
if(it->second == Entry)
return it;
}
return m_aList.end();
}
// ****************************************************************
// retrieve iterator by specific key
template <typename T> typename gjLookup<T>::gjIterator gjLookup<T>::__retrieve(const char* pcKey)noexcept
{
// loop through all entries
FOR_EACH(it, m_aList)
{
// compare string-keys
if(!std::strcmp(it->first.c_str(), pcKey))
return it;
}
return m_aList.end();
}
template <typename T> typename gjLookup<T>::gjConstIterator gjLookup<T>::__retrieve(const char* pcKey)const noexcept
{
// loop through all entries
FOR_EACH(it, m_aList)
{
// compare string-keys
if(!std::strcmp(it->first.c_str(), pcKey))
return it;
}
return m_aList.end();
}
#endif /* _GJ_GUARD_LOOKUP_H_ */