From f132b6c3b859c83fc07ba9bb01532baacf452314 Mon Sep 17 00:00:00 2001 From: Hara Kenji Date: Thu, 17 Jul 2014 16:19:50 +0900 Subject: [PATCH] Merge pull request #592 from jmdavis/split Add note to changelog about Duration.split. --- changelog.dd | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/changelog.dd b/changelog.dd index 5a0a13da91..bc1c5d9d15 100644 --- a/changelog.dd +++ b/changelog.dd @@ -13,6 +13,7 @@ $(BUGSTITLE Language Changes, ) $(BUGSTITLE Library Changes, +$(LI $(RELATIVE_LINK2 duration_split, Duration.get and its wrappers have been deprecated in favor of the new Duration.split.)) ) $(BUGSTITLE Linker Changes, @@ -58,6 +59,103 @@ $(BUGSTITLE Language Changes, $(BUGSTITLE Library Changes, +$(LI $(LNAME2 duration_split, Duration.get and its wrappers have been deprecated in favor of the new Duration.split:) + + $(P $(CXREF time, Duration.get) and its wrappers, $(CXREF time, Duration.weeks), + $(CXREF time, Duration.days), $(CXREF time, Duration.hours), and + $(CXREF time, Duration.seconds), as well as $(CXREF time, Duration.fracSec) (which + served a similar purpose as $(CXREF time, Duration.get) for the fractional second units) + have proven to be too easily confused with $(CXREF time, Duration.total), causing + subtle bugs. So, they have been deprecated. In their place, $(CXREF time, Duration.split) + has been added - and it's not only very useful, but it does a great job of showing off + what D can do. + + Whereas $(CXREF time, Duration.get) split out all of the units of a + $(CXREF time, Duration) and then returned only one of them, + $(CXREF time, Duration.split) splits out a $(CXREF time, Duration) into the units + that it's told to (which could be one unit or all of them) and returns all of + them. It has two overloads, both which take template arguments that indicate which + of the units are to be split out. The difference is in how the result is returned. + + As with most of the templates in core.time and std.datetime which take strings + to represent units, $(CXREF time, Duration.split) accepts $(D "weeks"), $(D "days"), + $(D "hours"), $(D "minutes"), $(D "seconds"), $(D "msecs"), $(D "usecs"), + $(D "hnsecs"), and $(D "nsecs"). + + The first overload returns the split out units as $(D out) parameters. + + --------- + auto d = weeks(5) + days(4) + hours(17) + seconds(2) + hnsecs(12_007); + short days; + long seconds; + int msecs; + d.split!("days", "seconds", "msecs")(days, seconds, msecs); + assert(days == 39); + assert(seconds == 61_202); + assert(msecs == 1); + --------- + + The arguments can be any integral type (though no protection is given against integer + overflow, so unless it's known that the values are going to be small, it's unwise to + use a small integral type for any of the arguments). + + The second overload returns a struct with the unit names as its fields. Only the + requested units are present as fields. All of the struct's fields are $(D long)s. + + --------- + auto d = weeks(5) + days(4) + hours(17) + seconds(2) + hnsecs(12_007); + auto result = d.split!("days", "seconds", "msecs")(); + assert(result.days == 39); + assert(result.seconds == 61_202); + assert(result.msecs == 1); + --------- + + Or if no units are given to the second overload, then it will return a struct with + all of the units save for $(D nsecs) (since $(D nsecs) would always be $(D 0) when + $(D hnsecs) is one of the units as $(CXREF time, Duration) has hnsec precision). + + --------- + auto d = weeks(5) + days(4) + hours(17) + seconds(2) + hnsecs(12_007); + auto result = d.split(); + assert(result.weeks == 5); + assert(result.days == 4); + assert(result.hours == 17); + assert(result.minutes == 0); + assert(result.seconds == 2); + assert(result.msecs == 1); + assert(result.usecs == 200); + assert(result.hnsecs == 7); + --------- + + Calling $(CXREF time, Duration.get) or its wrappers for each of the units would be + equivalent to that example, only less efficient when more than one unit is + requested, as the calculations would have to be done more than once. The exception + is $(CXREF time, Duration.fracSec) which would have given the total of the + fractional seconds as the requested units rather than splitting them out. + + --------- + // Equivalent to previous example + auto d = weeks(5) + days(4) + hours(17) + seconds(2) + hnsecs(12_007); + assert(d.weeks == 5); + assert(d.days == 4); + assert(d.hours == 17); + assert(d.minutes == 0); + assert(d.seconds == 2); + assert(d.fracSec.msecs == 1); + assert(d.fracSec.usecs == 1200); + assert(d.fracSec.hnsecs == 12_007); + --------- + + It is hoped that $(CXREF time, Duration.split) will be less confusing and thus + result in fewer bugs, but it's definitely the case that it's more powerful. It's + also a great example of D's metaprogramming capabilities given how it splits out + only the requested units and even is able to return a struct with fields with the + same names as the requested units. This on top of being able to handle a variety + of integral types as arguments. And its implemenation isn't even very complicated. + ) + +) + ) $(BUGSTITLE Linker Changes,