#include <string>
#include <stdexcept>
#include <iostream>
template <class T>
struct ConstrainedText {
std::string m;
protected:
ConstrainedText() {}
~ConstrainedText() {}
public:
bool is_valid() {
return T::is_valid_string(m);
}
static T Create(std::string const & s)
{
if (T::is_valid_string(s)) {
T t;
static_cast<ConstrainedText<T>&>(t).m = s;
return t;
}
throw std::runtime_error("invalid input!");
}
};
struct Angle : public ConstrainedText<Angle> {
static bool is_valid_string( std::string s ) {
return s == "deg" || s=="rad";
}
};
struct Length : public ConstrainedText<Length> {
static bool is_valid_string( std::string s ) {
return s == "mm" || s == "m" || s == "ft" || s == "in";
}
};
int main()
{
auto a = Angle::Create("deg");
auto l = Length::Create("mm");
try {
Angle::Create("bimbo");
} catch (std::runtime_error & pEx) {
std::cout << "exception as expected" << std::endl;
}
try {
Length::Create("bimbo");
} catch (std::runtime_error & pEx) {
std::cout << "exception as expected" << std::endl;
}
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHN0ZGV4Y2VwdD4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPGNsYXNzIFQ+ICAgICAgICAKc3RydWN0IENvbnN0cmFpbmVkVGV4dCB7ICAgICAgICAKICBzdGQ6OnN0cmluZyBtOyAgICAgICAgICAgICAgICAgCgpwcm90ZWN0ZWQ6CiAgQ29uc3RyYWluZWRUZXh0KCkge30KICB+Q29uc3RyYWluZWRUZXh0KCkge30KcHVibGljOiAKICBib29sIGlzX3ZhbGlkKCkgeyAgICAgICAgCiAgICByZXR1cm4gVDo6aXNfdmFsaWRfc3RyaW5nKG0pOyAgICAgICAgCiAgfSAgICAgICAgCiAgICAgICAgCiAgc3RhdGljIFQgQ3JlYXRlKHN0ZDo6c3RyaW5nIGNvbnN0ICYgcykKICB7CiAgICAgIGlmIChUOjppc192YWxpZF9zdHJpbmcocykpIHsKICAgICAgICAgIFQgdDsKICAgICAgICAgIHN0YXRpY19jYXN0PENvbnN0cmFpbmVkVGV4dDxUPiY+KHQpLm0gPSBzOwogICAgICAgICAgcmV0dXJuIHQ7CiAgICAgIH0KCiAgICAgIHRocm93IHN0ZDo6cnVudGltZV9lcnJvcigiaW52YWxpZCBpbnB1dCEiKTsKICB9Cn07ICAgICAgICAKICAgICAgICAKc3RydWN0IEFuZ2xlIDogcHVibGljIENvbnN0cmFpbmVkVGV4dDxBbmdsZT4geyAgICAgICAgCiAgIHN0YXRpYyBib29sIGlzX3ZhbGlkX3N0cmluZyggc3RkOjpzdHJpbmcgcyApIHsgICAgICAgICAKICAgICAgcmV0dXJuIHMgPT0gImRlZyIgfHwgcz09InJhZCI7ICAgICAgICAKICAgfSAgICAgICAgICAKfTsgICAgICAgIAogICAgICAgIAogICAgICAgIApzdHJ1Y3QgTGVuZ3RoIDogcHVibGljIENvbnN0cmFpbmVkVGV4dDxMZW5ndGg+IHsgICAgICAgIAogICBzdGF0aWMgYm9vbCBpc192YWxpZF9zdHJpbmcoIHN0ZDo6c3RyaW5nIHMgKSB7ICAgICAgICAgCiAgICAgIHJldHVybiBzID09ICJtbSIgfHwgcyA9PSAibSIgfHwgcyA9PSAiZnQiIHx8IHMgPT0gImluIjsgICAgICAgIAogICB9ICAgICAgICAgIAp9OyAgICAgICAgCgppbnQgbWFpbigpCnsKICAgYXV0byBhID0gQW5nbGU6OkNyZWF0ZSgiZGVnIik7CiAgIGF1dG8gbCA9IExlbmd0aDo6Q3JlYXRlKCJtbSIpOwoKICAgdHJ5IHsKICAgICAgIEFuZ2xlOjpDcmVhdGUoImJpbWJvIik7CiAgIH0gY2F0Y2ggKHN0ZDo6cnVudGltZV9lcnJvciAmIHBFeCkgewogICAgICAgc3RkOjpjb3V0IDw8ICJleGNlcHRpb24gYXMgZXhwZWN0ZWQiIDw8IHN0ZDo6ZW5kbDsKICAgfQoKICAgdHJ5IHsKICAgICAgIExlbmd0aDo6Q3JlYXRlKCJiaW1ibyIpOwogICB9IGNhdGNoIChzdGQ6OnJ1bnRpbWVfZXJyb3IgJiBwRXgpIHsKICAgICAgIHN0ZDo6Y291dCA8PCAiZXhjZXB0aW9uIGFzIGV4cGVjdGVkIiA8PCBzdGQ6OmVuZGw7CiAgIH0KfQ==