Forward compatibility: flex
[foam-extend-3.2.git] / src / foam / containers / HashTables / HashTable / HashTableIO.C
blob35c2326deebddcdcadefc344d66d4f1ed06b4973
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "HashTable.H"
27 #include "Istream.H"
28 #include "Ostream.H"
30 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
32 template<class T, class Key, class Hash>
33 Foam::HashTable<T, Key, Hash>::HashTable(Istream& is, const label size)
35     HashTableCore(),
36     nElmts_(0),
37     tableSize_(HashTableCore::canonicalSize(size)),
38     table_(NULL)
40     if (tableSize_)
41     {
42         table_ = new hashedEntry*[tableSize_];
44         for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
45         {
46             table_[hashIdx] = 0;
47         }
48     }
50     operator>>(is, *this);
54 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
56 template<class T, class Key, class Hash>
57 Foam::Ostream&
58 Foam::HashTable<T, Key, Hash>::printInfo(Ostream& os) const
60     label used = 0;
61     label maxChain = 0;
62     unsigned avgChain = 0;
64     for (label hashIdx = 0; hashIdx < tableSize_; ++hashIdx)
65     {
66         label count = 0;
67         for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
68         {
69             ++count;
70         }
72         if (count)
73         {
74             ++used;
75             avgChain += count;
77             if (maxChain < count)
78             {
79                 maxChain = count;
80             }
81         }
82     }
84     os  << "HashTable<T,Key,Hash>"
85         << " elements:" << size() << " slots:" << used << "/" << tableSize_
86         << " chaining(avg/max):" << (used ? (float(avgChain)/used) : 0)
87         << "/" << maxChain << endl;
89     return os;
93 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
95 template<class T, class Key, class Hash>
96 Foam::Istream& Foam::operator>>
98     Istream& is,
99     HashTable<T, Key, Hash>& L
102     is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
104     // Anull list
105     L.clear();
107     is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
109     token firstToken(is);
111     is.fatalCheck
112     (
113         "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
114         "reading first token"
115     );
117     if (firstToken.isLabel())
118     {
119         label s = firstToken.labelToken();
121         // Read beginning of contents
122         char delimiter = is.readBeginList("HashTable<T, Key, Hash>");
124         if (s)
125         {
126             if (2*s > L.tableSize_)
127             {
128                 L.resize(2*s);
129             }
131             if (delimiter == token::BEGIN_LIST)
132             {
133                 for (label i=0; i<s; i++)
134                 {
135                     Key key;
136                     is >> key;
137                     L.insert(key, pTraits<T>(is));
139                     is.fatalCheck
140                     (
141                         "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
142                         "reading entry"
143                     );
144                 }
145             }
146             else
147             {
148                 FatalIOErrorIn
149                 (
150                     "operator>>(Istream&, HashTable<T, Key, Hash>&)",
151                     is
152                 )   << "incorrect first token, '(', found " << firstToken.info()
153                     << exit(FatalIOError);
154             }
155         }
157         // Read end of contents
158         is.readEndList("HashTable");
159     }
160     else if (firstToken.isPunctuation())
161     {
162         if (firstToken.pToken() != token::BEGIN_LIST)
163         {
164             FatalIOErrorIn
165             (
166                 "operator>>(Istream&, HashTable<T, Key, Hash>&)",
167                 is
168             )   << "incorrect first token, '(', found " << firstToken.info()
169                 << exit(FatalIOError);
170         }
172         token lastToken(is);
173         while
174         (
175            !(
176                 lastToken.isPunctuation()
177              && lastToken.pToken() == token::END_LIST
178             )
179         )
180         {
181             is.putBack(lastToken);
183             Key key;
184             is >> key;
186             T element;
187             is >> element;
189             L.insert(key, element);
191             is.fatalCheck
192             (
193                 "operator>>(Istream&, HashTable<T, Key, Hash>&) : "
194                 "reading entry"
195             );
197             is >> lastToken;
198         }
199     }
200     else
201     {
202         FatalIOErrorIn
203         (
204             "operator>>(Istream&, HashTable<T, Key, Hash>&)",
205             is
206         )   << "incorrect first token, expected <int> or '(', found "
207             << firstToken.info()
208             << exit(FatalIOError);
209     }
211     is.fatalCheck("operator>>(Istream&, HashTable<T, Key, Hash>&)");
213     return is;
217 template<class T, class Key, class Hash>
218 Foam::Ostream& Foam::operator<<
220     Ostream& os,
221     const HashTable<T, Key, Hash>& L
224     // Write size and start delimiter
225     os << nl << L.size() << nl << token::BEGIN_LIST << nl;
227     // Write contents
228     for
229     (
230         typename HashTable<T, Key, Hash>::const_iterator iter = L.cbegin();
231         iter != L.cend();
232         ++iter
233     )
234     {
235         os << iter.key() << token::SPACE << iter() << nl;
236     }
238     // Write end delimiter
239     os << token::END_LIST;
241     // Check state of IOstream
242     os.check("Ostream& operator<<(Ostream&, const HashTable&)");
244     return os;
248 // ************************************************************************* //