Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / containers / HashTables / StaticHashTable / StaticHashTableIO.C
blob74c3c984c101ce028cd9284f84240faf9b3f8300
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "StaticHashTable.H"
27 #include "Istream.H"
28 #include "Ostream.H"
30 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
32 template<class T, class Key, class Hash>
33 Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
35     Istream& is,
36     const label size
39     StaticHashTableCore(),
40     keys_(StaticHashTableCore::canonicalSize(size)),
41     objects_(StaticHashTableCore::canonicalSize(size)),
42     nElmts_(0),
43     endIter_(*this, keys_.size(), 0),
44     endConstIter_(*this, keys_.size(), 0)
46     if (size < 1)
47     {
48         FatalErrorIn
49         (
50             "StaticHashTable<T, Key, Hash>::StaticHashTable(const label size)"
51         )   << "Illegal size " << size << " for StaticHashTable."
52             << " Minimum size is 1" << abort(FatalError);
53     }
55     operator>>(is, *this);
59 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
61 template<class T, class Key, class Hash>
62 Foam::Ostream&
63 Foam::StaticHashTable<T, Key, Hash>::printInfo(Ostream& os) const
65     label used = 0;
66     label maxChain = 0;
67     unsigned avgChain = 0;
69     // Find first non-empty entry
70     forAll(keys_, hashIdx)
71     {
72         const label count = keys_[hashIdx].size();
73         if (count)
74         {
75             ++used;
76             avgChain += count;
78             if (maxChain < count)
79             {
80                 maxChain = count;
81             }
82         }
83     }
85     os  << "StaticHashTable<T,Key,Hash>"
86         << " elements:" << size() << " slots:" << used << "/" << keys_.size()
87         << " chaining(avg/max):" << (used ? float(avgChain/used) : 0)
88         << "/" << maxChain << endl;
90     return os;
94 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
96 template<class T, class Key, class Hash>
97 Foam::Istream& Foam::operator>>(Istream& is, StaticHashTable<T, Key, Hash>& L)
99     is.fatalCheck("operator>>(Istream&, StaticHashTable<T, Key, Hash>&)");
101     // Anull list
102     L.clear();
104     is.fatalCheck("operator>>(Istream&, StaticHashTable<T, Key, Hash>&)");
106     token firstToken(is);
108     is.fatalCheck
109     (
110         "operator>>(Istream&, StaticHashTable<T, Key, Hash>&) : "
111         "reading first token"
112     );
114     if (firstToken.isLabel())
115     {
116         label s = firstToken.labelToken();
118         // Read beginning of contents
119         char delimiter = is.readBeginList("StaticHashTable<T, Key, Hash>");
121         if (s)
122         {
123             if (2*s > L.keys_.size())
124             {
125                 L.resize(2*s);
126             }
128             if (delimiter == token::BEGIN_LIST)
129             {
130                 for (label i=0; i<s; i++)
131                 {
132                     Key key;
133                     is >> key;
134                     L.insert(key, pTraits<T>(is));
136                     is.fatalCheck
137                     (
138                         "operator>>(Istream&, StaticHashTable<T, Key, Hash>&)"
139                         " : reading entry"
140                     );
141                 }
142             }
143             else
144             {
145                 FatalIOErrorIn
146                 (
147                     "operator>>(Istream&, StaticHashTable<T, Key, Hash>&)",
148                     is
149                 )   << "incorrect first token, '(', found " << firstToken.info()
150                     << exit(FatalIOError);
151             }
152         }
154         // Read end of contents
155         is.readEndList("StaticHashTable");
156     }
157     else if (firstToken.isPunctuation())
158     {
159         if (firstToken.pToken() != token::BEGIN_LIST)
160         {
161             FatalIOErrorIn
162             (
163                 "operator>>(Istream&, StaticHashTable<T, Key, Hash>&)",
164                 is
165             )   << "incorrect first token, '(', found " << firstToken.info()
166                 << exit(FatalIOError);
167         }
169         token lastToken(is);
170         while
171         (
172            !(
173                 lastToken.isPunctuation()
174              && lastToken.pToken() == token::END_LIST
175             )
176         )
177         {
178             is.putBack(lastToken);
180             Key key;
181             is >> key;
183             T element;
184             is >> element;
186             L.insert(key, element);
188             is.fatalCheck
189             (
190                 "operator>>(Istream&, StaticHashTable<T, Key, Hash>&) : "
191                 "reading entry"
192             );
194             is >> lastToken;
195         }
196     }
197     else
198     {
199         FatalIOErrorIn
200         (
201             "operator>>(Istream&, StaticHashTable<T, Key, Hash>&)",
202             is
203         )   << "incorrect first token, expected <int> or '(', found "
204             << firstToken.info()
205             << exit(FatalIOError);
206     }
208     is.fatalCheck("operator>>(Istream&, StaticHashTable<T, Key, Hash>&)");
210     return is;
214 template<class T, class Key, class Hash>
215 Foam::Ostream& Foam::operator<<
217     Ostream& os,
218     const StaticHashTable<T, Key, Hash>& L)
220     // Write size and start delimiter
221     os << nl << L.size() << nl << token::BEGIN_LIST << nl;
223     // Write contents
224     for
225     (
226         typename StaticHashTable<T, Key, Hash>::const_iterator iter = L.begin();
227         iter != L.end();
228         ++iter
229     )
230     {
231         os << iter.key() << token::SPACE << iter() << nl;
232     }
234     // Write end delimiter
235     os << token::END_LIST;
237     // Check state of IOstream
238     os.check("Ostream& operator<<(Ostream&, const StaticHashTable&)");
240     return os;
244 // ************************************************************************* //