RSC  0.16.0
ContainerIO.h
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is part of the RSC project
4  *
5  * Copyright (C) 2010-2016 Jan Moringen
6  *
7  * This file may be licensed under the terms of the
8  * GNU Lesser General Public License Version 3 (the ``LGPL''),
9  * or (at your option) any later version.
10  *
11  * Software distributed under the License is distributed
12  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
13  * express or implied. See the LGPL for the specific language
14  * governing rights and limitations.
15  *
16  * You should have received a copy of the LGPL along with this
17  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
18  * or write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The development of this software was supported by:
22  * CoR-Lab, Research Institute for Cognition and Robotics
23  * Bielefeld University
24  *
25  * ============================================================ */
26 
27 #pragma once
28 
29 #include <string>
30 #include <utility>
31 #include <vector>
32 #include <list>
33 #include <set>
34 #include <map>
35 #include <valarray>
36 #include <deque>
37 
38 #include <algorithm>
39 #include <iterator>
40 
41 #include <iostream>
42 
43 #include "rsc/rscexports.h"
44 
45 namespace std {
46 namespace detail {
47 
48 // Style helpers for pairs
49 
50 RSC_EXPORT void pair_style_delete(ios_base::event event_,
51  ios_base& stream,
52  int index);
53 
54 struct RSC_EXPORT pair_style {
55  string open_brace;
56  string separator;
57  string close_brace;
58 
59  static const int stream_storage;
60 
61  pair_style(const string& open_brace = "(",
62  const string& separator = ", ",
63  const string& close_brace = ")");
64 };
65 
66 template<typename T>
68  T value;
69 };
70 
71 // Style helpers for element sequence types
72 
73 RSC_EXPORT void element_sequence_style_delete(ios_base::event event_,
74  ios_base& stream,
75  int index);
76 
77 struct RSC_EXPORT element_sequence_style {
78  string separator;
81 
82  static const int stream_storage;
83 
84  element_sequence_style(const string& separator = ", ",
85  const string& first_separator = "",
86  const string& last_separator = "");
87 };
88 
89 template<typename T>
91  set_element_sequence_style(const T& value) : value(value) {};
92  T value;
93 };
94 
95 // Style helpers for container types
96 
97 RSC_EXPORT void container_style_delete(ios_base::event event_,
98  ios_base& stream,
99  int index);
100 
101 struct RSC_EXPORT container_style {
102  string open;
103  string close;
104 
105  static const int stream_storage;
106 
107  container_style(const string& open,
108  const string& close);
109 };
110 
111 template<typename T>
113  T value;
114 };
115 
116 }
117 
118 // Installing pair style
119 
120 template<typename Ch, typename Tr, typename T>
121 basic_ostream<Ch, Tr>&
122 operator<<(basic_ostream<Ch, Tr>& stream,
123  const detail::set_pair_style<T>& style) {
124  // Delete old style, if any, and install new style.
125  if (stream.pword(detail::pair_style::stream_storage))
126  delete reinterpret_cast<detail::pair_style*> (stream.pword(
128  else
129  stream.register_callback(&detail::pair_style_delete, 0);
130 
131  stream.pword(detail::pair_style::stream_storage) = new T(style.value);
132 
133  // Return the modified stream.
134  return stream;
135 }
136 
138 RSC_EXPORT extern const detail::set_pair_style<detail::pair_style>
140 
141 // Installing element sequence style
142 
143 template<typename Ch, typename Tr, typename T>
144 basic_ostream<Ch, Tr>&
145 operator<<(basic_ostream<Ch, Tr>& stream,
147  // Delete old style, if any, and install new style.
149  delete reinterpret_cast<detail::element_sequence_style*> (stream.pword(
151  else
152  stream.register_callback(&detail::element_sequence_style_delete, 0);
153 
154  stream.pword(detail::element_sequence_style::stream_storage) = new T(style.value);
155 
156  // Return the modified stream.
157  return stream;
158 }
159 
161 element_sequence(const string& separator = ", ",
162  const string& first_separator = "",
163  const string& last_separator = "");
164 
167 
168 // Installing Container style
169 
170 template<typename Ch, typename Tr, typename T>
171 basic_ostream<Ch, Tr>&
172 operator<<(basic_ostream<Ch, Tr>& stream,
173  const detail::set_container_style<T>& style) {
174  // Delete old style, if any, and install new style.
175  if (stream.pword(detail::container_style::stream_storage))
176  delete reinterpret_cast<detail::container_style*> (stream.pword(
178  else
179  stream.register_callback(&detail::container_style_delete, 0);
180 
181  stream.pword(detail::container_style::stream_storage) = new T(style.value);
182 
183  // Return the modified stream.
184  return stream;
185 }
186 
187 
194 
195 // Formatting pairs
196 
197 template<typename Ch, typename Tr, typename R, typename S>
198 basic_ostream<Ch, Tr>&
199 operator<<(basic_ostream<Ch, Tr>& stream, const pair<R, S>& pair) {
200  // Try to retrieve the installed style implementation. Create one,
201  // if none is installed.
202  if (!stream.pword(detail::pair_style::stream_storage))
203  stream << pair_default;
204 
205  detail::pair_style& style =
206  *reinterpret_cast<detail::pair_style*> (stream.pword(
208 
209  stream << style.open_brace << pair.first << style.separator << pair.second
210  << style.close_brace;
211  return stream;
212 }
213 
214 // Formatting containers
215 
216 template<typename Ch, typename Tr, typename T>
217 basic_ostream<Ch, Tr>&
218 operator<<(basic_ostream<Ch, Tr>& stream, const vector<T>& container) {
219  typedef vector<T> container_type;
220  typedef typename container_type::value_type value_type;
221 
223  stream << element_sequence_singleline;
224  }
225 
226  detail::element_sequence_style& element_sequence_style =
227  *reinterpret_cast<detail::element_sequence_style*>(stream.pword(
229  detail::container_style container_style
231  ? *reinterpret_cast<detail::container_style*>
233  : container_hash.value);
234 
235  stream << container_style.open;
236  if (container.size() >= 1) {
237  stream << element_sequence_style.first_separator;
238  copy(container.begin(), container.end() - 1,
239  ostream_iterator<value_type>(stream,
240  element_sequence_style.separator.c_str()));
241  stream << container.back();
242  stream << element_sequence_style.last_separator;
243  }
244  stream << container_style.close;
245  return stream;
246 }
247 
248 template<typename Ch, typename Tr, typename T>
249 basic_ostream<Ch, Tr>&
250 operator<<(basic_ostream<Ch, Tr>& stream, const deque<T>& container) {
251  typedef vector<T> container_type;
252  typedef typename container_type::value_type value_type;
253 
255  stream << element_sequence_singleline;
256  }
257 
258  detail::element_sequence_style& element_sequence_style =
259  *reinterpret_cast<detail::element_sequence_style*>(stream.pword(
261  detail::container_style container_style
263  ? *reinterpret_cast<detail::container_style*>
265  : container_d.value);
266 
267  stream << container_style.open;
268  if (container.size() >= 1) {
269  stream << element_sequence_style.first_separator;
270  copy(container.begin(), container.end() - 1,
271  ostream_iterator<value_type>(stream,
272  element_sequence_style.separator.c_str()));
273  stream << container.back();
274  stream << element_sequence_style.last_separator;
275  }
276  stream << container_style.close;
277  return stream;
278 }
279 
280 template<typename Ch, typename Tr, typename T>
281 basic_ostream<Ch, Tr>&
282 operator<<(basic_ostream<Ch, Tr>& stream, const list<T>& container) {
283  typedef list<T> container_type;
284  typedef typename container_type::value_type value_type;
285 
287  stream << element_sequence_singleline;
288  }
289 
290  detail::element_sequence_style& element_sequence_style =
291  *reinterpret_cast<detail::element_sequence_style*>(stream.pword(
293  detail::container_style container_style
295  ? *reinterpret_cast<detail::container_style*>
297  : container_brackets.value);
298 
299  stream << container_style.open;
300  if (!container.empty()) {
301  stream << element_sequence_style.first_separator;
302  copy(container.begin(), --container.end(),
303  ostream_iterator<value_type>(stream,
304  element_sequence_style.separator.c_str()));
305  stream << container.back();
306  stream << element_sequence_style.last_separator;
307  }
308  stream << container_style.close;
309  return stream;
310 }
311 
312 template<typename Ch, typename Tr, typename T>
313 basic_ostream<Ch, Tr>&
314 operator<<(basic_ostream<Ch, Tr>& stream, const set<T>& container) {
315  typedef set<T> container_type;
316  typedef typename container_type::value_type value_type;
317 
319  stream << element_sequence_singleline;
320  }
321 
322  detail::element_sequence_style& element_sequence_style =
323  *reinterpret_cast<detail::element_sequence_style*>(stream.pword(
325  detail::container_style container_style
327  ? *reinterpret_cast<detail::container_style*>(
329  : container_braces.value);
330 
331  stream << container_style.open;
332  if (!container.empty()) {
333  stream << element_sequence_style.first_separator;
334  copy(++container.begin(), container.end(),
335  ostream_iterator<value_type>(stream,
336  element_sequence_style.separator.c_str()));
337  stream << *container.begin();
338  stream << element_sequence_style.last_separator;
339  }
340  stream << container_style.close;
341  return stream;
342 }
343 
344 template<typename Ch, typename Tr, typename R, typename S>
345 basic_ostream<Ch, Tr>&
346 operator<<(basic_ostream<Ch, Tr>& stream, const map<R, S>& container) {
347  typedef map<R, S> container_type;
348 
350  stream << element_sequence_singleline;
351  }
352 
353  detail::element_sequence_style& element_sequence_style =
354  *reinterpret_cast<detail::element_sequence_style*>(stream.pword(
356  detail::container_style container_style
358  ? *reinterpret_cast<detail::container_style*>
360  : container_braces.value);
361 
362  stream << container_style.open;
363  stream << element_sequence_style.first_separator;
364  for (typename container_type::const_iterator it = container.begin(); it
365  != container.end();) {
366  stream << *it;
367  if (++it != container.end())
368  stream << element_sequence_style.separator;
369  }
370  stream << element_sequence_style.last_separator;
371  stream << container_style.close;
372  return stream;
373 }
374 
375 template<typename Ch, typename Tr, typename R, typename S>
376 basic_ostream<Ch, Tr>&
377 operator<<(basic_ostream<Ch, Tr>& stream, const multimap<R, S>& container) {
378  typedef multimap<R, S> container_type;
379 
381  stream << element_sequence_singleline;
382  }
383 
384  detail::element_sequence_style& element_sequence_style =
385  *reinterpret_cast<detail::element_sequence_style*>(stream.pword(
387  detail::container_style container_style
389  ? *reinterpret_cast<detail::container_style*>
391  : container_braces.value);
392 
393  stream << container_style.open;
394  stream << element_sequence_style.first_separator;
395  for (typename container_type::const_iterator it = container.begin(); it
396  != container.end();) {
397  stream << *it;
398  if (++it != container.end())
399  stream << element_sequence_style.separator;
400  }
401  stream << element_sequence_style.last_separator;
402  stream << container_style.close;
403  return stream;
404 }
405 
406 template<typename Ch, typename Tr, typename T>
407 basic_ostream<Ch, Tr>&
408 operator<<(basic_ostream<Ch, Tr>& stream, const valarray<T>& container) {
410  stream << element_sequence_singleline;
411  }
412 
413  detail::element_sequence_style& element_sequence_style =
414  *reinterpret_cast<detail::element_sequence_style*>(stream.pword(
416  detail::container_style container_style
418  ? *reinterpret_cast<detail::container_style*>
420  : container_parentheses.value);
421 
422  stream << container_style.open;
423  stream << element_sequence_style.first_separator;
424  for (unsigned int i = 0; i != container.size(); ++i) {
425  stream << container[i];
426  if (i != container.size() - 1)
427  stream << element_sequence_style.separator;
428  }
429  stream << element_sequence_style.last_separator;
430  stream << container_style.close;
431  return stream;
432 }
433 
434 /* TODO(jmoringe, 2012-11-12): unfinished
435 template<typename Ch, typename Tr, typename T>
436 basic_ostream<Ch, Tr>&
437 operator<<(basic_ostream<Ch, Tr>& stream, const slice_array<T>& container) {
438  typedef slice_array<T> container_type;
439  typedef typename container_type::value_type value_type;
440 
441  stream << "s(";
442  for (unsigned int i = 0; i != container.size(); ++i) {
443  stream << container[i];
444  if (i != container.size() - 1)
445  stream << ", ";
446  }
447  stream << ")";
448  return stream;
449 }*/
450 
451 }
const detail::set_container_style< detail::container_style > container_hash
const detail::set_container_style< detail::container_style > container_braces
detail::set_element_sequence_style< detail::element_sequence_style > element_sequence(const string &separator, const string &first_separator, const string &last_separator)
Definition: ContainerIO.cpp:98
const detail::set_container_style< detail::container_style > container_d
const detail::set_container_style< detail::container_style > container_brackets
const detail::set_element_sequence_style< detail::element_sequence_style > element_sequence_multiline
STL namespace.
void container_style_delete(ios_base::event event_, ios_base &stream, int)
Definition: ContainerIO.cpp:69
void pair_style_delete(ios_base::event event_, ios_base &stream, int)
Definition: ContainerIO.cpp:34
const detail::set_element_sequence_style< detail::element_sequence_style > element_sequence_singleline
const detail::set_pair_style< detail::pair_style > pair_default
Definition: ContainerIO.cpp:87
static const int stream_storage
Definition: ContainerIO.h:59
const detail::set_pair_style< detail::pair_style > pair_whitespace
Definition: ContainerIO.cpp:91
const detail::set_container_style< detail::container_style > container_none
static const int stream_storage
Definition: ContainerIO.h:105
const detail::set_container_style< detail::container_style > container_parentheses
void element_sequence_style_delete(ios_base::event event_, ios_base &stream, int)
Definition: ContainerIO.cpp:51