Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <type_traits>
- #include <iostream>
- struct no_validation {
- template <typename T>
- constexpr bool operator()(T value) {
- return true;
- }
- };
- template <typename Validator>
- class validator_traits {
- template <typename C> static constexpr std::true_type _has_message(decltype(&C::message));
- template <typename C> static constexpr std::false_type _has_message(...);
- template <typename C> static constexpr const char* _message(decltype(&C::message)) {
- return C::message;
- }
- template <typename C> static constexpr const char* _message(...) {
- return nullptr;
- }
- public:
- // true if there is a message associated with Validator; otherwise, false
- static constexpr bool has_message = std::is_same<
- decltype(_has_message<Validator>(nullptr)), std::true_type>();
- // returns nullptr if there is no message associated with Validator
- static constexpr const char* message = _message<Validator>();
- };
- // usage: int x = prompt<int>("x");
- // /* do something with x */
- //
- // int y = prompt<int>("y", [](auto y){ return y > 0; });
- // /* do something with y */
- //
- // // displays an associated validation message when validation fails
- // struct greater_than_zero {
- // static constexpr const char* message = "requires input to be greater than zero";
- // bool operator()(int x) { return x > 0; }
- // };
- // int z = prompt<int>("z", greater_than_zero());
- // /* do something with z */
- template <typename Result, typename Validator = no_validation, typename Traits = validator_traits<Validator>>
- Result prompt(const char* msg, Validator v = Validator()) {
- Result result;
- for (;;) {
- std::cout << msg << ": ";
- if (std::cin >> result) {
- if (v(result)) {
- return result;
- } else {
- if (Traits::has_message) {
- std::cout << Traits::message << std::endl;
- }
- }
- } else if (std::cin.fail()) {
- // typically set because formatted extraction failed
- std::cout << "wrong type entered" << std::endl;
- std::cin.clear();
- // discard all input data up to the newline
- std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
- } else if (std::cin.eof() || std::cin.bad()) {
- throw std::runtime_error("input failure: std::cin eof or bad bits set");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement