#include <string>
#include <type_traits>
#include <vector>
template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
class NumWords {
public:
/** Возвращает единицу измерения с правильным окончанием
* например:
* формы: день, дня, дней
* 1 день, 2 дня, 5 дней
* @param form1 1 форма (например, день)
* @param form2 2 форма (например, дня)
* @param form3 3 форма (например, дней)
*/
NumWords(const std::string &form1, const std::string &form2, const std::string &form3)
: forms{form1, form2, form3} {}
/** Возвращает единицу измерения с правильным окончанием
* например:
* формы: hour, hours
* 1 hour, 2 hours, 5 hours
* @param form1 1 форма (например, hour)
* @param form2 2 форма (например, hours)
*/
NumWords(const std::string &form1, const std::string &form2) : forms{form1, form2} {}
const std::string &operator[](T value) const {
if (forms.size() == 2) {
if ((value == 1) || (value < 0 && static_cast<typename std::make_signed<T>::type>(value) == -1)) {
return forms[0];
}
return forms[1];
}
auto data_100 = std::abs(static_cast<int>(value % 100));
if (data_100 > 10 && data_100 < 20) return forms[2];
auto data = std::abs(static_cast<int>(value % 10));
if (data >= 5) return forms[2];
if (data >= 2) return forms[1];
if (data == 0) return forms[2];
return forms[0];
}
private:
const std::vector<std::string> forms;
};
#include <iostream>
int main()
{
NumWords<int> words("минута", "минуты", "минут");
std::cout << 22 << words[22] << std::endl;
std::cout << 12 << words[12] << std::endl;
}
CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KI2luY2x1ZGUgPHZlY3Rvcj4KCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSA9IHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPHN0ZDo6aXNfaW50ZWdyYWw8VD46OnZhbHVlPjo6dHlwZT4KY2xhc3MgTnVtV29yZHMgewogICBwdWJsaWM6CgkvKiog0JLQvtC30LLRgNCw0YnQsNC10YIg0LXQtNC40L3QuNGG0YMg0LjQt9C80LXRgNC10L3QuNGPINGBINC/0YDQsNCy0LjQu9GM0L3Ri9C8INC+0LrQvtC90YfQsNC90LjQtdC8CgkgKiDQvdCw0L/RgNC40LzQtdGAOgoJICog0YTQvtGA0LzRizog0LTQtdC90YwsINC00L3Rjywg0LTQvdC10LkKCSAqIDEg0LTQtdC90YwsIDIg0LTQvdGPLCA1INC00L3QtdC5CgkgKiBAcGFyYW0gZm9ybTEgMSDRhNC+0YDQvNCwICjQvdCw0L/RgNC40LzQtdGALCDQtNC10L3RjCkKCSAqIEBwYXJhbSBmb3JtMiAyINGE0L7RgNC80LAgKNC90LDQv9GA0LjQvNC10YAsINC00L3RjykKCSAqIEBwYXJhbSBmb3JtMyAzINGE0L7RgNC80LAgKNC90LDQv9GA0LjQvNC10YAsINC00L3QtdC5KQoJICovCglOdW1Xb3Jkcyhjb25zdCBzdGQ6OnN0cmluZyAmZm9ybTEsIGNvbnN0IHN0ZDo6c3RyaW5nICZmb3JtMiwgY29uc3Qgc3RkOjpzdHJpbmcgJmZvcm0zKQoJICAgIDogZm9ybXN7Zm9ybTEsIGZvcm0yLCBmb3JtM30ge30KCgkvKiog0JLQvtC30LLRgNCw0YnQsNC10YIg0LXQtNC40L3QuNGG0YMg0LjQt9C80LXRgNC10L3QuNGPINGBINC/0YDQsNCy0LjQu9GM0L3Ri9C8INC+0LrQvtC90YfQsNC90LjQtdC8CgkgKiDQvdCw0L/RgNC40LzQtdGAOgoJICog0YTQvtGA0LzRizogaG91ciwgaG91cnMKCSAqIDEgaG91ciwgMiBob3VycywgNSBob3VycwoJICogQHBhcmFtIGZvcm0xIDEg0YTQvtGA0LzQsCAo0L3QsNC/0YDQuNC80LXRgCwgaG91cikKCSAqIEBwYXJhbSBmb3JtMiAyINGE0L7RgNC80LAgKNC90LDQv9GA0LjQvNC10YAsIGhvdXJzKQoJICovCglOdW1Xb3Jkcyhjb25zdCBzdGQ6OnN0cmluZyAmZm9ybTEsIGNvbnN0IHN0ZDo6c3RyaW5nICZmb3JtMikgOiBmb3Jtc3tmb3JtMSwgZm9ybTJ9IHt9CgoJY29uc3Qgc3RkOjpzdHJpbmcgJm9wZXJhdG9yW10oVCB2YWx1ZSkgY29uc3QgewoJCWlmIChmb3Jtcy5zaXplKCkgPT0gMikgewoJCQlpZiAoKHZhbHVlID09IDEpIHx8ICh2YWx1ZSA8IDAgJiYgc3RhdGljX2Nhc3Q8dHlwZW5hbWUgc3RkOjptYWtlX3NpZ25lZDxUPjo6dHlwZT4odmFsdWUpID09IC0xKSkgewoJCQkJcmV0dXJuIGZvcm1zWzBdOwoJCQl9CgkJCXJldHVybiBmb3Jtc1sxXTsKCQl9CgkJYXV0byBkYXRhXzEwMCA9IHN0ZDo6YWJzKHN0YXRpY19jYXN0PGludD4odmFsdWUgJSAxMDApKTsKCQlpZiAoZGF0YV8xMDAgPiAxMCAmJiBkYXRhXzEwMCA8IDIwKSByZXR1cm4gZm9ybXNbMl07CgkJYXV0byBkYXRhID0gc3RkOjphYnMoc3RhdGljX2Nhc3Q8aW50Pih2YWx1ZSAlIDEwKSk7CgkJaWYgKGRhdGEgPj0gNSkgcmV0dXJuIGZvcm1zWzJdOwoJCWlmIChkYXRhID49IDIpIHJldHVybiBmb3Jtc1sxXTsKCQlpZiAoZGF0YSA9PSAwKSByZXR1cm4gZm9ybXNbMl07CgkJcmV0dXJuIGZvcm1zWzBdOwoJfQoKICAgcHJpdmF0ZToKCWNvbnN0IHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBmb3JtczsKfTsKCiNpbmNsdWRlIDxpb3N0cmVhbT4KaW50IG1haW4oKQp7CiAgICBOdW1Xb3JkczxpbnQ+IHdvcmRzKCLQvNC40L3Rg9GC0LAiLCAi0LzQuNC90YPRgtGLIiwgItC80LjQvdGD0YIiKTsKICAgIHN0ZDo6Y291dCA8PCAyMiA8PCB3b3Jkc1syMl0gPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8IDEyIDw8IHdvcmRzWzEyXSA8PCBzdGQ6OmVuZGw7Cgp9Cg==