diff options
| author | Paul Eggert | 2022-08-01 00:38:32 -0700 |
|---|---|---|
| committer | Paul Eggert | 2022-08-01 01:17:13 -0700 |
| commit | 914cf4b91ba8bdf63cd10a66f970c396329beeab (patch) | |
| tree | edf43bdb4f21bcb3e4f3c53e32d87a898c60da38 /src | |
| parent | e3b6242938fa9bcc3aebaa0eddd6aa561136dbf1 (diff) | |
| download | emacs-914cf4b91ba8bdf63cd10a66f970c396329beeab.tar.gz emacs-914cf4b91ba8bdf63cd10a66f970c396329beeab.zip | |
Make time arithmetic more like comparison
Since time comparison says X == X, have time arithmetic behave
similarly for X - X. This should also be a bit faster due to not
having to test for floats and NaNs.
* src/timefns.c (time_arith, time_cmp):
Simplify by not worrying about NaNs, which are not time values.
(time_arith): Simplify by not worrying about subtracting nil from
nil; the caller now handles this.
(Ftime_subtract): Handle subtracting X from X specially.
Diffstat (limited to 'src')
| -rw-r--r-- | src/timefns.c | 44 |
1 files changed, 11 insertions, 33 deletions
diff --git a/src/timefns.c b/src/timefns.c index 25bfda513c2..c8becac8634 100644 --- a/src/timefns.c +++ b/src/timefns.c | |||
| @@ -1074,27 +1074,9 @@ lispint_arith (Lisp_Object a, Lisp_Object b, bool subtract) | |||
| 1074 | static Lisp_Object | 1074 | static Lisp_Object |
| 1075 | time_arith (Lisp_Object a, Lisp_Object b, bool subtract) | 1075 | time_arith (Lisp_Object a, Lisp_Object b, bool subtract) |
| 1076 | { | 1076 | { |
| 1077 | if (FLOATP (a) && !isfinite (XFLOAT_DATA (a))) | ||
| 1078 | { | ||
| 1079 | double da = XFLOAT_DATA (a); | ||
| 1080 | double db = float_time (b); | ||
| 1081 | return make_float (subtract ? da - db : da + db); | ||
| 1082 | } | ||
| 1083 | enum timeform aform, bform; | 1077 | enum timeform aform, bform; |
| 1084 | struct lisp_time ta = lisp_time_struct (a, &aform); | 1078 | struct lisp_time ta = lisp_time_struct (a, &aform); |
| 1085 | 1079 | struct lisp_time tb = lisp_time_struct (b, &bform); | |
| 1086 | if (FLOATP (b) && !isfinite (XFLOAT_DATA (b))) | ||
| 1087 | return subtract ? make_float (-XFLOAT_DATA (b)) : b; | ||
| 1088 | |||
| 1089 | /* Subtract nil from nil correctly, and handle other eq values | ||
| 1090 | quicker while we're at it. Compare here rather than earlier, to | ||
| 1091 | handle NaNs and check formats. */ | ||
| 1092 | struct lisp_time tb; | ||
| 1093 | if (BASE_EQ (a, b)) | ||
| 1094 | bform = aform, tb = ta; | ||
| 1095 | else | ||
| 1096 | tb = lisp_time_struct (b, &bform); | ||
| 1097 | |||
| 1098 | Lisp_Object ticks, hz; | 1080 | Lisp_Object ticks, hz; |
| 1099 | 1081 | ||
| 1100 | if (FASTER_TIMEFNS && BASE_EQ (ta.hz, tb.hz)) | 1082 | if (FASTER_TIMEFNS && BASE_EQ (ta.hz, tb.hz)) |
| @@ -1201,27 +1183,23 @@ See `format-time-string' for the various forms of a time value. | |||
| 1201 | For example, nil stands for the current time. */) | 1183 | For example, nil stands for the current time. */) |
| 1202 | (Lisp_Object a, Lisp_Object b) | 1184 | (Lisp_Object a, Lisp_Object b) |
| 1203 | { | 1185 | { |
| 1186 | /* Subtract nil from nil correctly, and handle other eq values | ||
| 1187 | quicker while we're at it. This means (time-subtract X X) does | ||
| 1188 | not signal an error if X is not a valid time value, but that's OK. */ | ||
| 1189 | if (BASE_EQ (a, b)) | ||
| 1190 | return timespec_to_lisp ((struct timespec) {0}); | ||
| 1191 | |||
| 1204 | return time_arith (a, b, true); | 1192 | return time_arith (a, b, true); |
| 1205 | } | 1193 | } |
| 1206 | 1194 | ||
| 1207 | /* Return negative, 0, positive if a < b, a == b, a > b respectively. | 1195 | /* Return negative, 0, positive if A < B, A == B, A > B respectively. |
| 1208 | Return positive if either a or b is a NaN; this is good enough | 1196 | A and B should be Lisp time values. */ |
| 1209 | for the current callers. */ | ||
| 1210 | static int | 1197 | static int |
| 1211 | time_cmp (Lisp_Object a, Lisp_Object b) | 1198 | time_cmp (Lisp_Object a, Lisp_Object b) |
| 1212 | { | 1199 | { |
| 1213 | if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a))) | ||
| 1214 | || (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))) | ||
| 1215 | { | ||
| 1216 | double da = FLOATP (a) ? XFLOAT_DATA (a) : 0; | ||
| 1217 | double db = FLOATP (b) ? XFLOAT_DATA (b) : 0; | ||
| 1218 | return da < db ? -1 : da != db; | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | /* Compare nil to nil correctly, and handle other eq values quicker | 1200 | /* Compare nil to nil correctly, and handle other eq values quicker |
| 1222 | while we're at it. Compare here rather than earlier, to handle | 1201 | while we're at it. This means (time-equal-p X X) does not signal |
| 1223 | NaNs. This means (time-equal-p X X) does not signal an error if | 1202 | an error if X is not a valid time value, but that's OK. */ |
| 1224 | X is not a valid time value, but that's OK. */ | ||
| 1225 | if (BASE_EQ (a, b)) | 1203 | if (BASE_EQ (a, b)) |
| 1226 | return 0; | 1204 | return 0; |
| 1227 | 1205 | ||