/* * This file is a part of CMSLU -- Content Management System like Unix * and is not publicly distributed * * Copyright (c) 2008, Tomasz Sowa * All rights reserved. * */ #ifndef headerfileugcontainer #define headerfileugcontainer #include #include #include #include "log.h" template class UGContainer { public: 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); void Clear(); Iterator FindId(long id); Iterator FindName(const std::string & 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() // : table(100) { } 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) { table.push_back(type); log << log2 << "UGCont: added, id: " << type.id << ", name: " << type.name << logend; AddIndexes( table.size() - 1 ); return --table.end(); } template void UGContainer::Clear() { table.clear(); table_id.clear(); table_name.clear(); } 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::string & 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 << log2 << "UGCont: added indexes to: id: " << table[pos].id << ", name: " << table[pos].name << logend; } template void UGContainer::RebuildIndexes() { log << log2 << "UGCont: rebuilding indexes" << logend; table_id.clear(); table_name.clear(); SizeType i, len = table.size(); for(i=0 ; i!=len ; ++i) AddIndexes( i ); log << log2 << "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