dyn_limit.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //
  2. // dyn_limit.h
  3. // pokemon
  4. //
  5. // Created by Sam Jaffe on 12/1/23.
  6. // Copyright © 2023 Sam Jaffe. All rights reserved.
  7. //
  8. #pragma once
  9. #include <math/clamp.h>
  10. #include <math/limit.h>
  11. namespace math {
  12. template <typename T, typename B = T> class DynBound final {
  13. public:
  14. using value_type = T;
  15. using underlying_type = value_type const &;
  16. using bound_type = B;
  17. private:
  18. bound_type lower_bound_{};
  19. bound_type upper_bound_{};
  20. value_type value_{};
  21. public:
  22. DynBound() = default;
  23. DynBound(value_type value, bound_type lower_bound, bound_type upper_bound)
  24. : lower_bound_(lower_bound), upper_bound_(upper_bound),
  25. value_(clamp(value, lower_bound_, upper_bound_)) {}
  26. template <bound_type MINIMUM_VALUE, bound_type MAXIMUM_VALUE>
  27. DynBound(Bound<value_type, MINIMUM_VALUE, MAXIMUM_VALUE> const & other)
  28. : lower_bound_(MINIMUM_VALUE), upper_bound_(MAXIMUM_VALUE),
  29. value_(other) {}
  30. explicit operator value_type const &() const { return value_; }
  31. value_type const &operator*() const { return value_; }
  32. value_type const *operator->() const { return &value_; }
  33. auto operator<=>(DynBound const &other) const noexcept = default;
  34. bool is_min() const { return value_ == lower_bound_; }
  35. bool is_max() const { return value_ == upper_bound_; }
  36. DynBound & operator+=(value_type by) {
  37. using std::min;
  38. value_ = min(static_cast<value_type>(value_ + by), upper_bound_);
  39. return *this;
  40. }
  41. DynBound & operator-=(value_type by) {
  42. using std::max;
  43. value_ = max(static_cast<value_type>(value_ - by), lower_bound_);
  44. return *this;
  45. }
  46. DynBound & operator++() { return operator+=(1); }
  47. DynBound & operator--() { return operator-=(1); }
  48. DynBound operator+(value_type by) const { return DynBound{*this} += by; }
  49. DynBound operator-(value_type by) const { return DynBound{*this} -= by; }
  50. DynBound operator++(int) {
  51. DynBound tmp{*this};
  52. operator++();
  53. return tmp;
  54. }
  55. DynBound operator--(int) {
  56. DynBound tmp{*this};
  57. operator--();
  58. return tmp;
  59. }
  60. };
  61. }