Advertisement
Guest User

Untitled

a guest
Feb 6th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.28 KB | None | 0 0
  1. #include <type_traits>
  2. #include <iostream>
  3.  
  4. struct no_validation {
  5. template <typename T>
  6. constexpr bool operator()(T value) {
  7. return true;
  8. }
  9. };
  10.  
  11. template <typename Validator>
  12. class validator_traits {
  13. template <typename C> static constexpr std::true_type _has_message(decltype(&C::message));
  14. template <typename C> static constexpr std::false_type _has_message(...);
  15. template <typename C> static constexpr const char* _message(decltype(&C::message)) {
  16. return C::message;
  17. }
  18. template <typename C> static constexpr const char* _message(...) {
  19. return nullptr;
  20. }
  21. public:
  22. // true if there is a message associated with Validator; otherwise, false
  23. static constexpr bool has_message = std::is_same<
  24. decltype(_has_message<Validator>(nullptr)), std::true_type>();
  25.  
  26. // returns nullptr if there is no message associated with Validator
  27. static constexpr const char* message = _message<Validator>();
  28. };
  29.  
  30. // usage: int x = prompt<int>("x");
  31. // /* do something with x */
  32. //
  33. // int y = prompt<int>("y", [](auto y){ return y > 0; });
  34. // /* do something with y */
  35. //
  36. // // displays an associated validation message when validation fails
  37. // struct greater_than_zero {
  38. // static constexpr const char* message = "requires input to be greater than zero";
  39. // bool operator()(int x) { return x > 0; }
  40. // };
  41. // int z = prompt<int>("z", greater_than_zero());
  42. // /* do something with z */
  43. template <typename Result, typename Validator = no_validation, typename Traits = validator_traits<Validator>>
  44. Result prompt(const char* msg, Validator v = Validator()) {
  45. Result result;
  46. for (;;) {
  47. std::cout << msg << ": ";
  48. if (std::cin >> result) {
  49. if (v(result)) {
  50. return result;
  51. } else {
  52. if (Traits::has_message) {
  53. std::cout << Traits::message << std::endl;
  54. }
  55. }
  56. } else if (std::cin.fail()) {
  57. // typically set because formatted extraction failed
  58. std::cout << "wrong type entered" << std::endl;
  59. std::cin.clear();
  60. // discard all input data up to the newline
  61. std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  62. } else if (std::cin.eof() || std::cin.bad()) {
  63. throw std::runtime_error("input failure: std::cin eof or bad bits set");
  64. }
  65. }
  66. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement