#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <locale>
#include <stdexcept>
#include <string>
template <typename Value, typename To>
To make_roman(Value value, To to) {
if (value < 1 || 3999 < value) {
throw std::range_error("int out of range for a Roman numeral");
}
static std::string const digits[4][10] = {
{ "", "M", "MM", "MMM", "", "", "", "", "", "" },
{ "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" },
{ "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" },
{ "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" },
};
for (int i(0), factor(1000); i != 4; ++i, factor /= 10) {
std::string const& s(digits[i][(value / factor) % 10]);
to = std::copy(s.begin(), s.end(), to);
}
return to;
}
class num_put
: public std::num_put<char>
{
template <typename Value>
iter_type format(iter_type to, std::ios_base& fmt, char fill,
Value v) const {
char buffer[16];
char* end(make_roman(v, buffer));
std::streamsize len(end - buffer);
std::streamsize width(std::max(fmt.width(0), len));
std::streamsize fc(width - (end - buffer));
switch (fmt.flags() & std::ios_base::adjustfield) {
default:
case std::ios_base::left:
to = std::copy(buffer, end, to);
to = std::fill_n(to, fc, fill);
break;
case std::ios_base::right:
case std::ios_base::internal:
to = std::fill_n(to, fc, fill);
to = std::copy(buffer, end, to);
}
return to;
}
iter_type do_put(iter_type to, std::ios_base& fmt, char fill,
long v) const {
return this->format(to, fmt, fill, v);
}
iter_type do_put(iter_type to, std::ios_base& fmt, char fill,
long long v) const {
return this->format(to, fmt, fill, v);
}
iter_type do_put(iter_type to, std::ios_base& fmt, char fill,
unsigned long v) const {
return this->format(to, fmt, fill, v);
}
iter_type do_put(iter_type to, std::ios_base& fmt, char fill,
unsigned long long v) const {
return this->format(to, fmt, fill, v);
}
};
int main()
{
try {
std::locale rloc(std::locale(), new num_put);
std::ostream lout(std::cout.rdbuf());
std::ostream rout(std::cout.rdbuf());
(lout << std::left).imbue(rloc);
(rout << std::right).imbue(rloc);
lout << "long=" << static_cast<long>(1234) << '\n'
<< "unsigned long=" << static_cast<unsigned long>(1234) << '\n'
<< "long long=" << static_cast<long long>(1234) << '\n'
<< "unsigned long long=" << static_cast<unsigned long long>(1234) << '\n'
;
for (int i = 59; i < 4000; i += 59) {
std::cout << std::setw(4) << i << '=';
lout << '\'' << std::setw(12) << i << "' ";
rout << '\'' << std::setw(12) << i << "'\n";
}
}
catch (std::exception const& ex) {
std::cout << "ERROR: " << ex.what() << '\n';
}
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGl0ZXJhdG9yPgojaW5jbHVkZSA8bG9jYWxlPgojaW5jbHVkZSA8c3RkZXhjZXB0PgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlLCB0eXBlbmFtZSBUbz4KVG8gbWFrZV9yb21hbihWYWx1ZSB2YWx1ZSwgVG8gdG8pIHsKICAgIGlmICh2YWx1ZSA8IDEgfHwgMzk5OSA8IHZhbHVlKSB7CiAgICAgICAgdGhyb3cgc3RkOjpyYW5nZV9lcnJvcigiaW50IG91dCBvZiByYW5nZSBmb3IgYSBSb21hbiBudW1lcmFsIik7CiAgICB9CiAgICBzdGF0aWMgc3RkOjpzdHJpbmcgY29uc3QgZGlnaXRzWzRdWzEwXSA9IHsKICAgICAgICB7ICIiLCAiTSIsICJNTSIsICJNTU0iLCAiIiwgIiIsICIiLCAiIiwgIiIsICIiIH0sCiAgICAgICAgeyAiIiwgIkMiLCAiQ0MiLCAiQ0NDIiwgIkNEIiwgIkQiLCAiREMiLCAiRENDIiwgIkRDQ0MiLCAiQ00iIH0sCiAgICAgICAgeyAiIiwgIlgiLCAiWFgiLCAiWFhYIiwgIlhMIiwgIkwiLCAiTFgiLCAiTFhYIiwgIkxYWFgiLCAiWEMiIH0sCiAgICAgICAgeyAiIiwgIkkiLCAiSUkiLCAiSUlJIiwgIklWIiwgIlYiLCAiVkkiLCAiVklJIiwgIlZJSUkiLCAiSVgiIH0sCiAgICB9OwogICAgZm9yIChpbnQgaSgwKSwgZmFjdG9yKDEwMDApOyBpICE9IDQ7ICsraSwgZmFjdG9yIC89IDEwKSB7CiAgICAgICAgc3RkOjpzdHJpbmcgY29uc3QmIHMoZGlnaXRzW2ldWyh2YWx1ZSAvIGZhY3RvcikgJSAxMF0pOwogICAgICAgIHRvID0gc3RkOjpjb3B5KHMuYmVnaW4oKSwgcy5lbmQoKSwgdG8pOwogICAgfQogICAgcmV0dXJuIHRvOwp9CgogICAgY2xhc3MgbnVtX3B1dAogICAgICAgIDogcHVibGljIHN0ZDo6bnVtX3B1dDxjaGFyPgogICAgewogICAgICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KICAgICAgICBpdGVyX3R5cGUgZm9ybWF0KGl0ZXJfdHlwZSB0bywgc3RkOjppb3NfYmFzZSYgZm10LCBjaGFyIGZpbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSB2KSBjb25zdCB7CiAgICAgICAgICAgIGNoYXIgYnVmZmVyWzE2XTsKICAgICAgICAgICAgY2hhciogZW5kKG1ha2Vfcm9tYW4odiwgYnVmZmVyKSk7CiAgICAKICAgICAgICAgICAgc3RkOjpzdHJlYW1zaXplIGxlbihlbmQgLSBidWZmZXIpOwogICAgICAgICAgICBzdGQ6OnN0cmVhbXNpemUgd2lkdGgoc3RkOjptYXgoZm10LndpZHRoKDApLCBsZW4pKTsKICAgICAgICAgICAgc3RkOjpzdHJlYW1zaXplIGZjKHdpZHRoIC0gKGVuZCAtIGJ1ZmZlcikpOwogICAgICAgICAgICBzd2l0Y2ggKGZtdC5mbGFncygpICYgc3RkOjppb3NfYmFzZTo6YWRqdXN0ZmllbGQpIHsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgY2FzZSBzdGQ6Omlvc19iYXNlOjpsZWZ0OgogICAgICAgICAgICAgICAgdG8gPSBzdGQ6OmNvcHkoYnVmZmVyLCBlbmQsIHRvKTsKICAgICAgICAgICAgICAgIHRvID0gc3RkOjpmaWxsX24odG8sIGZjLCBmaWxsKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHN0ZDo6aW9zX2Jhc2U6OnJpZ2h0OgogICAgICAgICAgICBjYXNlIHN0ZDo6aW9zX2Jhc2U6OmludGVybmFsOgogICAgICAgICAgICAgICAgdG8gPSBzdGQ6OmZpbGxfbih0bywgZmMsIGZpbGwpOwogICAgICAgICAgICAgICAgdG8gPSBzdGQ6OmNvcHkoYnVmZmVyLCBlbmQsIHRvKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdG87CiAgICAgICAgfQogICAgICAgIGl0ZXJfdHlwZSBkb19wdXQoaXRlcl90eXBlIHRvLCBzdGQ6Omlvc19iYXNlJiBmbXQsIGNoYXIgZmlsbCwKICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgdikgY29uc3QgewogICAgICAgICAgICByZXR1cm4gdGhpcy0+Zm9ybWF0KHRvLCBmbXQsIGZpbGwsIHYpOwogICAgICAgIH0KICAgICAgICBpdGVyX3R5cGUgZG9fcHV0KGl0ZXJfdHlwZSB0bywgc3RkOjppb3NfYmFzZSYgZm10LCBjaGFyIGZpbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICBsb25nIGxvbmcgdikgY29uc3QgewogICAgICAgICAgICByZXR1cm4gdGhpcy0+Zm9ybWF0KHRvLCBmbXQsIGZpbGwsIHYpOwogICAgICAgIH0KICAgICAgICBpdGVyX3R5cGUgZG9fcHV0KGl0ZXJfdHlwZSB0bywgc3RkOjppb3NfYmFzZSYgZm10LCBjaGFyIGZpbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIHYpIGNvbnN0IHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMtPmZvcm1hdCh0bywgZm10LCBmaWxsLCB2KTsKICAgICAgICB9CiAgICAgICAgaXRlcl90eXBlIGRvX3B1dChpdGVyX3R5cGUgdG8sIHN0ZDo6aW9zX2Jhc2UmIGZtdCwgY2hhciBmaWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBsb25nIHYpIGNvbnN0IHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMtPmZvcm1hdCh0bywgZm10LCBmaWxsLCB2KTsKICAgICAgICB9CiAgICB9OwogCmludCBtYWluKCkKewogICAgdHJ5IHsKICAgICAgICBzdGQ6OmxvY2FsZSAgcmxvYyhzdGQ6OmxvY2FsZSgpLCBuZXcgbnVtX3B1dCk7CiAgICAgICAgc3RkOjpvc3RyZWFtIGxvdXQoc3RkOjpjb3V0LnJkYnVmKCkpOwogICAgICAgIHN0ZDo6b3N0cmVhbSByb3V0KHN0ZDo6Y291dC5yZGJ1ZigpKTsKICAgICAgICAobG91dCA8PCBzdGQ6OmxlZnQpLmltYnVlKHJsb2MpOwogICAgICAgIChyb3V0IDw8IHN0ZDo6cmlnaHQpLmltYnVlKHJsb2MpOwoKICAgICAgICBsb3V0IDw8ICJsb25nPSIgPDwgc3RhdGljX2Nhc3Q8bG9uZz4oMTIzNCkgPDwgJ1xuJwogICAgICAgICAgICAgPDwgInVuc2lnbmVkIGxvbmc9IiA8PCBzdGF0aWNfY2FzdDx1bnNpZ25lZCBsb25nPigxMjM0KSA8PCAnXG4nCiAgICAgICAgICAgICA8PCAibG9uZyBsb25nPSIgPDwgc3RhdGljX2Nhc3Q8bG9uZyBsb25nPigxMjM0KSA8PCAnXG4nCiAgICAgICAgICAgICA8PCAidW5zaWduZWQgbG9uZyBsb25nPSIgPDwgc3RhdGljX2Nhc3Q8dW5zaWduZWQgbG9uZyBsb25nPigxMjM0KSA8PCAnXG4nCiAgICAgICAgICAgIDsKCiAgICAgICAgZm9yIChpbnQgaSA9IDU5OyBpIDwgNDAwMDsgaSArPSA1OSkgewogICAgICAgICAgICBzdGQ6OmNvdXQgPDwgc3RkOjpzZXR3KDQpIDw8IGkgPDwgJz0nOwogICAgICAgICAgICBsb3V0IDw8ICdcJycgPDwgc3RkOjpzZXR3KDEyKSA8PCBpIDw8ICInICI7CiAgICAgICAgICAgIHJvdXQgPDwgJ1wnJyA8PCBzdGQ6OnNldHcoMTIpIDw8IGkgPDwgIidcbiI7CiAgICAgICAgfQogICAgfQogICAgY2F0Y2ggKHN0ZDo6ZXhjZXB0aW9uIGNvbnN0JiBleCkgewogICAgICAgIHN0ZDo6Y291dCA8PCAiRVJST1I6ICIgPDwgZXgud2hhdCgpIDw8ICdcbic7CiAgICB9Cn0K