.. _program_listing_file__tmp_ws_src_ecl_core_ecl_formatters_include_ecl_formatters_number.hpp: Program Listing for File number.hpp =================================== |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/ecl_core/ecl_formatters/include/ecl/formatters/number.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /***************************************************************************** ** Ifdefs *****************************************************************************/ #ifndef ECL_FORMATTERS_NUMBER_HPP_ #define ECL_FORMATTERS_NUMBER_HPP_ /***************************************************************************** ** Includes *****************************************************************************/ #include "common.hpp" #include #include /***************************************************************************** ** Namespaces *****************************************************************************/ namespace ecl { /***************************************************************************** ** Format Tags *****************************************************************************/ enum IntegralBase { Bin, Hex, Dec, }; namespace interfaces { /***************************************************************************** ** FormatNumber Interface [Integral types] *****************************************************************************/ template < typename Number > class FormatNumber { public: /****************************************** ** C&D's *******************************************/ FormatNumber(int w = -1, ecl::Alignment a = NoAlign, ecl::IntegralBase b = Dec) : prm_width(w),prm_alignment(a),prm_base(b),width_(&prm_width),alignment_(&prm_alignment),base_(&prm_base),ready_to_format(false) {} virtual ~FormatNumber() {} /****************************************** ** Set *******************************************/ FormatNumber& base(ecl::IntegralBase b); FormatNumber& width(int w); FormatNumber& align(ecl::Alignment a); /****************************************** * Set Format Combinations ******************************************/ FormatNumber& operator ()(int w, ecl::Alignment a, ecl::IntegralBase b); /****************************************** ** Format a value *******************************************/ FormatNumber& operator() (Number n); /****************************************** ** Common format usages *******************************************/ FormatNumber& operator() (Number n, int w, ecl::IntegralBase b); FormatNumber& operator() (Number n, int w, ecl::Alignment a, ecl::IntegralBase b); /****************************************** ** Insert the formatter into a stream *******************************************/ template friend OutputStream& operator << (OutputStream& ostream, FormatNumber& formatter); protected: /****************************************** ** Paramaters *******************************************/ int prm_width, tmp_width; ecl::Alignment prm_alignment, tmp_alignment; ecl::IntegralBase prm_base, tmp_base; int *width_; ecl::Alignment *alignment_; IntegralBase *base_; bool ready_to_format; Number value_; /****************************************** ** Padding *******************************************/ template void pad(int n, OutputStream &ostream) const; template void prePad(int n, OutputStream &ostream) const; template void postPad(int n, OutputStream &ostream) const; /****************************************** ** Formatter Functions *******************************************/ template void formatBin(OutputStream &ostream) const; template void formatHex(OutputStream &ostream) const; template void formatDec(OutputStream &ostream) const; }; // FormatNumber /***************************************************************************** * FormatNumber Implementation [configuration] *****************************************************************************/ template FormatNumber& FormatNumber::base(ecl::IntegralBase b) { *base_ = b; return *this; } template FormatNumber& FormatNumber::width(int w) { *width_ = w; if ( ( *width_ > 0 ) && ( *alignment_ == NoAlign ) ) { *alignment_ = RightAlign; } return *this; } template FormatNumber& FormatNumber::align(ecl::Alignment a) { *alignment_ = a; if ( *alignment_ == NoAlign ) { *width_ = 0; } return *this; } template FormatNumber& FormatNumber::operator () (int w, ecl::Alignment a, ecl::IntegralBase b) { base(b); width(w); align(a); return *this; } /***************************************************************************** * FormatNumber Implementation [internal formatting] *****************************************************************************/ template template void FormatNumber::formatBin(OutputStream &ostream) const { int size = 8*sizeof(Number); prePad(*width_ - (size + 2),ostream); ostream << "0b"; for (int i = size - 1; i>=0; i--) { ostream << "01"[((value_ >> i) & 1)]; } postPad(*width_ - (size + 2),ostream); } template template void FormatNumber::formatHex(OutputStream &ostream) const { static const char hex_string[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; int size = 2*sizeof(Number); prePad(*width_ - (size + 2),ostream); ostream << "0x"; for (int i = size - 1; i>=0; i--) { // ostream << "0123456789abcdef"[((value_ >> i*4) & 0xF)]; ostream << hex_string[((value_ >> i*4) & 0xF)]; // Dont have to recreate this every time } postPad(*width_ - (size + 2),ostream); } template template void FormatNumber::formatDec(OutputStream &ostream) const { static ecl::Converter convert; char *s = convert(value_); int size = strlen(s); prePad(*width_ - size,ostream); ostream << s; postPad(*width_ - size,ostream); } template template void FormatNumber::prePad(int n, OutputStream &ostream) const { if ( n <= 0 ) { return; } switch ( *alignment_ ) { case ( NoAlign ) : { break; } case ( LeftAlign ) : { break; } case ( RightAlign ) : { pad(n,ostream); break; } case ( CentreAlign ) : { pad(n/2+ n%2,ostream); break; } // Add the remainder default : break; } } template template void FormatNumber::postPad(int n, OutputStream &ostream) const { if ( n <= 0 ) { return; } switch ( *alignment_ ) { case ( NoAlign ) : { break; } case ( LeftAlign ) : { pad(n,ostream); break; } case ( RightAlign ) : { break; } case ( CentreAlign ) : { pad(n/2,ostream); break; } // Do not add the remainder default : break; } } template template void FormatNumber::pad(int n, OutputStream &ostream) const { for (int i = n; i > 0; --i ) { ostream << ' '; } } /***************************************************************************** * FormatNumber Implementation [value] *****************************************************************************/ template FormatNumber& FormatNumber::operator()(Number n) { value_ = n; ready_to_format = true; return *this; } /***************************************************************************** * FormatNumber Implementation [temporary formatting] *****************************************************************************/ template FormatNumber& FormatNumber::operator() (Number n, int w, ecl::IntegralBase b) { width_ = &tmp_width; alignment_ = &tmp_alignment; base_ = &tmp_base; base(b); width(w); value_ = n; ready_to_format = true; return *this; } template FormatNumber& FormatNumber::operator() (Number n, int w, ecl::Alignment a, ecl::IntegralBase b) { width_ = &tmp_width; alignment_ = &tmp_alignment; base_ = &tmp_base; base(b); width(w); align(a); value_ = n; ready_to_format = true; return *this; } /***************************************************************************** * FormatNumber Implementation [streaming] *****************************************************************************/ template OutputStream& operator << (OutputStream &ostream, FormatNumber& formatter ) { bool ready = formatter.ready_to_format; ecl_assert_throw(ready, StandardException(LOC,UsageError,"The formatter cannot print any data - " "either there is no data available, or you have tried to use the " "formatter more than once in a single streaming operation. " "C++ produces unspecified results when functors are used multiply " "in the same stream sequence, so this is not permitted here.") ); if ( ready ) { switch(*(formatter.base_) ) { case(Bin) : { formatter.formatBin(ostream); break; } case(Hex) : { formatter.formatHex(ostream); break; } case(Dec) : { formatter.formatDec(ostream); break; } } if ( formatter.width_ != &(formatter.prm_width) ) { formatter.width_ = &(formatter.prm_width); formatter.alignment_ = &(formatter.prm_alignment); formatter.base_ = &(formatter.prm_base); } formatter.ready_to_format = false; } return ostream; } } // namespace interfaces /***************************************************************************** * Format Classes *****************************************************************************/ template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; template <> class Format : public interfaces::FormatNumber { public: Format(int w = -1, Alignment a = NoAlign, IntegralBase b = Dec) : interfaces::FormatNumber(w, a, b) {} virtual ~Format() {} }; } // namespace ecl #endif /*ECL_FORMATTERS_NUMBER_HPP_*/