#ifndef CHECK_MANIP_HPP #define CHECK_MANIP_HPP #include #include "typeinfo.hpp" #include "error.hpp" #include "stream.hpp" namespace Check { namespace Auxiliary { typedef Stream::SingleManip::PassByRef StringManip; typedef Stream::DoubleManip::PassByRef TwoStringManip; typedef Stream::SingleManip::PassByRef CharSetManip; typedef Stream::DoubleManip::PassByRef TwoCharSetManip; typedef Stream::DoubleManip::PassByRef CharSetStringManip; typedef Stream::TripleManip::PassByRef TwoCharSetStringManip; } Stream &boolAlpha(Stream &stream); inline Auxiliary::TwoStringManip boolAlpha( const char *trueString, const char *falseString); inline Auxiliary::TwoStringManip boolAlpha( const std::string &trueString, const std::string &falseString); inline Stream &noBoolAlpha(Stream &stream); inline Stream &failAtEnd(Stream &stream); inline Stream &noFailAtEnd(Stream &stream); inline Stream &skipWhite(Stream &stream); inline Stream &noSkipWhite(Stream &stream); inline Auxiliary::CharSetManip eat(const CharSet &charSet); inline Auxiliary::CharSetManip eatUntil(const CharSet &charSet); inline Stream &eatWhite(Stream &stream); inline Stream &eatUntilWhite(Stream &stream); template inline Stream &eat(Stream &stream); template <> inline Stream &eat(Stream &stream); inline Auxiliary::TwoCharSetManip eat( const CharSet &before, const CharSet &after); inline Stream &eatLine(Stream &stream); inline Auxiliary::CharSetManip eatLine(const CharSet &before); template inline Stream::SingleManip ensure(const Type &expected); inline Auxiliary::StringManip ensure(const char *expected); inline Auxiliary::StringManip ensure(const std::string &expected); inline Auxiliary::TwoCharSetStringManip ensure( const CharSet &before, const CharSet &after, const char *expected); inline Auxiliary::TwoCharSetStringManip ensure( const CharSet &before, const CharSet &after, const std::string &expected); inline Auxiliary::StringManip ensureLine(const char *expected); inline Auxiliary::StringManip ensureLine(const std::string &expected); inline Auxiliary::CharSetStringManip ensureLine( const CharSet &before, const char *expected); inline Auxiliary::CharSetStringManip ensureLine( const CharSet &before, const std::string &expected); inline Stream &ensureEndOfLine(Stream &stream); inline Stream &ensureEnd(Stream &stream); namespace Auxiliary { inline Stream &doBoolAlpha( Stream &stream, const std::string &trueStr, const std::string &falseStr) { stream.setBoolFormat(StringBoolean); stream.setTrueString(trueStr); stream.setFalseString(falseStr); return stream; } inline Stream &doEat(Stream &stream, const CharSet &charSet) { return stream.skip(charSet); } inline Stream &doEatUntil(Stream &stream, const CharSet &charSet) { return stream.skipUntil(charSet); } inline Stream &doEat( Stream &stream, const CharSet &before, const CharSet &after) { return stream.skip(before).skipUntil(after); } inline Stream &doEatLine(Stream &stream, const CharSet &before) { stream.skip(before).skipUntil(NewLineChars).get(); return stream; } template Stream &compareValues(Stream &stream, const Type &value, const Type &expected) { const Comparer comparer(value, expected); if (!comparer.isEqual()) { const Difference diff = comparer.difference(); if (diff.isEmpty()) incite(stream.formatError(), "Unexpected value"); else raise( stream.formatError(), "Unexpected value %s instead of %s", diff.first().c_str(), diff.second().c_str()); } return stream; } template Stream &doEnsure(Stream &stream, const Type &expected) { Type value; stream >> value; return compareValues(stream, value, expected); } Stream &doEnsure(Stream &stream, const std::string &expected) { std::string value; value.reserve(expected.length()); stream.get(value); return compareValues(stream, value, expected); } Stream &doEnsure( Stream &stream, const CharSet &before, const CharSet &after, const std::string &expected) { std::string value; value.reserve(expected.length()); stream.get(value, before, after); return compareValues(stream, value, expected); } Stream &doEnsureLine(Stream &stream, const std::string &expected) { std::string value; value.reserve(expected.length()); stream.getLine(value); return compareValues(stream, value, expected); } Stream &doEnsureLine( Stream &stream, const CharSet &before, const std::string &expected) { std::string value; value.reserve(expected.length()); stream.getLine(value, before); return compareValues(stream, value, expected); } } Stream &boolAlpha(Stream &stream) { stream.setBoolFormat(StringBoolean); stream.setTrueString("YES"); stream.setFalseString("NO"); return stream; } Auxiliary::TwoStringManip boolAlpha( const char *trueString, const char *falseString) { return Auxiliary::TwoStringManip(Auxiliary::doBoolAlpha, trueString, falseString); } Auxiliary::TwoStringManip boolAlpha( const std::string &trueString, const std::string &falseString) { return Auxiliary::TwoStringManip(Auxiliary::doBoolAlpha, trueString, falseString); } Stream &noBoolAlpha(Stream &stream) { stream.setBoolFormat(IntegerBoolean); return stream; } Stream &failAtEnd(Stream &stream) { stream.setEndMode(FailAtEnd); return stream; } Stream &noFailAtEnd(Stream &stream) { stream.setEndMode(IgnoreEnd); return stream; } Stream &skipWhite(Stream &stream) { stream.setWhiteMode(SkipWhite); return stream; } Stream &noSkipWhite(Stream &stream) { stream.setWhiteMode(ConsiderWhite); return stream; } Auxiliary::CharSetManip eat(const CharSet &charSet) { return Auxiliary::CharSetManip(Auxiliary::doEat, charSet); } Auxiliary::CharSetManip eatUntil(const CharSet &charSet) { return Auxiliary::CharSetManip(Auxiliary::doEatUntil, charSet); } Stream &eatWhite(Stream &stream) { return stream.skip(SpaceChars); } Stream &eatUntilWhite(Stream &stream) { return stream.skipUntil(SpaceChars); } template Stream &eat(Stream &stream) { Type value; return stream >> value; } template <> Stream &eat(Stream &stream) { return stream.skip(stream.beforeWord()).skipUntil(SpaceChars); } Auxiliary::TwoCharSetManip eat(const CharSet &before, const CharSet &after) { return Auxiliary::TwoCharSetManip(Auxiliary::doEat, before, after); } Stream &eatLine(Stream &stream) { stream.skipUntil(NewLineChars).get(); return stream; } Auxiliary::CharSetManip eatLine(const CharSet &before) { return Auxiliary::CharSetManip(Auxiliary::doEatLine, before); } template Stream::SingleManip ensure(const Type &expected) { return Stream::SingleManip(Auxiliary::doEnsure, expected); } Auxiliary::StringManip ensure(const char *expected) { return Auxiliary::StringManip(Auxiliary::doEnsure, expected); } Auxiliary::StringManip ensure(const std::string &expected) { return Auxiliary::StringManip(Auxiliary::doEnsure, expected); } Auxiliary::TwoCharSetStringManip ensure( const CharSet &before, const CharSet &after, const char *expected) { return Auxiliary::TwoCharSetStringManip( Auxiliary::doEnsure, before, after, expected); } Auxiliary::TwoCharSetStringManip ensure( const CharSet &before, const CharSet &after, const std::string &expected) { return Auxiliary::TwoCharSetStringManip( Auxiliary::doEnsure, before, after, expected); } Auxiliary::StringManip ensureLine(const char *expected) { return Auxiliary::StringManip(Auxiliary::doEnsureLine, expected); } Auxiliary::StringManip ensureLine(const std::string &expected) { return Auxiliary::StringManip(Auxiliary::doEnsureLine, expected); } Auxiliary::CharSetStringManip ensureLine( const CharSet &before, const char *expected) { return Auxiliary::CharSetStringManip(Auxiliary::doEnsureLine, before, expected); } Auxiliary::CharSetStringManip ensureLine( const CharSet &before, const std::string &expected) { return Auxiliary::CharSetStringManip(Auxiliary::doEnsureLine, before, expected); } Stream &ensureEndOfLine(Stream &stream) { if (!stream.seekEndOfLine()) incite(stream.formatError(), "Extra information"); return stream; } Stream &ensureEnd(Stream &stream) { if (!stream.seekEnd()) incite(stream.formatError(), "Extra information"); return stream; } } #endif /* CHECK_MANIP_HPP */