Unchecked interface: --------------------
date(year y, month m, day d);
This is the only order, there is no checking, the year, month and date objects do no validation themselves. They exist only to disambiguate the order of this low level constructor. This single order is chosen above any other because of the ISO standards. The use of the year, month and day objects add some type safety with no run time overhead, and so are acceptable. Each of these objects will *explicitly* convert from int:
date(year(2013), month(5), day(3)); // ok
date(2013, 5, 3); // compile time error
Why are we not using following constructor? date(int year, int month, int day); To clarify my position, benefits are not apparent to me. Since the order is strictly-defined, the writer of code has to remember the ordering in both cases. OTOH an year is typically in thousands: date(2013, 5, 3); It should ring a bell towards the ymd notation. The fact that constructor is named date already gives away its purpose. But then I haven't read any code that isn't written by me, or when the docs are not at hand, so I can always use second opinion.
I dislike the use of no_check_t at this level because I see it as unnecessarily verbose and ugly, and I'll have to look up how to spell it every time I use it (see the checked interface for why).
Checked interface: ------------------
I like the use of factory functions here. I also like an easy-to-remember, convenience, forgiving, type-safety. My still-preferred spelling for the factory functions (yes, more than 1) is:
date d = year(2013) / month(5) / day(3); date d = year(2013) / month(5) / 3; date d = month(5) / day(3) / year(2013); date d = month(5) / day(3) / 2013; date d = day(3) / month(5) / year(2013); date d = day(3) / month(5) / 2013;
These 3 orders are chosen among the possible 6 because these are the 3 that people actually use:
http://en.wikipedia.org/wiki/Date_format_by_country
The first two units have to explicit. The last unit can be implicit. Other rules are possible, but this one is a nice compromise between convenience and simplicity. It is an easy rule to remember, and the rule is easily checked by the compiler at compile time.
No questions there. I agree. And the fact that they can't be faster than constructor variants, I think it is okay to make it optimized for usability then.
I like this spelling of the checked factory function over:
make_unchecked_date(2013, may, 3); or
make_valid_date(2013, may, 3);
because I know I will remember how to spell the former 3 years from now, but I will have to look the latter up in a reference, unless I'm dealing with dates often enough that I memorize it.
In both interfaces, the year, month and day objects do no validity checking. The validity checks in the checked interface happen only at the time the full date is constructed.
Again, no bone of contention. And, orthogonal to the topic, i want to say that I am still waving for functions like: make_ordinal_date(2013, 45); make_week_date(2013, w7, 5); Because mixing them with other constructors would be confusing. Keeping the notation to make them seprately, but part of same date class at the end, is something like their relation with actual gregorian calendar. At which point I wonder, why can't we be symmetrical and allow a function like: make_date(2013, 2, 27); As Rob says compiler will optimize this call due to RVO. we can make it explicit using move constructor too.
Two date types:
1. Serial:
typedef duration<int, ratio_multiply<hours::period, ratio<24>>> days; typedef time_point<system_clock, days> day_point;
day_point is the serial date type. This is nothing but integral arithmetic with no validity checking. It has some convenience conversions to/from the serial date_time type: system_clock::time_point, and the field-date type...
2. Field date-type:
Something that stores year, month and day, maybe named date, maybe not. Provides conversions to and from day_point.
These two date types are analogous to the two C date types: time_t and tm. I have come to the conclusion that two types are necessary because each has its strengths and weaknesses in terms of performance. Each type should offer only the operations which it can do fast. E.g. there is no month() accessor on the serial date type, only on the field date type. If you have serial and you need the month, convert to the field type, and then you have it.
This design follows the philosophy of the containers, and whether or not any given container has an operator[](size_t), or a size() member. If you need an operation, and it isn't available on the container you have, you just have to move your data to a container that supports it. This aids in exposing performance bugs. It makes expensive operations explicit.
I don't think we should mirror the behaviour of tm and time_t here. Somebody who needs only thin wrappers around actual functions can already use them. The fact that they originated in C doesn't make them unusable. The need for date class exists only because there isn't one around that behaves like it. That means that we should provide a solid abstraction in this case. Ultimately, passing objects around would lead to more sub-optimal (and confusing) code. Why would we forego the chance that C++ has of gaining a proper date type?
Both checked and unchecked interfaces should be made constexpr. day_point is already constexpr (in C++14). The field date-type should be constexpr.
Anurag, please feel free to adopt or ignore any or all of this. I can also offer services in the creation of constexpr field<->serial conversions if that would be helpful. Best of luck in your gsoc!
I will not negate that I have opinions. But I am grateful for the invaluable feedback here. And we can't forget that my proposal rips off of yours. :D constexpr conversions are a case in point. They might have never struck me on my own. Maybe they might have, but who knows. I will try it on my own and wouldn't hesitate to contact you if I have problems. It would be much more rewarding that way. :-) Thanks everybody! Anurag. -- View this message in context: http://boost.2283326.n4.nabble.com/gsoc-2013-draft-proposal-for-chrono-date-... Sent from the Boost - Dev mailing list archive at Nabble.com.