Boost logo

Boost :

Subject: Re: [boost] [chrono/date] date conversion and arithmetic with unvalidated dates
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-05-06 15:49:10


Le 06/05/13 15:22, Howard Hinnant a écrit :
> On May 6, 2013, at 6:30 AM, "Vicente J. Botet Escriba" <vicente.botet_at_[hidden]> wrote:
>
>> Hi,
>>
>> Note that N3344 suggest only day arithmetic for a day representation (which is always valid) and suggest only only a date representation.
>>
>> Could we apply arithmetic operations on a unvalidated date (without striving on UB)?
>> e.g. day arithmetic on a ymd_date
>>
>> ymd_date d1(year(2013), may, day(66));
>> ymd_date d2 = d1 + day(1);
>>
>> If defined, which must be the value of d2?
>>
>> Could we convert a date representation to another one if the source date is unvalidated (without striving on UB)? e.g. ymd_date -> days_date
>>
>> ymd_date d1(year(2013), may, day(66));
>> days_date d2 = d1;
>>
>> If defined, which must be the value of d2?
> My understanding is that all of these operations (if unchecked at ymd_date construction time) are simply undefined behavior. This is what N3344 seems to be asking for.

N3344 doesn't suggest month and year arithmetic at all. They suggest to let these features for a higher layer.

Should the following pass.

     ymd_date dt(year(2012),feb,day(29));
     try {
       dt+=years(1);
       BOOST_TEST(false);
     } catch (...) {}

Or should dt contain an invalid date? I would expect that an exception
is thrown.

In the same way we are proposing constructors and factories that allows
the user to check/uncheck the validity of the entered date, arithmetic
operators can be considered also as date factories

I'd propose that arithmetic operators using operators validates the
result. For those that don't want to pay for validity check we can add
additional functions that don't check the validity

date& date::inc(years);
date& date::pre_inc();
date& date::post_inc();
date& date::dec(years);
date& date::pre_dec();
date& date::post_dec(years);
date sum(date, years);
date diff(date, years);

Or shouldn't we have two different classes, validated and unvalidated
dates, as Rob has suggested?
More I analyze the subject more I believe the separation is unavoidable.

     validated_date dt(year(2012),feb,day(29));
     try {
       dt+=years(1);
       assert(false);
     } catch (...) {}

     unvalidated_date dt(year(2012),feb,day(29));
     try {
       dt+=years(1);
       // the result of dt is 2013/feb/29 which is unchecked and invalid
     } catch (...) {
       assert(false);
     }

The user can move from one date type to the other

     unvalidated_date dt(year(2012),feb,day(29));
     try {
       dt=validate(dt) + years(1);
     } catch (...) {
       assert(false);
     }

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk