
Hello, as suggested by Paul Bristow in his response to my proposal on interval containers I started to integrate boost::date_time into my library examples. To my surprise I discovered that boost::date_time does not provide operator ++ (--) for it's date and time template classes. So the boost date and time classes are not Incrementable (Decrementable). One could say: they lack a tic-tac ;-) Which is for *time* kind of a major omission. Now, Incrementability seems most fundamental to me. Therefore, in the design of interval containers in my library, I avoided to reqire Addability for interval template parameters. Requiring only In(De)crementability I enable a broader set of instances for intervals and interval containers. Iterators for instance provide incrementation and decrementation but no addability in general (some do). Incrementability seems also more fundamental to me than Addability. Which is to say that a concept or algebra that offers Addability almost certainly also has a Incrementability, but not the other way round. Take for instance the Peano Axioms of natural numbers, where Incrementability is given in the form of the fundamental successor function. Therefore I would strongly suggest, that a class template that implements Addability/Subtractability (operators +, +=, -, -=) also implements In(De)crementability (operators ++ and --). This should apply even more to classes that resemble in their basic characteristics an integral numeric type like date and time do. For boost::date_time I tried to completed the code in this respect. I added 6 lines of code: boost\date_time\time_system_counted.hpp(114): counted_time_rep& operator ++(){++time_count_; return *this;} counted_time_rep& operator --(){--time_count_; return *this;} boost\date_time\int_adapter.hpp(191): int_adapter& operator ++() {++value_; return *this;} int_adapter& operator --() {--value_; return *this;} boost\date_time\time.hpp(179): time_type operator ++() { ++time_; return time_type(time_); } time_type operator --() { --time_; return time_type(time_); } With these minor additions to the code the 'party' example from my interval template library works fine with boost::date_time: ----------------------------------------------------------------------- #include <stdio.h> #include <iostream> #include <itl/itl_value.hpp> #include <itl/string_set.hpp> #include <itl/split_interval_map.hpp> #include <boost/date_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp> using namespace std; using namespace boost::posix_time; using namespace itl; typedef itl::set<string> GuestSetT; typedef split_interval_map<ptime, GuestSetT> PartyAttendenceHistoryT; void boost_party() { GuestSetT mary_harry; mary_harry.insert("Mary"); mary_harry.insert("Harry"); GuestSetT diana_susan; diana_susan.insert("Diana"); diana_susan.insert("Susan"); GuestSetT peter; peter.insert("Peter"); PartyAttendenceHistoryT party; party.insert( make_pair( rightopen_interval<ptime>( time_from_string("2008-05-20 19:30:00.000"), time_from_string("2008-05-20 23:00:00.000")), mary_harry) ); party.insert( make_pair( rightopen_interval<ptime>( time_from_string("2008-05-20 20:10:00.000"), time_from_string("2008-05-21 00:00:00.000")), diana_susan) ); party.insert( make_pair( rightopen_interval<ptime>( time_from_string("2008-05-20 22:15:00.000"), time_from_string("2008-05-21 00:30:00.000")), peter) ); PartyAttendenceHistoryT::iterator it = party.begin(); while(it != party.end()) { interval<ptime> when = (*it).first; // Who is at the party within the time interval 'when' ? GuestSetT who = (*it++).second; cout << "[" << to_simple_string(when.first()) << " - " << to_simple_string(when.last()) << "]" << ": " << who.as_string() << endl; } } int main() { cout << ">> Interval Template Library: Sample boost_party.cpp <<\n"; cout << "-------------------------------------------------------\n"; boost_party(); return 0; } Program output:
Interval Template Library: Sample boost_party.cpp <<
[2008-May-20 19:30:00 - 2008-May-20 20:09:59.999999]: Harry Mary [2008-May-20 20:10:00 - 2008-May-20 22:14:59.999999]: Diana Harry Mary Susan [2008-May-20 22:15:00 - 2008-May-20 22:59:59.999999]: Diana Harry Mary Peter Susan [2008-May-20 23:00:00 - 2008-May-20 23:59:59.999999]: Diana Peter Susan [2008-May-21 00:00:00 - 2008-May-21 00:29:59.999999]: Peter cheers Joachim ----- Interval Template Library (ITL) download from http://www.sourceforge.net/projects/itl documentation http://www.herold-faulhaber.de/itl

On Thu, May 22, 2008 at 3:56 PM, Joachim Faulhaber <afojgo@googlemail.com> wrote:
Incrementability seems also more fundamental to me than Addability. Which is to say that a concept or algebra that offers Addability almost certainly also has a Incrementability, but not the other way round. Take for instance the Peano Axioms of natural numbers, where Incrementability is given in the form of the fundamental successor function.
Not necessarily true. Strings under concatenation (a monoid) are Addable, but incrementing makes little sense. Further, incrementing on even the real numbers doesn't necessarily make sense, at least not when defined in terms of the successor function (which maps integers to integers). Complications also arise in, well, complex numbers. ;) Dates/times are a more unusual case because their underlying representation is integral, but as a physical concept they are continuous (as far as we know). Questions arise especially when considering the granularity of the date/time you are dealing with. Is foo_date+1 24 hours from now, or one second from now? Or perhaps one millisecond... I don't think incrementability is as simple as incrementing the private member of the date_time object. - Jim

2008/5/22, James Porter <porterj@alum.rit.edu>:
On Thu, May 22, 2008 at 3:56 PM, Joachim Faulhaber <afojgo@googlemail.com> wrote:
Incrementability seems also more fundamental to me than Addability. Which is to say that a concept or algebra that offers Addability almost certainly also has a Incrementability, but not the other way round. Take for instance the Peano Axioms of natural numbers, where Incrementability is given in the form of the fundamental successor function.
Not necessarily true. Strings under concatenation (a monoid) are Addable, but incrementing makes little sense.
only syntactically an Addability, semantically rather Concatenatablity (strange word ;-) But you are right. I focused too much on integral numerical types.
Further, incrementing on even the real numbers doesn't necessarily make sense,
therefor my interval containers provide a different implementation for continuous types that does not require incrementation.
at least not when defined in terms of the successor function (which maps integers to integers). Complications also arise in, well, complex numbers. ;)
Dates/times are a more unusual case because their underlying representation is integral, but as a physical concept they are continuous (as far as we know). Questions arise especially when considering the granularity of the date/time you are dealing with. Is foo_date+1 24 hours from now, or one second from now? Or perhaps one millisecond... What I've learned is that in boost::date_time, this is handled via different duration types
time_type operator+=(const date_duration_type& dd); time_type operator+=(const time_duration_type& td); which is nice. Yet as for date/time parameters for my interval and interval containers templates my implementation relies on the existence of incrementation on the least available time unit in order to decide things like [1704, 4712) == [1704, 4711]
I don't think incrementability is as simple as incrementing the private member of the date_time object.
The date and time implementations that I've seen so far are all based on integral numeric types including boost::date_time. Implicit in this implementation is the property of a least incrementable unit. Based on this property incrementation and decrementation can always be implemented. To me this seems to be a rather universal property and not only detail of the implementing private member. cheers Joachim

Joachim Faulhaber wrote:
only syntactically an Addability, semantically rather Concatenatablity (strange word ;-) But you are right. I focused too much on integral numerical types.
Trying to figure out what, qualitatively, makes a binary operation "addition" is a hard question, and probably out scope here, but I digress. :)
The date and time implementations that I've seen so far are all based on integral numeric types including boost::date_time. Implicit in this implementation is the property of a least incrementable unit. Based on this property incrementation and decrementation can always be implemented. To me this seems to be a rather universal property and not only detail of the implementing private member.
Actually, Visual Basic 6 uses a double to store DateTimes, with the integral portion representing date and the fractional portion representing time. Of course, Visual Basic 6 isn't what I'd recommend to use as a model for language design. I think it would make more sense to use the date/time iterators in Boost.DateTime (which I just now learned of!). They allow incrementing/decrementing with respect to a particular unit of measure, which lets the user completely ignore the underlying implementation of the date_time object. - Jim

Hi! Joachim Faulhaber schrieb:
which is nice. Yet as for date/time parameters for my interval and interval containers templates my implementation relies on the existence of incrementation on the least available time unit in order to decide things like [1704, 4712) == [1704, 4711]
I suggest to let the user specify a minimal unit. Depending on the application the user could think in seconds or less (time measuring for events), minutes (calendar application), days (hotel room occupation), months/years (records of employment). I'd like that.
Based on this property incrementation and decrementation can always be implemented.
For instance using a specified increment. :) Regards, Frank

2008/5/23 Frank Birbacher <bloodymir.crap@gmx.net>:
Hi!
Joachim Faulhaber schrieb:
which is nice. Yet as for date/time parameters for my interval and interval containers templates my implementation relies on the existence of incrementation on the least available time unit in order to decide things like [1704, 4712) == [1704, 4711]
I suggest to let the user specify a minimal unit.
I agree
Depending on the application the user could think in seconds or less (time measuring for events), minutes (calendar application), days (hotel room occupation), months/years (records of employment).
I'd like that.
so would I. Every implementation that is based on a numeric integral type provides that unit which is (internally) denoted as 1. The meaning assigned to the unit to be nanosecond, minute or decade is finally a question of interpretation. For every time<TimeSystem>- type the semantics of the minimal unit should be chosen as a static property of the types TimeSystem, that can not be changed for a given type-instance. That way, strong typing will help not to accidentally mix nanoseconds with decades ;-) So for every time type there is exacty one minimal time unit, the meaning of which can chosen as a static propery throu instantiation.
Based on this property incrementation and decrementation can always be implemented.
... using the specified increment. :)
cheers Joachim ----- Interval Template Library (ITL) download from http://www.sourceforge.net/projects/itl documentation http://www.herold-faulhaber.de/itl

Hi! Joachim Faulhaber schrieb:
For every time<TimeSystem>- type the semantics of the minimal unit should be chosen as a static property of the types TimeSystem, that can not be changed for a given type-instance. That way, strong typing will help not to accidentally mix nanoseconds with decades ;-)
Hmm, I thought of using the same type (e.g. ptime) with different units (seconds, hours, days). Just like a std::basic_string can be used with "char" but two different character traits. A time_duration can have mili- or microseconds resolution depending on the system. I would rather not like my program to take a thousand times more loop cycles for an incrementing loop just because I changed the system (issue of portability in my opinion).
So for every time type there is exacty one minimal time unit, the meaning of which can chosen as a static propery throu instantiation.
So for every time/traits pair there is exactly one minimal time unit... So for every type/traits pair there is exactly one minimal unit... :) Regards, Frank

2008/5/23 Frank Birbacher <bloodymir.crap@gmx.net>:
Hi!
Joachim Faulhaber schrieb:
For every time<TimeSystem>- type the semantics of the minimal unit should be chosen as a static property of the types TimeSystem, that can not be changed for a given type-instance. That way, strong typing will help not to accidentally mix nanoseconds with decades ;-)
Hmm, I thought of using the same type (e.g. ptime) with different units (seconds, hours, days). Just like a std::basic_string can be used with "char" but two different character traits.
Yes of course ... one class template with different instances. Yet different instances of the same class template are different types so compilers can help to avoid errors ... But ... to make the discussion more substantial and to give the authors of boost::date_time the acknowledgement that they surely deserve I am going to study the documentation more closely first before making more suggestions. As a first reading shows customization of resolution and iteration on different granularity levels are sagely provided. Regards Joachim

On Thu, May 22, 2008 at 4:56 PM, Joachim Faulhaber <afojgo@googlemail.com> wrote:
as suggested by Paul Bristow in his response to my proposal on interval containers I started to integrate boost::date_time into my library examples.
To my surprise I discovered that boost::date_time does not provide operator ++ (--) for it's date and time template classes. So the boost date and time classes are not Incrementable (Decrementable). One could say: they lack a tic-tac ;-) Which is for *time* kind of a major omission.
This came up in the units discussions, and had what I thought was a rather powerful argument against the inclusion of increment and decrement. for (some_time_type t = hours(9); t < hours(12+5); ++t) { // How many times does this loop? }
participants (4)
-
Frank Birbacher
-
James Porter
-
Joachim Faulhaber
-
Scott McMurray