Skip to content

Commit

Permalink
Merge pull request #592 from jmdavis/split
Browse files Browse the repository at this point in the history
Add note to changelog about Duration.split.
  • Loading branch information
9rnsr authored and AndrewEdwards committed Aug 16, 2014
1 parent eabf41c commit f132b6c
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions changelog.dd
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit f132b6c

Please sign in to comment.