12 #ifndef ECL_CONTAINERS_COMMON_FORMATTERS_HPP_ 13 #define ECL_CONTAINERS_COMMON_FORMATTERS_HPP_ 20 #include <ecl/config/macros.hpp> 21 #include <ecl/formatters/common.hpp> 22 #include <ecl/formatters/number.hpp> 23 #include <ecl/formatters/floats.hpp> 30 namespace formatters {
66 template <
typename Container >
72 typedef typename Container::value_type value_type;
80 FloatContainerFormatter(
const unsigned int p = 2,
const int w=-1) :
84 width_ptr(&prm_width),
87 ready_to_format(false)
90 virtual ~FloatContainerFormatter() {}
100 FloatContainerFormatter& precision(
const unsigned int p) { format.precision(p);
return *
this; }
111 FloatContainerFormatter& width(
const int w) { prm_width = w;
return *
this; }
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; }
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) {
153 ready_to_format =
true;
154 old_precision = format.precision();
157 width_ptr = &tmp_width;
170 template <
typename OutputStream,
typename Container_>
171 friend OutputStream& operator << (OutputStream& ostream, FloatContainerFormatter< Container_ > &formatter)
ecl_assert_throw_decl(StandardException);
174 long digits(value_type min_coeff, value_type max_coeff);
177 int tmp_width, prm_width;
180 const Container *container;
181 bool ready_to_format;
192 template <
typename Container >
194 long min_digits, max_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;
201 if ( ( min_digits == 0 ) && ( max_digits == 0 ) ) {
204 actual_digits = min_digits;
206 if ( min_coeff < 0 ) { actual_digits += 1; }
207 actual_digits += 1 + format.precision();
208 return actual_digits;
215 template <
typename OutputStream,
typename Container_>
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.") );
223 if ( *(formatter.width_ptr) == -1 ) {
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;
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; }
241 formatter.format.width(formatter.digits(min_coeff,max_coeff));
243 formatter.format.width(*(formatter.width_ptr));
249 typename Container_::const_iterator iter;
251 for ( iter = formatter.container->begin(); iter != formatter.container->end(); ++iter ) {
252 ostream << formatter.format(*iter) <<
" ";
259 if ( formatter.old_precision != -1 ) {
260 formatter.format.precision(formatter.old_precision);
261 formatter.old_precision = -1;
264 formatter.width_ptr = &(formatter.prm_width);
265 formatter.ready_to_format =
false;
#define LOC
Stringify the line of code you are at.
#define ecl_assert_throw(expression, exception)
Debug mode throw with a logical condition check.
Standard exception type, provides code location and error string.
TFSIMD_FORCE_INLINE const tfScalar & w() const
#define ecl_assert_throw_decl(exception)
Assure throw exception declaration.