/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2010, Tomasz Sowa * All rights reserved. * */ #ifndef headerfile_winix_core_ugcontainer #define headerfile_winix_core_ugcontainer #include #include #include #include #include "log.h" template class UGContainer { public: ~UGContainer(); // we have to use a pointer (Type*) here // because we are remembering some pointers to the items elsewhere // so the pointers should not be invalidated typedef typename std::vector Table; typedef typename Table::iterator Iterator; typedef typename Table::size_type SizeType; typedef typename std::map TableId; typedef typename std::map TableName; UGContainer(); Iterator Begin(); Iterator End(); SizeType Size(); bool Empty(); Iterator PushBack(const Type & type); // can return End() if the user already exists void Clear(); bool Is(long id); bool Is(const std::wstring & name); Iterator FindId(long id); Iterator FindName(const std::wstring & name); Type & operator[](SizeType pos); private: void AddIndexes(SizeType pos); void RebuildIndexes(); // main table Table table; // indexes TableId table_id; TableName table_name; }; template UGContainer::~UGContainer() { Clear(); } template UGContainer::UGContainer() { } template typename UGContainer::Iterator UGContainer::Begin() { return table.begin(); } template typename UGContainer::Iterator UGContainer::End() { return table.end(); } template typename UGContainer::SizeType UGContainer::Size() { return table.size(); } template bool UGContainer::Empty() { return table.empty(); } template typename UGContainer::Iterator UGContainer::PushBack(const Type & type) { if( Is(type.id) || Is(type.name) ) return End(); table.push_back(new Type(type)); log << log2 << "UGCont: added, id: " << type.id << ", name: " << type.name << logend; AddIndexes( table.size() - 1 ); return --table.end(); } template void UGContainer::Clear() { for(size_t i=0 ; i bool UGContainer::Is(long id) { typename TableId::iterator i = table_id.find(id); if( i == table_id.end() ) return false; return true; } template bool UGContainer::Is(const std::wstring & name) { typename TableName::iterator i = table_name.find(name); if( i == table_name.end() ) return false; return true; } template typename UGContainer::Iterator UGContainer::FindId(long id) { typename TableId::iterator i = table_id.find(id); if( i == table_id.end() ) return table.end(); return table.begin() + i->second; } template typename UGContainer::Iterator UGContainer::FindName(const std::wstring & name) { typename TableName::iterator i = table_name.find(name); if( i == table_name.end() ) return table.end(); return table.begin() + i->second; } template void UGContainer::AddIndexes(UGContainer::SizeType pos) { table_id.insert( std::make_pair(table[pos]->id, pos) ); table_name.insert( std::make_pair(table[pos]->name, pos) ); log << log4 << "UGCont: added indexes to: id: " << table[pos]->id << ", name: " << table[pos]->name << logend; } template void UGContainer::RebuildIndexes() { log << log4 << "UGCont: rebuilding indexes" << logend; table_id.clear(); table_name.clear(); SizeType i, len = table.size(); for(i=0 ; i!=len ; ++i) AddIndexes( i ); log << log4 << "UGCont: indexes rebuilt, table.size: " << table.size() << ", table_id.size: " << table_id.size() << ", table_name.size: " << table_name.size() << logend; } template Type & UGContainer::operator[](UGContainer::SizeType pos) { if( pos >= table.size() ) throw std::out_of_range("UGContainer: operator[]: index is out of range"); return *table[pos]; } #endif