/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2008-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. 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 headerfile_winix_core_ugcontainer #define headerfile_winix_core_ugcontainer #include #include #include "winixbase.h" namespace Winix { template class UGContainer : public WinixBase { public: UGContainer(); ~UGContainer(); typedef typename std::list Table; typedef typename Table::iterator Iterator; typedef typename Table::size_type SizeType; typedef typename std::map TableId; typedef typename std::map TableName; Iterator Begin(); Iterator End(); SizeType Size(); bool Empty(); Iterator PushBack(const Type & type, const std::wstring & name); // 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); bool Remove(long id); // main table Table table; private: // don't copy these objects UGContainer(const UGContainer &); UGContainer & operator=(const UGContainer &); void AddIndexes(Iterator iter, const std::wstring & name); void RebuildIndexes(); // table.size() has O(n) complexity size_t table_size; // indexes TableId table_id; TableName table_name; }; template UGContainer::~UGContainer() { Clear(); } template UGContainer::UGContainer() { Clear(); } // is private template UGContainer::UGContainer(const UGContainer &) { Clear(); } // is private template UGContainer & UGContainer::operator=(const UGContainer &) { Clear(); return *this; } 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, const std::wstring & name) { if( Is(type.id) || Is(name) ) return End(); table.push_back(type); table_size += 1; Iterator i = --table.end(); log << log3 << "UGCont: added, id: " << type.id << ", name: " << name << logend; AddIndexes(i, name); return i; } template void UGContainer::Clear() { table_size = 0; table.clear(); table_id.clear(); table_name.clear(); } template 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 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 i->second; } template void UGContainer::AddIndexes(UGContainer::Iterator iter, const std::wstring & name) { table_id.insert( std::make_pair(iter->id, iter) ); table_name.insert( std::make_pair(name, iter) ); log << log4 << "UGCont: added indexes to: id: " << iter->id << ", name: " << name << logend; } template void UGContainer::RebuildIndexes() { Iterator i; log << log4 << "UGCont: rebuilding indexes" << logend; table_id.clear(); table_name.clear(); for(i=table.begin() ; i!=table.end() ; ++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 bool UGContainer::Remove(long id) { typename TableId::iterator i = table_id.find(id); typename TableName::iterator n; bool result = false; if( i != table_id.end() ) { for(n=table_name.begin() ; n != table_name.end() ; ++n) { if( n->second == i->second ) { log << log4 << "UGCont: removed index_name to: id: " << i->second->id << ", name: " << n->first << logend; table_name.erase(n); break; } } log << log4 << "UGCont: removed index_id to: id: " << i->second->id << logend; log << log3 << "UGCont: removed: id: " << i->second->id << logend; table.erase(i->second); table_id.erase(i); result = true; } return result; } } // namespace Winix #endif