mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-11-04 04:09:57 +01:00 
			
		
		
		
	fix: remove executable flag and change back to 100644 (was 100755) Signed-off-by: Roger Meier <r.meier@siemens.com>
		
			
				
	
	
		
			260 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			260 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//
 | 
						|
// ListMap.h
 | 
						|
//
 | 
						|
// $Id: //poco/1.4/Foundation/include/Poco/ListMap.h#1 $
 | 
						|
//
 | 
						|
// Library: Foundation
 | 
						|
// Package: Hashing
 | 
						|
// Module:  ListMap
 | 
						|
//
 | 
						|
// Definition of the ListMap class.
 | 
						|
//
 | 
						|
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
 | 
						|
// and Contributors.
 | 
						|
//
 | 
						|
// SPDX-License-Identifier:	BSL-1.0
 | 
						|
//
 | 
						|
 | 
						|
 | 
						|
#ifndef Foundation_ListMap_INCLUDED
 | 
						|
#define Foundation_ListMap_INCLUDED
 | 
						|
 | 
						|
 | 
						|
#include "Poco/Foundation.h"
 | 
						|
#include "Poco/String.h"
 | 
						|
#include "Poco/Exception.h"
 | 
						|
#include <list>
 | 
						|
#include <utility>
 | 
						|
 | 
						|
 | 
						|
namespace Poco {
 | 
						|
 | 
						|
 | 
						|
template <class Key, class Mapped, class Container = std::list<std::pair<Key, Mapped> >, bool CaseSensitive = false >
 | 
						|
class ListMap
 | 
						|
	/// This class implements a multimap in terms of a sequential container.
 | 
						|
	/// The use for this type of associative container is wherever automatic
 | 
						|
	/// ordering of elements is not desirable. Naturally, this container will
 | 
						|
	/// have inferior data retrieval performance and it is not recommended for
 | 
						|
	/// use with large datasets. The main purpose within POCO is for Internet
 | 
						|
	/// messages (email message, http headers etc), to prevent autmomatic 
 | 
						|
	/// header entry reordering.
 | 
						|
{
 | 
						|
public:
 | 
						|
	typedef Key                 KeyType;
 | 
						|
	typedef Mapped              MappedType;
 | 
						|
	typedef Mapped&             Reference;
 | 
						|
	typedef const Mapped&       ConstReference;
 | 
						|
	typedef Mapped*             Pointer;
 | 
						|
	typedef const Mapped*       ConstPointer;
 | 
						|
	
 | 
						|
	typedef typename Container::value_type     ValueType;
 | 
						|
	typedef typename Container::size_type      SizeType;
 | 
						|
	typedef typename Container::iterator       Iterator;
 | 
						|
	typedef typename Container::const_iterator ConstIterator;
 | 
						|
	
 | 
						|
	ListMap()
 | 
						|
		/// Creates an empty ListMap.
 | 
						|
	{
 | 
						|
	}
 | 
						|
	
 | 
						|
	ListMap(std::size_t initialReserve):
 | 
						|
		_list(initialReserve)
 | 
						|
		/// Creates the ListMap with room for initialReserve entries.
 | 
						|
	{
 | 
						|
	}
 | 
						|
	
 | 
						|
	ListMap& operator = (const ListMap& map)
 | 
						|
		/// Assigns another ListMap.
 | 
						|
	{
 | 
						|
		ListMap tmp(map);
 | 
						|
		swap(tmp);
 | 
						|
		return *this;
 | 
						|
	}
 | 
						|
	
 | 
						|
	void swap(ListMap& map)
 | 
						|
		/// Swaps the ListMap with another one.
 | 
						|
	{
 | 
						|
		_list.swap(map._list);
 | 
						|
	}
 | 
						|
	
 | 
						|
	ConstIterator begin() const
 | 
						|
		/// Returns the beginning of the map.
 | 
						|
	{
 | 
						|
		return _list.begin();
 | 
						|
	}
 | 
						|
	
 | 
						|
	ConstIterator end() const
 | 
						|
		/// Returns the end of the map.
 | 
						|
	{
 | 
						|
		return _list.end();
 | 
						|
	}
 | 
						|
	
 | 
						|
	Iterator begin()
 | 
						|
		/// Returns the beginning of the map.
 | 
						|
	{
 | 
						|
		return _list.begin();
 | 
						|
	}
 | 
						|
	
 | 
						|
	Iterator end()
 | 
						|
		/// Returns the end of the map.
 | 
						|
	{
 | 
						|
		return _list.end();
 | 
						|
	}
 | 
						|
	
 | 
						|
	ConstIterator find(const KeyType& key) const
 | 
						|
		/// Finds the first occurence of the key and
 | 
						|
		/// returns iterator pointing to the found entry
 | 
						|
		/// or iterator pointing to the end if entry is
 | 
						|
		/// not found.
 | 
						|
	{
 | 
						|
		typename Container::const_iterator it = _list.begin();
 | 
						|
		typename Container::const_iterator end = _list.end();
 | 
						|
		for(; it != end; ++it)
 | 
						|
		{
 | 
						|
			if (isEqual(it->first, key)) return it;
 | 
						|
		}
 | 
						|
		return end;
 | 
						|
	}
 | 
						|
 | 
						|
	Iterator find(const KeyType& key)
 | 
						|
		/// Finds the first occurence of the key and
 | 
						|
		/// returns iterator pointing to the found entry
 | 
						|
		/// or iterator pointing to the end if entry is
 | 
						|
		/// not found.
 | 
						|
	{
 | 
						|
		typename Container::iterator it = _list.begin();
 | 
						|
		typename Container::iterator end = _list.end();
 | 
						|
		for(; it != end; ++it)
 | 
						|
		{
 | 
						|
			if (isEqual(it->first, key)) return it;
 | 
						|
		}
 | 
						|
		return end;
 | 
						|
	}
 | 
						|
 | 
						|
	Iterator insert(const ValueType& val)
 | 
						|
		/// Inserts the value into the map. If one or more values 
 | 
						|
		/// already exist, new value is inserted at the end of the 
 | 
						|
		/// block. Thus, all the equal value entries are located
 | 
						|
		/// sequentially at all times.
 | 
						|
		/// Returns iterator pointing to the newly inserted value 
 | 
						|
	{
 | 
						|
		Iterator it = find(val.first);
 | 
						|
 | 
						|
		if (it == _list.end())
 | 
						|
		{
 | 
						|
			_list.push_back(val);
 | 
						|
			it = _list.end();
 | 
						|
			--it;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			_list.insert(it, 1, val);
 | 
						|
		}
 | 
						|
 | 
						|
		return it;
 | 
						|
	}
 | 
						|
	
 | 
						|
	void erase(Iterator it)
 | 
						|
	{
 | 
						|
		_list.erase(it);
 | 
						|
	}
 | 
						|
	
 | 
						|
	SizeType erase(const KeyType& key)
 | 
						|
	{
 | 
						|
		SizeType count = 0;
 | 
						|
		Iterator it = find(key);
 | 
						|
		bool removed = false;
 | 
						|
		while (it != _list.end())
 | 
						|
		{
 | 
						|
			if (isEqual(it->first, key))
 | 
						|
			{
 | 
						|
				++count;
 | 
						|
				it = _list.erase(it);
 | 
						|
				removed = true;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				if (removed) return count;
 | 
						|
				++it;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		return count;
 | 
						|
	}
 | 
						|
	
 | 
						|
	void clear()
 | 
						|
	{
 | 
						|
		_list.clear();
 | 
						|
	}
 | 
						|
 | 
						|
	std::size_t size() const
 | 
						|
	{
 | 
						|
		return _list.size();
 | 
						|
	}
 | 
						|
 | 
						|
	bool empty() const
 | 
						|
	{
 | 
						|
		return _list.empty();
 | 
						|
	}
 | 
						|
 | 
						|
	ConstReference operator [] (const KeyType& key) const
 | 
						|
	{
 | 
						|
		ConstIterator it = find(key);
 | 
						|
		if (it != _list.end())
 | 
						|
			return it->second;
 | 
						|
		else
 | 
						|
			throw NotFoundException();
 | 
						|
	}
 | 
						|
 | 
						|
	Reference operator [] (const KeyType& key)
 | 
						|
	{
 | 
						|
		Iterator it = find(key);
 | 
						|
		if (it != _list.end())
 | 
						|
			return it->second;
 | 
						|
		else
 | 
						|
		{
 | 
						|
			ValueType value(key, Mapped());
 | 
						|
			Iterator it = insert(value);
 | 
						|
			return it->second;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
private:
 | 
						|
	template <typename T1, typename T2>
 | 
						|
	bool isEqual(T1 val1, T2 val2) const
 | 
						|
	{
 | 
						|
		return val1 == val2;
 | 
						|
	}
 | 
						|
 | 
						|
	bool isEqual(const std::string& s1, const std::string& s2) const
 | 
						|
	{
 | 
						|
		if (!CaseSensitive)
 | 
						|
			return Poco::icompare(s1, s2) == 0;
 | 
						|
		else
 | 
						|
			return s1 == s2;
 | 
						|
	}
 | 
						|
 | 
						|
	bool isEqual(const std::string& s1, const char* s2) const
 | 
						|
	{
 | 
						|
		return isEqual(s1, std::string(s2));
 | 
						|
	}
 | 
						|
 | 
						|
	bool isEqual(const char* s1, const std::string& s2) const
 | 
						|
	{
 | 
						|
		return isEqual(std::string(s1), s2);
 | 
						|
	}
 | 
						|
 | 
						|
	bool isEqual(const char* s1, const char* s2) const
 | 
						|
	{
 | 
						|
		return isEqual(std::string(s1), std::string(s2));
 | 
						|
	}
 | 
						|
 | 
						|
	Container _list;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
} // namespace Poco
 | 
						|
 | 
						|
 | 
						|
#endif // Foundation_ListMap_INCLUDED
 |