astrotypes  0.0
HeaderField.cpp
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2018 PulsarSearchSoft
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 #include <boost/units/quantity.hpp>
26 #include <boost/units/cmath.hpp>
27 #include <iostream>
28 #include <exception>
29 #include <cmath>
30 
31 namespace pss {
32 namespace astrotypes {
33 namespace sigproc {
34 
35 template<typename T>
37  : BaseT(header_label, h)
38 {
39 }
40 
41 template<typename T>
42 HeaderField<T>::HeaderField(SigProcLabel const& header_label, Header& h, T const& t)
43  : BaseT(header_label, h)
44  , _var(t)
45 {
46 }
47 
48 template<typename T>
49 HeaderField<T>::HeaderField(SigProcLabel const& header_label, Header& h, HeaderField const& t)
50  : BaseT(header_label, h)
51  , _var(t._var)
52 {
53 }
54 
55 template<typename T>
57 {
58  _var = var;
59  return *this;
60 }
61 
62 template<typename T>
64 {
65  _var = reinterpret_cast<HeaderField<T> const&>(h)._var;
66 }
67 
68 template<typename T>
69 unsigned HeaderField<T>::read(std::istream& stream)
70 {
71  T v;
72  auto count = SigProcVariable<T>::read(stream, v);
73  _var=v;
74  return count;
75 }
76 
77 template<typename T>
78 unsigned HeaderField<T>::write(std::ostream& stream) const
79 {
80  return SigProcVariable<T>::write(stream, *_var);
81 }
82 
83 template<typename T>
84 void HeaderField<T>::write_info(std::ostream& stream) const
85 {
86  stream << std::setprecision(16) << *_var;
87 }
88 
89 template<typename T>
91 {
92  _var.reset();
93 }
94 
95 template<typename T>
97 {
98  return _var.is_set();
99 }
100 
101 template<typename T>
103 {
104  return *this == reinterpret_cast<HeaderField const&>(f);
105 }
106 
107 template<typename T>
109 {
110  return *f._var == *_var;
111 }
112 // -------------- std::vector specialization
113 template<typename T>
115  , SigProcLabel const& item_label
116  , SigProcLabel const& end_label
117  , Header& header)
118  : BaseT(start_label, header)
119  , _item_label_handler(_var)
120  , _end_label(end_label)
121  , _item_label(item_label)
122 {
123  // register the read handlers
124  BaseT::add_read(end_label, _end_label_handler, header);
125  BaseT::add_read(item_label, _item_label_handler, header);
126 }
127 
128 template<typename T>
130  , SigProcLabel const& item_label
131  , SigProcLabel const& end_label
132  , Header& header
133  , HeaderField const& copy)
134  : BaseT(start_label, header)
135  , _var(copy._var)
136  , _item_label_handler(_var)
137  , _end_label(end_label)
138  , _item_label(item_label)
139 {
140  // register the read handlers
141  BaseT::add_read(end_label, _end_label_handler, header);
142  BaseT::add_read(item_label, _item_label_handler, header);
143 }
144 
145 template<typename T>
147 {
148  _var.clear();
149 }
150 
151 template<typename T>
152 bool HeaderField<std::vector<T>>::is_set() const
153 {
154  return !_var.empty();
155 }
156 
157 template<typename T>
158 unsigned HeaderField<std::vector<T>>::read(std::istream&)
159 {
160  _var.clear();
161  return 0;
162 }
163 
164 template<typename T>
165 unsigned HeaderField<std::vector<T>>::ItemField::read(std::istream& stream)
166 {
167  T v;
168  unsigned c = SigProcVariable<T>::read(stream, v);
169  _vec.emplace_back(v);
170  return c;
171 }
172 
173 template<typename T>
174 unsigned HeaderField<std::vector<T>>::write(std::ostream& stream) const
175 {
176  unsigned size=0;
177  for(auto const& var : _var) {
178  stream << _item_label;
179  size += _item_label.size();
180  size += SigProcVariable<T>::write(stream, var);
181  }
182  // write out the end marker
183  stream << _end_label;
184  size += _end_label.size();
185 
186  return size;
187 }
188 
189 template<typename T>
190 std::string const& HeaderField<std::vector<T>>::header_info(std::string const&) const
191 {
192  return _item_label.string();
193 }
194 
195 template<typename T>
196 void HeaderField<std::vector<T>>::write_info(std::ostream& stream) const
197 {
198  // list all the elements if its a reasonable number
199  std::string sep="";
200  stream << "(";
201  if(_var.size() < 4) {
202  for( auto const& var : _var )
203  {
204  stream << sep << var;
205  sep = ", ";
206  }
207  }
208  else {
209  stream << _var[0] << ", " << _var[1] << ", ..., " << _var.back();
210  }
211  stream << ") " << _var.size() << " elements";
212 }
213 
214 template<typename T>
215 bool HeaderField<std::vector<T>>::operator==(HeaderFieldBase const& h) const
216 {
217  return *this == reinterpret_cast<HeaderField<std::vector<T>> const&>(h);
218 }
219 
220 template<typename T>
221 bool HeaderField<std::vector<T>>::operator==(const HeaderField& h) const
222 {
223  if(h._var.size() != _var.size()) return false;
224  return true; // only checks if sizes are the same. is this enough?
225 }
226 
227 template<typename T>
228 void HeaderField<std::vector<T>>::operator=(const HeaderFieldBase& h )
229 {
230  _var = reinterpret_cast<HeaderField<std::vector<T>> const&>(h)._var;
231 }
232 
233 // ------ HeaderFieldWithTolerance ------
234 template<typename T, typename ToleranceType>
236  : BaseT(header_label, header)
237  , _tolerance(t)
238 {
239 }
240 
241 template<typename T, typename ToleranceType>
243  : BaseT(header_label, header, copy)
244  , _tolerance(t)
245 {
246 }
247 
248 template<typename T, typename ToleranceType>
250 {
251  static_cast<BaseT&>(*this) = h;
252  return *this;
253 }
254 
255 template<typename T, typename ToleranceType>
257 {
258  return *this == reinterpret_cast<HeaderFieldWithTolerance const&>(h);
259 }
260 
261 namespace {
262 template<typename T2>
263 struct compare_tolerance
264 {
265  template<typename T1>
266  static inline
267  bool exec(T1 const& t1, T2 const& t2) {
268  return t1 < t2;
269  }
270 };
271 
272 template<typename T2>
273 struct compare_tolerance<HeaderField<T2>>
274 {
275  template<typename T1>
276  static inline
277  bool exec(T1 const& t1, HeaderField<T2> const& t2) {
278  if(t2.is_set())
279  return t1 < static_cast<T2 const&>(t2);
280  return true;
281  }
282 };
283 
284 } // namespace
285 
286 template<typename T, typename ToleranceType>
288 {
289  // allow for ADL lookups defaulting to std
290  using std::abs;
291  return compare_tolerance<typename std::decay<ToleranceType>::type>::exec(abs(*this->_var - *h._var) , _tolerance);
292 }
293 
295 {
296  h.add(header_name, *this);
297 }
298 
299 inline void HeaderFieldBase::add_read(SigProcLabel const& header_label, HeaderFieldBase& field, Header& header)
300 {
301  header.add_read(header_label, field);
302 }
303 
304 } // namespace sigproc
305 } // namespace astrotypes
306 } // namespace pss
307 
308 
309 
class to provide a virtual lookup table for read/write the varoious types of SigProcVariables ...
Definition: HeaderField.h:44
HeaderFieldWithTolerance(SigProcLabel const &header_label, Header &header, ToleranceType const &)
bool operator==(const HeaderFieldBase &) const override
static unsigned write(std::ostream &, T const &var)
write the provided variable to the stream
void reset() override
reset the variable to undefined state
Definition: HeaderField.cpp:90
specialisation to allow the == operator to return true if the values are within specified tolerance ...
Definition: HeaderField.h:122
Store SigProc header information.
Definition: Header.h:73
HeaderField & operator=(T const &var)
Definition: HeaderField.cpp:56
static unsigned read(std::istream &, T &var)
read form the stream into the variable provided
bool operator==(const HeaderFieldBase &) const override
void write_info(std::ostream &) const override
an information string about the value in the field (for debugging etc)
Definition: HeaderField.cpp:84
unsigned read(std::istream &) override
read into variable
Definition: HeaderField.cpp:69
void add(SigProcLabel const &label, HeaderFieldBase &field)
add a field to be parsed for read and write
Definition: HeaderBase.cpp:245
HeaderFieldWithTolerance & operator=(T const &var)
void add_read(SigProcLabel const &label, HeaderFieldBase &field)
add a field to be parsed for read only
Definition: HeaderBase.cpp:255
bool is_set() const override
return true if the variable has been set, false otherwise
Definition: HeaderField.cpp:96
unsigned write(std::ostream &) const override
serialise a variable to sigproc header format
Definition: HeaderField.cpp:78
void add_read(SigProcLabel const &header_label, HeaderFieldBase &field, Header &header)
add the provided field as a read_only parameter