iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VectorUtilsImpl.H
Go to the documentation of this file.
1 /*! @file
2  @author Unknown
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 #include <sstream>
35 #include <iostream>
37 
38 // ######################################################################
39 template <class Ch, class Tr, class T> inline
40 std::basic_ostream<Ch,Tr> & std::operator<<(std::basic_ostream<Ch,Tr> & out, std::vector<T> const & v)
41 {
42  out << "[";
43  for (uint i=0; i < v.size(); ++i)
44  {
45  out << v[i];
46  if (i < v.size() - 1) out << ",";
47  }
48  out << "]";
49  return out;
50 }
51 
52 // ######################################################################
53 template <class Ch, class Tr, class T> inline
54 std::basic_istream<Ch,Tr>& std::operator>>(std::basic_istream<Ch,Tr> & in, std::vector<T> & result)
55 {
56  bool bracketStart = false;
57  // Ignore empty strings
58  if (!in.good()) return in;
59  char c = in.peek();
60 
61  // Ignore whitespace
62  while (isspace(c)) c = in.get();
63 
64  // Move all space in strings to the end of the string and then erase them
65  //tmpstring.erase(std::remove_if(tmpstring.begin(), tmpstring.end(), isspace),tmpstring.end());
66  // Go through string and find initial '[' and final ']' if present
67  // Check if first string has leading '['
68  if (c == '[')
69  {
70  bracketStart = true; // Throw away bracket
71  c = in.get();
72  }
73 
74  // Check what's next
75  c = in.get();
76 
77  // Ignore whitespace
78  while (isspace(c)) c = in.get();
79 
80  // When finding separators, must count open/closing braces/parentheses and get back to zero
81  std::string openSep = "[{(<";
82  std::string closeSep = "]})>";
83  std::vector<int> count = { 0, 0, 0, 0};
84  std::vector<std::string> splitVec;
85  std::string curString = "";
86  while(in.good())
87  {
88  bool storeChar = true;
89  bool commaCounts = true;
90  switch(c)
91  {
92  case '[': ++count[0]; break;
93  case '{': ++count[1]; break;
94  case '(': ++count[2]; break;
95  case '<': ++count[3]; break;
96  case ']':
97  --count[0];
98  // Need to check if we hit the last ], if so, we need to round up all remaining characters and process them
99  if ( (bracketStart && count[0] != -1) || (! bracketStart && count[0] != 0) ) commaCounts = false;
100  for (uint idx = 1; idx < 4; ++idx)
101  // If non zero count, ignore end bracket
102  if (count[idx] != 0) { commaCounts = false; break; }
103 
104  if (commaCounts)
105  {
106  splitVec.push_back(curString);
107  curString = "";
108  storeChar = false;
109  }
110  break;
111  case '}': --count[1]; break;
112  case ')': --count[2]; break;
113  case '>': --count[3]; break;
114  case ',': // Element break character
115  for (uint idx = 0; idx < 4; ++idx)
116  // If non zero count, ignore comma
117  if (count[idx] != 0) { commaCounts = false; break; }
118 
119  if (commaCounts)
120  {
121  splitVec.push_back(curString);
122  curString = "";
123  storeChar = false;
124  }
125  break;
126 
127  default:
128  // Ignore
129  break;
130  }
131  // Ignore the element break character
132  if (storeChar) curString.push_back(c);
133  c=in.get();
134 
135  // Ignore whitespace
136  while (isspace(c)) c = in.get();
137  }
138  // Check if we should have ended with another bracket
139  if (bracketStart && count[0]!= -1)
140  {
141  throw nrt::exception::
142  Exception(std::string("Malformed std::vector string representation, missing end ']'").c_str());
143  }
144  // Check if we should have *NOT* ended with another bracket
145  if (!bracketStart && count[0]!= 0)
146  {
147  throw nrt::exception::
148  Exception(std::string("Malformed std::vector string representation (missing '[' ?)").c_str());
149  }
150  for (uint idx = 1; idx < 4; ++idx)
151  {
152  // If non zero count we have a malformed string
153  if (count[idx] != 0)
154  {
155  throw nrt::exception::Exception((std::string("Malformed std::vector string representation, incorrect number of '")
156  + openSep.substr(idx,1) + std::string("' and '") + closeSep.substr(idx,1)
157  ).c_str());
158  }
159  }
160  result.resize(splitVec.size());
161  std::stringstream s;
162  for (uint i = 0; i <splitVec.size(); ++i)
163  {
164  s.clear();
165  s.str(splitVec[i]);
166  T tmp; s >> tmp;
167  result[i] = tmp;
168  }
169  return in;
170 }
171 
172 // ######################################################################
173 template <class Ch, class Tr, class T1, class T2> inline
174 std::basic_ostream<Ch,Tr> & std::operator<<(std::basic_ostream<Ch,Tr> & out, std::map<T1,T2> const & v)
175 {
176  out << "[";
177  bool isFirst=true;
178  for(auto const & cur : v)
179  {
180  if (isFirst) isFirst = false; else out << ",";
181  out << cur.first << ":" << cur.second;
182  }
183  out << "]";
184  return out;
185 }
186 
187 
188 // ######################################################################
189 template <class Ch, class Tr, class T1, class T2> inline
190 std::basic_istream<Ch,Tr>& std::operator>>(std::basic_istream<Ch,Tr>& in, std::map<T1,T2>& result)
191 {
192  bool bracketStart = false;
193 
194  // Ignore empty strings
195  if(!in.good())
196  return in;
197  char c = in.peek();
198  // Ignore whitespace
199  while(isspace(c))
200  c = in.get();
201  // Move all space in strings to the end of the string and then erase them
202  //tmpstring.erase(std::remove_if(tmpstring.begin(), tmpstring.end(), isspace),tmpstring.end());
203  // Go through string and find initial '[' and final ']' if present
204  // Check if first string has leading '['
205  if(c=='[')
206  {
207  bracketStart=true;
208  // Throw away bracket
209  c = in.get();
210  }
211  // Check what's next
212  c = in.get();
213  // Ignore whitespace
214  while(isspace(c))
215  c = in.get();
216 
217  // When finding separators, must count open/closing braces/parentheses and get back to zero
218  std::string openSep = "[{(<";
219  std::string closeSep = "]})>";
220  std::vector<int> count = { 0, 0, 0, 0};
221  std::string curString="";
222  T1 key;
223  T2 value;
224  bool keyValid = false;
225  std::stringstream s;
226  while(in.good())
227  {
228  bool storeChar=true;
229  bool commaCounts=true;
230  bool colonCounts=true;
231  switch(c)
232  {
233  case '[':
234  count[0]++;
235  break;
236  case '{':
237  count[1]++;
238  break;
239  case '(':
240  count[2]++;
241  break;
242  case '<':
243  count[3]++;
244  break;
245  case ']':
246  count[0]--;
247  // Need to check if we hit the last ], if so, we need to round up all remaining characters and process them
248  if( (bracketStart && count[0]!=-1) ||
249  (!bracketStart && count[0]!=0))
250  commaCounts=false;
251  for(uint idx=1;idx<4;++idx)
252  {
253  // If non zero count, ignore end bracket
254  if(count[idx]!=0)
255  {
256  //std::cout << "Idx failed for zero count check: " << idx << std::endl;
257  commaCounts=false;
258  break;
259  }
260  }
261  if(commaCounts)
262  {
263  if(!keyValid)
264  {
265  throw nrt::exception::Exception(std::string("Malformed std::map missing key").c_str());
266  }
267  //std::cout << "Putting string due to last ]" << curString << std::endl;
268  s.clear();
269  s.str(curString);
270  s >> value;
271  curString = "";
272  storeChar=false;
273  // Assign key to value for last item
274  result[key] = value;
275  // Key is no longer valid
276  keyValid=false;
277  }
278  break;
279  case '}':
280  count[1]--;
281  break;
282  case ')':
283  count[2]--;
284  break;
285  case '>':
286  count[3]--;
287  break;
288  case ':': // Key break character
289  for(uint idx=0;idx<4;++idx)
290  {
291  // If non zero count, ignore comma
292  if(count[idx]!=0)
293  {
294  colonCounts=false;
295  break;
296  }
297  }
298  if(colonCounts)
299  {
300  s.clear();
301  s.str(curString);
302  s >> key;
303  curString = "";
304  storeChar=false;
305  keyValid=true;
306  }
307  break;
308  case ',': // Value break character
309  for(uint idx=0;idx<4;++idx)
310  {
311  // If non zero count, ignore comma
312  if(count[idx]!=0)
313  {
314  commaCounts=false;
315  break;
316  }
317  }
318  if(commaCounts)
319  {
320  if(!keyValid)
321  {
322  throw nrt::exception::Exception(std::string("Malformed std::map missing key").c_str());
323  }
324  s.clear();
325  s.str(curString);
326  s >> value;
327  curString = "";
328  storeChar=false;
329  // Assign key to value
330  result[key] = value;
331  // Key is no longer valid
332  keyValid=false;
333  }
334  break;
335  default:
336  // Ignore
337  break;
338  }
339  // Ignore the element break character
340  if(storeChar)
341  curString.push_back(c);
342  c=in.get();
343  // Ignore whitespace
344  while(isspace(c))
345  c = in.get();
346  }
347  // Check if we should have ended with another bracket
348  if(bracketStart && count[0]!= -1)
349  {
350  throw nrt::exception::Exception(std::string("Malformed std::map string representation, missing end ']'").c_str());
351  }
352  // Check if we should have *NOT* ended with another bracket
353  if(!bracketStart && count[0]!= 0)
354  {
355  throw nrt::exception::Exception(std::string("Malformed std::map string representation (missing '[' ?)").c_str());
356  }
357  for(uint idx=1;idx<4;++idx)
358  {
359  // If non zero count we have a malformed string
360  if(count[idx]!=0)
361  {
362  throw nrt::exception::Exception((std::string("Malformed std::map string representation, incorrect number of '")
363  + openSep.substr(idx,1) + std::string("' and '") + closeSep.substr(idx,1)
364  ).c_str());
365  }
366  }
367  if(!bracketStart)
368  {
369  if(!keyValid)
370  {
371  throw nrt::exception::Exception(std::string("Malformed std::map missing key").c_str());
372  }
373  s.clear();
374  s.str(curString);
375  s >> value;
376  curString = "";
377  // Assign key to value
378  result[key] = value;
379  // Key is no longer valid
380  keyValid=false;
381  }
382  return in;
383 }