[chrono] v0.4.5 Documentation update + warnings removal + bug fixes

Hi, I have made some minor modifications to the Boost.Chrono library as requested on these mailing lists. The implementaton is stable. Waiting for the review I plan to add yet a lightweight stopwatch, as suggested by Tom Tan on a personal mail, which stores a reference to a generalization of the Clock duration or an accumulator of the Clock duration. I'll concentrate also in improving the documentation and the tests. Anthony Williams will be the review manager and I hope we could find a date soon. Even if the review's date is not annonced yet, it will be great if some of you make a pre-review, so the conflicting issues are managed before the review. The library can be downloaded from http://www.boostpro.com/vault/index.php?action=downloadfile&filename=chrono.zip&directory=System& and the documentation is online on the sandbox http://svn.boost.org/svn/boost/sandbox/chrono/libs/chrono/doc/html/index.htm.... New Features since v0.4.3: Version 0.4.5, July 6, 2010 Documentation update Documentation a.. Overview rewriting b.. Added missing thread_clock reference. c.. How to implement a thread_clock tutorial removed. d.. References section renamed to External Resources. e.. Added links to source examples. f.. Added links between Models and Concepts. g.. Added macros descriptions. h.. Cleanup. Bug Fixes a.. Valgrind fixes: "Conditional jump or move depends on uninitialised value(s)" b.. Take care of Boost.System break on version 1.44 c.. gcc.4.4 "warning: suggest parentheses around '&&' within '||' " removal. Version 0.4.4, February 22, 2010 Warning fixes Bug Fixes a.. scoped_suspend warning removal b.. error_code management completed _____________________ Vicente Juan Botet Escribá http://viboes.blogspot.com/

vicente.botet wrote:
Even if the review's date is not annonced yet, it will be great if some of you make a pre-review, so the conflicting issues are managed before the review.
Here are comments from my reading of the initial sections of the document. Hopefully, I can offer comments on the User's Guide another time. _____________ Overview This section appears to be a sibling of the immediately following Description section, but includes a one-item TOC leading to the Motivation section which is also found by following the navigation icons to the next section. This is confusing. I'd expect the Overview section to include a TOC leading to the Motivation section first, and the Description section second, which means moving Description to its own page. I'd expect the How to Use This Documentation section to remain on the same page as the Overview section. _____________ Description Para 1, bullet 1: The durations order is a bit jarring: "minutes, seconds, and nanoseconds" would read better. As written, that bullet suggests that days might not be included, while duration's interface clearly means that year cannot be, though year360 might be. Therefore, you might change the bullet to read, "A means to represent time durations managed by the generic [duration] class. Examples include days, minutes, and nanoseconds, which can be represented with a fixed number of clock ticks per unit." That better explains what might be included and not. Para 1, bullet 2: s/One facility for/A type/ Para 1, bullet 3: s/any given/a particular/ s/symbolic bundle/pairing/ What is a "native time_point?" That phrase suggests there are others, so why the distinction here? Para 2: Change to read, "The library also provides some infrastructure to support the main features but which may prove useful in user applications. Para 2, bullet 1: This same text is repeated in the description of common_type found by following the link. In both cases, change the description to, "a traits class used to deduce a type common to as many as three types, useful as the return type of functions operating on multiple input types such as in mixed-mode arithmetic." Para 2, bullet 2: This can be improved somewhat and note that there is no description like this before the ratio class template documentation found by following the link here. I suggest this rewording: A class template, [ratio], for specifying compile time, rational constants such as 1/3 of a nanosecond or the number of inches per meter. ratio represents a compile time ratio of compile time constants with support for compile time arithmetic with overflow and division by zero protection." Para 3, bullet 1: You mention a "middle layer" but there has been no previous mention of any layers. Stopwatch is the first part of the library I would describe as a "facility" given that there is a concept and some class templates. Hence, "A facility to measure elapsed time with the ability to start, stop, suspend, or resume measurement." Para 3, bullet 2: Given this reference to a "higher layer," one might now infer that the features described in the first two paragraphs were the lower layer, but it would be better to avoid references to layers, at least within the Description section. You also use the term "stopclock" as though its meaning is apparent. It isn't. The description doesn't clearly convey the meaning either. I looked at the documentation for basic_stopclock and stopclock and found nothing to help. I can infer that it is to measure elapsed time like a stopwatch, but, perhaps, with less precision, though I have no confidence in that inference. I can't suggest how to rewrite this bullet without understanding "stopclock." Para 3, bullet 2, subbullet 3: This bullet isn't of much value in this introductory text, particularly as there is no explicit mention of any characters until this point. Para 4: The phrasing is awkward and paragraph five is closely related, yet orphaned. Try, "To make the timing facilities more generally useful, Boost.Chrono provides a number of clocks that are thin wrappers around the operating system's time APIs, thereby allowing the extraction of read (wall clock) time, user CPU time, system CPU time, etc.:" Para 4, bullet 1: s/, capturing real-CPU/ captures real (wall clock) CPU/ Para 4, bullet 2: s/, capturing user-CPU/ captures user CPU/ Para 4, bullet 3: s/, capturing system-CPU/ captures system CPU/ Para 4, bullet 4: Change to, "A tuple-like class, [process_cpu_clock], that captures real, user CPU, and system CPU times together." Para 5: Change to a fifth bullet of paragraph four, rewritten as, "Thread clocks, when supported by a platform." Para 6: Awkward phrasing. Try, "Lastly, Boost.Chrono includes typeof registration for [duration] and [time_point] to permit using emulated auto with C++03 compilers." This should probably reference the Typeof library. _____________ How to Use This Documentation Para 1, bullets 3-5: This are worded repetitively. Change to this pattern, "Free functions are rendered in the code font followed by (), as in free_function()." Para 2: Is there no include all header for Chrono? _____________ Motivation This section should precede the Description section. It is here that you're trying to sell the library. Once hooked, the reader will want to read a description. _____ Time Join the two paragraphs. Para 2: The series in the last sentence is written wrongly. Try, "However, overly simplistic solutions can be dangerous and inefficient, and won't adapt as the computer industry evolves." Para 4: The point of referencing N2661 is because it is the basis for time support in C++0x and, therefore, the interfaces provided in Boost.Chrono, unless I'm mistaken. Therefore, reword this paragraph to, "Boost.Chrono aims to implement the new time facilities in C++0x, as proposed in [N2661: A Foundation to Sleep On]. That document provides background and motivation for key design decisions and is the source of a good deal of information in this documentation." _____ Wall clock versus system and user time As with the Description section, this could be worded better. Try, "To make the timing facilities of Boost.Chrono more generally useful, the library provides a number of clocks that are thin wrappers around the operating system's process time API, thereby allowing the extraction of read (wall clock) time, user CPU time, and system CPU time. (On POSIX-like systems, this relies on times(). On Windows, it relies on GetProcessTimes().)" _____ Reporting slapsed[sic] time s/slapsed/elapsed/ in the heading Para 1: s/block/code block/ s/captures the mechanism to measure the/is a mechanism to measure/ s/eleapsed/elapsed/ Para 1, last sentence: I'm not sure what you mean by "allowing to make a single measure." Para 2, sentence 1: Try, "It is often necessary to report elapsed time on a user display or in a log file. [stopwatch_reporter<>] provides a runtime reporting mechanism for this purpose which can be invoked in just one line of code." _____ Caveat emptor This section doesn't belong in Motivation. This should be in the Description section, I think. _____ How reliable are these measures? This section doesn't belong in Motivation. This should be in the Getting Started section, I think. Para 1: s/context on which you can get/cases which can lead to/ Para 1, bullet 1: This can be worded more clearly: "It is not possible to measure events that transpire at rates of the same order of magnitude as the clock's precision with any reliability. For example, a 10ms clock cannot be used reliably to measure elapsed times of tens of milliseconds. The library provides a [high_resolution_clock] that gives you the highest resolution time available on your platform. That will give the best precision, but can only be used for reliable measurement of events that elapse about an order of magnitude slower than that clock's precision." Para 1, bullet 2: Try, "Using a process clock in a multithreaded application will give elapsed time for the process as a whole, including threads other than the calling thread. To get time elapsed for a specific thread, use the supplied [thread_clock] which returns time elapsed for the calling thread only, if supported by the platform." Para 1, bullet 3: This can be expressed more clearly: "When stopclocks are nested, usually from stopclocks appearing in each of several nested function calls, the overhead of the stopclock processing begins to be significant relative to run time of the code being measured. The innermost measurements remain accurate, but those in the outermost layers can measure too much overhead to be trustworthy." Para 2: Try this rephrasing: Most of the stopclock overhead is likely due to logging. Para 2, bullet 1: The wording is awkward. Try, "Don't flush log information while measuring elapsed time. A [stopwatch_accumulator] can make that simple. Alternatively, an asynchronous stream would permit normal logging but by a thread other than the one being measured." Para 2, bullet 2: s/intrinsec/intrinsic/ This could be worded more clearly: "Add a mechanism to track the difference between the application time and stopclock time. If a [Clock] models [SuspendibleClock] and its precision is sufficiently fine, this mechanism could suspend the [Clock]'s counting while reporting measurements and resume it thereafter." _____________ Template Class stopwatch_reporter<> s/a everything/everything/ s/precission/precision/ Why is stopwatch_reporter a stopwatch plus reporting? That is, why doesn't stopwatch include the reporting and have done or stopwatch_reporter reference a stopwatch? There should be something describing such design decisions in your documentation, whether here or elsewhere is unimportant. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Hi, thanks for your inside rewording. I have taken most of them in account. Next follows answers to some questions or some questions to your comments. ----- Original Message ----- From: "Stewart, Robert" <Robert.Stewart@sig.com> To: <boost@lists.boost.org> Sent: Wednesday, August 11, 2010 2:47 PM Subject: Re: [boost] [chrono] v0.4.5 Documentation update + warnings removal + bug fixes
vicente.botet wrote:
Even if the review's date is not annonced yet, it will be great if some of you make a pre-review, so the conflicting issues are managed before the review.
Here are comments from my reading of the initial sections of the document. Hopefully, I can offer comments on the User's Guide another time.
Thanks, this will be very helpful.
_____________ Overview
This section appears to be a sibling of the immediately following Description section, but includes a one-item TOC leading to the Motivation section which is also found by following the navigation icons to the next section. This is confusing.
I'd expect the Overview section to include a TOC leading to the Motivation section first, and the Description section second, which means moving Description to its own page. I'd expect the How to Use This Documentation section to remain on the same page as the Overview section.
I have made the Description a section that follows the Motivation.
_____________ Description
Para 1, bullet 3:
s/any given/a particular/ s/symbolic bundle/pairing/
As Clocks are not instantiated, what about "symbolic pairing"?
What is a "native time_point?" That phrase suggests there are others, so why the distinction here?
The library works only with time points supported natively by the platform. I can remove native here if this is confusing.
Para 3, bullet 2:
Given this reference to a "higher layer," one might now infer that the features described in the first two paragraphs were the lower layer, but it would be better to avoid references to layers, at least within the Description section. You also use the term "stopclock" as though its meaning is apparent. It isn't. The description doesn't clearly convey the meaning either. I looked at the documentation for basic_stopclock and stopclock and found nothing to help. I can infer that it is to measure elapsed time like a stopwatch, but, perhaps, with less precision, though I have no confidence in that inference.
I can't suggest how to rewrite this bullet without understanding "stopclock."
I have had a lot of trouble finding a name for the stopclock class. Stopclocks and Stopwatches differ only in one feature: the ability of Stopclocks to report the elapsed time on a output stream, either by an explicit request, or implicitly at the destruction of the Stopclock. A stopclock<Clock> is a synomym of a stopwatch_reporter<stopwatch<Clock> >. If the name is confusing, I will need to find a better one. Any suggestions?
Para 3, bullet 2, subbullet 3:
This bullet isn't of much value in this introductory text, particularly as there is no explicit mention of any characters until this point.
Maybe I need to add that the report is done on an output stream (including wide char streams).
_____________ How to Use This Documentation
Para 2:
Is there no include all header for Chrono?
We can consider that the current package has 4 libraries: * common_type for type_traits * ratio * chrono * stropwatches When we include boost/chrono.hpp we include only the standard. Of course this includes also the #include <boost/type_traits/common_type.hpp> #include <boost/ratio.hpp> We can consider that #include <boost/stopwatches.hpp> is the top level include file.
_____________ Motivation
This section should precede the Description section. It is here that you're trying to sell the library. Once hooked, the reader will want to read a description.
_____ Reporting slapsed[sic] time
Para 1, last sentence:
I'm not sure what you mean by "allowing to make a single measure."
This is in oposition to the ability of stopwatch_accumulator to manage with multiple measures samples. I will remove this part of the sentence.
Para 2, sentence 1:
Try, "It is often necessary to report elapsed time on a user display or in a log file. [stopwatch_reporter<>] provides a runtime reporting mechanism for this purpose which can be invoked in just one line of code."
_____ How reliable are these measures?
This section doesn't belong in Motivation. This should be in the Getting Started section, I think.
This section is the motivation for stopwatches accumulators, and suspendible clocks. Maybe the wording should be improved. Thanks again, Vicente

On 2010-08-13 10:17, vicente.botet wrote:
We can consider that the current package has 4 libraries: * common_type for type_traits * ratio * chrono * stropwatches
Meaning that if it is accepted into boost there will actually be three new libraries (ratio, chrono, stopwatches)?

----- Original Message ----- From: "Roland Bock" <rbock@eudoxos.de> To: <boost@lists.boost.org> Sent: Friday, August 13, 2010 11:04 AM Subject: Re: [boost] �
On 2010-08-13 10:17, vicente.botet wrote:
We can consider that the current package has 4 libraries: * common_type for type_traits * ratio * chrono * stropwatches
Meaning that if it is accepted into boost there will actually be three new libraries (ratio, chrono, stopwatches)?
This is a matter of choice. Clearly common_type should goes to the TypeTraits library. ratio could be included as a standalone library. Whether chrono and stopwatches are separated is up to us. If the boost community consider that it is better to package them as three separated libraries, I will do the break. Do the community considers that the break need to be done before review or can it be done after? Any opinions? Best, Vicente

On 08/13/2010 07:11 PM, vicente.botet wrote:
We can consider that the current package has 4 libraries:
* common_type for type_traits * ratio * chrono * stropwatches
Meaning that if it is accepted into boost there will actually be three new libraries (ratio, chrono, stopwatches)?
This is a matter of choice. Clearly common_type should goes to the TypeTraits library. ratio could be included as a standalone library. Whether chrono and stopwatches are separated is up to us. If the boost community consider that it is better to package them as three separated libraries, I will do the break. Do the community considers that the break need to be done before review or can it be done after?
Any opinions?
I'd prefer two libraries: ratio chrono (including stopwatches)

vicente.botet wrote:
Rob Stewart wrote:
vicente.botet wrote:
_____________ Description
Para 1, bullet 3:
s/any given/a particular/ s/symbolic bundle/pairing/
As Clocks are not instantiated, what about "symbolic pairing"?
I don't think the distinction is helpful. Clock is a concept that pairs time_point and duration. As a concept, it is understood that it isn't instantiated.
What is a "native time_point?" That phrase suggests there are others, so why the distinction here?
The library works only with time points supported natively by the platform. I can remove native here if this is confusing.
Actually, "platform native time point" might be better. Otherwise, just "time_point."
Para 3, bullet 2:
I can't suggest how to rewrite this bullet without understanding "stopclock."
I have had a lot of trouble finding a name for the stopclock class. Stopclocks and Stopwatches differ only in one feature: the ability of Stopclocks to report the elapsed time on a output stream, either by an explicit request, or implicitly at the destruction of the Stopclock. A stopclock<Clock> is a synomym of a stopwatch_reporter<stopwatch<Clock> >.
This sort of description should appear here: http://svn.boost.org/svn/boost/sandbox/chrono/libs/chrono/doc/html/boost_chr.... That is: "A stopclock is a stopwatch with the ability to report elapsed time on an output stream."
If the name is confusing, I will need to find a better one. Any suggestions?
The name in no way represents the class' purpose or behavior, so a different name is definitely in order. I imagine you settled on "stopclock" because you wanted to avoid a long name. My first thought is that stopwatch_reporter<stopwatch<Clock>> is the better spelling because it clearly shows that the reporting functionality is being added to a stopwatch. However, a non-nested class template is simpler to write and gives a name to the feature, so how about the direct and obvious "reporting_stopwatch?"
Para 3, bullet 2, subbullet 3:
This bullet isn't of much value in this introductory text, particularly as there is no explicit mention of any characters until this point.
Maybe I need to add that the report is done on an output stream (including wide char streams).
That's a better way to handle it.
_____________ How to Use This Documentation
Para 2:
Is there no include all header for Chrono?
We can consider that the current package has 4 libraries: * common_type for type_traits * ratio * chrono * stropwatches
When we include boost/chrono.hpp we include only the standard. Of course this includes also the #include <boost/type_traits/common_type.hpp> #include <boost/ratio.hpp>
We can consider that
#include <boost/stopwatches.hpp>
is the top level include file.
My point was that you indicated a set of multiple include directives should be assumed for all examples. I would expect a single include directive to have covered the examples.
_____________ Motivation
_____ Reporting slapsed[sic] time
Para 1, last sentence:
I'm not sure what you mean by "allowing to make a single measure."
I will remove this part of the sentence.
I think that's better. Now, BTW, s/the measure of the/measuring/.
Para 2, sentence 1:
Try, "It is often necessary to report elapsed time on a user display or in a log file. [stopwatch_reporter<>] provides a runtime reporting mechanism for this purpose which can be invoked in just one line of code."
Did you miss this one? I think you should mention reporting uses other than the display and a log file seems a good choice. I also don't like "at the user level" as the introduction to this paragraph.
_____ How reliable are these measures?
This section doesn't belong in Motivation. This should be in the Getting Started section, I think.
This section is the motivation for stopwatches accumulators, and suspendible clocks. Maybe the wording should be improved.
There's too much detail here for the Motivation section. Besides, to motivate the use of the library, you don't need to explain deficiencies and provisions to overcome them. This belongs elsewhere. There should be a FAQ or Implementation Issues section for details like you have here. If you still think something should be in the Motivation section, maybe this will be enough: "There are a number of things that can lead to unreliable measurement (see [here] for more details), but they mostly amount to reporting overhead. Boost.Chrono provides two ways to improve reliability of time measurements. A [stopwatch_accumulator] only reports statistics once all measurements have been acquired, which removes reporting overhead from the measurements. The other approach is to use a [SuspendibleClock] such that the reporting overhead can be ignored by suspending elapsed time tracking during reporting operations." _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

----- Original Message ----- From: "Stewart, Robert" <Robert.Stewart@sig.com> To: <boost@lists.boost.org> Sent: Friday, August 13, 2010 2:43 PM Subject: Re: [boost] [chrono] v0.4.5 Documentation update + warnings removal +�ug fixes
vicente.botet wrote:
Rob Stewart wrote:
vicente.botet wrote:
_____________ Description
Para 1, bullet 3:
s/any given/a particular/ s/symbolic bundle/pairing/
As Clocks are not instantiated, what about "symbolic pairing"?
I don't think the distinction is helpful. Clock is a concept that pairs time_point and duration. As a concept, it is understood that it isn't instantiated.
OK.
What is a "native time_point?" That phrase suggests there are others, so why the distinction here?
The library works only with time points supported natively by the platform. I can remove native here if this is confusing.
Actually, "platform native time point" might be better. Otherwise, just "time_point."
I left just time_point.
Para 3, bullet 2:
I can't suggest how to rewrite this bullet without understanding "stopclock."
I have had a lot of trouble finding a name for the stopclock class. Stopclocks and Stopwatches differ only in one feature: the ability of Stopclocks to report the elapsed time on a output stream, either by an explicit request, or implicitly at the destruction of the Stopclock. A stopclock<Clock> is a synomym of a stopwatch_reporter<stopwatch<Clock> >.
This sort of description should appear here: http://svn.boost.org/svn/boost/sandbox/chrono/libs/chrono/doc/html/boost_chr.... That is: "A stopclock is a stopwatch with the ability to report elapsed time on an output stream."
Done.
If the name is confusing, I will need to find a better one. Any suggestions?
The name in no way represents the class' purpose or behavior, so a different name is definitely in order. I imagine you settled on "stopclock" because you wanted to avoid a long name. My first thought is that stopwatch_reporter<stopwatch<Clock>> is the better spelling because it clearly shows that the reporting functionality is being added to a stopwatch. However, a non-nested class template is simpler to write and gives a name to the feature, so how about the direct and obvious "reporting_stopwatch?"
What others think? Other suggestions for the shortcut?
_____________ How to Use This Documentation
Para 2:
Is there no include all header for Chrono?
We can consider that the current package has 4 libraries: * common_type for type_traits * ratio * chrono * stropwatches
When we include boost/chrono.hpp we include only the standard. Of course this includes also the #include <boost/type_traits/common_type.hpp> #include <boost/ratio.hpp>
We can consider that
#include <boost/stopwatches.hpp>
is the top level include file.
My point was that you indicated a set of multiple include directives should be assumed for all examples. I would expect a single include directive to have covered the examples.
OK. I will suppose every example includes #include <boost/stopwatches.hpp>
_____________ Motivation
_____ Reporting slapsed[sic] time
Para 1, last sentence:
I'm not sure what you mean by "allowing to make a single measure."
I will remove this part of the sentence.
I think that's better. Now, BTW, s/the measure of the/measuring/.
Done.
Para 2, sentence 1:
Try, "It is often necessary to report elapsed time on a user display or in a log file. [stopwatch_reporter<>] provides a runtime reporting mechanism for this purpose which can be invoked in just one line of code."
Did you miss this one? I think you should mention reporting uses other than the display and a log file seems a good choice. I also don't like "at the user level" as the introduction to this paragraph.
Yes. Done now.
_____ How reliable are these measures?
This section doesn't belong in Motivation. This should be in the Getting Started section, I think.
This section is the motivation for stopwatches accumulators, and suspendible clocks. Maybe the wording should be improved.
There's too much detail here for the Motivation section. Besides, to motivate the use of the library, you don't need to explain deficiencies and provisions to overcome them. This belongs elsewhere. There should be a FAQ or Implementation Issues section for details like you have here.
I've moved to the Rationale section.
If you still think something should be in the Motivation section, maybe this will be enough:
"There are a number of things that can lead to unreliable measurement (see [here] for more details), but they mostly amount to reporting overhead. Boost.Chrono provides two ways to improve reliability of time measurements. A [stopwatch_accumulator] only reports statistics once all measurements have been acquired, which removes reporting overhead from the measurements. The other approach is to use a [SuspendibleClock] such that the reporting overhead can be ignored by suspending elapsed time tracking during reporting operations."
Yes, this should be enough. Thanks again, Vicente

On 8/10/2010 11:00 AM, vicente.botet wrote:
Hi,
I have made some minor modifications to the Boost.Chrono library as requested on these mailing lists. The implementaton is stable. ... Even if the review's date is not annonced yet, it will be great if some of you make a pre-review, so the conflicting issues are managed before the review.
Is it necessary for common_type to fallback to Boost.TypeOf in the absence of decltype? In what situations is (bool ? T : U) not either T, U, or some additional const/volatile qualifications on T or U, possibly transposed with some reference or pointer qualifiers? In other words, when does (bool ? T : U) manufacture some new "3rd type" out of the blue? - Jeff

Hi, ----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Friday, August 13, 2010 5:35 PM Subject: Re: [boost] [chrono] v0.4.5 Documentation update + warnings removal + bug fixes
On 8/10/2010 11:00 AM, vicente.botet wrote:
Hi,
I have made some minor modifications to the Boost.Chrono library as requested on these mailing lists. The implementaton is stable. ... Even if the review's date is not annonced yet, it will be great if some of you make a pre-review, so the conflicting issues are managed before the review.
Is it necessary for common_type to fallback to Boost.TypeOf in the absence of decltype? In what situations is (bool ? T : U) not either T, U, or some additional const/volatile qualifications on T or U, possibly transposed with some reference or pointer qualifiers?
In other words, when does (bool ? T : U) manufacture some new "3rd type" out of the blue?
(bool ? T : U) is incorrect as the ?: operator don't works on types but on expression. This is exactle the role of typeof. Are I'm missing something? Best, Vicente

On 8/13/2010 9:16 AM, vicente.botet wrote:
Hi, ----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 5:35 PM Subject: Re: [boost] [chrono] v0.4.5 Documentation update + warnings removal + bug fixes
On 8/10/2010 11:00 AM, vicente.botet wrote:
Hi,
I have made some minor modifications to the Boost.Chrono library as requested on these mailing lists. The implementaton is stable. ... Even if the review's date is not annonced yet, it will be great if some of you make a pre-review, so the conflicting issues are managed before the review.
Is it necessary for common_type to fallback to Boost.TypeOf in the absence of decltype? In what situations is (bool ? T : U) not either T, U, or some additional const/volatile qualifications on T or U, possibly transposed with some reference or pointer qualifiers?
In other words, when does (bool ? T : U) manufacture some new "3rd type" out of the blue?
(bool ? T : U) is incorrect as the ?: operator don't works on types but on expression. This is exactle the role of typeof. Are I'm missing something?
Okay, sorry, my fault for being lazy ;) Replace (bool ? T : U) with (b ? t : u); b of type bool; t of type T; u of type U; and t and u are rvalues unless T and U (respectively) are (lvalue) reference types. Additionally, common_type operates on types, not expressions, so you know the types you're working with in the hypothetical conditional expression. - Jeff

----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Friday, August 13, 2010 6:49 PM Subject: Re: [boost] �
On 8/13/2010 9:16 AM, vicente.botet wrote:
Hi, ----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 5:35 PM Subject: Re: [boost] [chrono] v0.4.5 Documentation update + warnings removal + bug fixes
On 8/10/2010 11:00 AM, vicente.botet wrote:
Hi,
I have made some minor modifications to the Boost.Chrono library as requested on these mailing lists. The implementaton is stable. ... Even if the review's date is not annonced yet, it will be great if some of you make a pre-review, so the conflicting issues are managed before the review.
Is it necessary for common_type to fallback to Boost.TypeOf in the absence of decltype? In what situations is (bool ? T : U) not either T, U, or some additional const/volatile qualifications on T or U, possibly transposed with some reference or pointer qualifiers?
In other words, when does (bool ? T : U) manufacture some new "3rd type" out of the blue?
(bool ? T : U) is incorrect as the ?: operator don't works on types but on expression. This is exactle the role of typeof. Are I'm missing something?
Okay, sorry, my fault for being lazy ;) Replace (bool ? T : U) with (b ? t : u); b of type bool; t of type T; u of type U; and t and u are rvalues unless T and U (respectively) are (lvalue) reference types.
This is exactly what is in the code, other than I use functions instead of variables. static bool m_f(); // workaround gcc bug; not required by std static T m_t(); static U m_u(); public: typedef BOOST_TYPEOF_TPL(m_f() ? m_t() : m_u()) type; We need however to transform the expression "(b ? t : u)" on a type and I don't see how to achieve it without typeof. Do you?
Additionally, common_type operates on types, not expressions, so you know the types you're working with in the hypothetical conditional expression.
This is correct, but I don't see how this is related to your concern. Vicente

On 8/13/2010 10:03 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 6:49 PM Subject: Re: [boost] �
On 8/13/2010 9:16 AM, vicente.botet wrote:
Hi, ----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 5:35 PM Subject: Re: [boost] [chrono] v0.4.5 Documentation update + warnings removal + bug fixes
Is it necessary for common_type to fallback to Boost.TypeOf in the absence of decltype? In what situations is (bool ? T : U) not either T, U, or some additional const/volatile qualifications on T or U, possibly transposed with some reference or pointer qualifiers?
In other words, when does (bool ? T : U) manufacture some new "3rd type" out of the blue?
(bool ? T : U) is incorrect as the ?: operator don't works on types but on expression. This is exactle the role of typeof. Are I'm missing something?
Okay, sorry, my fault for being lazy ;) Replace (bool ? T : U) with (b ? t : u); b of type bool; t of type T; u of type U; and t and u are rvalues unless T and U (respectively) are (lvalue) reference types.
This is exactly what is in the code, other than I use functions instead of variables.
Sure.
static bool m_f(); // workaround gcc bug; not required by std static T m_t(); static U m_u(); public: typedef BOOST_TYPEOF_TPL(m_f() ? m_t() : m_u()) type;
We need however to transform the expression "(b ? t : u)" on a type and I don't see how to achieve it without typeof. Do you?
My question is, if you can enumerate all possible candidates for (b ? t : u ) in terms of simple (C++03) transformations on T and U, then there's no need for Boost.TypeOf. You can get by with the "sizeof() trick", a la a slightly more elaborate boost::is_convertible. This could make the implementation more complex, but more robust (for C++03), which I think is an overall win. Do you agree? So...back to my original question? I'm definitely not saying with certainty that an implementation that does not use Boost.TypeOf is possible. I'm just no expert on the conditional operator, and I'm looking for an instance where (b ? t : u) can't be determined from applying simple transformations (e.g., removing reference qualifiers, or adding cv qualifiers) to T and U.
Additionally, common_type operates on types, not expressions, so you know the types you're working with in the hypothetical conditional expression.
This is correct, but I don't see how this is related to your concern.
It's not; it was meant to address your comment that "?: operator don't works on types but on expression", but I think we're on the same page now. - Jeff

----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Friday, August 13, 2010 7:28 PM Subject: Re: [boost] � On 8/13/2010 10:03 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 6:49 PM Subject: Re: [boost] �
My question is, if you can enumerate all possible candidates for (b ? t : u ) in terms of simple (C++03) transformations on T and U, then there's no need for Boost.TypeOf. You can get by with the "sizeof() trick", a la a slightly more elaborate boost::is_convertible. This could make the implementation more complex, but more robust (for C++03), which I think is an overall win. Do you agree? So...back to my original question? I'm definitely not saying with certainty that an implementation that does not use Boost.TypeOf is possible. I'm just no expert on the conditional operator, and I'm looking for an instance where (b ? t : u) can't be determined from applying simple transformations (e.g., removing reference qualifiers, or adding cv qualifiers) to T and U. _______________________________________________ I'm not an expert either and I don't see how we can get it without typeof. Anyway, how the possible implementation could be more robust? Vicente

On 8/13/2010 10:47 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 7:28 PM Subject: Re: [boost] �
My question is, if you can enumerate all possible candidates for (b ? t : u ) in terms of simple (C++03) transformations on T and U, then there's no need for Boost.TypeOf. You can get by with the "sizeof() trick", a la a slightly more elaborate boost::is_convertible. This could make the implementation more complex, but more robust (for C++03), which I think is an overall win. Do you agree? [...] _______________________________________________
I'm not an expert either and I don't see how we can get it without typeof. Anyway, how the possible implementation could be more robust?
[Changed subject to be more accurate.] Perhaps robust wasn't the right word. More general? Essentially, I think it's "better" if common_type doesn't rely on Boost.TypeOf, as then it will work regardless of type registration in C++03. I don't know if this is a relevant concern at this point in time, though. Don't most C++ compilers in wide use support an efficient implementation of BOOST_TYPEOF or decltype? As for an implementation independent of Boost.TypeOf, this might be relevant, although not necessarily definitive: http://msdn.microsoft.com/en-us/library/e4213hs1%28VS.90%29.aspx I'm not sure what is meant by "pointer conversions" and "reference conversions", but I'd guess it just unions cv qualifiers and chooses the better conversion to one pointer/reference type or the other. E.g., choose the better conversion between (b ? t : u) to T {maybe-cv} & and U {maybe-cv} &, where t is of type T& and u is of type U&. I think a Boost.TypeOf-less implementation of common_type is possible because I don't think the compiler can manufacture some mysterious "3rd type" out of thin air from the types of the lhs and rhs expressions of the conditional operator. In other words, given struct X0; struct X1; struct X2; bool cond(); X0 x0(); X1 x1(); then (cond() ? x0() : x1()) can't possibly be anything related to X2, no matter how X0, X1, and X2 are defined. Is that accurate? If so, it must be that (cond() ? x0() : x1()) must have type X0 or X1. Determining which of those 2 choices it is can be deduced using the "sizeof trick": typedef char (&y0)[1]; typedef char (&y1)[2]; y0 deduce(X0); y1 deduce(X1); static const bool is_x0 = sizeof( deduce(cond() ? x0() : x1()) ) == sizeof( y0 ); Obviously, some care needs to be taken when these definitions of deduce produce ambiguous overloads, but hopefully I've better conveyed the idea. And if this whole endeavor sounds completely unnecessary, feel free to say so, and I'll drop the discussion ;) - Jeff

----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Saturday, August 14, 2010 10:16 AM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf] On 8/13/2010 10:47 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 7:28 PM Subject: Re: [boost] �
My question is, if you can enumerate all possible candidates for (b ? t : u ) in terms of simple (C++03) transformations on T and U, then there's no need for Boost.TypeOf. You can get by with the "sizeof() trick", a la a slightly more elaborate boost::is_convertible. This could make the implementation more complex, but more robust (for C++03), which I think is an overall win. Do you agree? [...] _______________________________________________
I'm not an expert either and I don't see how we can get it without typeof. Anyway, how the possible implementation could be more robust?
[Changed subject to be more accurate.] Perhaps robust wasn't the right word. More general? Essentially, I think it's "better" if common_type doesn't rely on Boost.TypeOf, as then it will work regardless of type registration in C++03. I don't know if this is a relevant concern at this point in time, though. Don't most C++ compilers in wide use support an efficient implementation of BOOST_TYPEOF or decltype? As for an implementation independent of Boost.TypeOf, this might be relevant, although not necessarily definitive: http://msdn.microsoft.com/en-us/library/e4213hs1%28VS.90%29.aspx I'm not sure what is meant by "pointer conversions" and "reference conversions", but I'd guess it just unions cv qualifiers and chooses the better conversion to one pointer/reference type or the other. E.g., choose the better conversion between (b ? t : u) to T {maybe-cv} & and U {maybe-cv} &, where t is of type T& and u is of type U&. I think a Boost.TypeOf-less implementation of common_type is possible because I don't think the compiler can manufacture some mysterious "3rd type" out of thin air from the types of the lhs and rhs expressions of the conditional operator. In other words, given struct X0; struct X1; struct X2; bool cond(); X0 x0(); X1 x1(); then (cond() ? x0() : x1()) can't possibly be anything related to X2, no matter how X0, X1, and X2 are defined. Is that accurate? If so, it must be that (cond() ? x0() : x1()) must have type X0 or X1. Determining which of those 2 choices it is can be deduced using the "sizeof trick": typedef char (&y0)[1]; typedef char (&y1)[2]; y0 deduce(X0); y1 deduce(X1); static const bool is_x0 = sizeof( deduce(cond() ? x0() : x1()) ) == sizeof( y0 ); Obviously, some care needs to be taken when these definitions of deduce produce ambiguous overloads, but hopefully I've better conveyed the idea. And if this whole endeavor sounds completely unnecessary, feel free to say so, and I'll drop the discussion ;) - Jeff _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Saturday, August 14, 2010 10:16 AM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf] On 8/13/2010 10:47 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 7:28 PM Subject: Re: [boost] �
My question is, if you can enumerate all possible candidates for (b ? t : u ) in terms of simple (C++03) transformations on T and U, then there's no need for Boost.TypeOf. You can get by with the "sizeof() trick", a la a slightly more elaborate boost::is_convertible. This could make the implementation more complex, but more robust (for C++03), which I think is an overall win. Do you agree? [...] _______________________________________________
I'm not an expert either and I don't see how we can get it without typeof. Anyway, how the possible implementation could be more robust?
[Changed subject to be more accurate.] Perhaps robust wasn't the right word. More general? Essentially, I think it's "better" if common_type doesn't rely on Boost.TypeOf, as then it will work regardless of type registration in C++03. I don't know if this is a relevant concern at this point in time, though. Don't most C++ compilers in wide use support an efficient implementation of BOOST_TYPEOF or decltype? As for an implementation independent of Boost.TypeOf, this might be relevant, although not necessarily definitive: http://msdn.microsoft.com/en-us/library/e4213hs1%28VS.90%29.aspx I'm not sure what is meant by "pointer conversions" and "reference conversions", but I'd guess it just unions cv qualifiers and chooses the better conversion to one pointer/reference type or the other. E.g., choose the better conversion between (b ? t : u) to T {maybe-cv} & and U {maybe-cv} &, where t is of type T& and u is of type U&. I think a Boost.TypeOf-less implementation of common_type is possible because I don't think the compiler can manufacture some mysterious "3rd type" out of thin air from the types of the lhs and rhs expressions of the conditional operator. In other words, given struct X0; struct X1; struct X2; bool cond(); X0 x0(); X1 x1(); then (cond() ? x0() : x1()) can't possibly be anything related to X2, no matter how X0, X1, and X2 are defined. Is that accurate? If so, it must be that (cond() ? x0() : x1()) must have type X0 or X1. Determining which of those 2 choices it is can be deduced using the "sizeof trick": typedef char (&y0)[1]; typedef char (&y1)[2]; y0 deduce(X0); y1 deduce(X1); static const bool is_x0 = sizeof( deduce(cond() ? x0() : x1()) ) == sizeof( y0 ); Obviously, some care needs to be taken when these definitions of deduce produce ambiguous overloads, but hopefully I've better conveyed the idea. And if this whole endeavor sounds completely unnecessary, feel free to say so, and I'll drop the discussion ;) - Jeff _______________________________________________ Hi Jeff, Yes I see now better what was your idea. Have you tried to implement it? I will try the approach to see what I can get, but I'm not sure to been able to manage with the ambiguous overloads. Howard, what do you think about this approach? Have you already tried something like that? Thanks, Vicente

_____________________ Vicente Juan Botet Escribá http://viboes.blogspot.com/ ----- Original Message ----- From: "vicente.botet" <vicente.botet@wanadoo.fr> To: <boost@lists.boost.org> Sent: Saturday, August 14, 2010 1:15 PM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf] ----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Saturday, August 14, 2010 10:16 AM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf] On 8/13/2010 10:47 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 7:28 PM Subject: Re: [boost] �
My question is, if you can enumerate all possible candidates for (b ? t : u ) in terms of simple (C++03) transformations on T and U, then there's no need for Boost.TypeOf. You can get by with the "sizeof() trick", a la a slightly more elaborate boost::is_convertible. This could make the implementation more complex, but more robust (for C++03), which I think is an overall win. Do you agree? [...] _______________________________________________
I'm not an expert either and I don't see how we can get it without typeof. Anyway, how the possible implementation could be more robust?
[Changed subject to be more accurate.] Perhaps robust wasn't the right word. More general? Essentially, I think it's "better" if common_type doesn't rely on Boost.TypeOf, as then it will work regardless of type registration in C++03. I don't know if this is a relevant concern at this point in time, though. Don't most C++ compilers in wide use support an efficient implementation of BOOST_TYPEOF or decltype? As for an implementation independent of Boost.TypeOf, this might be relevant, although not necessarily definitive: http://msdn.microsoft.com/en-us/library/e4213hs1%28VS.90%29.aspx I'm not sure what is meant by "pointer conversions" and "reference conversions", but I'd guess it just unions cv qualifiers and chooses the better conversion to one pointer/reference type or the other. E.g., choose the better conversion between (b ? t : u) to T {maybe-cv} & and U {maybe-cv} &, where t is of type T& and u is of type U&. I think a Boost.TypeOf-less implementation of common_type is possible because I don't think the compiler can manufacture some mysterious "3rd type" out of thin air from the types of the lhs and rhs expressions of the conditional operator. In other words, given struct X0; struct X1; struct X2; bool cond(); X0 x0(); X1 x1(); then (cond() ? x0() : x1()) can't possibly be anything related to X2, no matter how X0, X1, and X2 are defined. Is that accurate? If so, it must be that (cond() ? x0() : x1()) must have type X0 or X1. Determining which of those 2 choices it is can be deduced using the "sizeof trick": typedef char (&y0)[1]; typedef char (&y1)[2]; y0 deduce(X0); y1 deduce(X1); static const bool is_x0 = sizeof( deduce(cond() ? x0() : x1()) ) == sizeof( y0 ); Obviously, some care needs to be taken when these definitions of deduce produce ambiguous overloads, but hopefully I've better conveyed the idea. And if this whole endeavor sounds completely unnecessary, feel free to say so, and I'll drop the discussion ;) - Jeff _______________________________________________ Hi Jeff, Yes I see now better what was your idea. Have you tried to implement it? I will try the approach to see what I can get, but I'm not sure to been able to manage with the ambiguous overloads. Howard, what do you think about this approach? Have you already tried something like that? Thanks, Vicente _______________________________________________ Hi again, I have reached to manage with the ambiguous overloads and all the tests works as before. I have do it as follows: namespace detail { template <class T, class U> struct common_type_2 { private: BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T)); BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U)); static bool m_f(); // workaround gcc bug; not required by std #if !defined(BOOST_NO_RVALUE_REFERENCES) \ && !defined(BOOST_NO_DECLTYPE) static T&& m_t(); static U&& m_u(); public: typedef decltype(m_f() ? m_t() : m_u()) type; #else static T m_t(); static U m_u(); #if 0 public: typedef BOOST_TYPEOF_TPL(m_f() ? m_t() : m_u()) type; #else typedef char (&yes)[1]; typedef char (&no)[2]; static yes deduce(T); static no deduce(U); public: typedef typename mpl::if_c< sizeof( deduce(m_f() ? m_t() : m_u()) ) == sizeof( yes ), T, U >::type type; #endif #endif }; template <class T> struct common_type_2<T, T> { typedef T type; }; } #if !defined(BOOST_NO_VARIADIC_TEMPLATES) template <class T, class U> struct common_type<T, U> #else template <class T, class U> struct common_type<T, U, void> #endif : detail::common_type_2<T,U> { };

On 8/14/2010 6:43 AM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@wanadoo.fr> To:<boost@lists.boost.org> Sent: Saturday, August 14, 2010 1:15 PM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf] Hi Jeff,
Yes I see now better what was your idea. Have you tried to implement it?
I have. Unfortunately, 1) it will take some effort to remove dependencies on other in-house utilities; 2) my implementation is quite a bit more complex; and 3) the extra complexity is probably necessary. I will explain below.
I will try the approach to see what I can get, but I'm not sure to been able to manage with the ambiguous overloads.
I will comment on this below, as well.
Howard, what do you think about this approach? Have you already tried something like that?
Thanks, Vicente _______________________________________________
Hi again,
I have reached to manage with the ambiguous overloads and all the tests works as before.
I have do it as follows: [...template code removed...] #if 0 public: typedef BOOST_TYPEOF_TPL(m_f() ? m_t() : m_u()) type; #else typedef char (&yes)[1]; typedef char (&no)[2]; static yes deduce(T); static no deduce(U); public: typedef typename mpl::if_c< sizeof( deduce(m_f() ? m_t() : m_u()) ) == sizeof( yes ), T, U>::type type;
#endif [...more template code removed...]
As far as I know, this will generally only give the right result of common_type<T,U> for non-reference and non-pointer T's and U's. Unfortunately, it won't take care of cases such as common_type< int const *, int volatile * > -> int const volatile *. Reference types are even trickier, as their common_type could be either an lvalue reference (this is similar to the pointer case) or an rvalue. Here is a summary of the logic I use. For concreteness, we wish to compute common_type<T,U>, which is the type of the "conditional expression" (*), (bool_() ? t() : u()), where bool_() has type bool, t() has return type T, and u() has return type U. For simplicity, assume that cv qualifiers have already been stripped from T and U, as they don't affect the type of common_type<T,U>. First, we obtain a set of "candidate types", with the property that common_type<T,U> is among these candidate types. Once we have a finite set of candidate types, we can apply an extension of the "sizeof trick" (used above for deduce) to determine which of the candidates is the actual desired type. The set of candidate types will be constructed to make it easy to avoid ambiguous overloads, since we will remove duplicates, and either all candidate types will be reference types or all candidate types will be non-reference (and non-cv-qualified) types. To determine these candidate types, the logic goes roughly as follows (apply in order): (1) If T and U are reference types, say, T = T' & and U = U' &: If the conditional expression (*) is an rvalue, go on to (2) (this is a property that can be determined via another "sizeof trick"). Otherwise, the set of candidate types is { T' &, U' &, T' [cvU'] &, U' [cvT'] & }; where [cvX'] are the cv-qualifiers on X'; and assume duplicates are removed. (2) If T and U (after stripping any reference and cv qualifiers), are pointer types, say, T = T' * and U = U' *: The set of candidate types is { T' *, U' *, T' [cvU'] *, U' [cvT'] * }; where [cvX'] is as before; and assume duplicates are removed. (3) If T and U (after stripping any reference and cv qualifiers) are both builtin integral types: The set of candidate types is { T, U, make_signed(T), make_signed(U), make_unsigned(T), make_unsigned(U) }, with duplicates removed. This should catch any transfers of signed-ness or unsigned-ness. (4) If none of the above, then the set of candidate types is simply { T, U } (again, duplicates are removed, and these are the types after removal of reference and cv qualifiers). Case (4) is the case you've implemented in the code above, but (I think) it really should be the least prioritized case. I haven't rigorously tested this logic out, so I don't know if the preceding is a complete description of the conditional operator, but I think it should be pretty close. What do you think? - Jeff

----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Monday, August 16, 2010 8:23 AM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf]
On 8/14/2010 6:43 AM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@wanadoo.fr> To:<boost@lists.boost.org> Sent: Saturday, August 14, 2010 1:15 PM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf] Hi Jeff,
Yes I see now better what was your idea. Have you tried to implement it?
I have. Unfortunately, 1) it will take some effort to remove dependencies on other in-house utilities; 2) my implementation is quite a bit more complex; and 3) the extra complexity is probably necessary.
Hi, Yes, the case I solved is the basic case. Do you mind to send me privately your implementation. I'm sure it will take me less effort to implement it from your implementation than starting from zero. Best, Vicente

On Aug 14, 2010, at 7:15 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr." <jhellrung@ucla.edu> To: <boost@lists.boost.org> Sent: Saturday, August 14, 2010 10:16 AM Subject: Re: [boost] [chrono] [dependence of common_type on Boost.TypeOf]
On 8/13/2010 10:47 AM, vicente.botet wrote:
----- Original Message ----- From: "Jeffrey Lee Hellrung, Jr."<jhellrung@ucla.edu> To:<boost@lists.boost.org> Sent: Friday, August 13, 2010 7:28 PM Subject: Re: [boost] �
My question is, if you can enumerate all possible candidates for (b ? t : u ) in terms of simple (C++03) transformations on T and U, then there's no need for Boost.TypeOf. You can get by with the "sizeof() trick", a la a slightly more elaborate boost::is_convertible. This could make the implementation more complex, but more robust (for C++03), which I think is an overall win. Do you agree? [...] _______________________________________________
I'm not an expert either and I don't see how we can get it without typeof. Anyway, how the possible implementation could be more robust?
[Changed subject to be more accurate.]
Perhaps robust wasn't the right word. More general? Essentially, I think it's "better" if common_type doesn't rely on Boost.TypeOf, as then it will work regardless of type registration in C++03. I don't know if this is a relevant concern at this point in time, though. Don't most C++ compilers in wide use support an efficient implementation of BOOST_TYPEOF or decltype?
As for an implementation independent of Boost.TypeOf, this might be relevant, although not necessarily definitive:
http://msdn.microsoft.com/en-us/library/e4213hs1%28VS.90%29.aspx
I'm not sure what is meant by "pointer conversions" and "reference conversions", but I'd guess it just unions cv qualifiers and chooses the better conversion to one pointer/reference type or the other. E.g., choose the better conversion between (b ? t : u) to T {maybe-cv} & and U {maybe-cv} &, where t is of type T& and u is of type U&.
I think a Boost.TypeOf-less implementation of common_type is possible because I don't think the compiler can manufacture some mysterious "3rd type" out of thin air from the types of the lhs and rhs expressions of the conditional operator. In other words, given
struct X0; struct X1; struct X2;
bool cond(); X0 x0(); X1 x1();
then (cond() ? x0() : x1()) can't possibly be anything related to X2, no matter how X0, X1, and X2 are defined. Is that accurate? If so, it must be that (cond() ? x0() : x1()) must have type X0 or X1. Determining which of those 2 choices it is can be deduced using the "sizeof trick":
typedef char (&y0)[1]; typedef char (&y1)[2]; y0 deduce(X0); y1 deduce(X1);
static const bool is_x0 = sizeof( deduce(cond() ? x0() : x1()) ) == sizeof( y0 );
Obviously, some care needs to be taken when these definitions of deduce produce ambiguous overloads, but hopefully I've better conveyed the idea.
And if this whole endeavor sounds completely unnecessary, feel free to say so, and I'll drop the discussion ;)
- Jeff _______________________________________________
Hi Jeff,
Yes I see now better what was your idea. Have you tried to implement it? I will try the approach to see what I can get, but I'm not sure to been able to manage with the ambiguous overloads.
Howard, what do you think about this approach? Have you already tried something like that?
I haven't tried this approach because every compiler I need to target has either typeof or decltype. The definition of the conditional operator (which common_type is defined in terms of in the C++0x draft) is fairly tricky. That being said, if a platform lacks typeof or decltype, I'm sure some heroics on the implementation of common_type would be much appreciated by those using that platform. -Howard
participants (5)
-
Howard Hinnant
-
Jeffrey Lee Hellrung, Jr.
-
Roland Bock
-
Stewart, Robert
-
vicente.botet