Multiscale Universal Interface  2.0
A Concurrent Framework for Coupling Heterogeneous Solvers
stream.h
Go to the documentation of this file.
1 /*****************************************************************************
2 * Multiscale Universal Interface Code Coupling Library *
3 * *
4 * Copyright (C) 2019 Y. H. Tang, S. Kudo, X. Bian, Z. Li, G. E. Karniadakis *
5 * *
6 * This software is jointly licensed under the Apache License, Version 2.0 *
7 * and the GNU General Public License version 3, you may use it according *
8 * to either. *
9 * *
10 * ** Apache License, version 2.0 ** *
11 * *
12 * Licensed under the Apache License, Version 2.0 (the "License"); *
13 * you may not use this file except in compliance with the License. *
14 * You may obtain a copy of the License at *
15 * *
16 * http://www.apache.org/licenses/LICENSE-2.0 *
17 * *
18 * Unless required by applicable law or agreed to in writing, software *
19 * distributed under the License is distributed on an "AS IS" BASIS, *
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
21 * See the License for the specific language governing permissions and *
22 * limitations under the License. *
23 * *
24 * ** GNU General Public License, version 3 ** *
25 * *
26 * This program is free software: you can redistribute it and/or modify *
27 * it under the terms of the GNU General Public License as published by *
28 * the Free Software Foundation, either version 3 of the License, or *
29 * (at your option) any later version. *
30 * *
31 * This program is distributed in the hope that it will be useful, *
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
34 * GNU General Public License for more details. *
35 * *
36 * You should have received a copy of the GNU General Public License *
37 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
38 *****************************************************************************/
39 
51 #ifndef MUI_STREAM_H_
52 #define MUI_STREAM_H_
53 
54 #include <memory>
55 #include <algorithm>
56 
57 #include "../general/endian_traits.h"
58 
59 namespace mui {
60 
61 class istream {
62 public:
63  virtual ~istream() {}
64  virtual void read( char* ptr, std::size_t size ) = 0;
65 };
66 
67 class ostream {
68 public:
69  virtual ~ostream() {}
70  virtual void write( const char* ptr, std::size_t size ) = 0;
71 };
72 
73 class iostream : public istream, public ostream {
74 public:
75  virtual ~iostream() {}
76 };
77 
78 template<template<typename T, typename =std::allocator<T> > class Seq,
79  typename Alloc=std::allocator<char> >
80 class container_stream: public iostream {
81 public:
83  void read( char* ptr, std::size_t size ){
84  if( content.size() < size ) throw("");
85  std::copy_n(content.begin(),size,ptr);
86  content.erase(content.begin(),content.begin()+size);
87  }
88  void write( const char* ptr, std::size_t size ){
89  content.insert(content.end(),ptr,ptr+size);
90  }
91  Seq<char,Alloc>& data() { return content; }
92  const Seq<char,Alloc>& data() const { return content; }
93 private:
94  Seq<char,Alloc> content;
95 };
96 
97 /*
98  * inputiterator_stream is a istream from InputIterator
99  */
100 template<typename ConstInputIterator>
101 class iitr_stream: public istream {
102 public:
103  iitr_stream( const iitr_stream& ) = default;
104  iitr_stream( ConstInputIterator cur_ )
105  : cur(cur_) {}
107  void read( char* ptr, std::size_t sz ) {
108  std::copy_n(cur,sz,ptr);
109  std::advance(cur,sz);
110  }
111 
112  ConstInputIterator current() const { return cur; }
113 private:
114  ConstInputIterator cur;
115 };
116 
117 template<typename ConstInputIterator>
119 {
120  return iitr_stream<ConstInputIterator>(begin);
121 }
122 
123 /*
124  * outputiterator_stream is a ouput_stream to OutputIterator
125  */
126 template<typename OutputIterator>
127 class oitr_stream: public ostream {
128 public:
129  oitr_stream( const oitr_stream& ) = default;
130  oitr_stream( OutputIterator begin ) : cur(begin) {}
132  void write( const char* ptr, std::size_t sz ) {
133  cur = std::copy_n(ptr,sz,cur);
134  }
135 
136  OutputIterator current() const { return cur; }
137 private:
138  OutputIterator cur;
139 };
140 
141 template<typename OutputIterator>
143 {
144  return oitr_stream<OutputIterator>(cur);
145 }
146 
147 /*
148  * ocount_stream can be used for calculate the size of serialized data.
149  */
150 class ocount_stream : public ostream {
151 public:
152  ocount_stream(std::size_t off=0u) : sum(off) {}
154 
155  std::size_t size() const { return sum; }
156  void write( const char*, std::size_t size ) { sum += size; }
157 private:
158  std::size_t sum;
159 };
160 
161 inline std::size_t streamed_size() { return 0u; }
162 
163 template<typename T, typename... Args>
164 std::size_t streamed_size( const T& a, const Args&... args )
165 {
166  ocount_stream stream;
167  stream << a;
168  return stream.size() + streamed_size(args...);
169 }
170 
171  // Use SFINAE to enable this only for types we marked as not
172  // requiring endian conversion
173  template<typename T,
174  typename std::enable_if<endian_traits<T>::convert == false>::type* = nullptr>
175  istream& operator>>(istream& stream, T& dest) {
176  stream.read(reinterpret_cast<char*>(&dest), sizeof(T));
177  return stream;
178  }
179 
180  // Use SFINAE to enable this only for types we marked as requiring
181  // endian conversion
182  template<typename T,
183  typename std::enable_if<endian_traits<T>::convert == true>::type* = nullptr>
184  istream& operator>>(istream& stream, T& dest) {
185  detail::endian_converter<sizeof(T)> conv;
186  stream.read(conv.data.buf, sizeof(T));
187  conv.betoh();
188  std::memcpy(reinterpret_cast<char*>(&dest),
189  conv.data.buf, sizeof(T));
190  return stream;
191  }
192 
193  // Use SFINAE to enable this only for types we marked as not
194  // requiring endian conversion
195  template<typename T,
196  typename std::enable_if<endian_traits<T>::convert == false>::type* = nullptr>
197  ostream& operator<<(ostream& stream, const T& src) {
198  stream.write(reinterpret_cast<const char*>(&src), sizeof(T));
199  return stream;
200  }
201 
202  // Use SFINAE to enable this only for types we marked as requiring
203  // endian conversion
204  template<typename T,
205  typename std::enable_if<endian_traits<T>::convert == true>::type* = nullptr>
206  ostream& operator<<(ostream& stream, const T& src) {
207  detail::endian_converter<sizeof(T)> conv;
208  std::memcpy(conv.data.buf,
209  reinterpret_cast<const char*>(&src), sizeof(T));
210  conv.htobe();
211  stream.write(conv.data.buf, sizeof(T));
212  return stream;
213  }
214 
215 template<typename F, typename S>
216 istream& operator>> ( istream& stream, std::pair<F,S>& pair )
217 {
218  stream >> pair.first >> pair.second;
219  return stream;
220 }
221 template<typename F, typename S>
222 ostream& operator<< ( ostream& stream, const std::pair<F,S>& pair )
223 {
224  stream << pair.first << pair.second;
225  return stream;
226 }
227 
228 template<typename T>
229 istream& operator>> ( istream& stream, std::complex<T>& cx )
230 {
231  T r, i;
232  stream >> r >> i;
233  cx.real(r);
234  cx.imag(i);
235  return stream;
236 }
237 template<typename T>
238 ostream& operator<< ( ostream& stream, const std::complex<T>& cx )
239 {
240  stream << cx.real() << cx.imag();
241  return stream;
242 }
243 
244 }
245 
246 #endif
INT cur_
Definition: bin.h:59
Definition: stream.h:80
const Seq< char, Alloc > & data() const
Definition: stream.h:92
void write(const char *ptr, std::size_t size)
Definition: stream.h:88
void read(char *ptr, std::size_t size)
Definition: stream.h:83
Seq< char, Alloc > & data()
Definition: stream.h:91
~container_stream()
Definition: stream.h:82
Definition: stream.h:101
~iitr_stream()
Definition: stream.h:106
iitr_stream(const iitr_stream &)=default
iitr_stream(ConstInputIterator cur_)
Definition: stream.h:104
void read(char *ptr, std::size_t sz)
Definition: stream.h:107
ConstInputIterator current() const
Definition: stream.h:112
Definition: stream.h:73
virtual ~iostream()
Definition: stream.h:75
Definition: stream.h:61
virtual ~istream()
Definition: stream.h:63
virtual void read(char *ptr, std::size_t size)=0
Definition: stream.h:150
std::size_t size() const
Definition: stream.h:155
~ocount_stream()
Definition: stream.h:153
void write(const char *, std::size_t size)
Definition: stream.h:156
ocount_stream(std::size_t off=0u)
Definition: stream.h:152
Definition: stream.h:127
~oitr_stream()
Definition: stream.h:131
OutputIterator current() const
Definition: stream.h:136
void write(const char *ptr, std::size_t sz)
Definition: stream.h:132
oitr_stream(OutputIterator begin)
Definition: stream.h:130
oitr_stream(const oitr_stream &)=default
Definition: stream.h:67
virtual void write(const char *ptr, std::size_t size)=0
virtual ~ostream()
Definition: stream.h:69
T
Definition: dim.h:363
Definition: comm.h:54
istream & operator>>(istream &stream, smalluint &sml)
Definition: comm_tcp.h:103
ostream & operator<<(ostream &stream, const smalluint &sml)
Definition: comm_tcp.h:127
oitr_stream< OutputIterator > make_ostream(OutputIterator cur)
Definition: stream.h:142
std::size_t streamed_size()
Definition: stream.h:161
iitr_stream< ConstInputIterator > make_istream(ConstInputIterator begin)
Definition: stream.h:118