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 >
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 
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 
177  int tmp_width, prm_width;
178  int* width_ptr;
180  const Container *container;
182 };
183 
192 template <typename Container >
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_ */
Embedded control libraries.
FloatContainerFormatter(const unsigned int p=2, const int w=-1)
#define LOC
unsigned int precision() const
Access the current precision used by this formatter.
#define ecl_assert_throw(expression, exception)
Container::value_type value_type
Catches the container element&#39;s type.
FloatContainerFormatter & precision(const unsigned int p)
Sets the precision format parameter.
UsageError
FloatContainerFormatter & operator()(Container &c, const unsigned int p, const int w)
RightAlign
FloatContainerFormatter & operator()(const unsigned int p, const int w)
Parent interface for formatters of fixed size float/double containers.
FloatContainerFormatter & operator()(const Container &c)
FloatContainerFormatter & width(const int w)
Sets the width format parameter.
#define ECL_LOCAL
long digits(value_type min_coeff, value_type max_coeff)


ecl_containers
Author(s): Daniel Stonier
autogenerated on Mon Feb 28 2022 22:18:43