
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <random>
#include <cctype>


using namespace std;

// // klasa bazowa do konwersji napisów
// class StrConverter {
// public:
//     StrConverter(const string& in) : INPUT(in) { }
//     virtual std::string convert()  {
//         return doConvert(INPUT);
//     }
// private:
//     virtual string doConvert(const string& in) = 0;
//     const string& INPUT;
// };

// // zamienia male litery ASCII na odpowiadające im wielkie litery
// class StrToUpper : public StrConverter {
// public:
//     StrToUpper(const std::string& in) : StrConverter(in) {}
// private:
//     virtual string doConvert(const string& in) {
//         string out;
//         for(int i=0; i< in.size(); ++i) {
//             out.push_back( toupper( in[i] ) );
//             //toupper zmienia na wielka litere. 'toupper' wystarczy w tym zadaniu
//             //znaki poza ASCII nie musza byc konwertowane.
//         }
//         return out;
//     }
// };

// // zamienia sekwencje bialych znakow na pojedynczą spacje
// class StrCutWhite : public StrConverter {
// public:
//     StrCutWhite(const std::string& in) : StrConverter(in) {}
// private:
//     virtual string doConvert(const string& in) {
//         string out;
//         bool drop = false;
//         for( char c : in ) {
//             if( isspace(c) ) { //w tym zadaniu 'isspace' wystarczy
//                 if( !drop ) {
//                     drop = true; //bedzie pomijal biale znaki
//                     out.push_back(' ');
//                 }
//             } else { //to nie bialy znak
//                 drop = false;
//                 out.push_back(c);
//             }
//         }
//         return out;
//     }
// };

// //po kazdych N znakach wstawia znak nowej linii
// class StrMaxLine : public StrConverter {
// public:
//     StrMaxLine(const string& in, unsigned int maxline) : StrConverter(in), MAX_LINE_(maxline) {}
// private:
//     const unsigned int MAX_LINE_; //przechowuje N
//     virtual string doConvert(const string& in) {
//         string out;
//         unsigned int count = 0;
//         for( string::const_iterator i = in.begin(); i < in.end(); ++i ) {
//             out.push_back(*i);
//             ++count;
//             if(count >= MAX_LINE_) {
//                 out.push_back('\n');
//                 count = 0;
//             }
//         }
//         return out;
//     }
// };


// /** klasa bazowa do konwersji napisów */
class StrConverter {
public:
	StrConverter(const string& in) : INPUT(in) { }

	std::string convert() {
		std::string out;
		for( char c : INPUT ) {
			string cc = convertChar(c);
			out += cc;
		}
		return out;
	}
private:
	virtual string convertChar(char c) = 0;
	const string& INPUT;
};


class StrToUpper : public StrConverter {
public:
	StrToUpper(const std::string& in) : StrConverter(in) {}
private:
	virtual string convertChar(char c) {
		return string( 1, toupper( c ) );
	}
};


class StrCutWhite : public StrConverter {
public:
	StrCutWhite(const std::string& in) : StrConverter(in) {}
private:
	bool drop_;

	virtual string convertChar(char c) {
		if( isspace(c) ) { //w tym zadaniu 'isspace' wystarczy
			if( drop_ )
				return string(); //empty string
			else {
				drop_ = true; //bedzie pomijal biale znaki
				return string(1, ' ');
			}
		} else { //to nie bialy znak
			drop_ = false;
			return string(1, c);
		}
	}
};


/** konwersja napisu, po każdych N znakach wstawia znak '\n', tzn. nowej linii */
class StrMaxLine : public StrConverter {
public:
	StrMaxLine(const string& in, unsigned int maxline) : StrConverter(in), MAX_LINE_(maxline), count_(0) {}
private:
	const unsigned int MAX_LINE_; //maximum chars number in line
	unsigned int count_;

	virtual string convertChar(char c) {
		string out(1, c);
		++count_;
		if(count_ >= MAX_LINE_) {
			out += '\n';
			count_ = 0;
		}
		return out;
	}
};

int main() {

    string s = R"(
/** klasa bazowa do transformat napisów */
class StringConverter {
public:
    StringConverter() { }
    virtual std::string convert(const std::string& in)  = 0;
};
)";
    cout << StrToUpper(s).convert() << endl;
    cout << StrCutWhite(s).convert() << endl;
    cout << StrMaxLine(s,10).convert() << endl;
    return 0;
}
