Краевая олимпиада 2019. Дорешивание / std.check.src.manip.hpp

ru en cn

с начала прошло: 2155 д. 10:57
страница обновлена: 22.12.2024 02:58

std.check.src.manip.hpp: src/manip.hpp

#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 */
Дальневосточный федеральный университет