multiless.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package missinggo
  2. type (
  3. // A function that returns equality, and less than. Used for lazily evaluating arguments.
  4. SameLessFunc func() (same, less bool)
  5. // A helper for long chains of "less-than" comparisons, where later comparisons are only
  6. // required if earlier ones haven't resolved the comparison.
  7. MultiLess struct {
  8. ok bool
  9. less bool
  10. }
  11. )
  12. // True iff the left is less than the right. Will return false if they're equal, or unresolved.
  13. // (Which is okay in certain circumstances.)
  14. func (me *MultiLess) Less() bool {
  15. return me.ok && me.less
  16. }
  17. // Returns the result of the less-than comparison chains. Panics if the case was not resolved.
  18. func (me *MultiLess) Final() bool {
  19. if !me.ok {
  20. panic("undetermined")
  21. }
  22. return me.less
  23. }
  24. // Returns less-than, and whether the comparison was definitely resolved.
  25. func (me *MultiLess) FinalOk() (left, ok bool) {
  26. return me.less, me.ok
  27. }
  28. // `f` is only evaluated if the result is not yet determined.
  29. func (me *MultiLess) Next(f SameLessFunc) {
  30. if me.ok {
  31. return
  32. }
  33. same, less := f()
  34. if same {
  35. return
  36. }
  37. me.ok = true
  38. me.less = less
  39. }
  40. // Like Next, but the arguments are already evaluated.
  41. func (me *MultiLess) StrictNext(same, less bool) {
  42. me.Next(func() (bool, bool) { return same, less })
  43. }
  44. // Compare booleans, where the lesser is the true one, if the other is false.
  45. func (me *MultiLess) NextBool(l, r bool) {
  46. me.StrictNext(l == r, l)
  47. }
  48. // Next use a common comparison result, where < 0 is less and 0 is equal.
  49. func (me *MultiLess) Compare(i int) {
  50. me.StrictNext(i == 0, i < 0)
  51. }