#ifndef PRINTABLEH #define PRINTABLEH #include #include //for ostringstream #include //for std::isprint #include //for std::iswprint #include //for numeric_limits #include "except.h" using namespace std; template class basic_printable { CHAR c; typedef typename char_traits::int_type int_type; static bool isprint(CHAR c) throw (); static bool isprint(int_type i) throw (); static int_type code(CHAR c) throw (); static int_type code(int_type i) throw () {return i;} public: basic_printable& operator=(CHAR c) throw (except); basic_printable& operator=(int_type i) throw (except); basic_printable(CHAR c) throw (except) {*this = c;} basic_printable(int_type i) throw (except) {*this = i;} operator CHAR() const throw () { return c; } }; typedef basic_printable printable_t; typedef basic_printable wprintable_t; template <> inline bool printable_t::isprint(char c) throw () { return std::isprint(static_cast(c)) != 0; } template <> inline bool printable_t::isprint(char_traits::int_type i) throw () { return i >= 0 && i <= numeric_limits::max() && std::isprint(i) != 0; } template <> inline bool wprintable_t::isprint(wchar_t wc) throw () { return iswprint(wc) != 0; } template <> inline bool wprintable_t::isprint(char_traits::int_type i) throw () { return i >= numeric_limits::min() && i <= numeric_limits::max() && iswprint(i) != 0; } template <> inline char_traits::int_type printable_t::code(char c) throw () { return static_cast(c); } template <> inline char_traits::int_type wprintable_t::code(wchar_t wc) throw () { return wc; } template basic_printable& basic_printable::operator=(CHAR c) throw (except) { if (!isprint(c)) { ostringstream ost; ost << "character code " << code(c) << " is not printable"; throw except(ost); } this->c = c; return *this; } template basic_printable& basic_printable::operator=(int_type i) throw (except) { if (!isprint(i)) { ostringstream ost; ost << "character code " << code(i) << " is not printable"; throw except(ost); } c = i; return *this; } template inline basic_printable& operator+=(basic_printable& p, typename char_traits::int_type i) throw (except) { return p = static_cast(p) + i; } template inline basic_printable& operator-=(basic_printable& p, typename char_traits::int_type i) throw (except) { return p = static_cast(p) - i; } template inline basic_printable& operator++(basic_printable& p) throw (except) { return p += 1; } template inline basic_printable& operator--(basic_printable& p) throw (except) { return p -= 1; } template inline const basic_printable operator++(basic_printable& p, int) throw (except) { const basic_printable old = p; ++p; return old; } template inline const basic_printable operator--(basic_printable& p, int) throw (except) { const basic_printable old = p; --p; return old; } template inline const basic_printable operator+(basic_printable p, int i) throw (except) { return p += i; } template inline const basic_printable operator+(int i, basic_printable p) throw (except) { return p += i; } template inline const basic_printable operator-(basic_printable p, int i) throw (except) { return p -= i; } template static basic_istream& operator>>(basic_istream& ist, basic_printable& p) throw (except) { CHAR c; //uninitialized variable if (ist >> c) { //if (operator>>(ist, c).operator void *()) { p = c; //p.operator=(c); } return ist; } inline wostream& operator<<(wostream& ost, wprintable_t& p) throw () { return ost << static_cast(p); } inline bool operator<(const printable_t& a, const printable_t& b) { return static_cast(a) < static_cast(b); } inline bool operator<(const wprintable_t& a, const wprintable_t& b) { return static_cast(a) < static_cast(b); } inline bool operator==(const printable_t& a, const printable_t& b) { return static_cast(a) == static_cast(b); } inline bool operator==(const wprintable_t& a, const wprintable_t& b) { return static_cast(a) == static_cast(b); } inline bool operator<=(const printable_t& a, const printable_t& b) { return static_cast(a) <= static_cast(b); } inline bool operator<=(const wprintable_t& a, const wprintable_t& b) { return static_cast(a) <= static_cast(b); } inline bool operator!=(const printable_t& a, const printable_t& b) { return !(a == b); } inline bool operator!=(const wprintable_t& a, const wprintable_t& b) { return !(a == b); } inline bool operator>(const printable_t& a, const printable_t& b) { return b < a; } inline bool operator>(const wprintable_t& a, const wprintable_t& b) { return b < a; } inline bool operator>=(const printable_t& a, const printable_t& b) { return b <= a; } inline bool operator>=(const wprintable_t& a, const wprintable_t& b) { return b <= a; } #endif