failbit.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. // Copyright © 2019 Ariadne Devos
  3. #ifndef _sHT_FAILBIT_H
  4. #define _sHT_FAILBIT_H
  5. #include <sHT/test.h>
  6. /* See doc/failbit.rst */
  7. /* TODO: Sparse */
  8. #define sHT_with_failbit
  9. #define _sHT_failbit(T) (((T) -1) ^ ((T) -1) >> 1)
  10. _Static_assert(_sHT_failbit(unsigned) != 0, "above macro incorrect");
  11. _Static_assert((_sHT_failbit(unsigned) & (_sHT_failbit(unsigned) - 1u)) == 0, "above macro incorrect");
  12. _Static_assert(_sHT_failbit(unsigned) << 1 == 0u, "above macro incorrect");
  13. /** no-failure-p?
  14. Ensures:
  15. (z): nonspec: ret ↔ good(T, x) */
  16. #define sHT_good(T, x) (sHT_and_none((x), _sHT_failbit(T)))
  17. /** failure-p?
  18. Ensures:
  19. (z): nonspec: ret ↔ ¬good(T, x) */
  20. #define sHT_bad(T, x) sHT_lt0(x)
  21. /** Start the failbit machine in the success state
  22. Requires:
  23. (a): failbit_clean(T, x)
  24. Ensures:
  25. (y): good(T, ret)
  26. (z): fail_value(T, ret) = x */
  27. #define sHT_success(T, x) (x)
  28. /** Start the failbit machine in the error state
  29. Requires:
  30. (a): failbit_clean(T, x)
  31. Ensures:
  32. (y): ¬good(T, ret)
  33. (z): fail_value(T, ret) = x */
  34. #define sHT_fail(T, x) ((x) | _sHT_failbit(T))
  35. /** Fail machine `f` if `c`
  36. Requires:
  37. (a): (read ∧ write ∧ set) (*f)
  38. Invariant:
  39. (p): fail_value(T, *f)
  40. Ensures:
  41. (z): good(T, new *f) ↔ good(T, old *f) ∧ ¬c */
  42. #define sHT_fail_if(T, f, c) \
  43. do { \
  44. *(f) |= (c) ? _sHT_failbit(T) : 0; \
  45. } while (0)
  46. /** Ensures: (z): ret = fail_value(T, f) */
  47. #define sHT_fail_value(T, f) ((f) & ~_sHT_failbit(T))
  48. /** type T, 2 ** (log2(\max(T)) - 1) (see sHT_failbit_clean) */
  49. #define sHT_failbit_limit(T) (_sHT_failbit(T))
  50. /* (not supposed to be used by code, yet) */
  51. /** ∀i : ℕ, 0 ≤ i < failbit_limit(T) ↔ failbit_clean(T, i) */
  52. #define sHT_failbit_clean(T, x) /* !((x) & _sHT_failbit(T)) */
  53. /* Transfer the failbit of `f` to `n`, with some restrictions.
  54. Requires:
  55. (a): fail_value(T, f) = 0
  56. (b): failbit_clean(T, n)
  57. (required, as `n`'s msb may not leak into good(T, ret))
  58. Ensures:
  59. (y): good(T, ret) ↔ good(T, f)
  60. (z): fail_value(T, ret) = n */
  61. #define sHT_transfer_failure_novalue(T, f, n) ((f) | (n))
  62. #endif