cast.h 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. //
  2. // cast.h
  3. // string-utils
  4. //
  5. // Created by Sam Jaffe on 2/13/21.
  6. // Copyright © 2021 Sam Jaffe. All rights reserved.
  7. //
  8. #pragma once
  9. #include <cstdlib>
  10. #include <string>
  11. #include <type_traits>
  12. #include <utility>
  13. #include "any_of.h"
  14. #define cast_number_impl(type, func, ...) \
  15. bool cast(std::string const &str, type &to) { \
  16. char *rval; \
  17. to = func(str.c_str(), &rval, ##__VA_ARGS__); \
  18. return rval == str.c_str() + str.length(); \
  19. }
  20. namespace string_utils {
  21. template <typename T, typename = std::enable_if_t<std::is_constructible<T, std::string const &>{}>>
  22. bool cast(std::string const &str, std::string &to) { to = T(str); return true; }
  23. cast_number_impl(long, std::strtol, 10)
  24. cast_number_impl(long long, std::strtoll, 10)
  25. cast_number_impl(float, std::strtof)
  26. cast_number_impl(double, std::strtod)
  27. cast_number_impl(long double, std::strtold)
  28. bool cast(std::string const &str, int &to) {
  29. long tmp;
  30. bool rval = cast(str, tmp);
  31. to = static_cast<int>(tmp);
  32. return rval && tmp == static_cast<long>(to);
  33. }
  34. bool cast(std::string const &str, bool &to) {
  35. if (any_of(str, "true", "TRUE", "YES", "1")) {
  36. to = true;
  37. return true;
  38. } else if (any_of(str, "false", "FALSE", "NO", "0")) {
  39. to = false;
  40. return true;
  41. }
  42. return false;
  43. }
  44. template <typename T>
  45. auto cast(std::string const &str) {
  46. using string_utils::cast;
  47. std::pair<T, bool> rval;
  48. rval.second = cast(str, rval.first);
  49. return rval;
  50. }
  51. }