common/formatters.hpp
Go to the documentation of this file.
1 
8 /*****************************************************************************
9 ** Ifdefs
10 *****************************************************************************/
11 
12 #ifndef ECL_CONTAINERS_COMMON_FORMATTERS_HPP_
13 #define ECL_CONTAINERS_COMMON_FORMATTERS_HPP_
14 
15 /*****************************************************************************
16 ** Includes
17 *****************************************************************************/
18 
19 #include <cmath>
20 #include <ecl/config/macros.hpp>
24 
25 /*****************************************************************************
26 ** Namespaces
27 *****************************************************************************/
28 
29 namespace ecl {
30 namespace formatters {
31 
32 /*****************************************************************************
33 ** Using
34 *****************************************************************************/
35 
36 /*****************************************************************************
37 ** Interface [FloatContainerFormatter]
38 *****************************************************************************/
39 
66 template <typename Container >
67 class ECL_LOCAL FloatContainerFormatter {
68  public:
69  /******************************************
70  ** Typedefs
71  *******************************************/
72  typedef typename Container::value_type value_type;
80  FloatContainerFormatter(const unsigned int p = 2, const int w=-1) :
81  old_precision(-1),
82  tmp_width(-1),
83  prm_width(w),
84  width_ptr(&prm_width),
85  format(w,p,ecl::RightAlign,ecl::Fixed),
86  container(NULL),
87  ready_to_format(false)
88  {}
89 
90  virtual ~FloatContainerFormatter() {}
91 
100  FloatContainerFormatter& precision(const unsigned int p) { format.precision(p); return *this; } // Permanent
111  FloatContainerFormatter& width(const int w) { prm_width = w; return *this; } // Permanent
118  unsigned int precision() const { return format.precision(); }
126  FloatContainerFormatter& operator()(const unsigned int p, const int w) { format.precision(p); prm_width = w; return *this; } // Permanent
137  FloatContainerFormatter& operator()(const Container &c) { container = &c; ready_to_format = true; return *this; }
151  FloatContainerFormatter& operator()(Container &c, const unsigned int p, const int w) {
152  container = &c;
153  ready_to_format = true;
154  old_precision = format.precision();
155  format.precision(p);
156  tmp_width = w;
157  width_ptr = &tmp_width;
158  return *this;
159  } //temporary
160 
170  template <typename OutputStream, typename Container_>
171  friend OutputStream& operator << (OutputStream& ostream, FloatContainerFormatter< Container_ > &formatter);
172 
173  private:
174  long digits(value_type min_coeff, value_type max_coeff);
175 
176  int old_precision;
177  int tmp_width, prm_width;
178  int* width_ptr;
179  Format< value_type > format;
180  const Container *container;
181  bool ready_to_format;
182 };
183 
192 template <typename Container >
193 long FloatContainerFormatter<Container>::digits(value_type min_coeff, value_type max_coeff) {
194  long min_digits, max_digits;
195  long actual_digits;
196  min_digits = static_cast<long> ( ceil(log10(fabs(min_coeff)+1)) );
197  max_digits = static_cast<long> ( ceil(log10(fabs(max_coeff)+1)) );
198  if ( min_digits < max_digits ) {
199  actual_digits = max_digits;
200  } else {
201  if ( ( min_digits == 0 ) && ( max_digits == 0 ) ) {
202  min_digits = 1;
203  }
204  actual_digits = min_digits;
205  }
206  if ( min_coeff < 0 ) { actual_digits += 1; }
207  actual_digits += 1 + format.precision();
208  return actual_digits;
209 }
210 
211 /******************************************
212 ** Streamer
213 *******************************************/
214 
215 template <typename OutputStream, typename Container_>
216 OutputStream& operator << (OutputStream& ostream, FloatContainerFormatter< Container_ > &formatter) {
217  ecl_assert_throw(formatter.ready_to_format, StandardException(LOC,UsageError,"The formatter cannot print any data - "
218  "either there is no data available, or you have tried to use the "
219  "formatter more than once in a single streaming operation. "
220  "C++ produces unspecified results when functors are used multiply "
221  "in the same stream sequence, so this is not permitted here.") );
222 
223  if ( *(formatter.width_ptr) == -1 ) {
224  /******************************************
225  ** Compute min,max coefficients
226  *******************************************/
227  typename Container_::value_type min_coeff, max_coeff;
228  const typename Container_::value_type *cur_coeff;
229  min_coeff = (*formatter.container)[0];
230  max_coeff = min_coeff;
231 
232 // for (size_t i = 1; i < N; ++i ) {
233  for ( unsigned int i = 1; i < formatter.container->size(); ++i) {
234  cur_coeff = &(*formatter.container)[i];
235  if ( *cur_coeff > max_coeff ) { max_coeff = *cur_coeff; }
236  if ( *cur_coeff < min_coeff ) { min_coeff = *cur_coeff; }
237  }
238  /*********************
239  ** Set format width
240  **********************/
241  formatter.format.width(formatter.digits(min_coeff,max_coeff));
242  } else {
243  formatter.format.width(*(formatter.width_ptr));
244  }
245 
246  /*********************
247  ** Stream
248  **********************/
249  typename Container_::const_iterator iter;
250  ostream << "[ ";
251  for ( iter = formatter.container->begin(); iter != formatter.container->end(); ++iter ) {
252  ostream << formatter.format(*iter) << " ";
253  }
254  ostream << "]";
255 
256  /*********************
257  ** Reset if temporary
258  **********************/
259  if ( formatter.old_precision != -1 ) {
260  formatter.format.precision(formatter.old_precision);
261  formatter.old_precision = -1;
262 
263  }
264  formatter.width_ptr = &(formatter.prm_width);
265  formatter.ready_to_format = false;
266 
267  ostream.flush();
268  return ostream;
269 }
270 
271 } // namespace formatters
272 } // namespace ecl
273 
274 #endif /* ECL_CONTAINERS_COMMON_FORMATTERS_HPP_ */
ecl::formatters::operator<<
OutputStream & operator<<(OutputStream &ostream, const ByteArrayFormatter< CharType, M > &formatter)
Definition: array/formatters.hpp:207
ecl::UsageError
UsageError
ECL_LOCAL
#define ECL_LOCAL
ecl::Fixed
Fixed
ecl::RightAlign
RightAlign
floats.hpp
common.hpp
number.hpp
ecl::Format< value_type >
ecl_assert_throw
#define ecl_assert_throw(expression, exception)
ecl::formatters::FloatContainerFormatter::digits
long digits(value_type min_coeff, value_type max_coeff)
Definition: common/formatters.hpp:205
ecl::formatters::FloatContainerFormatter
Parent interface for formatters of fixed size float/double containers.
Definition: common/formatters.hpp:79
ecl::formatters::FloatContainerFormatter< ecl::Stencil< Container > >::value_type
ecl::Stencil< Container > ::value_type value_type
Catches the container element's type.
Definition: common/formatters.hpp:94
macros.hpp
ecl
Embedded control libraries.


ecl_containers
Author(s): Daniel Stonier
autogenerated on Wed Mar 2 2022 00:16:34