1/* FILE:		hashmap.cpp
2 *  DATE MODIFIED:	31-Aug-07
3 *  DESCRIPTION:	Helper template for compiling FST data structure
4 *                      from a GRXML file.
5 *			A doubly indexed map class using two maps.
6 *			Indices are a user-defined  type and an int index.
7 *                      Both are unique indices.
8 *			The int index has automatic non-reusable numbering.
9 *
10 *  DESCRIPTION:	Part of the  SREC graph compiler project source files.
11 *
12 *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
13 *                                                                           *
14 *  Licensed under the Apache License, Version 2.0 (the 'License');          *
15 *  you may not use this file except in compliance with the License.         *
16 *                                                                           *
17 *  You may obtain a copy of the License at                                  *
18 *      http://www.apache.org/licenses/LICENSE-2.0                           *
19 *                                                                           *
20 *  Unless required by applicable law or agreed to in writing, software      *
21 *  distributed under the License is distributed on an 'AS IS' BASIS,        *
22 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 *  See the License for the specific language governing permissions and      *
24 *  limitations under the License.                                           *
25 *                                                                           *
26 *---------------------------------------------------------------------------*/
27
28#include <map>
29#include <string>
30#include <iostream>
31#include <fstream>
32
33#include "hashmap.h"
34#include "sub_grph.h"
35using namespace std;
36
37
38template <typename T1, typename T2>
39HashMap<T1,T2>::HashMap():
40m_NextAutoIndex(0)
41{
42}
43
44template <typename T1, typename T2>
45void HashMap<T1,T2>::setName(std::string s)
46{
47  m_Name = s;
48}
49
50template <typename T1, typename T2>
51bool HashMap<T1,T2>::insert( T1 const & index, T2 const & value)
52{
53
54  pair<typename std::map<T1,T2>::iterator,bool> result = m_Map.insert( make_pair(index, value) );
55    if (!result.second) {
56	return false;
57    }
58
59    return true;
60}
61
62template <typename T1, typename T2>
63bool HashMap<T1,T2>::remove( T1 const & index )
64{
65  m_Map.erase( index );
66  return true;
67}
68
69template <typename T1, typename T2>
70bool HashMap<T1,T2>::isEmpty()
71{
72    return m_Map.empty();
73}
74
75
76template <typename T1, typename T2>
77bool HashMap<T1,T2>::clear()
78{
79    m_Map.clear();
80    return true;
81}
82
83
84
85template <typename T1, typename T2>
86bool HashMap<T1,T2>::getIndex( T2 const & value, T1 *index )
87{
88   //do something with all elements having a certain value
89   typename std::map<T1,T2>::iterator pos;
90   for (pos = m_Map.begin(); pos != m_Map.end(); ++pos) {
91      if (pos->second == value) {
92	  *index = (pos->first);
93	  return true;
94      }
95   }
96   return false;
97}
98
99template <typename T1, typename T2>
100bool HashMap<T1,T2>::getFirst( T1 *index, T2 *value )
101{
102    if (m_Map.empty() ) {
103	return false;
104    }
105    //do something with all elements having a certain value
106    typename std::map<T1,T2>::iterator pos;
107    m_pPos= m_Map.begin();
108    *index = m_pPos->first;
109    *value=  m_pPos->second;
110    return true;
111}
112
113template <typename T1, typename T2>
114bool HashMap<T1,T2>::getNext( T1 *index, T2 *value )
115{
116    if ( m_Map.empty() ) {
117	return false;
118    }
119    if ( ++m_pPos == m_Map.end() )  {
120	return false;
121    }
122    *index = m_pPos->first;
123    *value=  m_pPos->second;
124    return true;
125}
126
127template <typename T1, typename T2>
128bool HashMap<T1,T2>::getValue(T1 const & index, T2 *value)
129{
130    typename std::map<T1,T2>::iterator pos;
131    pos = m_Map.find(index);
132    if (m_Map.end() != pos) {
133	*value = pos->second;
134	return true;
135    }
136    return false;
137}
138
139template <typename T1, typename T2>
140int HashMap<T1,T2>::size()
141{
142    return m_Map.size();
143}
144
145template <typename T1, typename T2>
146void HashMap<T1,T2>::print()
147{
148    typename std::map<T1,T2>::iterator pos;
149    cout << "======= '" <<  m_Name <<"' =======" << std::endl;
150    for (pos = m_Map.begin(); pos != m_Map.end(); ++pos) {
151	cout << pos->first <<" : " << pos->second << std::endl;
152   }
153}
154
155template <typename T1, typename T2>
156void HashMap<T1,T2>::writeFile( std::string fileName )
157{
158    ofstream outfile;
159    outfile.open ( fileName.c_str() );
160    typename std::map<T1,T2>::iterator pos;
161    for (pos = m_Map.begin(); pos != m_Map.end(); ++pos) {
162	outfile << pos->first << " " << pos->second << std::endl;
163    }
164    outfile.close();
165}
166
167template <typename T1, typename T2>
168typename std::map<T1,T2>::iterator HashMap<T1,T2>::begin()
169{
170  m_pPos = m_Map.begin();
171  return m_pPos;
172}
173
174template <typename T1, typename T2>
175typename std::map<T1,T2>::iterator HashMap<T1,T2>::end()
176{
177  m_pPos = m_Map.end();
178  return m_pPos;
179}
180
181// Declare known data types so that we don't need to put this in hashmap.h.
182// If user needs others the put the declaration in a separate user file.
183template class HashMap<int,string>;
184template class HashMap<int, int>;
185template class HashMap<string, SubGraph* >;
186template class HashMap<std::string,int>;
187template class HashMap<std::string, HashMap<std::string, int>*>;
188template class HashMap<std::string, std::string>;
189