File: hashMap.h

package info (click to toggle)
ball 1.5.0%2Bgit20180813.37fc53c-11.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 239,928 kB
  • sloc: cpp: 326,149; ansic: 4,208; python: 2,303; yacc: 1,778; lex: 1,099; xml: 958; sh: 322; javascript: 164; makefile: 88
file content (172 lines) | stat: -rw-r--r-- 4,241 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#ifndef BALL_DATATYPE_HASHMAP_H
#define BALL_DATATYPE_HASHMAP_H

#ifndef BALL_COMMON_EXCEPTION_H
# include <BALL/COMMON/exception.h>
#endif

#ifndef BALL_DATATYPE_STRING_H
# include <BALL/DATATYPE/string.h>
#endif

#ifndef BALL_DATATYPE_TRIPLE_H
# include <BALL/DATATYPE/triple.h>
#endif

#ifndef BALL_DATATYPE_QUADRUPLE_H
# include <BALL/DATATYPE/quadruple.h>
#endif

#include <boost/unordered_map.hpp>
#include <boost/functional/hash.hpp>

namespace boost
{
	template<>
	struct hash<BALL::String>
	{
		size_t operator () (const BALL::String& s) const { return boost::hash<std::string>()(s); }
	};

	template <typename T1, typename T2, typename T3>
	struct hash<BALL::Triple<T1, T2, T3> >
	{
		size_t operator () (const BALL::Triple<T1, T2, T3>& s) const
		{
			size_t hash = 0;
			boost::hash_combine(hash, s.first);
			boost::hash_combine(hash, s.second);
			boost::hash_combine(hash, s.third);

			return hash;
		}
	};

	template <typename T1, typename T2, typename T3, typename T4>
	struct hash<BALL::Quadruple<T1, T2, T3, T4> >
	{
		size_t operator () (const BALL::Quadruple<T1, T2, T3, T4>& s) const
		{
			size_t hash = 0;
			boost::hash_combine(hash, s.first);
			boost::hash_combine(hash, s.second);
			boost::hash_combine(hash, s.third);
			boost::hash_combine(hash, s.fourth);

			return hash;
		}
	};
}

namespace BALL
{
	/**
		@brief HashMap class based on the STL map (containing serveral convenience functions)

		@ingroup Datastructures
	*/
	template <class Key, class T>
	class HashMap : public boost::unordered_map<Key, T>
	{
		public:

			/**
			 * @brief HashMap illegal key exception
			 * 
			 * @ingroup Exceptions
			 */
			class IllegalKey : public Exception::GeneralException
			{
				public:
					IllegalKey(const char* file, int line)
						: Exception::GeneralException(file, line)
					{
					}
			};
			
			///@name OpenMS style typedefs
			//@{
			typedef boost::unordered_map<Key, T> Base;
			typedef typename Base::value_type ValueType;
			typedef Key KeyType;
			typedef typename Base::value_type* PointerType;
			typedef typename Base::iterator Iterator;
			typedef typename Base::const_iterator ConstIterator;
			//@}

			///Test whether the map contains the given key.
			inline bool has(const Key& key) const
			{
				return Base::find(key) != Base::end();
			}

			/**
			 * @brief Return a constant reference to the element whose key is @p key.
			 *
			 * @exception IllegalKey if the given key does not exist
			*/
			const T& operator [] (const Key& key) const;

			/// Return a mutable reference to the element whose key is @p key. If an element with the key @p key does not exist, it is inserted.
			T& operator [] (const Key& key);

			/// Equality operator. Check whether two two hashmaps contain the same elements. O(n) runtime.
			bool operator == (const HashMap<Key, T>& rhs) const;
			
			/// Return the size of the hash map.
			/// TODO: Remove this. This narrows the precision of size_t! (But of course breaks persistence...)
			Size size() const { return Base::size(); }
	};
	
	//******************************************************************************************
	// Implementations of template methods
	//******************************************************************************************
	
	template <class Key, class T>
	const T& HashMap<Key, T>::operator [] (const Key& key) const
	{
		ConstIterator it = this->find(key);
		if (it == Base::end())
		{
			throw IllegalKey(__FILE__, __LINE__);
		}
		else
		{
			return it->second;
		}
	}

	template <class Key, class T>
	bool HashMap<Key, T>::operator == (const HashMap<Key, T>& rhs) const
	{
		// No equality if sizes differ.
		if (Base::size() != rhs.size()) 
		{
			return false;	
		}

		// Equality if bothe have the same size and every element of lhs is 
		// is contained in lhs. Testing the other way round is obviously
		// unnecessary.
		ConstIterator it(Base::begin());
		for (; it != Base::end(); ++it)
		{
			if (!rhs.has(it->first)) return false;
		}

		return true;
	}
	
	template <class Key, class T>
	T& HashMap<Key, T>::operator [] (const Key& key)
	{
		return Base::operator[] (key);
	}

} // namespace BALL

#endif // BALL_DATATYPE_HASHMAP_H