RE: [PATCH] Re: STDCXX-1072 SPARC V8 mutex alignment requirements
Liviu, I built the library and tests before and after your change with the 64-bit flag, and I saw no differences in the number of failed tests between the builds. I've attached the output of 'gmake -k runall' before and after your change to STDCXX-1072 in case you want to look over them. I wrote up the following test case to prove that I could reproduce the issue using the compile/link options used to build the stdcxx tests. The code is below.. [vitek@andromeda] 138 % cat t.cpp #include thread.h #include synch.h #include malloc.h int main () { int *ip; mutex_t *mp; ip = (int*)malloc(sizeof (int) + sizeof (mutex_t)); mp = (mutex_t*)(ip + 1); mutex_init(mp, USYNC_THREAD | LOCK_ROBUST, 0); mutex_lock(mp); mutex_unlock(mp); mutex_destroy(mp); free(ip); } [vitek@andromeda] 139 % gmake t CC -c -D_RWSTDDEBUG -mt -I/amd/homes/vitek/tmp/stdcxx-4.2.x/include \ -I/build/vitek/stdcxx-4.2.x_sunpro-5.8_sunos-5.10-patched/include \ -I/amd/homes/vitek/tmp/stdcxx-4.2.x/tests/include \ -library=%none -g -m64 +w -errtags -erroff=hidef t.cpp CC t.o -o t -L/build/vitek/stdcxx-4.2.x_sunpro-5.8_sunos-5.10-patched/rwtest \ -lrwtest15S -library=%none -mt -m64 \ -L/build/vitek/stdcxx-4.2.x_sunpro-5.8_sunos-5.10-patched/lib \ -lstd15S -lm Bus Error (core dumped) [vitek@andromeda] 140 % I also tested with POSIX mutexes and saw the same behavior. Travis From: Liviu Nicoara Sent: Thursday, October 11, 2012 5:28 AM To: dev@stdcxx.apache.org Subject: Re: [PATCH] Re: STDCXX-1072 SPARC V8 mutex alignment requirements I applied the patch on 4.2.x. If someone with access to a SPARC machine could give it a runall and post the results here it would be awesome. I will postpone closing the incident until then. Thanks! Liviu
RE: STDCXX-1071 numpunct facet defect
Only major versions can break binary. The versioning policy for stdcxx can be found here.. http://stdcxx.apache.org/versions.html Travis -Original Message- From: Liviu Nicoara [mailto:nikko...@hates.ms] Sent: Friday, September 28, 2012 3:52 AM To: dev@stdcxx.apache.org Subject: Re: STDCXX-1071 numpunct facet defect I thought I replied but I see no trace of my post: On 09/27/12 20:27, Martin Sebor wrote: On 09/27/2012 06:41 AM, Liviu Nicoara wrote: On 09/26/12 20:12, Liviu Nicoara wrote: I have created STDCXX-1071 and linked to STDCXX-1056. [...] I am open to all questions, the more the better. Most of my opinions have been expressed earlier, but please ask if you want to know more. I am attaching here the proposed (4.3.x) patch and the timings results (after re-verifying the correctness of the timing program and the results). The 4.2.x patch, the 4.3.x patch, the test program and the results file are also attached to the incident. The patch isn't binary compatible. We can't remove data members in a minor release. We could only do it in a major release. I posted two patches, one for 4.3.x and one for 4.2.x (the latter is binary compatible). My understanding was that minor version revisions may break binary compatibility. Liviu
RE: STDCXX-1072 SPARC V8 mutex alignment requirements
-Original Message- From: Liviu Nicoara Sent: Friday, September 28, 2012 5:29 AM In short, my reading about this issue is that the kernel patch changed the alignment of the userland mutex objects from a machine word to a double-word boundary. No changes are required of the users who use such objects in their programs unless users create mutex objects in buffers which may not be aligned on a proper boundary. Your reading of this is consistent with my previous understanding of the problem, so that is good. I still don't have access to a SPARC machine. Any feed-back and/or SPARC build results are more than welcome! I can provide build results for SPARCV9 if we want them, but I thought that the problem only came up on 32-bit SPARCV8 builds. The patch assumes the type `long double' exists on every platform. While I do believe that it is available everywhere, we have lots of conditional code guarding its use in the library now. If we are going to use `long double' in this context, we should guard it with _RWSTD_NO_LONG_DOUBLE. I think an even cleaner solution is to switch to using __rw_aligned_buffer instead. It gives us a single point of failure for alignment issues like this, and it makes the code self-documenting and easier to read. As for your concerns about binary compatibility, I think that everything should be okay. We aren't changing the size of anything that is being passed around, we're just changing its alignment. I could be wrong, but I'm pretty sure that we're safe.
RE: STDCXX-1072 SPARC V8 mutex alignment requirements
Liviu, Sorry I didn't look until just now, but it appears that I could have re-opened STDCXX-1066. I only see the 'Reopen Issue' button for STDCXX issues, but it is most definitely there. Perhaps there is some sort of permission issue for you? Also, STDCXX-1066 appears to have been a duplicate of STDCXX-1040. Travis -Original Message- From: Liviu Nicoara Sent: Friday, September 28, 2012 5:29 AM I have created the above and linked it to the closed STDCXX-1066.
Re: [jira] [Closed] (STDCXX-1066) SPARCV8 requires pthread_mutex_t and pthread_cond_t to be aligned on an 8-byte boundary
I asked around and we don't have one available at this time. Travis Liviu Nicoara wrote: On 9/25/12 7:56 PM, Stefan Teleman (JIRA) wrote: [ https://issues.apache.org/jira/browse/STDCXX-1066?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Anybody around here, except Stefan, who has access to a SPARC V8 machine updated to the specified kernel update or later, and who is willing to run a simple test program? It's a 5 minute job at most. Thanks! Stefan Teleman closed STDCXX-1066. -- Resolution: Won't Fix Bug will not be fixed upstream. It is fixed in the Solaris releases. SPARCV8 requires pthread_mutex_t and pthread_cond_t to be aligned on an 8-byte boundary --- Key: STDCXX-1066 URL: https://issues.apache.org/jira/browse/STDCXX-1066 Project: C++ Standard Library Issue Type: Bug Components: Thread Safety Affects Versions: 4.2.1, 4.2.2, 4.2.x, 4.3.x Environment: Solaris 10 Update 6 or later on SPARCV8 [32-bit] Defect is compiler-independent - in reality it only affects Sun Studio and GCC. Reporter: Stefan Teleman Labels: features, runtime, threads Fix For: 4.2.2, 4.2.x, 4.3.x Attachments: _config-gcc.h.stdcxx-1066.patch, _config-sunpro.h.stdcxx-1066.patch, ctype.cpp.stdcxx-1066.patch, exception.cpp.stdcxx-1066.patch, ios.cpp.stdcxx-1066.patch, iostream.cpp.stdcxx-1066.patch, iostream.stdcxx-1066.patch, locale_body.cpp.stdcxx-1066.patch, locale_classic.cpp.stdcxx-1066.patch, messages.cpp.stdcxx-1066.patch, _mutex.h.stdcxx-1066.patch, time_put.cpp.stdcxx-1066.patch, use_facet.h.stdcxx-1066.patch Starting with Solaris 10 Update 6, on SPARCV8, pthread_mutex_t and pthread_cond_t MUST be aligned on an 8-byte boundary. Misaligned access will result in either SEGV or SIGBUS. There are numerous places in the multi-threaded version of stdcxx where pthread_mutex_t and/or pthread_cond_t types are contained within an union, but with an enforced alignment different than 8. All these instances must be corrected, and #ifdef-guarded for SPARCV8. Patches to follow shortly, this is just opening the issue. Warning: the patchset resolving this issue is very large, and it affects a large number of files. -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira
RE: STDCXX-1066 [was: Re: STDCXX forks]
Comments below... -Original Message- From: Stefan Teleman Sent: Monday, September 24, 2012 5:46 AM Subject: Re: STDCXX-1066 [was: Re: STDCXX forks] On Mon, Sep 24, 2012 at 8:21 AM, Liviu Nicoara nikko...@hates.ms wrote: In the light of your inability to answer the simplest questions about the correctness and usefulness of this patch, I propose we strike the patch in its entirety. Let me make something very clear to you: what I am doing here is a courtesy to the stdcxx project. Thank you for your contribution. There is a good chance that without your activity on this project over the last few months that it would be in the attic. There is no requirement in my job description to waste hours arguing with you in pointless squabbles over email. Nor is there a requirement in the APL V2.0 which would somehow compel us to redistribute our source code changes. The problem here is that code changes are expected to pass review. They must follow established conventions, solve the problem in a reasonable and portable way, provide a test case (where one doesn't already exist), as well as make sense to everyone who is working with the product. Several of the changes included don't make sense to the rest of us. Unless we manage to figure them out on our own or you manage to explain them to us, then the changes should probably be excluded from the code. For example, the changes to src/exception.cpp don't make sense to me. Here is the relevant diff... +#if defined(_RWSTD_STRICT_SPARCV8_MUTEX_ALIGNMENT) +# pragma pack(8) +# pragma align 8(__rw_aligned_buffer) +#endif + // facet must never be destroyed static __rw_aligned_buffer_Msgs msgs; It seems that we trying to give 8-byte alignment to a class of type __rw_aligned_buffer. The point of __rw_aligned_buffer is to give us a block of properly aligned data, and if it isn't aligned, then it is broken. So, why are we using a pragma for alignment here (and potentially in other places) when it seems that there is a bug in __rw_aligned_buffer that we should be addressing? Of course, if this is a problem with aligned buffer, we need a testcase. Another example are the changes to src/ctype.cpp +#if defined(_RWSTD_STRICT_SPARCV8_MUTEX_ALIGNMENT) +# pragma pack(8) +# pragma align 8(f) +# pragma align 8(pf) +#endif static union { +#if defined(_RWSTD_STRICT_SPARCV8_MUTEX_ALIGNMENT) +unsigned long long align_; +unsigned char data_ [sizeof (_STD::ctypechar)]; +#else void *align_; char data_ [sizeof (_STD::ctypechar)]; +#endif } f; static __rw_facet* const pf = new (f) _STD::ctypechar(__rw_classic_tab, false, ref); pfacet = pf; +#if defined(_RWSTD_STRICT_SPARCV8_MUTEX_ALIGNMENT) +# pragma pack(0) +#endif This change seems to give alignment to `f' in two different ways, and it seems to be applying alignment to the pointer (the issue Liviu has brought up). It seems like the simpler fix would be to unconditionally add union members to `f' so that we get the proper alignment (much like we try to do in __rw_aligned_buffer), or an even better solution would be to use __rw_aligned_buffer. We could and should re-work the instances in the library where we might use mutex and condition objects that are misaligned wrt the mentioned kernel update. Yeah, why don't you go ahead and do that. Just like you fixed stdcxx- 1056. There is no need for comments like this. Stefan, if you are feeling singled out and attacked because your patches aren't accepted without question, it might be a good idea to go back and look through the mailing list archives. We have _all_ been in this position. Nearly every time I posted a patch for the first year working on stdcxx was like this, and I've been doing C++ software for 15 years. The company where I work currently has a review process that is just as rigorous as what you're seeing with stdcxx now. The process isn't there to attack anyone personally, but to ensure the quality and maintainability of the library for years to come. Travis
RE: [PATCH] STDCXX-853
Liviu, Should the volatile be to the left of the intT typename here? I know it is equivalent, but it is weird to look at the line of code below and see that we're following two different conventions. Travis ___ From: Liviu Nicoara Sent: Sunday, September 23, 2012 8:34 AM To: dev@stdcxx.apache.org Subject: [PATCH] STDCXX-853 Umm, I didn't think to search for a corresponding incident and I considered the defect to be so minor as to not warrant an issue. The following patch has been applied already on 4.2.x: Index: tests/support/atomic_xchg.cpp === --- tests/support/atomic_xchg.cpp (revision 1388732) +++ tests/support/atomic_xchg.cpp (revision 1388733) @@ -297,7 +297,7 @@ void run_test (intT, thr_args_base::tag_ // compute the expected result, skipping zeros by incrementing // expect twice when it overflows and wraps around to 0 (zero is // used as the lock variable in thread_routine() above) -intT expect = intT (1); +intT volatile expect = intT (1); const unsigned long nincr = (Args::nthreads_ * Args::nincr_) / 2U;
RE: STDCXX-1056 : numpunct fix
-Original Message- From: Stefan Teleman Sent: Thursday, September 20, 2012 6:00 PM To: dev@stdcxx.apache.org Cc: Liviu Nicoara Subject: Re: STDCXX-1056 : numpunct fix On Thu, Sep 20, 2012 at 8:44 PM, C. Bergström cbergst...@pathscale.com wrote: I do have a program which triggers the race conditions: 22.locale.numpunct.mt. Part of the official test harness. I don't think anyone is claiming that there isn't a thread safety problem in the locales. I'm open to the possibility, and I'm willing to review changes that fix the problem, but I want some understanding of what the problem actually is and how the changes actually address the problem before signing off. I also find it hard to believe the changes to the facet cache (and many of the other changes) are necessary to eliminate any data races that were reported by these tools. Changing the cache size from 8 to 64 is _clearly_ not going to fix a data race. It might reduce the likelihood of one occurring, but it isn't going to fix it. I also fail to understand how not reducing the size of the cache fixes a data race either. These changes all appear to be optimizations, and as such, should _not_ be included in changes to fix thread-safety issues. Perhaps we could go about this a different way. Test your code without the changes to the facet cache changes in _C_manage and report back on what you find. Or, perhaps more simply, provide minimal diffs (as required by the patching process) to fix the data race issues that you've outlined. The real reason why they don't want to accept what the instrumentation tools are saying is very simple: they don't LIKE reading what the tools are saying. So, blame the tools, pretend that as long as it doesn't crash again there's no bug and hope for the best. My previous e-mail attempted to indicate that I don't trust the output that these tools have provided. I have no understanding of how the tool managed to find a data race in __rw_allocate (or _C_manage). Do you? Doesn't this output give you some doubt about the accuracy of the tool? I have no problem using a tool to make my job easier. Sometimes those tools are wrong. The two cases mentioned above call into question the accuracy of the tool being used, and it is important to understand why those failures are being seen (or why I am wrong about the given code being safe). But I am very glad this is on a public mailing list, so everyone can read what's going on here. As am I. I've raised concerns about the tools you're using to detect problems. I've pointed out what I believe to be two false positives, and you've accused me of being incompetent and afraid of what the tools are saying. You've offered no explanation about these apparent false positives and you've not provided any explanation for why you don't see similar false positives when you run the code on the patched library. I've raised concerns about some of the changes you've provided being unnecessary to resolve the issue at hand (a thread safety issue) and labeled them as optimizations (your original e-mail seemed to indicate you were under the same impression). As Liviu pointed out, the bug fix changes should be handled separately from the optimization. I wholeheartedly agree. You called out premature optimization as evil, in a discussion about patches you provided that include optimizations and no testcase showing that your changes are not premature and provide measureable benefit. Then you rail on... Then, to top it off, you go on to call me a know-it-all who isn't capable of figuring out my own bugs. I'm sorry, but that isn't acceptable. Travis
RE: STDCXX-1056 : numpunct fix
-Original Message- From: Stefan Teleman [mailto:stefan.tele...@gmail.com] Sent: Friday, September 21, 2012 2:14 AM To: dev@stdcxx.apache.org Subject: Re: STDCXX-1056 : numpunct fix On Fri, Sep 21, 2012 at 2:28 AM, Travis Vitek travis.vi...@roguewave.com wrote: You called out premature optimization as evil, in a discussion about patches you provided that include optimizations and no testcase showing that your changes are not premature and provide measureable benefit. Then you rail on... I didn't call premature optimization evil. Donald Knuth did. If you disagree with him, please feel free to let him know. He's on faculty at Stanford. I never said I disagree with the Knuth quote. I just said you have to apply it consistently. Is your change an optimization or not? If it is, then is it a premature optimization? Do we have a test case (or test results) to indicate that there is a discernible performance improvement? You are one of the deniers of the existence of this thread safety problem in the facets code, going back to early February of this year. Again from my previous e-mail. quote I don't think anyone is claiming that there isn't a thread safety problem in the locales. I'm open to the possibility, and I'm willing to review changes that fix the problem, but I want some understanding of what the problem actually is and how the changes actually address the problem before signing off. /quote Between the release of stdcxx 4.2.1 in 2008 and the beginning of this month, when the possibility of this thread safety problem was finally acknowledged, did you really not know that 22.locale.numpunct.mt and 22.locale.moneypunct.mt have been crashing or getting stuck? Did you really not know that these crashes were typical symptoms of race conditions? I find that very hard to believe, given that the problem has been reported several times before February of this year. I have provided this list with test results showing that my patch *does* fix the race condition problems identified by all the tools at my disposal. I'm willing to bet you never looked at it. You dismissed it outright, just because you didn't like the *idea* that increasing the size of the cache, and eliminating that useless cache resizing would play an important role in eliminating the race conditions. I looked at every line of your proposed patch _before_ my last e-mail. Despite the fact that you didn't provide it in the expected format (diff) and it included many changes that are unrelated and make little sense. I have yet to see an alternative patch being proposed here, which would eliminate the race conditions, and which I am willing to test just as thoroughly as I've tested mine. The only thing i've seen are continued attempts at dismissing the existence of these race conditions I'm _not_ denying the existence of the problem. Please re-read all of my correspondence on this issue. If you don't believe me after that, re-read it again.
RE: STDCXX-1056 : numpunct fix
-Original Message- From: Stefan Teleman [mailto:stefan.tele...@gmail.com] Sent: Thursday, September 20, 2012 10:11 AM To: dev@stdcxx.apache.org Subject: Re: STDCXX-1056 : numpunct fix On Thu, Sep 20, 2012 at 8:07 AM, Liviu Nicoara nikko...@hates.ms wrote: But have you measured the amount of memory consumed by all STDCXX locale data loaded in one process? How much absolute time is spent in resizing the locale and facet buffers? What is the gain in space and time performance with such a change versus without? Just how fragmented the heap becomes and is there a performance impact because of it, etc.? IOW, before changing the status quo one must show an objective defect, produce a body of evidence, including a failing test case for the argument. sizeof(std::locale) * number_of_locales. I'll let you in on a little secret: once you call setlocale(3C) and localeconv(3C), the Standard C Library doesn't release its own locale handles until process termination. So you might think you save a lot of memory by destroying and constructing the same locales. You're really not. It's the Standard C Library locale data which takes up a lot of space. You have a working knowledge of all Standard C Library implementations? What I do know for a fact that this optimization did, was to cause the races conditions reported by 4 different thread analyzers. Race conditions are a show-stopper for me, and they are not negotiable. The following is found near the top of the _C_manage method of __rw_facet. // acquire lock _RWSTD_MT_STATIC_GUARD (_RW::__rw_facet); None of the shared data related to is read/written outside of the critical section protected by that lock, and given the declaration for that shared data it cannot be accessed by any code outside that function. Put bluntly, there is no way that there is a race condition relating to the caching code itself. Your Performance Analyzer output indicates a race (7 race accesses) for _C_manage... http://s247136804.onlinehome.us/22.locale.numpunct.mt.1.er.ts/ Specifically, it is calling out the following block of code. ## 70 488. *__rw_access::_C_get_pid (*pfacet) = 489. _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, (type + 1) / 2); The function _C_get_pid simply exposes a reference to a data member of the given facet. That function is thread safe. Provided that pfacet (the parameter passed to _C_manage) isn't being accessed by another thread, there is no way that this code is not safe. It is possible that calling code is not safe, but this code is clean. Regardless, the proposed patch to _C_manage does nothing to change this block of code. I do not understand how you can claim that this change eliminated the race conditions you are so offended by. It is possible that other changes you have made eliminated the data races, but I do not see how this change has any effect. And I love minimalistic code, and hate waste at the same time, especially in a general purpose library. To each its own. Here's a helpful quote: We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. It's from Donald Knuth. By that measure, your entire patch could be considered evil. I've seen no evidence that the subsequent two allocation/copy/deallocate/sort cycles required to get from 8 to 64 entries is measurably more expensive, and I've seen nothing to indicate that a normal application using the C++ Standard Library would be creating and destroying locale instances in large numbers, or that doing so has a measureable impact on performance. And I love correct code which doesn't cause thread analyzers to report more than 12000 race conditions for just one test case. I've said it before and I will say it again: race conditions are a showstopper and are not negotiable. Period. When the code in question has 12 threads that invoke a function 1000 times, you've found 1 race condition. I do agree data races are bad and should be fixed. But making changes to 'optimize' the code instead of fixing it is actually much worse. The patch is in scope for the issue at hand. The issue is that std::numpunct and std::moneypunct are not thread safe. This has been confirmed by 4 different thread analyzers, even after applying your _numpunct.h patch. I looked at the output from the thread analyzer. It points out a data race in __rw::__rw_allocate(), indicating that a memset() is responsible for a data race... http://s247136804.onlinehome.us/22.locale.numpunct.mt.1.er.ts/file.14.src.txt.html#line_43 Assuming that `operator new' is indeed thread safe (I didn't bother to look), I'm curious to hear how this is an actual data race. I'm also curious to hear how you managed to avoid having the same race appear in the output that you submitted with the proposed patch. You are more than welcome to
RE: Intel C++ bug reports?
On 09/05/12 04:20, Liviu Nicoara wrote: On 09/04/12 21:25, Martin Sebor wrote: On 09/04/2012 07:02 PM, Liviu Nicoara wrote: Hi guys, snip Looking at the test below, though, it depends on undefined behavior (signed overflow) so there's no compiler bug. Making max volatile fools icc just enough to produce the expected output (while still relying on undefined behavior). It would be good to clean it up, though. I think computing UINT_MAX instead and shifting it right by the number of sign bits (i.e., 1) should work. I _know_ it's undefined behavior. :) My case is that Intel is also the only compiler failing this test. On that grounds alone they should look at it -- I know the gcc guys do when it comes to their compiler. Let them shoot it down if they so wish. Rogue Wave filed an issue with Intel on 2011/04/25 (issue #628095). They shot it down. Travis
RE: Apache Standard C++ Project chair change
On Wed, May 16, 2012 at 5:47 AM, Stefan Teleman stefan.tele...@gmail.com wrote: I am going to ask the following questions in the open. Perhaps this way I will get an answer: 1. Apparently, Bill's emails were sent and replied to on the private list. I have not received any of them, although I am on the private list. Or at least, I was on the private list as recently as late March. Is this a case of mailing list malfunction? If that is the case, it should be fixed. The e-mails regarding the ICLAs were sent to the @private list on 5/1. 2. Which Bill are we talking about? I know of two Bills at stdcxx. A clarification would be welcome. William A. Rowe Jr. 3. There was a recent and important PMC change at stdcxx. Congratulations to Jim Jagielski for his new role as PMC Chair. Again, I learned of this change yesterday, and that only from Jim's email. I haven't received any notification about Jim's appointment prior to yesterday, although, to be fair, I knew about it at the beginning of May, because I read the ASF Board Minutes. Again, why wasn't there any notification of this change? I read about it in the e-mail entitled 'ASF Board Meeting Summary - April 18, 2012'. I don't normally read the meeting minutes, but I figured something was coming given the kerfuffle over the lack of a March status report (all of which was discussed on the @private list). 4. The nightly build emails, which had restarted towards the end of February/beginning of March, have stopped. Why is that? It looks like the February builds were kicked off manually by Farid. I'm not sure if the build system is configured to poll svn automatically or not, but the last submit to stdcxx was on 2/20, so there has been no need to do any builds since that time. Travis
RE: svn commit: r1242128 - in /stdcxx/branches/4.2.x: include/valarray tests/regress/26.valarray.binary.stdcxx-1061.cpp
Yes. Unfortunately I spent too much time trying to make sure I followed the process (which I've forgotten) and not enough time making sure my code was correct. Will fix immediately. Travis -Original Message- From: Martin Sebor [mailto:mse...@gmail.com] Sent: Wednesday, February 08, 2012 3:31 PM To: dev@stdcxx.apache.org Cc: vi...@apache.org; comm...@stdcxx.apache.org Subject: Re: svn commit: r1242128 - in /stdcxx/branches/4.2.x: include/valarray tests/regress/26.valarray.binary.stdcxx-1061.cpp ... +int main () +{ +const int a[] = { 0, 1, 0, 3, 0, -5, 0, -7, 0, -11 }; + +const std::valarrayint v0 (a, sizeof a); I'm sure you meant sizeof a / sizeof *a here... +const std::valarraybool v1 = std::operator (v0, 1); + +for (std::size_t i = 0; i sizeof a; ++i) and the same or v0.size() here. Martin +assert ((a [i] 1) == v1 [i]); + +return 0; +} +
RE: [VOTE] Retirement of stdcxx to the 'Attic'?
While often have little or no time for extracurricular activities, I'm willing to start participating on a limited basis. So -1. Travis -Original Message- From: William A. Rowe Jr. [mailto:wr...@rowe-clan.net] Sent: Thursday, February 02, 2012 9:04 AM To: dev@stdcxx.apache.org Subject: [VOTE] Retirement of stdcxx to the 'Attic'? Fans and contributors, it appears that the stdcxx project is entirely dormant. The ASF has launched a new 'Attic' project over the past two years, to neatly retire dormant works until and unless a community comes along who wishes to revive the effort. As a simple formality your votes please; [ ] +1 - stdcxx committee should be retired, with code sent to the Attic [X] -1 - No, stdcxx should not fold, I am still contributing, and [would serve|am serving] on its project management committee The results of this vote will be taken up by the ASF Board of Directors at their 15 Feb meeting.
RE: svn commit: r693419 - /stdcxx/branches/4.3.x/etc/config/xfail.txt
-Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Author: faridz Date: Tue Sep 9 03:20:19 2008 New Revision: 693419 URL: http://svn.apache.org/viewvc?rev=693419view=rev Log: 2008-09-09 Farid Zaripov [EMAIL PROTECTED] Merged r693416 from branches/4.2.x * etc/config/xfail.txt (21.string.exceptions): Added an expected test failure due to STDCXX-1009. (21.string.stdcxx-1009): Added an expected test failure due to STDCXX-1009. (25.uninitialized.copy.stdcxx-976): Added an expected test failure due to STDCXX-976. Is there some reason that you didn't just fix the regression shown in STDCXX-1009? Travis Modified: stdcxx/branches/4.3.x/etc/config/xfail.txt Modified: stdcxx/branches/4.3.x/etc/config/xfail.txt
RE: svn commit: r680756 - in /stdcxx/branches/4.2.x: include/loc/_codecvt.cc include/loc/_codecvt.h include/loc/_collate.cc include/loc/_collate.h include/loc/_moneypunct.cc include/loc/_moneypunct.h
Author: sebor Date: Tue Jul 29 09:24:16 2008 New Revision: 680756 Modified: stdcxx/branches/4.2.x/include/loc/_codecvt.h URL: http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/include/loc/ _codecvt.h?rev=680756r1=680755r2=680756view=diff === === --- stdcxx/branches/4.2.x/include/loc/_codecvt.h (original) +++ stdcxx/branches/4.2.x/include/loc/_codecvt.h Tue Jul 29 09:24:16 2008 @@ -120,6 +120,8 @@ _EXPLICIT codecvt (_RWSTD_SIZE_T __ref = 0): _RW::__rw_facet (__ref) { } +virtual ~codecvt () _RWSTD_ATTRIBUTE_NOTHROW; + Are you sure you don't want to be using _RWSTD_DECLARE_NOTHROW here, and _RWSTD_DEFINE_NOTHROW with the definition. I only see _RWSTD_ATTRIBUTE_NOTHROW being defined for gcc, and that means compile error for all other configurations. What is the rationale for using the attribute instead of a throw spec? I realize that _RWSTD_ATTRIBUTE_NOTHROW will end up being an empty throw spec on most platforms, but I don't understand the advantage of using the attribute. I see that you use both in this changelist, but I don't understand why you selected one over the other. It seems that the only difference is that, in the worst case, using throw specs might require an try/catch block be inserted into the definition of the destructor and that should not result in much additional code. Of course this would only happen if the compiler cannot determine that no exception is thrown by base or member destructors, which it should be able to do if they are appropriately decorated. That said, it seems that it would be best to decorate the base class (_RW::__rw_facet) destructor similarly, regardless of what decoration is being used. // 22,2,1,5,1, p1 result out (state_type __state, const intern_type* __from, const intern_type* __from_end, @@ -188,7 +190,7 @@ _EXPLICIT codecvt (_RWSTD_SIZE_T = 0); -virtual ~codecvt (); +virtual ~codecvt () _RWSTD_ATTRIBUTE_NOTHROW; I see no mention of adding this attribute in the changelog. Should there be? Travis
RE: svn commit: r680756 - in /stdcxx/branches/4.2.x: include/loc/_codecvt.cc include/loc/_codecvt.h include/loc/_collate.cc include/loc/_collate.h include/loc/_moneypunct.cc include/loc/_moneypunct.h
Travis Vitek wrote: Are you sure you don't want to be using _RWSTD_DECLARE_NOTHROW here, and _RWSTD_DEFINE_NOTHROW with the definition. I only see _RWSTD_ATTRIBUTE_NOTHROW being defined for gcc, and that means compile error for all other configurations. What is the rationale for using the attribute instead of a throw spec? I realize that _RWSTD_ATTRIBUTE_NOTHROW will end up being an empty throw spec on most platforms, but I don't Whoops, I meant to say _RWSTD_DECLARE_NOTHROW here...
RE: svn commit: r678483 - /stdcxx/branches/4.2.x/tests/regress/27.streambuf.buffer.stdcxx-808.cpp
Author: elemings Date: Mon Jul 21 09:59:24 2008 New Revision: 678483 URL: http://svn.apache.org/viewvc?rev=678483view=rev Log: 2008-07-21 Eric Lemings [EMAIL PROTECTED] Nit picking... :) There is supposed to be two spaces between your username and e-mail address. It seems that you're missing the comment that describes what revision(s) you are merging. You might have a look at the following change for reference. http://svn.apache.org/viewvc?view=revrevision=676093 Travis STDCXX-808 * tests/regress/27.streambuf.buffer.stdcxx-808.cpp: Add regression test case that has failed in previous releases. Added: stdcxx/branches/4.2.x/tests/regress/27.streambuf.buffer.stdcxx-808.cpp - copied unchanged from r678475, stdcxx/branches/4.3.x/tests/regress/27.streambuf.buffer.stdcxx-808.cpp
fallback support for traits
I've already implemented fallback support for many traits. Here is a list of those that I can think of off of the top of my head... __rw_is_class __rw_is_union __rw_is_empty __rw_is_polymorphic __rw_is_abstract __rw_is_convertible __rw_is_base_of __rw_has_trivial_ctor __rw_has_trivial_copy __rw_has_trivial_assign __rw_has_trivial_dtor __rw_has_nothrow_ctor __rw_has_nothrow_copy __rw_has_nothrow_assign All of the fallbacks are supposed to provide a correct result where possible, otherwise they should return a pessimistic result. I.e. The fallback __rw_has_trivial_ctorT::value will be true for all (possibly cv-qualified) scalar types, but will evaluate to false for class types (struct, union or class). Now I have to figure out what to do for a few more traits. Specifically __rw_alignment_of and __rw_aligned_storage. As it stands now, these traits require definition of _RWSTD_TT_ALIGN_OF() and _RWSTD_TT_ALIGNED_POD() to be defined. If the macros are not provided, we will see a compile failure. As I see it, my options are... 1. put code that will prevent instantiation in the the type declaration (i.e. static_assert) 2. provide a suitable default that is not correct, but can be used to detect the failure 3. disable traits entirely by defining _RWSTD_NO_EXT_CXX_0X if the macros have not been defined 4. disable the affected traits (and their tests) if the macros have not been defined As I see it, option 4 is probably best. Especially given the recent discussion of removing all three alignment traits in favor of the new alignof and alignas keywords and non-trivial unions. Input anyone? Travis
RE: fallback support for traits
Travis Vitek wrote: As I see it, my options are... 1. put code that will prevent instantiation in the the type declaration (i.e. static_assert) 2. provide a suitable default that is not correct, but can be used to detect the failure 3. disable traits entirely by defining _RWSTD_NO_EXT_CXX_0X if the macros have not been defined 4. disable the affected traits (and their tests) if the macros have not been defined Another option would be to write config tests to look for __alignof() and alignof(). If these are found, then we could use them. If not we could get the alignment of a few primitive types, and I could provide an aligned_storage implementation that supports only these alignments. The test would need to check a bunch of macros, but it would all work out.
RE: fallback support for traits
Martin Sebor wrote: Travis Vitek wrote: I've already implemented fallback support for many traits. Here is a list of those that I can think of off of the top of my head... __rw_is_class __rw_is_union __rw_is_empty __rw_is_polymorphic __rw_is_abstract __rw_is_convertible __rw_is_base_of __rw_has_trivial_ctor __rw_has_trivial_copy __rw_has_trivial_assign __rw_has_trivial_dtor __rw_has_nothrow_ctor __rw_has_nothrow_copy __rw_has_nothrow_assign All of the fallbacks are supposed to provide a correct result where possible, otherwise they should return a pessimistic result. I.e. The fallback __rw_has_trivial_ctorT::value will be true for all (possibly cv-qualified) scalar types, but will evaluate to false for class types (struct, union or class). Now I have to figure out what to do for a few more traits. Specifically __rw_alignment_of and __rw_aligned_storage. As it stands now, these traits require definition of _RWSTD_TT_ALIGN_OF() and _RWSTD_TT_ALIGNED_POD() to be defined. If the macros are not provided, we will see a compile failure. But only for the unusual specializations where the alignment isn't the same as one of the fundamental types, right? I can't see how to implement aligned_storageS,A even for alignments that are equal to the alignments of fundamental types if I have no way to get the alignment a a fundamental type as an integral constant value. As I see it, my options are... 1. put code that will prevent instantiation in the the type declaration (i.e. static_assert) 2. provide a suitable default that is not correct, but can be used to detect the failure 3. disable traits entirely by defining _RWSTD_NO_EXT_CXX_0X if the macros have not been defined 4. disable the affected traits (and their tests) if the macros have not been defined As I see it, option 4 is probably best. Especially given the recent discussion of removing all three alignment traits in favor of the new alignof and alignas keywords and non-trivial unions. We still need to write up the issue... Yeah. As for providing the traits only conditionally, I'm not sure that's the best approach. If we feel it likely that some of them will end up getting yanked from the working paper we should probably avoid providing them at all, otherwise we might be stuck maintaining them for a long time. Providing them only for some platforms would also make them difficult to use portably (we'd have to expose some kind of config macro for users to check whether the trait is defined or not). Why would we need to support them? If we disabled them by default and told users the functionality is experimental and depends on the direction of the standard, then it seems that we should be free to yank them. Of course that requires that the functionality be disabled by default (which we're currently talking about changing). So my preference would be either (2) or (5), with option 5 being to disable the aligned traits unconditionally until we know for certain that they aren't going away. I would be okay with that also. Out of curiosity, what do other implementations do? Ah, here is the answer. I had written code to try to detect alignment, and it worked on msvc-7.1 and msvc-8.0, but failed to compile on gcc-4.3 and eccp-3.10. As it turns out the Boost library is using a very similar trick that appears to work on both compilers. So this gets me an implementation of __rw_alignment_of. With that I should be able to provide a fallback implementation of __rw_aligned_storage that works with fundamental alignments. Thank you for nudging me to look back at the reference implementation. Travis Martin Input anyone? Travis
RE: [jira] Commented: (STDCXX-900) 22.locale.time.get test fails 15 assertions
Martin Sebor wrote: Travis Vitek (JIRA) wrote: Well, most of these failures are destined to fail until the test is rewritten. Are you sure you meant that the test needs to be rewritten? (I'm trying to reconcile that with your subsequent comment about binary compatibility). The entire test doesn't need to be rewritten, just the assertions that deal with %U and %W... TEST (T (0, 0, 0, 0, 0, 320, 2, 60), 9, 1, U, 0, Eof); Even if I had a perfect implementation (i.e. I called the gnu strptime function internally), the first assertion could never be made to pass. Given a Sunday-based week number of 9, I cannot possibly guess the year, weekday and day of year to be 2220 AD, Tuesday and 60 respectively. The assertion is bad. This assertion needs to be updated or removed entirely. At the very least the expected date should be all zeros as the below testcase does. TEST (T (0, 0, 0, 0, 0, 0, 0), 0, 1, W, 0, Eof); I modify time_get::do_get() to consume and ignore characters that match %U and %W from the stream. This would get the assertion to pass, but it wouldn't be incredibly useful. It is impossible to reliably parse any useful date-time information from a string that contains only the formatted week number. Just a note; the gnu strptime() succeeds if parsing only the week number, but it doesn't modify the date. On solaris, that same call seems to fail if it encounters the %U or %W specifier in the format string, even if that string contains a fully formatted date. The test tries to to do just this for {{%U}} and {{%W}}. I'm not exactly sure what the expected behavior should be, given the above results on linux and solaris. Perhaps parsing the values and not using them is sufficient, or just failing outright when reading them (as it does now). Regardless of what we decide, Even if we have a partially specified date (I believe we need at least the year and day of week), we still need somewhere to store the additional data so that we can store the value we parse, and then after the parsing is done so that we can use it to calculate something useful. At the very least I think we'll be breaking binary compatibility. So, for the time being, I think the right thing to do is to fix the portion of the test that attempts to to verify {{%U}} and {{%W}} so that it expects failure. As mentioned above... If we wish to fully support this extension, then we should add a new test that verifies {{%U}} and {{%W}} with the necessary format specifiers and then fix the code for 4.3 or later. The test would need include something like this. As mentioned in my previous post, I think we would need to break binary compatibility to even have a chance of making these pass. // expect 2008-12-29 given 2009-W01-1 TEST (T (0, 0, 0, 29, 12, 28, 1, 363), 2009-W01-1, 1, %Y-W%W-%d, 0, Eof); // expect 2010-01-03 given 2009-W53-7 TEST (T (0, 0, 0, 3, 1, 30, 3, 3), 2009-W53-7, 1, %Y-W%W-%d, 0, Eof); Travis
RE: [jira] Commented: (STDCXX-900) 22.locale.time.get test fails 15 assertions
Martin Sebor wrote: Travis Vitek wrote: Martin Sebor wrote: Travis Vitek (JIRA) wrote: Well, most of these failures are destined to fail until the test is rewritten. Are you sure you meant that the test needs to be rewritten? (I'm trying to reconcile that with your subsequent comment about binary compatibility). The entire test doesn't need to be rewritten, just the assertions that deal with %U and %W... TEST (T (0, 0, 0, 0, 0, 320, 2, 60), 9, 1, U, 0, Eof); Oh. Well, it's entirely possible that some of them are bogus. The ChangeLog entry for the change that added them back in 2002 (see p4 change 138327) isn't helpful: * Exercised std::time_getwchar_t. * Exercised facet with user-defined LC_TIME data. * Exercised extensions implementing the full POSIX spec. It could be that I added the assertions even though they were failing, thinking I'd get the missing functionality implemented next, and then got distracted by something and never got back to it. Yeah, it looks like this may have been the case. IMO, we should definitely remove bogus assertions. Unless we already have one, we should also open an issue to get these directives implemented. We can then decide exactly how and to what extent. Well I don't really feel that the assertions should be removed. I think the assertions should test things that are possible. I.e., the assertions should be something like... TEST (T (0, 0, 0, 0, 0, 0, 0), 9, 1, U, 0, Eof); TEST (T (0, 0, 0, 0, 0, 0, 0), 2, 1, W, 0, Eof); This would verify that the value is parsed, but not used (because there isn't enough information available), or even TEST (T (0, 0, 0, 0, 0, 0, 0), 9, 1, U, 0, Fail); TEST (T (0, 0, 0, 0, 0, 0, 0), 2, 1, W, 0, Fail); This would verify that the format specifier is rejected, and would need to be fixed when the appropriate support is added. I'd also expect to see the following assertions added (and possibly others that verify the week is being used to help calculate the resulting date). // expect 2008-12-29 given 2009-W01-1 TEST (T (0, 0, 0, 29, 12, 28, 1, 363), 2009-W01-1, 10, %Y-W%W-%d, 0, Eof); // or Fail // expect 2010-01-03 given 2009-W53-7 TEST (T (0, 0, 0, 3, 1, 30, 3, 3), 2009-W53-7, 10, %Y-W%W-%d, 0, Eof); // of Fail Of course that would mean that we'd have tests that are verifying the feature is not implemented. In that case I guess it would be best to just comment out the assertions and add a note explaining why. Input? Even if I had a perfect implementation (i.e. I called the gnu strptime function internally), the first assertion could never be made to pass. Given a Sunday-based week number of 9, I cannot possibly guess the year, weekday and day of year to be 2220 AD, Tuesday and 60 respectively. The assertion is bad. This assertion needs to be updated or removed entirely. At the very least the expected date should be all zeros as the below testcase does. TEST (T (0, 0, 0, 0, 0, 0, 0), 0, 1, W, 0, Eof); I modify time_get::do_get() to consume and ignore characters that match %U and %W from the stream. This would get the assertion to pass, but it wouldn't be incredibly useful. Right. It is impossible to reliably parse any useful date-time information from a string that contains only the formatted week number. Just a note; the gnu strptime() succeeds if parsing only the week number, but it doesn't modify the date. [...] Even if we have a partially specified date (I believe we need at least the year and day of week), we still need somewhere to store the additional data so that we can store the value we parse, and then after the parsing is done so that we can use it to calculate something useful. At the very least I think we'll be breaking binary compatibility. I remember this dilemma when implementing it. I don't recall how I thought it could be dealt with except for some hackery (borrowing some otherwise unused struct tm members for temporary storage in between recursive calls). I'd hate to see us break binary compatibility just for this. Yeah, there aren't any 'unused' members on most platforms, so that is a no-go. We certainly can't hope to make any changes to the public API of the facet. Yeah. I think I'll remove the offending assertions (with your approval) and just file a new issue to get support for the %{E,O}{U,W} format specifiers added and I'll leave it at that. Travis
Potential eccp-3.9 bug
I'm porting the traits to the EDG compiler, and I'm running into failures in the test suite. Here is a simple testcase to illustrate... $ cat t.cpp eccp t.cpp template int N struct S { }; const bool a = __has_trivial_constructor( S1 ); t.cpp, line 6: error: an incomplete class type is not allowed const bool a = __has_trivial_constructor( S1 ); ^ t.cpp, line 6: warning: variable a was declared but never referenced const bool a = __has_trivial_constructor( S1 ); ^ 1 error detected in the compilation of t.cpp. The problem is that the template (S1 in this case) has not been instantiated, and the compiler chokes trying to use the helper because the type is not 'complete'. It seems like that is a bug and that referring to S1 here should result in the type being instantiated if the compiler requires it. The problem is that many of the trait tests do this type of thing. I can work around this pretty easily by explicitly instantating each template in each test, but this is tedious (there are many). I was thinking about doing something like this... #define _INSTANTIATE(T) \ typedef typename\ __rw_conditional__rw_is_class_or_unionT::value, \ T::type, \ void::type _RWSTD_PASTE(dummy, __LINE__); And then sneaking a void typedef into each of my user defined types, and then using this macro in the TEST () macro that I use all over the tests. Is there a better way? Travis
RE: email delays?
Martin Sebor wrote: Anyone else seeing major delays in list mail delivery? I sent a response to Travis' post Re: Potential eccp-3.9 bug at 3:36 MDT. It's now 3:53 and I still don't see it (I do see it in archives: http://markmail.org/message/35nmnhmbrlysknhv). I wonder if the problem is on our end at Rogue Wave? I dunno, but I noticed it a few days ago. I respondet to RE: svn commit: r675044... at 2:20pm on Wednesday. The message arrived in my inbox at 5:08pm and shows up in the archive at 9:19pm [http://tinyurl.com/65duhb]. Martin
RE: Potential eccp-3.9 bug
Martin Sebor wrote: Travis Vitek wrote: I'm porting the traits to the EDG compiler, and I'm running into failures in the test suite. Here is a simple testcase to illustrate... $ cat t.cpp eccp t.cpp template int N struct S { }; const bool a = __has_trivial_constructor( S1 ); t.cpp, line 6: error: an incomplete class type is not allowed const bool a = __has_trivial_constructor( S1 ); ^ t.cpp, line 6: warning: variable a was declared but never referenced const bool a = __has_trivial_constructor( S1 ); ^ 1 error detected in the compilation of t.cpp. The problem is that the template (S1 in this case) has not been instantiated, and the compiler chokes trying to use the helper because the type is not 'complete'. It seems like that is a bug and that referring to S1 here should result in the type being instantiated if the compiler requires it. I agree. I just sent EDG an email with your test case and CC'd you on it. Thank you for reviewing and submitting. The problem is that many of the trait tests do this type of thing. I can work around this pretty easily by explicitly instantating each template in each test, but this is tedious (there are many). I'm not sure I understand why you are even considering working around it. Doesn't the bug make the built-in traits pretty much unusable in generic code? Not always. If the template is instantiated the error would not be seen. Martin I was thinking about doing something like this... #define _INSTANTIATE(T) \ typedef typename\ __rw_conditional__rw_is_class_or_unionT::value, \ T::type, \ void::type _RWSTD_PASTE(dummy, __LINE__); And then sneaking a void typedef into each of my user defined types, and then using this macro in the TEST () macro that I use all over the tests. Is there a better way? Travis
RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utiliti
Eric Lemings wrote: Travis Vitek wrote: Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp ... +rw_assert (0 == std::strcmp (s, string), __FILE__, __LINE__, + s == \string\, got false, expected true); The tuple is holding the original pointer (not a copy), so I think you can check the actual pointer here. True. But if that assumption became invalid for whatever reason, the code above would still work. Assumptions are bad. Robustness is good. :) As I see it, the tuple implementation is required to hold a copy of an object of the specified type (const char* in this case). If you don't verify the value held is indeed a copy, you are not actually verifying the requirements. This is wrong, and wrong is much worse than bad. :) Brad.
RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utiliti
Martin Sebor wrote: Eric Lemings wrote: Travis Vitek wrote: Eric Lemings wrote: Travis Vitek wrote: The tuple is holding the original pointer (not a copy), so I think you can check the actual pointer here. True. But if that assumption became invalid for whatever reason, the code above would still work. Assumptions are bad. Robustness is good. :) As I see it, the tuple implementation is required to hold a copy of an object of the specified type (const char* in this case). If you don't verify the value held is indeed a copy, you are not actually verifying the requirements. This is wrong, and wrong is much worse than bad. :) Question: const char* s1 = string; const char* s2 = string; // s1 guaranteed to equal s2? It's unspecified. The compiler is allowed to merge strings. It's allowed to even go as far as to point s2 at (s1 + 1) in the snippet below: const char* s1 = Xstring; const char* s2 = string; Just so we're clear, the case that should be happening with tuple is the following... const char* s1 = string; const char* s2 (s1); assert (s1 == s2); The following code works just fine with both the gnu tuple implementation and ours. I'm not sure why the Brad is seeing the assertion failure. $ cat t.cpp g++ -std=gnu++0x t.cpp ./a.out echo good #include tuple #include assert.h static const char* s = hello world; int main () { const std::tupleconst char* t (s); assert (std::get0(t) == s); return 0; } $ good $ gmake t ./t echo good gcc -c -I/amd/devco/vitek/stdcxx/4.3.x/include/ansi -D_RWSTDDEBUG -D_RWSTD_EXT_CXX_0X -I/amd/devco/vitek/stdcxx/4.3.x/include -I/build/vitek/4.3.0/11S/include -I/amd/devco/vitek/stdcxx/4.3.x/tests/include -pedantic -nostdinc++ -g -std=gnu++0x -W -Wall -Wcast-qual -Winline -Wshadow -Wwrite-strings -Wno-long-long -Wcast-align -Wno-empty-body -Wno-parentheses t.cpp gcc t.o -o t -L/build/vitek/4.3.0/11S/rwtest -lrwtest11S -L/build/vitek/4.3.0/11S/lib -lstd11S -lsupc++ -lm good Martin
RE: Static assertions in tests?
Martin Sebor wrote: Eric Lemings wrote: For compile-time tests, would it be preferable to use a static assertion or continue using good ol' rw_assert() even for compile-time checks? In the former case, the test will fail to build and, in the latter case, the compile-time check will not be easily distinguisable from other runtime assertions. I would recommend against using one component of the library (static_assert) to test another. The approach taken by existing tests is to verify types and signatures by using them in ways that would make the tests ill-formed if they didn't match the requirements, causing a compiler error. You can see examples of this approach in the 23.vector.cons.cpp test that was just mentioned. I happen to use this trick .. typedef char assert_0 [(cond) ? 1 : -1]; Martin
RE: Another potential hole in the tuple specs
Eric Lemings wrote: Martin Sebor wrote: Eric Lemings wrote: [...] A const assignment operator? Sounds unorthodox but I'll try it out. My current workaround is to declare std::ignore mutable (i.e. non-const). A const assignment operator (if it works) would be preferable; no visible workaround required. Remember that even the absence (or presence) of the const qualifier on things like std::ignore can be detected by conformance test suites so dropping it is not a viable option. Assuming the draft standard is actually correct, that is. In this case, I don't think there is any real need for std::ignore to be a constant really. (Thinking about asking whether std::ignore really needs to be a constant on the committee reflector.) I could agree that it shouldn't _need_ to be const given that it needs no member data and it is just a placeholder type. But I'd be willing to bet that this was an intentional design decision. I tried making std::ignore const and adding const to the internal assignment operator. I also tried adding overloads for const and non-const assignment. Still got errors in all cases. The following testcase works just fine (on acc-6.16, gcc-4.3.1 msvc-8.0) namespace std { struct _Ignore { template class _TypeT void operator=(const _TypeT) const { } }; // should make this extern and define in a .cpp const _Ignore ignore = std::_Ignore (); } // namespace std int main () { std::ignore = 1; std::ignore = 1.f; std::ignore = std::ignore; std::ignore = (void (*)(int))0; return 0; } Perhaps you could post the error and a testcase? The only other recourse I can think of is to use remove_const on the element types where appropriate. I'm sure the above strategy will work. Brad.
RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utiliti
Author: elemings Date: Tue Jul 8 16:13:36 2008 New Revision: 675044 URL: http://svn.apache.org/viewvc?rev=675044view=rev Log: 2008-07-08 Eric Lemings [EMAIL PROTECTED] STDCXX-958 * include/tuple: Second parameter in value move ctor of pair specialization missing rvalue reference. (make_tuple, get, relational operators): Explicitly declare as inline functions. (tie): Implemented. * include/rw/_tuple.h: Fix move semantics in heterogenous move assignment operator. (__rw_ignore): Add assignment operator to ignore all values. * tests/utilities/20.tuple.cnstr.cpp: Added VV for tuple state and invariants. Manually inspected proper construction of all test tuples. Updated/corrected/added tests as necessary. * tests/utilities/20.tuple.creation.cpp: Added simple tie() test. * tests/utilities/20.tuple.h: Minor stylistic changes. * tests/utilities/20.tuple.helpers.cpp: Same. Modified: stdcxx/branches/4.3.x/include/rw/_tuple.h stdcxx/branches/4.3.x/include/tuple stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp stdcxx/branches/4.3.x/tests/utilities/20.tuple.h stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.cpp Modified: stdcxx/branches/4.3.x/include/rw/_tuple.h URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/rw/_ tuple.h?rev=675044r1=675043r2=675044view=diff === === --- stdcxx/branches/4.3.x/include/rw/_tuple.h (original) +++ stdcxx/branches/4.3.x/include/rw/_tuple.h Tue Jul 8 16:13:36 2008 @@ -174,7 +174,14 @@ }; -struct __rw_ignore { /* empty */ }; +struct __rw_ignore +{ +template class _TypeT +inline __rw_ignore const +operator= (const _TypeT /*unused*/) const { +return *this; +} +}; I think the commented out parameter name should be removed. I don't see this in existing code, and I personally find it a bit distracting. This can probably be changed to use a void return type, which will simplify the code further. You only really need the return type to chain assignments or to call a function on the result, none of which we should be doing. Modified: stdcxx/branches/4.3.x/include/tuple URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/tupl e?rev=675044r1=675043r2=675044view=diff === === --- stdcxx/branches/4.3.x/include/tuple (original) +++ stdcxx/branches/4.3.x/include/tuple Tue Jul 8 16:13:36 2008 @@ -211,7 +211,7 @@ #if !defined _RWSTD_NO_RVALUE_REFERENCES template class _TypeU1, class _TypeU2 -_EXPLICIT tuple (_TypeU1 __x, _TypeU2 __y) +_EXPLICIT tuple (_TypeU1 __x, _TypeU2 __y) : _Base (_RWSTD_FORWARD (_TypeU1, __x), _RWSTD_FORWARD (_TypeU2, __y)) { /* empty */ } Same here with the comment describing the empty function body. @@ -377,7 +381,7 @@ // 20.3.1.5, element access: template _RWSTD_SIZE_T _Index, class _Head, class... _Tail -_TYPENAME tuple_element_Index, tuple_Head, _Tail... ::_Ref +inline _TYPENAME tuple_element_Index, tuple_Head, _Tail... ::_Ref get (tuple_Head, _Tail... __tuple) { typedef tuple_element_Index, tuple_Head, _Tail... _Tuple; In the recent past Martin recommended not using the _TYPENAME macro. It isn't hurting anything, but it could probably be removed. I know that I no longer use it in the traits code. I also noticed the _EXPLICIT macro above. I think that one should be added to the list. Martin? @@ -385,7 +389,7 @@ } template _RWSTD_SIZE_T _Index, class _Head, class... _Tail -_TYPENAME tuple_element_Index, tuple_Head, _Tail... ::_ConstRef +inline _TYPENAME tuple_element_Index, tuple_Head, _Tail... ::_ConstRef get (const tuple_Head, _Tail... __tuple) { typedef tuple_element_Index, tuple_Head, _Tail... _Tuple; @@ -396,59 +400,67 @@ // 20.3.1.6, relational operators: template class... _TypesT, class... _TypesU -bool operator== (const tuple_TypesT... __x, - const tuple_TypesU... __y) +inline bool +operator== (const tuple_TypesT... __x, +const tuple_TypesU... __y) { return _RWSTD_STATIC_CAST (const _RW::__rw_tuple_TypesT..., __x) == _RWSTD_STATIC_CAST (const _RW::__rw_tuple_TypesU..., __y); I think there is a formatting issue here. The prevailing style is for the operator to start of the next line, but for the operands to be lined up on their left. As an example return__some_really_long_expression_1 == __some_really_long_expression_2; I don't really like it all that much, but I'm using it in the traits code all over the place. } _RWSTD_SPECIALIZED_FUNCTION -bool operator== (const tuple /*__x*/, - const tuple /*__y*/) +inline bool +operator== (const tuple /*__x*/, +const tuple /*__y*/) {
Makefile issues on hp-ux
I'm seeing some weird errors when porting some code to acc-6.16, and I figured that I'd mention it because I've wasted a considerable amount of time trying to figure out why my code isn't compiling. The following is a transcript of what I've been seeing... $ pwd /build/vitek/4.3.0/11S/tests $ gmake 20.meta.trans.sign aCC -AA -g +d +DD64 +w +W392,655,684,818,819,849 +W2193,2236,2261,2340,2401,2487 +W4227,4229,4231,4235,4237,4249 +W4255,4272,4284,4285,4286,4296,4297 +W3348 -D_RWSTDDEBUG -D_RWSTD_EXT_CXX_0X -I/amd/devco /vitek/stdcxx/4.3.x/include -I/build/vitek/4.3.0/11S/include -I/amd/devco/vitek/stdcxx/4.3.x/tests/include -L/build/vitek/4.3.0/11S/rwtest -lrwtest11S -AA +nostl -Wl,+s +DD64 -L/build/vitek/4.3.0/11S/lib /amd/devco/vitek/stdcxx/4.3.x/tests/utilities/20.meta.trans.sign.cpp /build/vitek/4.3.0/11S/lib/libstd11S.a /build/vitek/4.3.0/11S/rwtest/librwtest11S.a -lstd11S -lm -o 20.meta.trans.sign /amd/devco/vitek/stdcxx/4.3.x/tests/utilities/20.meta.trans.sign.cpp, line 38: error #2005-D: could not open source file stddef.h #include stddef.h ^ /amd/devco/vitek/stdcxx/4.3.x/tests/utilities/20.meta.trans.sign.cpp, line 149: error #2020: identifier size_t is undefined size_t got_size, size_t exp_size, ^ /amd/devco/vitek/stdcxx/4.3.x/tests/utilities/20.meta.trans.sign.cpp, line 149: error #2020: identifier size_t is undefined size_t got_size, size_t exp_size, ^ 3 errors detected in the compilation of /amd/devco/vitek/stdcxx/4.3.x/tests/utilities/20.meta.trans.sign.cpp. $ cp /nfs/devco/vitek/stdcxx/4.3.x/tests/utilities/20.meta.trans.sign.cpp ./ $ gmake 20.meta.trans.sign aCC -c -D_RWSTDDEBUG -D_RWSTD_EXT_CXX_0X -I/amd/devco/vitek/stdcxx/4.3.x/include -I/build/vitek/4.3.0/11S/include -I/amd/devco/vitek/stdcxx/4.3.x/tests/include -AA -g +d +DD64 +w +W392,655,684,818,819,849 +W2193,2236,2261,2340,2401,2487 +W4227,4229,4231,4235,4237,4249 +W4255,4272,4284,4285,4286,4296,4297 +W3348 20.meta.trans.sign.cpp aCC 20.meta.trans.sign.o -o 20.meta.trans.sign -L/build/vitek/4.3.0/11S/rwtest -lrwtest11S -AA +nostl -Wl,+s+DD64 -L/build/vitek/4.3.0/11S/lib -lstd11S -lm You might have noticed that the first gmake invocation results in a single compile/link rule, and the second invocation results in separate compile/link rules. When using the single build rule, the +nostl flag is passed to the compilation stage, which essentially removes the standard (the implicit ones) include paths from the compile line. Travis
RE: implementation of Unary Traits
Martin Sebor wrote: Eric Lemings wrote: Martin Sebor wrote: Travis Vitek wrote: [...] If you ask what I prefer, I'm going to tell you I prefer the second option (that is essentially what I wrote originally). But, honestly, for me to care either way, I need to know that there actually a noticeable performance difference between the two techniques. FYI: I used gcc 4.3 and EDG eccp to measure the difference between the compilation times of each of the two approaches (i.e., using specialization vs using remove_cv). In a program involving 10,000 invocations of is_void on distinct types, the specialization approach was 5 and 10 times faster than the one using remove_cv when using gcc and eccp, respectively. In the same program using only 1000 types, the specialization solution compiled 2 and 3 times faster, respectively. With gcc, the compiler also required about half the amount of system memory to compile the specialization-based solution than the other one. (I didn't measure eccp memory usage). This confirms that template metaprogramming is significantly more costly in terms of system resources than alternative approaches, at least in the gcc and eccp implementations. We should re-run the same tests with other compilers to get a complete picture. That's not unexpected: like everything in computing, it's a tradeoff. To get a really complete picture, you'd have to compare the metaprogramming approach to the run-time alternatives. There are no runtime alternatives to the Unary Traits. We are discussing the pros and cons of one kind of a generic program vs another. To illustrate on an example, I was comparing the compilation efficiency of this code (I called it the alternative approach in my comment): template class T struct is_void { typedef false_type type; }; template struct is_voidvoid { typedef true_type type; }; template struct is_voidconst void { typedef true_type type; }; template struct struct is_voidvolatile void { typedef true_type type; }; template struct struct is_voidconst volatile void { typedef true_type type; }; to this code (which I called template metaprogramming): template class T struct is_void_impl { typedef false_type type; }; template struct struct is_void_implvoid { typedef true_type type; }; template class T is_void: is_void_impltypename remove_cvT::type { }; Martin Here is one alternative that we might want to consider. Instead of stripping cv qualifiers, we add them and then provide a specialization for the cv-qualified type. template class T struct is_cv_void { typedef false_type type; }; template struct struct is_cv_voidconst volatile void { typedef true_type type; }; template class T is_void: is_cv_voidconst volatile T { }; It is a bit of a compromise between the two implementations shown above. This has the advantage over the alternative approach that it reduces the number of templates to parse. It also eliminates the need to instantiate remove_cv that is used in the template metaprogramming case. Martin, if you still have your performance numbers, could you compare this to the previously proposed options? Travis
RE: ABI stability of aligned_union et al
Martin Sebor wrote: Martin Sebor wrote: The mangling of std::aligned_union depends on support for variadic templates in that specializations of the template will be mangled differently depending on whether _RWSTD_NO_VARIADIC_TEMPLATES is #defined or not. It seems that it should be possible to assure compatible mangling between the two, After thinking about it some more I no longer believe this is doable. With variadic templates the mangled aligned_union will involve only the names of the types the template is instantiated on. Without them I don't see any way to emulate this unique behavior. I.e., given a class template X that takes, say, 2 template arguments, I don't see a way to prevent the compiler from including the names of both template arguments in the mangled name for the specialization of the template on just one argument. The second argument is always there, even if it's not actually referenced in code. So it seems to me that if we provide workarounds for the absence of support for variadic templates in the compiler there will be no way to migrate from a compiler without the feature to one with it without breaking the ABI of code that uses templates like aligned_union or tuple. So, I'll ask again. Should we remove the workarounds for missing variadic template support to avoid any future compatibility issues? This would essentially remove parts of c++0x until the compiler provided the necessary support to do it the right way, but I don't really see that as a bad thing. Travis but I'm not 100% sure, and if it is, that it's worth the effort. There might be other templates where we may not easily be able to achieve compatibility. I suppose the big question then is: should we try to fortify the implementation against ABI changes caused by changes in the techniques used in the implementation of C++ 0x? In the past we didn't concern ourselves with this issue but since we can expect compilers to only start supporting some of the new core language features such as variadic templates only slowly and piecemeal, a few at a time, I think it's a concern that we need to address early on. Thoughts? Martin
RE: implementation of Unary Traits
Martin Sebor wrote: Travis Vitek wrote: [...] Originally I wanted separate headers for each trait, but it was determined that the overhead from including all of these small files would be to much, so I suggested splitting traits up into groups based on what they did (rw/_add_cv.h, rw/_remove_cv.h, ...) but that was vetoed also. I think there are two separate issues/questions here: 1. should the UnaryTraits make use of the remove_cv trait or should they be partially specialized and remove the cv qualifiers directly? 2. what is the optimal organization of individual traits into headers? This thread started with question (1). While I think that (2) still needs to be discussed (and the decision for (1) has an impact on (2)), I think we might want to have the two discussions in separate threads. I suggest we focus on (1) first since I believe it's the more important of the two issues. I hope/expect that the right approach for (2) will become more clear after we've decided (1). I think this is probably long overdue. I should have provided a set of alternatives and prompted a vote before I committed the traits code, but I'm sure we'll get it all ironed out. I'll create a wiki page for this so that we can document what we've come up with. [...] If you ask what I prefer, I'm going to tell you I prefer the second option (that is essentially what I wrote originally). But, honestly, for me to care either way, I need to know that there actually a noticeable performance difference between the two techniques. Initially, I had a slight bias for the first approach. I started warming up to the second one because the code reuse seems like a cleaner, better design. But now that we've seen how much more costly in terms of system resources during compilation the second approach is I think the specialization approach might be the way to go after all, not just for traits, but in general. Yes, thanks for taking the time to evaluate this. If I had to read the code I'd prefer to see the first approach, but it does appear that the second approach (explicit specialization for each cv-qualified type) is going to reduce compile time costs for us and our users. I'd still like to measure the compilation performance of the first alternative to get a more complete picture. I'm unclear what approach you are talking about here. Are you talking about doing more testing of the techniques using the remove_cv trait, or something else? Let me know your thoughts. Martin
Traits used by the implementation
In an effort to better organize the type traits, I'm attempting to figure out what traits we expect to be using in the implementation. I see that the tuple implementation is using __rw_remove_reference and that there are already some parts of the library that use __rw_is_same (from rw/_select.h) and __rw_select (which is similar to __rw_conditional__rw_is_integralT::value, void*, int). It is my thinking that the above listed traits, the __rw_has_trivial_*, __rw_has_nothrow_*, __rw_is_pod, __rw_is_void, __rw_is_array, __rw_conditional, __rw_enable_if and __rw_disable_if traits would all be useful in the library implementation. So these traits, and their dependencies should probably be made available internally. That would mean that the following traits would be kept in namespace __rw (I've provided a list of traits and their dependencies near the end of this message). __rw_is_void __rw_is_array __rw_is_scalar __rw_is_arithmetic __rw_is_enum __rw_is_pointer __rw_is_member_pointer __rw_is_reference __rw_is_lvalue_reference __rw_is_rvalue_reference __rw_is_same __rw_is_const __rw_remove_cv __rw_is_trivial __rw_is_standard_layout __rw_is_pod __rw_remove_all_extents __rw_has_trivial_ctor __rw_has_trivial_copy __rw_has_trivial_dtor __rw_has_trivial_assign __rw_has_nothrow_ctor __rw_has_nothrow_copy __rw_has_nothrow_assign Other traits would be removed from namespace __rw and their implementation moved to type_traits. Are there any other traits that might be useful inside the library implementation? Travis Traits with no dependencies __rw_is_void __rw_is_integral __rw_is_floating_point __rw_is_array __rw_is_pointer __rw_is_lvalue_reference __rw_is_rvalue_reference __rw_is_union (**) __rw_is_class (**) __rw_is_member_pointer __rw_remove_pointer __rw_remove_reference __rw_remove_extent __rw_remove_all_extents __rw_remove_const __rw_remove_volatile __rw_is_same __rw_is_base_of (*) __rw_conditional __rw_enable_if __rw_disable_if __rw_aligned_storage __rw_is_signed __rw_is_unsigned __rw_rank __rw_extent __rw_alignment_of (*) * requires compiler support ** could be implemented without compiler support it if the other had it. Traits and their dependencies __rw_is_standard_layout (*) __rw_is_scalar __rw_remove_cv __rw_remove_all_extents __rw_is_trivial (*) __rw_is_scalar __rw_remove_cv __rw_remove_all_extents __rw_has_trivial_ctor (*) __rw_is_pod __rw_remove_all_extents __rw_has_trivial_copy (*) __rw_is_pod __rw_is_reference __rw_has_trivial_dtor (*) __rw_is_pod __rw_is_reference __rw_remove_all_extents __rw_has_trivial_assign (*) __rw_is_pod __rw_is_const __rw_is_reference __rw_has_nothrow_ctor (*) __rw_has_trivial_ctor __rw_has_nothrow_copy (*) __rw_has_trivial_copy __rw_has_nothrow_assign (*) __rw_has_trivial_assign __rw_is_pod (*) __rw_remove_all_extents __rw_is_standard_layout __rw_is_trivial __rw_is_function (*) __rw_is_void __rw_is_array __rw_is_lvalue_reference __rw_is_rvalue_reference __rw_is_member_object_pointer __rw_is_function __rw_is_member_function_pointer __rw_is_function __rw_is_reference __rw_is_lvalue_reference __rw_is_rvalue_reference __rw_is_arithmetic __rw_is_integral __rw_is_floating_point __rw_is_fundamental __rw_is_arithmetic __rw_is_void __rw_is_object __rw_is_function __rw_is_reference __rw_is_void __rw_is_scalar __rw_is_arithmetic __rw_is_enum __rw_is_pointer __rw_is_member_pointer [__rw_is_same, __rw_remove_cv] std::nullptr_t __rw_is_compound __rw_is_array __rw_is_function __rw_is_pointer __rw_is_reference __rw_is_class __rw_is_union __rw_is_enum __rw_is_member_pointer __rw_add_lvalue_reference __rw_is_void __rw_is_reference __rw_is_rvalue_reference __rw_add_rvalue_reference __rw_is_object __rw_is_function __rw_remove_cv __rw_remove_const __rw_remove_volatile __rw_add_const: __rw_is_function __rw_is_reference __rw_add_volatile: __rw_is_function __rw_is_reference __rw_add_cv: __rw_add_const __rw_add_volatile __rw_add_pointer __rw_remove_reference __rw_is_convertible (*): __rw_is_array __rw_is_function __rw_remove_extent __rw_add_pointer __rw_add_lvalue_reference __rw_is_void __rw_aligned_union: __rw_conditional __rw_decay: __rw_remove_reference __rw_conditional __rw_is_function __rw_add_pointer __rw_remove_cv __rw_is_array __rw_remove_extent __rw_make_signed, __rw_make_unsigned __rw_remove_cv
RE: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp
Martin Sebor wrote: I searched library headers and sources for how we define unions and with the exception of limits_bits.cpp we always follow this rule. Unless there is a reason not to make this change to aligned_union, I think we should change both limits_bits.cpp and aligned_union to always define the member with the more strict alignment requirement first, just for peace of mind. Is there any reason/advantage to having the char buffer first? If the first member is used to define the alignment, then you have to know (at compile time) which of the union members has the strictest alignment requirement so that it can be put first. This problem comes up in the definition of __rw_aligned_buffer. On most implementations the members are ordered according to the scheme you mentioned previously, but it is very possible for them to be out of order. union { #ifndef _RWSTD_NO_LONG_DOUBLE long double _C_pad; #else double _C_pad; #endif // _RWSTD_NO_LONG_DOUBLE void *_C_void_pad; void (*_C_pfn_pad)(); char_C_data [sizeof (_TypeT)]; } _C_buf; Travis
RE: svn commit: r672048 - /stdcxx/branches/4.3.x/tests/utilities/
Martin Sebor wrote: [EMAIL PROTECTED] wrote: Author: vitek Date: Thu Jun 26 15:48:21 2008 New Revision: 672048 URL: http://svn.apache.org/viewvc?rev=672048view=rev Log: 2008-06-27 Travis Vitek [EMAIL PROTECTED] * tests/utilities/20.forward.cpp [_RWSTD_NO_EXT_CXX_0X]: Add guard to get test to compile and run when extension is not explicitly enabled. Include rw/_defs.h explicitly in case rw_driver.h does not. Every stdcxx header should always end up #including rw/_defs.h so that no code outside the library needs to (as always, there are unavoidable exceptions). rw_driver.h includes the header via rw_testdefs.h which in turn should be #included by every test driver header. Yes, I know. Are there any circumstances when this doesn't happen? No. My comment is misleading. I'm simply applying the undocumented style for #include directives in stdcxx [http://tinyurl.com/6abxfz], which is quoted below... 2. include directives are in alphabetical order, with rw/_defs.h being last (it still ends up getting included first, indirectly, by the first header); the exception here is when a stdcxx config macro needs to be tested before the first #include directive Martin
RE: implementation of Unary Traits
Martin Sebor wrote: Travis Vitek wrote: Martin Sebor wrote: The implementation of Unary Traits (e.g., is_void) uses explicit specialization on all four combinations of cv-qualifiers for each trait (plain, const, volatile, and const volatile). I'm wondering if the alternative approach of stripping the qualifiers before dispatching to just one explicit specialization has been considered. That is what I had originally done. I forgot about that. [...] The only issue is that this creates a cyclic dependency between traits defined in rw/_meta_cv.h and those in rw/_meta_cat.h. But only because of the __rw_add_xxx Transformation Traits. Not because of the __rw_is_xxx Unary Traits, correct? Yes. IMO, the two categories belong in separate headers anyway. Not just logically but also (and mainly) because unlike the latter, I don't expect us to be needing the former in [many] other areas of the library. I can accept that. Originally I wanted separate headers for each trait, but it was determined that the overhead from including all of these small files would be to much, so I suggested splitting traits up into groups based on what they did (rw/_add_cv.h, rw/_remove_cv.h, ...) but that was vetoed also. An easy way to 'fix' this would be to forward declare __rw_remove_cv in rw/_meta_cat.h and then include rw/_meta_cv.h at the bottom, but this goes against our conventions. Another option was to put the remove-cv traits into their own header, but this went against your request to organize the traits in files according to some rationale. My suggested guideline is to group traits according to how likely they are to be used in other areas of the library. It seems that your 'suggested guideline' is in direct conflict with your 'requirement' that the traits be arranged into files according to some 'well defined rationale'. This is the same reasoning you used to reject my proposal of splitting related traits into separate files. From what I gather, you are suggesting that all traits go into type_traits unless they are likely to be used in other areas of the library. If they are 'likely' to be used in other parts of the library, then they go into some other header(s), the names of which depend on some yet to be determined naming scheme. So the 'well defined rationale' does not seem to be very well defined. I expect the is_cv-kind of traits to be used pervasively (in containers and some algorithms). OTOH, I expect the add_cv ones to be used only exceedingly rarely, if ever. Traits that are not used in other library headers can be defined directly in type_traits or grouped in implementation-specific headers according to some other sensible criteria. Okay, I've already taken two shots at this. One that I showed as an initial implementation for review, and the other which has been committed to subversion. I don't have a strong preference as long as they don't get pulled in to translation units unnecessarily. This is in conflict with the feedback you provided on my initial traits implementation. You didn't like that each trait was in its own header, yet no trait was unnecessarily pulled in. The potential advantage of this approach is fewer declarations, smaller translation units, and thus (presumably) faster compilation. There has to be a balance somewhere. Absolutely. If all traits are in one file, we have few includes, but lots of unnecessary declarations. If we spread them all out, then we have few unnecessary declarations, but many includes. Both can _potentially_ lead to (ever so slightly) longer compile times in some cases and shorter ones in other cases. I'm definitely open to suggestions and I'm willing to make any necessary changes. Unfortunately any suggestion has to take the following criteria into consideration... A. the number of trait headers should be kept to a minimum (to keep compile times down) B. there should not be many unnecessary declarations in any header (to keep compile times down) C. traits should be put into files according to some well defined rationale (to keep things organized) Unfortunately, I don't really see a clear path to satisfying all of the above requirements. I can think of a couple of options that satisfy these. I'm not sure how palatable I find them yet, but I might get over their (initial) lack of appeal if the payoff is worth it. YMMV. One is to drop the cv specializations of the __rw_is_xxx traits and define the standard traits in terms of both remove_cv and the __rw traits, like so: template class _TypeT struct is_void: integral_constantbool, _RW::__rw_is_voidtypename _RW::__rw_remove_cv_TypeT::type::value { }; or more concisely: template class _TypeT struct is_void: integral_constantbool, _RWSTD_IS_VOID (_TypeT)::value { }; with _RWSTD_IS_VOID() being #defined like so: #define _RWSTD_IS_VOID(T) \ _RW::__rw_is_voidtypename
RE: C++ 0x testing
Martin Sebor wrote: Eric Lemings wrote: Martin Sebor wrote: Unless I'm missing something, C++ 0x testing is currently disabled in nightly builds. I.e., because tests for the newly added C++ 0x features are guarded by the _RWSTD_NO_CXX_0X macro and because _RWSTD_EXT_CXX_0X is not #defined, the tests are compiled into what essentially amounts an empty main(). Yes. With type traits and tuple being nearly done, I think it's time to start exercising these and any other new components in nightly builds. One approach that might be easily implementable at least for gcc is the one suggested in a recent thread: for 4.3.x, add -std=gnu++0x to the set of compiler options for gcc 4.3 and beyond, and make _RWSTD_EXT_CXX_0X synonymous with gcc's __GXX_EXPERIMENTAL_CXX0X__. This should be okay. Is there a better approach? I'd like to get things set up sometime this week. Rather than hard-code the flags, I suggest a command-line make definition; e.g. make _RWSTD_EXT_CXX_0X=1 ... I thought this is the way it was originally proposed. I'm not sure where the _RWSTD_EXT_CXX_0X macro came from or why C++ 0x is disabled by default even for compilers that it works with. I remember suggesting _RWSTD_NO_EXT_CXX_0X but not _RWSTD_EXT_CXX_0X. Of course, it's entirely possible that I forgot. Travis, what's your insight into this? The discussion that I remember (I should check the archives) we said that we wanted to disable the c++0x extensions by default, but wanted to provide a way to enable them. We had also said that we wanted to enable them by default at some time in the future. This was the primitive method that I came up with to allow for this while still allowing us to do manual builds. I don't rally see a huge advantage to doing it the way I have it now, and I'm completely open to removing the _RWSTD_EXT_CXX_0X macro and using compiler specific macros or even config tests to see if we can safely attempt to use the c++0x extensions. Anyways, the gcc.config flag appends the appropriate compiler flags and defines only if this make variable is defined; e.g. ifeq ($(_RWSTD_EXT_CXX_0X),1) CXXFLAGS += -std=gnu++0x -D_RWSTD_EXT_CXX_0X endif This would work also. This is what I was expecting to have to do until we opted to enable the extensions by default (for 5.0.0). I'm suggesting we unconditionally enable it on 4.3.x in builds with gcc 4.3 (and all other compilers where it's intended to be tested). Just gcc-4.3 and msvc-8.0 right now. I haven't bothered to work with any other platforms because it seems the traits implementation is still in limbo. IIUC, the approach outlined above won't help us test the implementation in nightly builds because it'll still leave C++ 0x disabled unless we also change the buildntest script to define the make variable the way you show. If we were to take this approach I don't see the advantage over simply setting CXXOPTS=-std=gnu++0x instead. It seems to me that most users are more likely to be familiar and comfortable with using compiler options than with #defining our config macros. If we are absolutely confident that we won't introduce any incompatibilities, then I don't see any serious problems with doing this. The only issue I can think of is that the library may configure differently with -std=gnu++0x and the users could want build without it. Doing it this way would make it more difficult to remove the flag. Martin
RE: implementation of Unary Traits
Sorry for top posting... Yes, the __rw_is_convertible_implT,U::_C_make should probably be changed to return __rw_remove_cv_TypeT::type (probably with a typedef). We should probably add a case for this in the 20.meta.rel.cpp test also. I'm on vacation today otherwise I'd make the necessary changes myself. Travis -Original Message- From: Martin Sebor on behalf of Martin Sebor Sent: Thu 6/26/2008 10:12 PM To: dev@stdcxx.apache.org Subject: Re: implementation of Unary Traits Eric Lemings wrote: -Original Message- From: Martin Sebor [mailto:[EMAIL PROTECTED] On Behalf Of Martin Sebor Sent: Thursday, June 26, 2008 5:45 PM To: dev@stdcxx.apache.org Subject: implementation of Unary Traits The implementation of Unary Traits (e.g., is_void) uses explicit specialization on all four combinations of cv-qualifiers for each trait (plain, const, volatile, and const volatile). I'm wondering if the alternative approach of stripping the qualifiers before dispatching to just one explicit specialization has been considered. The potential advantage of this approach is fewer declarations, smaller translation units, and thus (presumably) faster compilation. Though I'm using a relational (binary) type trait, I'm getting warnings because the cv-qualifiers are not being stripped. A test case is always helpful: #include type_traits int main () { return !std::is_convertibleconst int, int::value; } Seems like is_convertible might need to strip top-level cv qualifiers from the types. What do you think, Travis? Martin gcc -c -I/work/stdcxx/branches/4.3.x/include/ansi -D_RWSTDDEBUG -pthread -I/work/stdcxx/branches/4.3.x/include -I/build/stdcxx-4.3.x-15D/include -I/work/stdcxx/branches/4.3.x/tests/include -std=gnu++0x -D_RWSTD_EXT_CXX_0X -W -Wall -Wcast-qual -Winline -Wshadow -Wwrite-strings -Wno-long-long -Wcast-align /work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp /work/stdcxx/branches/4.3.x/include/rw/_meta_rel.h: In instantiation of '__rw::__rw_is_convertible_implconst int, int': /work/stdcxx/branches/4.3.x/include/rw/_meta_rel.h:93: instantiated from '__rw::__rw_is_convertible_3const int, int, false, false' /work/stdcxx/branches/4.3.x/include/rw/_meta_rel.h:122: instantiated from '__rw::__rw_is_convertible_2const int, int, false' /work/stdcxx/branches/4.3.x/include/rw/_meta_rel.h:145: instantiated from '__rw::__rw_is_convertible_1const int, int, false, false' /work/stdcxx/branches/4.3.x/include/rw/_meta_rel.h:163: instantiated from '__rw::__rw_is_convertibleconst int, int' /work/stdcxx/branches/4.3.x/include/tuple:68: instantiated from 'std::tupleconst int::_C_is_compatibleint' /work/stdcxx/branches/4.3.x/include/tuple:123: instantiated from 'std::tuple_Types::tuple(_TypesU ...) [with _TypesU = int, _TypesT = const int]' /work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp:103: instantiated from here /work/stdcxx/branches/4.3.x/include/rw/_meta_rel.h:77: warning: type qualifiers ignored on function return type Brad.
RE: spacing suggestion for new code
Martin Sebor wrote: Eric Lemings wrote: -Original Message- From: Martin Sebor [mailto:[EMAIL PROTECTED] On Behalf Of Martin Sebor Sent: Thursday, June 26, 2008 5:21 PM To: dev@stdcxx.apache.org Subject: spacing suggestion for new code While reviewing all the new code that's been added I'm finding it difficult to spot where one namespace-scope definition ends and another starts because the spacing between them (the number of newlines) is the same as the spacing between members, namely 1 blank line. I find code easier to read when namespace scope definitions of functions and classes that span more than one line are separated by two blank lines. Existing code likely isn't completely consistent in this regard, and I'm sure examples of both styles could be found, but I'd like to think the two-line style is prevalent. Either way, in the interest of readability, I'd like to suggest that we adopt the two-line spacing style for all new code. Yes? That's my general preference as well. I prefer to use two lines to separate unrelated logical groups. If the groups are related, I'll use 1 line to separate them. Within a logical group, I do not use any blank lines. Your rule sounds a bit more complex than what I'm suggesting. Determining what logically belongs together requires an understanding of the definitions. What I'm looking for is a purely visual clue to help me tell one namespace-scope declarative region (mostly just class or function definition) from another. Should either scheme apply to linkage specifiers? Personally, I like the flexibility to use zero lines in some places... // i prefer this... _RWSTD_NAMESPACE(__rw) { struct __rw_whatever_type; } // namespace __rw // as opposed to this... _RWSTD_NAMESPACE(__rw) { struct __rw_whatever_type; } // namespace __rw As long as the number of lines of whitespace doesn't outnumber the number of lines of 'code', I'm fine with using multiple lines of whitspace. Other than that, I don't really have a preference. Travis
RE: question about aligned_storage
Martin Sebor wrote: Travis Vitek wrote: [...] The only functionality I have available to me for doing alignment (on the tested platforms) is __declspec(align(#)) on Microsoft and __attribute__ ((aligned(#))) on gcc-4.3. Both of these support functions require that the alignment value be a power of two. The Microsoft compiler has the 8192 limit. An upper limit is acceptable (it should be mentioned in one of the appendices to the spec). I'm more interested in alignments that aren't powers of 2. It's not clear to me why restricting the template to powers of 2 is okay or why it's difficult not to support all of them up to the limit. I'm not saying it is okay to limit them to powers of two, I'm just saying that non-power of two values won't work on the platforms that are currently supported. The aligned attribute on gcc pukes if you use non-power-of-two alignment values. $ cat z.cpp; g++ z.cpp a.out int main () { typedef char dummy __attribute__ ((aligned(3))); return 0; } z.cpp: In function 'int main()': z.cpp:4: error: requested alignment is not a power of 2 I could implement the specializations of the helper for all possible values up to the upper limit and then let the compiler puke when it can't honor the alignment that was requested. It is not 'difficult' to do this, I just don't see it as useful because I can't test them until I have at least one compier that supports the ability to do non-power-of-two alignments. The draft shows a 'typical implementation' of aligned_storage that uses the new alignas keyword, but alignas doesn't appear to be supported anywhere. That's probably because they didn't want to favor any existing implementation over others. I don't see this as a problem with the standard not wanting to favor one implementation over another, it is a problem because no current implementation supports the new keyword. The following code is very similar to that typical implementation, but it does not compile because value passed to the aligned attribute has to be a literal, not a constant expression. That's what you for using a crappy compiler ;-) It compiles with gcc. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19163 Uh, yeah, it compiles... but watch out for: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36625 but it is utterly useless because of this bug. You can't use the nested aligned type. Talk about crappy compilers. We should open an enhancement request with Microsoft. I'll do that. Martin
RE: Unnamed template parameters
Eric Lemings wrote: Anyone recall if some compilers might have problems and/or issue warnings about unnamed template parameters? E.g., template class struct S; Martin mentioned in a review of your code that he remmbers it not being safe on at least one compiler. I have not encountered such a compiler, and I know that I'm doing it with non-type template parameters in the traits code. Or is this safe practice? Brad.
RE: 22.locale.codecvt.out test failure
Martin Sebor wrote: Travis Vitek wrote: The named test fails on all platforms with an EXEC error. It looks like the problem is that when trying to build the executable '22.locale.codecvt.out', it actually generates an output file for the test '22.locale.codecvt', which is obviously not going to be executable. [...] I know this worked at one time because I was involved in the discussion for fixing this problem the last time it came up [http://tinyurl.com/5nv7qx]. Any ideas why this problem is back to haunt us? There are two tests with similar names: 22.locale.codecvt and 22.locale.codecvt.out I suspect that when 22.locale.codecvt runs, its output is redirected to 22.locale.codecvt.out. Is there an echo in here? :) If this is true, we might want to change the exec utility (which does the redirection) to send the output of tests somewhere else. Sure, that is one option. But that doesn't answer my question. Why is this failing now, after it worked in the past. See https://issues.apache.org/jira/browse/STDCXX-650 Now my new question is, why change the output file extension? It seems that would have a better chance of causing additional failures. Martin
RE: question about aligned_storage
Martin Sebor wrote: Martin Sebor wrote: Travis Vitek wrote: [...] The draft shows a 'typical implementation' of aligned_storage that uses the new alignas keyword, but alignas doesn't appear to be supported anywhere. That's probably because they didn't want to favor any existing implementation over others. I don't see this as a problem with the standard not wanting to favor one implementation over another, it is a problem because no current implementation supports the new keyword. That might have been the point: use a made up keyword that doesn't exist on any implementation so as not to suggest that one should be preferred over the others. (Just guessing.) But I'm guessing wrong, of course. Again, I missed an important detail in your post: that alignas is a new C++ keyword (I didn't know that). Sorry, I need to pay closer attention. Given alignas, aligned_storage seems completely superfluous. I wonder why it's even still there... The only real benefit is that the name aligned_storage tells exactly what it does and it provides a default alignment for the requested size. Martin
RE: 22.locale.codecvt.out test failure
Martin Sebor wrote: Travis Vitek wrote: Martin Sebor wrote: Travis Vitek wrote: I'm absolutely certain it worked in the recent past, but I'll go back and do a build to make sure I'm not totally insane. You don't need to. Do a search among the older build logs under http://stdcxx.apache.org/builds/4.2.x/logs/ instead. Here's a recent list: linux_suse-10.0-em64t-gcc-4.1.0-12D-654664-log.gz.txt linux_suse-10.0-em64t-gcc-4.1.0-12D-655584-log.gz.txt linux_suse-10.0-em64t-gcc-4.1.0-12D-656010-log.gz.txt [...] AFAIK, this doesn't do me much good unless I can guess the revision used to do a build on a given platform. How am I to browse the list of old build logs? They're all in people.apache.org:/www/stdcxx.apache.org/builds/*/logs/ To get the listing I sent, run: ssh people.apache.org \ cd /www/stdcxx.apache.org/builds/4.2.x/logs \ ls linux_suse-10.0-em64t-gcc-4.1.0-12D-*-log.gz.txt Thanks. The location was the thing that I was missing. I didn't realize that stdcxx.apache.org was hosted on people.apache.org. Regardless, I don't see any build results that are old enough to show me what I need. I pulled tags/4.2.1 and did a build on AIX. After looking at the results I noticed the problem (maybe everyone else noticed it already). The test 22.locale.codecvt is a new test and didn't exist at the time STDCXX-650 was closed. Martin
RE: status of type_traits with gcc
-Original Message- From: Martin Sebor [mailto:[EMAIL PROTECTED] On Behalf Of Martin Sebor Sent: Thursday, June 26, 2008 3:31 PM To: dev@stdcxx.apache.org Subject: Re: status of type_traits with gcc Travis Vitek wrote: Martin Sebor wrote: I'm getting compilation errors with gcc 4.3. Is the implementation supposed to be stable at this point with any compiler or are there still some major issues? I just did a sync of 4.3.x and a build with CXXFLAGS=-std=gnu++0x -D_RWSTD_EXT_CXX_0X and didn't run into any problems with type_traits or the 20.meta.*.cpp tests (though 20.forward.cpp and 26.valarray.cassign.cpp both fail to compile). I did another build without those flags and I do see some compile errors in both the traits and tuple code. I'll fix the traits issues. Thanks. I hadn't realized I needed -std=gnu++0x and was getting a ton of errors. That, and I also forgot to reconfigure to get _RWSTD_NO_VARIADIC_TEMPLATES #defined. Btw., to make using C++ 0x easier we might want to automatically #define _RWSTD_EXT_CXX_0X when the __GXX_EXPERIMENTAL_CXX0X__ macro is #defined (and #undef _RWSTD_NO_VARIADIC_TEMPLATES and other config macros #defined as a result of the absence of the option during configuration). Yeah, but some of these options might break compatibility. Imagine an exported function that takes an rvalue reference parameter. The library would be configured without rvalue references, but then the user 'enables' c++0x support by compiling with -std=gnu++0x. Now they might get a link error, right? Travis
RE: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp
Martin Sebor wrote: Travis Vitek wrote: I'm not absolutely sure I'm reading the documentation you linked to correctly, but here goes... It's possible that I misread the text. I was pretty sure (and still am) I remembered discussing the alignment issue before but I couldn't (and still can't) find it in the archives. I pointed to this page because that was the best I could come up with in the absence of anything else. Maybe it's a red herring. It could also be that the issue I think I'm remembering had less to do with alignment than something else (aliasing, maybe), but given the choice between placing the more strictly aligned type first and the unaligned buffer second or doing laying them down in the reverse order I'd go for the former even if there is no real issue. I searched library headers and sources for how we define unions and with the exception of limits_bits.cpp we always follow this rule. Unless there is a reason not to make this change to aligned_union, I think we should change both limits_bits.cpp and aligned_union to always define the member with the more strict alignment requirement first, just for peace of mind. Good thing you didn't look at my original implementation of aligned_union. :) Is there any reason/advantage to having the char buffer first? Not that I know of. I'll update them all. The first paragraph of that documentation says Individual members of a union are mapped the same way as members of the structure. That is, each of the members, if not a union, is mapped as if it were a member of a structure. This means that the first storage locations for each of the members of a union do not overlay each other if each of the members requires different alignment and therefore different padding before the beginning of the member. This violates C99 (6.7.2.1 p5) Not all compilers support C99, and of those that do not all of them conform to 100% of the requirements. The layout of structs and unions is an ABI issue, and it's quite possible that there are systems that can't afford to break the ABI for compatibility reasons. Sure. I didn't have a copy of C90 handy, but I'd be willing to bet that it had some similar requirement in there. I'm sure most compilers conform to C90 given that they have had nearly 20 years to do so.
RE: implementation of Unary Traits
Martin Sebor wrote: The implementation of Unary Traits (e.g., is_void) uses explicit specialization on all four combinations of cv-qualifiers for each trait (plain, const, volatile, and const volatile). I'm wondering if the alternative approach of stripping the qualifiers before dispatching to just one explicit specialization has been considered. That is what I had originally done. The following code may be eerily familiar to you. #include tr1/_remove_cv.h #include rw/_defs.h _RWSTD_NAMESPACE (__rw) { template class _TypeT struct __rw_is_void_impl { enum { _C_value = 0 }; }; _RWSTD_SPECIALIZED_CLASS struct __rw_is_void_implvoid { enum { _C_value = 1 }; }; template class _TypeT struct __rw_is_void { enum { _C_value = __rw_is_void_impl _TYPENAME __rw_remove_cv_TypeT::_C_type ::_C_value }; }; } // namespace __rw The only issue is that this creates a cyclic dependency between traits defined in rw/_meta_cv.h and those in rw/_meta_cat.h. An easy way to 'fix' this would be to forward declare __rw_remove_cv in rw/_meta_cat.h and then include rw/_meta_cv.h at the bottom, but this goes against our conventions. Another option was to put the remove-cv traits into their own header, but this went against your request to organize the traits in files according to some rationale. The potential advantage of this approach is fewer declarations, smaller translation units, and thus (presumably) faster compilation. There has to be a balance somewhere. If all traits are in one file, we have few includes, but lots of unnecessary declarations. If we spread them all out, then we have few unnecessary declarations, but many includes. Both can _potentially_ lead to (ever so slightly) longer compile times in some cases and shorter ones in other cases. I'm definitely open to suggestions and I'm willing to make any necessary changes. Unfortunately any suggestion has to take the following criteria into consideration... A. the number of trait headers should be kept to a minimum (to keep compile times down) B. there should not be many unnecessary declarations in any header (to keep compile times down) C. traits should be put into files according to some well defined rationale (to keep things organized) Unfortunately, I don't really see a clear path to satisfying all of the above requirements. Martin
RE: question about aligned_storage
Martin Sebor wrote: Travis Vitek wrote: Martin Sebor wrote: While looking at the hoops we jump through to implement aligned_storage I recalled the gcc __attribute__ (aligned (N)). Is there any to use it to simplify the implementation for gcc? We already do. You're a step (or a few) ahead of me, as usual... :) You give me more credit than I deserve. I'm making this stuff up as I go... :) Have a look at the definition of the macro _RWSTD_TT_ALIGNED_POD(). You mean the one in rw/_gcc-config.h on the 103 character long line? (You almost got away with it ;-) Yeah, I have a few long lines. I need to clean up the mess that I've made. I might be able to eliminate __rw_aligned_storage_impl if I wanted to do a partial specialization of __rw_aligned_storage on the _Align non-type template parameter and I could also eliminate __rw_default_alignment, but that is about as much as I think I could reduce it. I'm probably missing something but is aligned_storage only specified for alignment of powers of 2? (It looks to me as though those are the only alignments we support.) Yes. I probably need to do something here, but I'm not sure what. Table 51 says _Align shall be equal to alignment_ofT::value for some type T or to `default-alignment' This essentially says that I need to support all valid alignment values on the platform. Fortunately, for the time being the power of two restriction is okay. The only functionality I have available to me for doing alignment (on the tested platforms) is __declspec(align(#)) on Microsoft and __attribute__ ((aligned(#))) on gcc-4.3. Both of these support functions require that the alignment value be a power of two. The Microsoft compiler has the 8192 limit. The draft shows a 'typical implementation' of aligned_storage that uses the new alignas keyword, but alignas doesn't appear to be supported anywhere. The following code is very similar to that typical implementation, but it does not compile because value passed to the aligned attribute has to be a literal, not a constant expression. template std::size_t _Size, std::size_t _Align = __rw_default_alignment_Size::value struct __rw_aligned_storage { typedef struct { char _C_align [_Size] __attribute__ ((aligned(_Align))); } type; }; Travis Martin See http://tinyurl.com/5kmvdy for reference. Martin
RE: __rw_and (Was RE: Some internal aliases for __rw_integral_constant?)
Eric Lemings wrote: Okay, another proposal for inclusion though this particular utility may be a stretch unless you understand variadic templates very well. template bool... struct __rw_and; template struct __rw_and: std::true_type {}; template bool _Bool0, bool... _BoolN struct __rw_and_Bool0, _BoolN... : _RWSTD_BOOL_CONST (_Bool0 __rw_and_BoolN...::value) {}; For example: template class... _TypesT struct tuple { template class... _TypesU struct __rw_is_compat : __rw_andstd::is_convertible_TypesT, _TypesU::value... { static_assert (sizeof... (_TypesT) == sizeof... (_TypesU), tuple sizes must be equal); }; }; Interesting. I have seen similar utilities, but they usually took two parameters, so I never really saw them as useful. This, on the other hand, does seem useful. I'm assuming you are considering a fallback implementation like I have for aligned_union when variadic templates aren't supported. Here are some quick tests that I tried out on it: typedef tuplechar, int, long T1; std::cout T1::__rw_is_compatchar, short, int::value std::endl; std::cout T1::__rw_is_compatconst char, const int, const long::value std::endl; std::cout T1::__rw_is_compatfloat, int, long::value std::endl; std::cout T1::__rw_is_compatvoid*, int, long::value std::endl; // fires the static assertion //std::cout T1::__rw_is_compatchar, short::value // std::endl; Might just save that one for later but worth posting at least. :) Brad.
RE: :decay related question
Martin Sebor wrote: Travis Vitek wrote: Eric Lemings wrote: Page 490, section 20.3.1.2, paragraph 1 in the latest draft says this: Let Ui be decayTi::type for each Ti in Types. Then each Vi in Vtypes is X if Ui equals reference_wrapperX, otherwise Vi is Ui. What do you suppose the relationship is between type `X' and types `Ti' and `Ui'? I see how the latter two types are deduced from the type list `Types' but not so sure about how type `X' is deduced from `Types'. I'm looking at this and I have no idea where VTypes and X are coming from. Is that an issue, or am I missing something? Have you found an issue for any of this? (If not, we/I will need to open one.) I don't see one. Unless Brad knows something that we don't, I think it should be brought up. Martin That said, I think X is supposed to be Ti. If that were the case then the definition would make some sense [at least to me]. Let Ui be decayTi::type for each Ti in Types. Then each Vi in VTypes is Ti if Ui equals reference_wrapperTi, otherwise Vi is Ui. If that is right, then it essentially says that the 'make_tuple' function transforms reference_wrapperT back to T and for other types does the normal decay transformation [function to funciton pointer, array to array pointer, and cv-stripping of all other types]. Travis Brad.
RE: svn commit: r669735 - in /stdcxx/branches/4.3.x: include/rw/_meta_other.h include/type_traits tests/utilities/20.meta.trans.other.cpp
Martin Sebor wrote: [EMAIL PROTECTED] wrote: Author: vitek Date: Thu Jun 19 15:52:34 2008 New Revision: 669735 URL: http://svn.apache.org/viewvc?rev=669735view=rev Log: 2008-06-19 Travis Vitek [EMAIL PROTECTED] STDCXX-926 [...] +template size_t _Size, size_t _Align = __rw_default_alignment_Size::value struct __rw_aligned_storage { [...] typedef union { -unsigned char __data [_Len]; -// not implemented +unsigned char __size [_Size]; + +typename +__rw_aligned_storage_impl_Align::_C_type __align; I believe there are platforms where unions are aligned on the boundary given by the first member. This one looks like it might be one of them: http://tinyurl.com/472744. Unless I'm mistaken we should switch the order of the two members to make sure the union is properly aligned. I'm not absolutely sure I'm reading the documentation you linked to correctly, but here goes... The first paragraph of that documentation says Individual members of a union are mapped the same way as members of the structure. That is, each of the members, if not a union, is mapped as if it were a member of a structure. This means that the first storage locations for each of the members of a union do not overlay each other if each of the members requires different alignment and therefore different padding before the beginning of the member. This violates C99 (6.7.2.1 p5) As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence, and a union is a type consisting of a sequence of members whose storage overlap. And (6.7.2.1 p14) The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members, and vise versa. It also voilates C++03 (expr.rel p2) If two pointers point to data members of the same union object, they compare equal (after conversion to void*, if necessary). Even so, the last paragraph of Rules for mapping one pair says The pair is now a unit of fixed length and alignment requirement, its length is the sum of the two lengths plus padding, and its alignment requirement is the higher of the two alignment requirements (if they differ). So the alignment would still be correct as the alignment requirement is weakest (smallest) for char types, so the alignment that would be used would be the alignment of the other type. Please correct me if I'm misinterpreting any of this. Travis Also, strictly speaking, names of data members should have the _C_ prefix (double underscores are used for locals and function parameters). Agreed. I will fix. Martin
22.locale.codecvt.out test failure
The named test fails on all platforms with an EXEC error. It looks like the problem is that when trying to build the executable '22.locale.codecvt.out', it actually generates an output file for the test '22.locale.codecvt', which is obviously not going to be executable. $ gmake 22.locale.codecvt.out gcc -c -I/amd/devco/vitek/stdcxx/trunk/include/ansi -D_RWSTDDEBUG -I/amd/devco/vitek/stdcxx/trunk/include -I/build/vitek/5.0.0/11S/include -I/amd/devco/vitek/stdcxx/trunk/tests/include -pedantic -nostdinc++ -g -W -Wall -Wcast-qual -Winline -Wshadow -Wwrite-strings -Wno-long-long -Wcast-align /amd/devco/vitek/stdcxx/trunk/tests/localization/22.locale.codecvt.cpp gcc 22.locale.codecvt.o -o 22.locale.codecvt -L/build/vitek/5.0.0/11S/rwtest -lrwtest11S -L/build/vitek/5.0.0/11S/lib -lstd11S -lsupc++ -lm LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/build/vitek/5.0.0/11S/lib ./22.locale.codecvt 22.locale.codecvt.out 21 I know this worked at one time because I was involved in the discussion for fixing this problem the last time it came up [http://tinyurl.com/5nv7qx]. Any ideas why this problem is back to haunt us? Travis
RE: svn commit: r668347 - /stdcxx/branches/4.3.x/tests/utilities/20.meta.rel.cpp
Martin Sebor wrote: [EMAIL PROTECTED] wrote: Author: vitek Date: Mon Jun 16 16:35:21 2008 New Revision: 668347 URL: http://svn.apache.org/viewvc?rev=668347view=rev Log: 2008-06-16 Travis Vitek [EMAIL PROTECTED] [...] @@ -346,7 +332,7 @@ TEST (std::is_convertible, int (), int ()(char), false); TEST (std::is_convertible, int*, void*, true); -TEST (std::is_convertible, int (*)(), void*, true); +TEST (std::is_convertible, int (*)(), void*, false); Should the convertibility of functions with different language linkages, and that of member function pointers, be exercised as well? Absolutely. Will enhance test. Martin
RE: HP aCC 3.63 compilation error in 21.string.append.stdcxx-438.cpp
Martin Sebor wrote: Travis Vitek wrote: Martin Sebor wrote: The test fails to compile with HP aCC 3.63. The error messages point to the patch for the issue: http://svn.apache.org/viewvc?view=revrevision=629550 Actually, I think it was me that caused the problem, in the following change: http://svn.apache.org/viewvc?view=revrevision=669747 The fix was for STDCXX-170 and friends, but break on every compiler when the Iterator::operator*() returns a temporary (which is legal). That's what I thought was your objection to Farid's patch. Yes, it was. Unfortunately I forgot about this issue part way through making my patch. Am I to understand that the code somehow detects whether operator*() returns a rvalue or lvalue and the branch with the cast is only supposed to be entered for lvalues? Sort of. The code checks that the _InputIter is a pointer. If it is, then we know it is safe to use the pointer to check for overlap. (I'm still uncomfortable with the cast and would like to understand why it's safe). It seems that the cast itself is legal because expr.static.cast says An expression e can be explicitly converted to a type T using static_cast of the form static_castT(e) if the declaration T t(e); is well-formed, for some invented temporary variable t. The declaration const_reference t(*__first); is legal if *__first is convertible to value_type, which is required, so everything seems okay here, right? The problem with the original testcase was that the cast can end up giving us a pointer to a temporary if *__first doesn't return a reference, which can result in invalid results. The testcase I provided showed this. My fix eliminated the cast (which caused breakage), but verifies that __first is actually a raw pointer type before trying to get a reference out of it. So I think that we may be able to combine the two patches to come up with a usable fix. If we avoid doing the cast until we know that __first is a pointer, then we can be sure that the cast is giving us reliable results. If __first is not a pointer, then all bets are off and we have to fall back to making a copy. It looks like I'd need to do a special case when the iterator type is pointer. I don't see any way to legally check for no overlap without that, so the only option I can see then is to always make the copy and fix it with an overload selection trick (which would only be appropriate for 4.3.x). I think it should be fine to optimize just the common case (const_pointer) and leave the rest unoptimized (i.e., make a copy). Or can you think of another common use that should be optimized as well? I think all cv-qualified pointer types could be optimized in this way. Travis Looking at the patch I don't see how the reinterpret_cast to const_reference can possibly be correct, and I'm not sure we satisfactorily resolved the same question the first time it was raised back in March: http://markmail.org/message/eijfmt3wxhg25bvs Farid? Thanks Martin
RE: question about aligned_storage
Martin Sebor wrote: While looking at the hoops we jump through to implement aligned_storage I recalled the gcc __attribute__ (aligned (N)). Is there any to use it to simplify the implementation for gcc? We already do. Have a look at the definition of the macro _RWSTD_TT_ALIGNED_POD(). I might be able to eliminate __rw_aligned_storage_impl if I wanted to do a partial specialization of __rw_aligned_storage on the _Align non-type template parameter and I could also eliminate __rw_default_alignment, but that is about as much as I think I could reduce it. See http://tinyurl.com/5kmvdy for reference. Martin
RE: svn commit: r667636 - /stdcxx/branches/4.3.x/include/rw/_forward.h
Martin Sebor wrote: Eric Lemings wrote: Gah. I have to update my docs as well: template parameters are documented using the @tparam tag rather than the @param tag. I thought we said we wouldn't be using doxygen comments in library code. Am I misremembering? I know that it was requested that I remove the doxygen comments from the type traits stuff I have been working on, but I decided it would be best to commit them with the comments intact and remove them only if necessary. I mentioned this to Brad in our off-list correspondence, and he has opted to do the same. As I sit here thinking about it, I can't remember exactly why it was decided that they should be removed. Perhaps it is best to have this discussion again, but on the list this time. To start, I'm not sure I understand the motivation for _not_ using doxygen in the library headers. I realize that having documentation in the code is a departure from what stdcxx has done in the past, but I'm not convinced that this is a bad thing. Travis Martin http://www.stack.nl/~dimitri/doxygen/commands.html#cmdtparam Brad.
RE: svn commit: r667636 - /stdcxx/branches/4.3.x/include/rw/_forward.h
Martin Sebor wrote: Eric Lemings wrote: Travis Vitek wrote: Martin Sebor wrote: I thought we said we wouldn't be using doxygen comments in library code. Am I misremembering? I know that it was requested that I remove the doxygen comments from the type traits stuff I have been working on, but I decided it would be best to commit them with the comments intact and remove them only if necessary. I mentioned this to Brad in our off-list correspondence, and he has opted to do the same. As I sit here thinking about it, I can't remember exactly why it was decided that they should be removed. Perhaps it is best to have this discussion again, but on the list this time. To start, I'm not sure I understand the motivation for _not_ using doxygen in the library headers. I realize that having documentation in the code is a departure from what stdcxx has done in the past, but I'm not convinced that this is a bad thing. I'll add a couple points to that for the record. Much of this was precipitated when I noticed that GNU libstdc++ also includes their documentation right in the library headers and source code. Why? Because most, if not all, C/C++ preprocessors will strip comments by default during a first pass. Thus, the impact of extensive documentation comments on overall build times is negligible. Of course preprocessors strip comments. It's required by the language standards. But regardless of the translation stage at which the stripping takes place, it isn't without cost. I gave a number of arguments against Doxygen comments in stdcxx headers: 1) existing code doesn't use it and converting the raw HTML docs to Doxygen is an enormous task that none of us has the time to take on; Doxygenating new code without doing the same for the existing code is inconsistent and won't help us produce end-user documentation for the finished product Since we aren't providing any html documentation for any c++0x code at this time, maybe we should stop using html documentation? :P So the options are-- a) not document the c++0x code at all b) write up documentation for all new code in html to be consistent with what is used currently c) move all existing documentation over to doxygen before a single doxygen comment is added to the new code Another important point is that the stdcxx project doesn't have anyone volunteering time to write documentation. If we want the documentation, we're likely going to have to do it ourselves, and I find using doxygen comments _much_ simpler than writing html. I know that at Rogue Wave we have an xslt that transforms from doxygen generated xml files to html documentation, so unless using doxygen is totally ruled out, that can be used to bridge between the old html pages and generated ones. 2) Doxygen markups are harder to read than ordinary comments (see 3), and in the library headers the volume of such comments will, in many cases, dwarf the amount of code If the code is well written, comments are usually reserved for situations where they are necessary to describe what the code is actually supposed to be doing. Most frequently this type of comment would be found in the body of a function definition. Doxygen comments, on the other hand, usually appear with the declarations, so the type of comments that you would usually need to read aren't necessarily in the same place as the doxygen comments. Additionally, your editor can likely be configured to hide the doxygen comments if you don't want to see them. As for readability, consider this. There are currently no comments describing what a given library class or function is expected to do. If you want to see what the expected behavior is, you get to walk yourself through the implementation, or you get to fire up a web browser and look at the html documentation. If the documentation is added as doxygen comments, they are in the code. They may be slightly less readable than plain english text due to the additional markup, but there is _nothing_ that is stopping you from looking to the implementation or firing up a web browser like you did before. 3) unless/until there is infrastructure to generate the HTML docs from the Doxygen comments documenting the library (or other parts of stdcxx) using Doxygen markups serves no purpose Which would you like first, the chick or the egg? The infrastructure will never be built to generate html documentation from doxygen comments if we don't have doxygen comments to generate documentation from. 4) the HTML generated from stdcxx headers is unavoidably ugly because of the necessity to uglify names (leading underscores, etc.) I thought leading underscores made code run faster. :) Doxygen doesn't have to document everything that it sees. There are many ways to control what will be documented. You can tell it to only generate documentation for things that have doxygen style comments
RE: tests/utilities/20.meta.help.cpp
Martin Sebor wrote: Travis Vitek wrote: Eric Lemings wrote: Just a brief side note. I was just reviewing this test and noticed that pointers are not tested though they are valid scalar types suitable for use as integral_constant parameters. I think references may be valid parameters also. I'm not sure. The first thing that jumps to mind is that a pointer is not of 'integral' type. An enumeration isn't really an integral type either, but they are implicitly convertible to one. Pointers aren't convertible to integral type without a cast. According to temp.arg.nontype, a non-type, non-template template parameter must be one of -- an integral constant expression -- the name of a non-type template-parameter -- the address of an object or function with external linkage... -- a constant expression that evaluates to a null pointer value -- a constant expression that evaluates to a null member pointer value -- a pointer to member So, yes, it is legal to use a pointer as a non-type template parameter. The issue I have is that the integral_constantT,V is supposed to define an integral constant of type T with value V. Section expr.const says that a constant expression is an integral constant expression if it is of integral or enumeration type. An integral constant expression can be used as an array bound, a case expression, a bit field length, enumeration initializer, static member initializer and as integral or enumeration non-type template arguments. I'm pretty sure you can't use a pointer value as an array bound, case expression, bit field length or enumeration initializer, so they aren't really integral constants. So I am sure you can instantiate std::integral_constantvoid (class_t::*)(), class::method, but I'm not sure if it something that should be tested. If there's an implementation technique that would make the instantiation ill-formed then I think it should be tested. According to class.mem (p4) and class.static.data (p4) you aren't allowed to initialize static members using a constant-initializer (i.e. in the member declaration) if they are not of const integral or const enumeration type. So the above instantiation on member pointer should be prevented by the compiler. A quick test with msvc-8.0 and gcc-4.3 show that this is the case. The following would be legal, but I'm already testing integral constants for all integral types and an enum type, so I think I'm covered. More important, though, the standard should specify the requirements on the template arguments. If there are no such requirements for something as fundamental as integral_const, either in the latest working draft or in one of the concepts papers (such as N2622), we should at least bring it up on the list and/or open an issue to have the spec clarified. The standard does specify the requirements of the template arguments, but only through association (to be an integral constant member, it has to be a const static that is initialized with a constant-initializer, and a constant initializer only works for enum and integral types). Is this significant enough to warrant bringing up an issue? Travis
RE: svn commit: r668225 - /stdcxx/branches/4.3.x/etc/config/src/VA_LIST_FUNC_MACRO.cpp
Eric Lemings wrote: Martin Sebor wrote: My point was that I couldn't find a way to use a feature that depends on variadic macros on platforms where they are not supported. In other words, I can't picture what the #else branch below would look like: #ifndef _RWSTD_NO_VARIADIC_MACROS # define RW_ASSERT(expr, ...) \ rw_assert (expr, 0, __LINE__, __VA_LIST__) #else # define RW_ASSERT(expr, ???) ... #endif You're right. There is no backward-compatible workaround which essentially rules out using variadic macros in these cases. I think I've showed this trick before, but it won't work with template parameters, only function parameters. struct Variadic { void operator()(const char* fmt, ...); }; #define VARIADIC Variadic().operator() Of course you would use it like this... VARIADIC(hello %s, world!); Travis Brad.
RE: svn commit: r669747 - /stdcxx/branches/4.2.x/include/string.cc
Eric Lemings wrote: Author: vitek Date: Thu Jun 19 16:58:34 2008 New Revision: 669747 ... +#include rw/_typetraits.h Uhgh. The missing underscore in that header name just really bugs me for some reason. Any objections to renaming it as rw/_type_traits.h and updating all code that includes it? Its an internal header so we have that privilage and no end-user code should be affected. I don't like it either, but I think it will be best to just leave it as-is. I'm pretty sure that file is going to go away for 4.3 and later, so we'd just be making (a little) more work for ourselves in the meantime. Brad.
RE: preconditions for aligned_union
Eric Lemings wrote: Travis Vitek wrote: I'm looking at the standard, and it appears that the following is legal... struct incomplete_t; std::aligned_union0, void, incomplete_t::type aligned_t; [...] Now I could implement aligned_union to ignore incomplete types (they have no alignment requirement), but this might cause problems if someone tried to use the result. How so? If someone uses only such types in the list (probably a very rare use case), a zero result should be expected. If alignable types are mixed with such non-alignable types, the result would be as if no such non-alignable types were given. What if none of the provided types have an alignment requirement or size? What should the alignment be? What should the size be? So I'd say just ignore non-alignable types. So you see no problem with the following code failing at runtime due to misalignment or insufficient space? struct incomplete_t; // supposed to be 'suitable for use as uninitialized // storage for any object whose type listed and will // be at least Len bytes std::aligned_union1, incomplete_t::type aligned_buf; struct incomplete_t { long double val; // [...] }; void save_value (const long double v) { ((incomplete_t*)aligned_buf)-val = v; } I'm pretty sure that the standard assumes we will use std::alignment_of and std::aligned_storage to implement std::aligned_union. If that is the case, then the requirement for the type to be complete would be implied. Travis
RE: preconditions for aligned_union
Eric Lemings wrote: Travis Vitek wrote: So you see no problem with the following code failing at runtime due to misalignment or insufficient space? struct incomplete_t; // supposed to be 'suitable for use as uninitialized // storage for any object whose type listed and will // be at least Len bytes std::aligned_union1, incomplete_t::type aligned_buf; struct incomplete_t { long double val; // [...] }; void save_value (const long double v) { ((incomplete_t*)aligned_buf)-val = v; } Yeah, that could be problematic...if the standard actually allows it. With the wording that is currently provided, I believe that the above code is completely legal. That is why I brought up the issue in the first place. I'm pretty sure that the standard assumes we will use std::alignment_of and std::aligned_storage to implement std::aligned_union. If that is the case, then the requirement for the type to be complete would be implied. The only other possible course of action that I see is to check for incomplete and other non-alignable types at compile-time and generate a diagnostic. Not sure how you would do that with type traits but, if its possible, that might be more well-behaved. Actually, detection is quite easy. The implementation of __rw_aligned_union that I wrote a while back should detect it [I use a union internally you can't put an incomplete type in a union]. Honestly it would actually be much more trouble to allow it, but I'm pretty sure it could be done. I'm hoping that Martin will eventually be able to provide some clarification or file a defect report for us. Travis
preconditions for aligned_union
I'm looking at the standard, and it appears that the following is legal... struct incomplete_t; std::aligned_union0, void, incomplete_t::type aligned_t; Does anyone have any idea what the expected behavior of such code would be? The comments in table 51 of the current draft say template std::size_t Len, class... Types struct aligned_union; The member typedef type shall be a pod type suitable for use as uninitialized storage for any object whose type is listed in Types; its size shall be at least Len. The static member alignment_value shall be an integral constant of type std::size_t whose value is the strictest alignment of all types listed in Types. The problem is that void and incomplete types don't have a size or alignment requirements. It appears that this is an oversight in the standard. The related trait alignment_ofT requires that T be a complete type, a reference type, or an array of unknown bound, but not a function type or cv-void type. Now I could implement aligned_union to ignore incomplete types (they have no alignment requirement), but this might cause problems if someone tried to use the result. Travis
RE: _RWSTD_NO_EXT_CXX_0X Include Check
Eric Lemings wrote: This is part of the type_traits header: $TOPDIR/include/type_traits: ... 30 #ifndef _RWSTD_TYPE_TRAITS_INCLUDED 31 #define _RWSTD_TYPE_TRAITS_INCLUDED 32 33 #include rw/_defs.h 34 35 #ifdef _RWSTD_NO_EXT_CXX_0X 36 # error _RWSTD_NO_EXT_CXX_0X defined and C++0x header included 37 #endif ... Shouldn't lines 35-37 come before line 30 so the header isn't even parsed if there is an include error? In other words: ... #ifdef _RWSTD_NO_EXT_CXX_0X # error _RWSTD_NO_EXT_CXX_0X defined and C++0x header included #endif #ifndef _RWSTD_TYPE_TRAITS_INCLUDED #define _RWSTD_TYPE_TRAITS_INCLUDED #include rw/_defs.h ... You have to include rw/_defs.h before you do the _RWSTD_NO_EXT_CXX_0X check because that macro might be defined in one of the files included from there. So that means moving the rw/_defs.h include outside of the header guard. This would require an additional file open [or a lookup at the very least] as well as a condition check every time the file was included from client code. It doesn't look conventional but, technically, it is slightly more efficient. I'd like to see some evidence that this change would have any noticeable effect in terms of compile times. Brad.
RE: Compile error in __rw_aligned_union
Eric Lemings wrote: I'm getting the following compile error on Linux systems: [...] Here's the offending code: 92 union { 93 unsigned char __pad [_Len]; 94 typename __rw_aligned_union_Len, Types...::_C_type __align; 95 } _C_type; I'm guessing that is supposed to be a recursive instantiation of __rw_aligned_union_impl? __rw_aligned_union isn't even seen by the compiler until after this specialization. Yes. Fixed in r668277. Brad.
RE: Empty member initializers
Eric Lemings wrote: Travis Vitek wrote: Eric Lemings wrote: How about member templates? Are these unilaterally supported by all compilers now? From below... _RWSTD_NO_INLINE_MEMBER_TEMPLATES /* not used at all */ Well there's an INLINE_MEMBER_TEMPLATES.cpp check and then there's a separate MEMBER_TEMPLATES.cpp check. I assume they check different things. :) Yes, I realize this. The former checks that inline member templates are supported. The latter checks that member templates can be defined outside the body of the class. AFAICT, inline member templates are used in library code without guards, so you can safely assume support for 4.2.x and later. If you want anything further than that [i.e. member templates defined outside the body of the class, member template overloads, ...], you have to look to see what all of the supported compilers allow. If one or more of the currently supported compilers defines _RWSTD_NO_MEMBER_TEMPLATES, then you will likely have to work around the issue in any new code. If none of them define it, then some decision will have to be made if it is safe to assume support for other compilers or not. Travis Brad.
RE: Missing test results
The html page is only a summary. It doesn't show results for programs that run successfully. If you click the links for the actual build result files, you'll see that the results for the tests you're looking for are there. Travis -Original Message- From: Eric Lemings [mailto:[EMAIL PROTECTED] Sent: Fri 6/13/2008 2:44 PM To: dev@stdcxx.apache.org Subject: Missing test results I'm still noticing some tests not being reported in the nightly test results, particularly 21.string.exceptions and 22.locale.synopsis. How do I get these missing tests added to nightly testing? Thanks, Brad.
RE: _RWSTD_STATIC_ASSERT
Yes. Will fix. -Original Message- From: Eric Lemings [mailto:[EMAIL PROTECTED] Sent: Fri 6/13/2008 12:19 PM To: dev@stdcxx.apache.org Subject: _RWSTD_STATIC_ASSERT The macro is defined with one argument if no built-in static_assert is available but with two arguments if it is available. Should be defined with two arguments either way. Brad.
RE: remove_reference
Martin Sebor wrote: Eric Lemings wrote: -Original Message- From: Travis Vitek Sent: Thursday, June 12, 2008 4:18 PM To: Eric Lemings Subject: RE: remove_reference Eric Lemings ... I think you sorta missed my point. My point is that if the internal type traits do not provide any real added value, why bother with them? Say you have an internal class __rw_foo and a public class foo which derives from __rw_foo but is virtual identical, why have __rw_foo at all? Why not move everything in __rw_foo directly into foo? Sorry, I understood what you were getting at, I just didn't come right out and provide the answer you were looking for. Yes, we intend to use traits in the library implementation where we can take advantage of them for performance improvements. The example I provided above is just one of many situations that we may do so. Performance improvements...such as taking advantage of built-in compiler type traits? If that were the case, I could see the rationale for using internal type traits as a proxy for such optimization. So I guess there is SOME value after all. :) The original idea, IIRC, was to expose the implementation of the traits in the form of _RWSTD_XXX() macros to be used by the rest of our code, including the standard type traits template. Each macro would expand into either the compiler built-in for compilers that supported them or to our own __rw_xxx trait otherwise. The reason for this was to avoid paying a penalty in terms of increased compile times and keep the type_traits header free of unnecessary clutter when using the compiler-provided traits, as well as to avoid namespace pollution when using the traits. So I've managed to diverge from the original idea. This is almost funny considering all of the discussion that we had about the need for internal traits to inherit from __rw_integral_constant. Well, now that I've finally got the traits in subversion, I could go back and 'fix' this to compile out the implementation types when the necessary compiler support is not available. Something more like my original implementation. #ifndef _RWSTD_IS_POD template class _TypeT struct __rw_is_pod { enum { _C_value =_RWSTD_IS_TRIVIAL(_Type) _RWSTD_IS_STANDARD_LAYOUT(_Type) }; }; # define _RWSTD_IS_POD(T) _RW::__rw_is_podT::type #endif Martin
RE: remove_reference
Eric Lemings wrote: Hmm. So what's the benefit in providing internal type traits at all? Seems to me that they only serve to slow down compile times. Why not just break the public type traits into internal headers and include them all from the type_traits header? Or do we have some plans for the internal type traits that I'm unaware of? It is my understanding that the internal traits exist to avoid namespace pollution. Say we wanted to optimize std::uninitialized_fill for pod types. If we used std::is_pod, then the user would be able to use that type and possibly others without including type_traits. Honestly, I don't see this as a great benefit, but it is something that has been important to the implementation in the past. As for the argument of slowing down compile times, there has been some bickering about this in the past; should we put comments in the headers or should we be splitting up large headers into multiple small ones and should we coalesce multiple headers into one. I don't buy it unless someone has a reasonable testcase as evidence. Travis Brad. -Original Message- From: Travis Vitek Sent: Thursday, June 12, 2008 11:51 AM To: Eric Lemings Subject: RE: remove_reference Yes, and the internal ones don't inherit from integral_constantT,V, they inherit from __rw_integral_constantT,V [where applicable] Travis -Original Message- From: Eric Lemings Sent: Thursday, June 12, 2008 10:48 AM To: Travis Vitek Subject: RE: remove_reference So the only key difference is that they -- the internal type traits -- can be included by group rather than the whole? Brad. -Original Message- From: Travis Vitek Sent: Thursday, June 12, 2008 11:33 AM To: Eric Lemings Subject: RE: remove_reference They are intended to be exactly the same. They are used by the implementation of the public traits. -Original Message- From: Eric Lemings Sent: Thursday, June 12, 2008 10:27 AM To: Travis Vitek Subject: RE: remove_reference Anything especially that I need to be aware of when using the internal type traits? Or are they virtually the same as the public type traits? Brad. -Original Message- From: Travis Vitek Sent: Thursday, June 12, 2008 10:59 AM To: Eric Lemings Subject: RE: remove_reference If you wanted std::remove_reference, you'd have to include type_traits. That is where all of the standard traits are defined. If you want the internal trait _RW::__rw_remove_reference, you could still include type_traits if you wanted, or you could include rw/_meta_ref.h. I decided to break them down by their section in the standard. The remove_reference template is actually in meta.trans.ref, but that name would have been too long. I plan on submitting sometime this afternoon. I need to verify everything on gcc 4.3 again and that should be it. Travis -Original Message- From: Eric Lemings Sent: Thursday, June 12, 2008 9:12 AM To: Travis Vitek Subject: remove_reference Travis, Based on your latest version, which header would I include if I just wanted the std::remove_reference type modifier? Brad.
RE: static_assert config check
Martin Sebor wrote: Travis Vitek wrote: Eric Lemings wrote: How's this for a suitable configuration check for static_assert? // compile-only test static_assert (sizeof (char) == 1, impossible); template int I struct S { static_assert (I = 0, template parameter I must be non-negative); }; I've written an errily similar test already (pasted below) I think you should probably instantiate S somewhere and it might be a good idea put a line break before 'struct' so that your code conforms to our 'coding standards'. [...] It's probably overkill, but just as an FYI, to verify this works both ways the test would need to be negative, i.e., named NO_XXX, and write #define _RWSTD_NO_XXX to stdout if the negative assert failed to fire. So how exactly is the test supposed to write anything to stdout if it doesn't compile? If the expression of the static_assert is false, the program is ill-formed and the compiler is to emit a diagnostic. I'm looking at this and if I name the test NO_STATIC_ASSERT.cpp and it fails to compile, the macro _RWSTD_NO_STATIC_ASSERT wll be defined, so using the NO_ prefix doesn't really buy me anything. I don't think it would be right to make it so that if a NO_XXX test fails to compile the macro _RWSTD_NO_XXX will not be defined. The only way I see to ensure that static_assert is actually working both ways is to write two tests, one testing for passing conditions [STATIC_ASSERT_PASS.cpp], and the other testing for failing conditions [STATIC_ASSERT_FAIL.cpp]. Then we would define _RWSTD_NO_STATIC_ASSERT like so... #if!defined (_RWSTD_NO_STATIC_ASSERT_PASS) || defined (_RWSTD_NO_STATIC_ASSERT_FAIL) // STATIC_ASSERT_PASS.cpp failed to compile // STATIC_ASSERT_FAIL.cpp compiled without error # define _RWSTD_NO_STATIC_ASSERT #endif Is that overkill? Martin template int _N struct S { static_assert (0 _N, fail); }; template int _N void f () { static_assert (0 _N, fail); } int main () { S1 s1; f1(); static_assert (1, pass); return 0; }
RE: Empty member initializers
Eric Lemings wrote: Travis Vitek wrote: This all gets back to the discussion we were having a few weeks ago about which compiler features we should expect the compiler support for 4.3.x. I'm adding a Wiki page listing these compiler requirements but I can only think of one or two ATM. What else should be on this list? Well, I'd like to think that we could eliminate all of these. Without some of them them it becomes much more difficult or impossible to implement some of meta classes. _RWSTD_NO_CLASS_PARTIAL_SPEC _RWSTD_NO_BOOL I can live with keeping the following, but a modern compiler should really support these _RWSTD_NO_TYPENAME _RWSTD_NO_EXPLICIT _RWSTD_NO_EXPLICIT_ARG _RWSTD_NO_FRIEND_TEMPLATE _RWSTD_NO_FUNC_PARTIAL_SPEC _RWSTD_NO_NEW_FUNC_TEMPLATE_SYNTAX _RWSTD_NO_NEW_CLASS_TEMPLATE_SYNTAX _RWSTD_NO_INLINE_MEMBER_TEMPLATES /* not used att all */ _RWSTD_NO_NAMESPACE _RWSTD_NO_LONG_DOUBLE _RWSTD_NO_LONG_LONG _RWSTD_NO_WCHAR_T _RWSTD_NO_NATIVE_WCHAR_T Brad.
RE: static_assert config check
Eric Lemings wrote: Travis Vitek wrote: ... I've written an errily similar test already (pasted below) I like your test better except for two things. 1. Need a static assert at file scope similar to the one in main(). 2. Change main() to foo(). We don't need (nor want) to run the a program; just compile the source file (which is when static_assert's are supposed to fire). True on both counts. On a related note, we already have __rw_compile_assert [see rw/_defs.h], but it doesn't work at global or class scope. I provided an __rw_static_assert for use with type_traits in my original patch, but it didn't work outside of a template. I've got an updated version that will work in all cases. I'm thinking that I should replace the existing __rw_compile_assert with __rw_static_assert, and then define a macro _RWSTD_STATIC_ASSERT(Cond,Mesg) that uses static_assert if it exists, or falls back to ours as needed. Brad.
RE: An internal add_const_reference type trait
Eric Lemings wrote: Travis, According to our plans for type traits, is this how you would define an internal class template that combines the add_constT and add_referenceT type modifiers? #include rw/_type_traits.h _RWSTD_NAMESPACE (__rw) { template class _TypeT class __rw_add_const_ref { typedef _TYPENAME __rw_add_const_TypeT::type _ConstT; public: typedef _TYPENAME __rw_add_reference_ConstT::type type; }; } // namespace __rw It is really close. I'd probably make it a struct and if there was any complicated logic it would move into an impl struct to reduce clutter in the outer class. If you need the above trait, I should let you know that TR1 had add_reference, but C++0x replaces that with add_lvalue_reference and add_rvalue_reference. So it you should probably use the new names as we probably won't have an __rw_add_reference trait. #include rw/_typetraits.h _RWSTD_NAMESPACE (__rw) { template class _TypeT struct __rw_add_const_ref { typedef _TYPENAME __rw_add_lval_ref _TYPENAME __rw_add_const_TypeT::type ::type type; }; } // namespace __rw Also, it'd be nice if you jot down some of these plans for type traits on the C++0x Wiki http://wiki.apache.org/stdcxx/Cpp0x; e.g., header names, internal utilities, TODO work, etc. ;) Yes, I know. Given that discussion on the topic has died down I could actually document what we've arrived at. Thanks, Brad.
RE: type_traits progress
Eric Lemings wrote: Travis Vitek wrote: ... rw/_meta_other.h * __rw_enable_if * __rw_conditional What do you think of this? Another possibility to consider is grouping them all in a subdir of the include/rw directory; e.g., #include rw/meta/_cv.h. I figure some C++0x components will need multiple header files rather than one or two huge 100k files. It might make sense for such components to add a subdir within the include/rw directory. You're killing me! Just when I thought this thread had died... :) The discussion up to this point has led me to believe that the best thing to do is to throw all of the internal trait implementations into a single file and then separate out traits into their own files only as necessary. I _really_ don't like this as it makes for one _very_ long [probably 2000 lines] and messy header. It feels is very 'organic' and doesn't seem very well planned out at all. As I posted previously, I'd like to gather similar traits into their own files. Martin didn't seem very keen on this idea because there was no rationale for the proposed organization. There were no clear rules as to what to name the headers and what should be included in each of them. I'd love to create a rw/meta directory for all of the traits stuff. Unfortunately this isn't a scheme that we use for any of the other implementation files, so unless we can come up with an organization policy, I'm thinking we should probably stick with what we're doing. Brad.
RE: Empty member initializers
Eric Lemings wrote: From $TOPDIR/include/rw/_pair.h: 64 // 20.2.2, p2 65 pair () 66 #ifndef _RWSTD_NO_EMPTY_MEM_INITIALIZER 67 : first (/* lwg issue 265 */), second () { } 68 #else 69 // assumes types satisfy the CopyConstructible requirements 70 : first (first_type ()), second (second_type ()) { } 71 #endif // _RWSTD_NO_EMPTY_MEM_INITIALIZER Are empty member initializers something we still need to concern ourselves with? Is LWG issue 265 still pertinent? According to the defect, the resolution is in the current working paper, so I don't think you need to worry about it changing. I don't know of any modern compilers for which the EMPTY_MEM_INITIALIZER.cpp test would fail. This all gets back to the discussion we were having a few weeks ago about which compiler features we should expect the compiler support for 4.3.x. Thanks, Brad.
RE: Default BUILDTYPE and/or BUILDMODE?
Eric Lemings wrote: What is the default BUILDTYPE if it is not defined in the build (make) command? 11s Here are some values from $builddir/makefile.in when BUILDTYPE is not specified: CONFIG_H = gcc-4.1.1- BUILDTYPE = BUILDMODE = LIBBASE= std$(BUILDTYPE) Are these values correct? I haven't looked but do the docs say if BUILDTYPE (or BUILDMODE) is required? From section 5 of the README Note that exactly one of BUILDTYPE and BUILDMODE must be defined. This comment is not totally accurate from a user perspective. They are allowed to provide neither as indicated by the quote pasted below... Or what the default is? Again, from section 5 of the README The build-type argument is optional. When not specified a build type of 11s is assumed. If there isn't a default, I think we should establish one: shared, reentrant in all snapshots (i.e. all development) and release on all systems, wide builds on wide systems in snapshots and releases that support them, debug in snapshots, and optimized in releases. I only followed that sentence for the first 20 words or so. I don't understand what you mean when you refer to 'snapshots' and 'releases'. It sounds like you are proposing that the default be different based on who is doing the build? Thanks, Brad.
RE: string concatenation trouble under Nanodesktop PSPE
pegasus2000 wrote: I've identified a problem in your library. In the file: .\include\rw\_defs.h at row 455 #if !defined(_RWSTD_NEW_CAPACITY_RATIO) // using long doubles to eliminate bogus warnings on g++ 2.95.2/sparc // (-W -O2/3 only): warning: overflow on truncation to integer # define _RWSTD_NEW_CAPACITY_RATIO 1.618L #endif #if !defined(_RWSTD_MINIMUM_STRING_CAPACITY) # define _RWSTD_MINIMUM_STRING_CAPACITY 128U #endif #if !defined(_RWSTD_STRING_CAPACITY_RATIO) # define _RWSTD_STRING_CAPACITY_RATIO 1.618L #endif Well, some embedded processors have troubles with long double type. This is the case of PSPE Emulated Processor. So, I've modified the value to 1.618F and it works. The port proceeds well. Each day I improve the compatibility. I've signalled this to you because I thought that it should be useful for you. Thanks! I suggest you to insert and #ifdef for embedded processors. Actually, Farid made a change for 4.2.0 that eliminated the use of floating point math for capacity calculations. You can find information about that change in Jira and in Subversion http://issues.apache.org/jira/browse/STDCXX-226 http://svn.apache.org/viewvc?view=revrevision=605548 Travis
RE: svn commit: r663757 - in /stdcxx/branches/4.3.x/etc/config/src: RVALUE_REFERENCES.cpp VARIADIC_TEMPLATES.cpp
Martin Sebor wrote: + * + * Copyright 1999-2008 Rogue Wave Software, Inc. The starting year cannot be before the code was written. Martin Another mistake I'll remember to never make. Fixed in http://svn.apache.org/viewvc?view=revrevision=664036.
RE: svn commit: r663377 - in /stdcxx/branches/4.2.x: include/valarray src/valarray.cpp tests/numerics/26.class.gslice.cpp tests/regress/26.valarray.sub.stdcxx-955.cpp
Martin Sebor wrote: [EMAIL PROTECTED] wrote: Author: vitek Date: Wed Jun 4 14:48:36 2008 New Revision: 663377 [...] Modified: stdcxx/branches/4.2.x/src/valarray.cpp URL: http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/src/valarray .cpp?rev=663377r1=663376r2=663377view=diff === === --- stdcxx/branches/4.2.x/src/valarray.cpp (original) +++ stdcxx/branches/4.2.x/src/valarray.cpp Wed Jun 4 14:48:36 2008 @@ -41,8 +41,12 @@ { _RWSTD_SIZE_T __n = _C_length.size (); -while (__n _C_r_length [__n - 1] == _C_length [__n - 1] - 1) ---__n; +for (/**/; __n; --__n) +{ The brace should be on the line above :) Blarg! +if ( _C_length [__n - 1] + _C_r_length [__n - 1] != _C_length [__n - 1] - 1) Also, I wonder if it might help generate more optimal code to write the loop like so: while (__n) { --__n; if (_C_length [n] _C_r_length [n] != _C_length [n] - 1) break; } It is possible it would help generate better code, but this code changes the behavior of the loop. We now decrement __n before checking the condition; when we break __n will be off-by-one. Obviously we can deal with that by incrementing __n before the break. I'll take a quick look at some disassembly and decide if it is worth making the change or not. The duplicate check for (0 == n) below could probably be hoisted into the loop for even more optimal code, something like this: for ( ; ; ) { if (0 == n) { _C_reset = true; break; } --n; if (_C_length [n] _C_r_length [n] != _C_length [n] - 1) break; } +break; +} if (0 == __n) { _C_reset= true;
RE: integral_constant (Was RE: New config macros for 4.3.x)
Eric Lemings wrote: Hey Travis, how confident are you in your std::integral_constant class template? Is that ready to be checked in? If so, I need it to implement std::tuple_size class template. I've committed a type_traits header that has only an implementation of integral_constantT,V and the required typedefs true_type and false_type. I also added the test. See [r664141|http://svn.apache.org/viewvc?rev=664141view=rev]. Travis Brad. -Original Message- From: Travis Vitek [mailto:[EMAIL PROTECTED] Sent: Thursday, June 05, 2008 3:56 PM To: dev@stdcxx.apache.org Subject: RE: New config macros for 4.3.x I'll commit them right away. I've updated them taking Martin's feedback into consideration. Travis -Original Message- From: Martin Sebor [mailto:[EMAIL PROTECTED] On Behalf Of Martin Sebor Sent: Thursday, June 05, 2008 2:09 PM To: dev@stdcxx.apache.org Subject: Re: New config macros for 4.3.x Eric Lemings wrote: Unless someone can think of a reason not to do this, I was wondering if we couldn't go ahead and commit the new config tests for r-value referenes and variadic templates that Travis wrote into the 4.3.x branch? We'll almost certainly need these checks in 4.3.x. Sounds reasonable to me. Martin Thanks, Brad.
RE: Experiment with variadic templates
Eric Lemings wrote: Consider the following little program: --- [...] #include cstddef template class... TypesT struct tuple_size : integerstd::size_t, sizeof... (TypesT) { }; #include iostream int main () { typedef tuple tuple0; std::cout tuple_size tuple0 ::value std::endl; typedef tuple int tuple1; std::cout tuple_size tuple1 ::value std::endl; return 0; } --- Compiling with gcc-4.3 using the -std=gnu++0x option (gcc-4.3.1 was just released BTW), I get the following output: 1 1 The first line should print '0', shouldn't it? Or no? No. The output is as expected. Your tuple_size template doesn't give the size of the tuple, it gives the number of arguments in the template parameter pack named TypesT. In both cases the number of template arguments provided is exactly 1. If you want thenumber of elements in the tuple, you need to get at them through the tuple. // this is called if we are not dealing with a tuple template class... _Types struct tuple_size : integral_constant_RWSTD_SIZE_T, 0 { }; template class... _Types struct tuple_size tuple_Types... : integral_constant_RWSTD_SIZE_T, sizeof... (_Types) { // this is used when the template parameter is a tuple. // it strips the tuple away and accesses the template // parameter pack. }; Brad.
RE: cin under Nanodesktop PSPE
pegasus2000 wrote: We are working on your library and I can say that it gives already good results under PSP. Under PSPE there are troubles, but we are solving them. Per esempio, the trouble with io_base:init:init was derived by the fact that, under PSPE, the global constructors and destructors weren't initialized by the system at startup. A dedicated module under PSP does this now. I have another trouble. Consider the following routine: [...] I have seen that cin *p has a different behaviour that scanf. And, in fact, when I press the ENTER key on the virtual keyboard of the PSP, cin doesn't transfer the value in *p, and the message I'm here isn't printed on the screen. Can you say me what is the routine that manages cin ? So, I can patch it for nd. The object `cin' is of type `std::istream'. The underlying stream buffer type is `std::filebuf'. At the lowest level the filebuf is going to call `__rw_fread' which defers to `fread' or `read' to read data from stdin. Travis
RE: string concatenation trouble under Nanodesktop PSPE
pegasus2000 wrote: Consider the following program: #include nanodesktop.h // of the string class which is part of the // Standard Template Library #include string #include cstdlib #include iostream using namespace std; // concat - return the concatenation of two strings string concat(string s1, string s2) { return s1 + s2; } int main(int argc, char* pArgs[]) { ndInitSystem (); // create a string that is the sum of two smaller strings cout string1 + string2 = concat(string1 , string2) endl; } The program crashes when executes s1+s2. I need the stack trace at that point, so I can check in which routine the trouble is localized. I have no way to tell where the program is crashing so I can't really give you much more information. All I can tell you is that most of the string functionality is implemented in `include/string' and `include/string.cc'. But you already knew that, right? BTW, it seems to me that it would make debugging much simpler if you had built a debug version of the libraries for the PC. Then you could take the code that fails on the PSP and step into it on the PC. Travis
RE: svn commit: r662858 [1/3] - in /stdcxx/branches/4.2.x/tests: algorithms/ containers/ diagnostics/ include/ intro/ iostream/ iterators/ localization/ numerics/ regress/ self/ src/ strings/ support/
Author: elemings Date: Tue Jun 3 12:09:49 2008 New Revision: 662858 URL: http://svn.apache.org/viewvc?rev=662858view=rev Log: 2008-06-03 Eric Lemings [EMAIL PROTECTED] STDCXX-810 * tests/include/alg_test.h, tests/include/environ.h, tests/include/testdefs.h tests/include/any.h, tests/include/driver.h, tests/include/file.h, tests/include/valcmp.h, tests/include/cmdopt.h: Renamed using `rw_' prefix. * tests/include/21.strings.h, tests/include/23.list.h, tests/include/23.containers.h: Replaced `21.' and `23.' prefixes with `rw_' prefix. Also changed `list' to `lists' since the other two headers are also plural. * Updated #include directives where necessary in all test driver and test suite header and source files (too many to list). This change appears to have broken nightly builds for 4.2.x on all platforms. The portions of the test suite that have not yet been migrated over to Apache depend on the names of the old headers [testdefs.h, file.h, environ.h, valcmp.h...] and this causes the test library to fail to compile. http://stdcxx.apache.org/builds/4.2.x/hpux-11.31-ia64-6.16.html http://stdcxx.apache.org/builds/4.2.x/linux_redhat_el-5.0-em64t-icc-9.1. html http://stdcxx.apache.org/builds/4.2.x/linux_redhat_el-4.4-amd64-gcc-3.4. 6.html http://stdcxx.apache.org/builds/4.2.x/linux_redhat_el-5.0-em64t-gcc-4.3. 0.html http://stdcxx.apache.org/builds/4.2.x/solaris-10-amd64-sunpro-5.9.html The build results on windows may look like there are no failures, but they are experiencing the same problems... Compiling... value.cpp [...] test.cpp $(TOPDIR)\tests\include\test.h(25) : fatal error C1083: Cannot open include file: 'file.h': No such file or directory string.cpp $(TOPDIR)\tests\include\test.h(25) : fatal error C1083: Cannot open include file: 'file.h': No such file or directory singleton.cpp [...] dbgprint.cpp $(TOPDIR)\tests\src\dbgprint.h(27) : fatal error C1083: Cannot open include file: 'testdefs.h': No such file or directory ctype.cpp [...] 21.strings.cpp Generating Code... --- .rwtest - 3 error(s), 1 warning(s) Travis
RE: svn commit: r662858 [1/3] - in /stdcxx/branches/4.2.x/tests: algorithms/ containers/ diagnostics/ include/ intro/ iostream/ iterators/ localization/ numerics/ regress/ self/ src/ strings/ support/
Eric Lemings wrote: Eric Lemings wrote: Travis Vitek wrote: This change appears to have broken nightly builds for 4.2.x on all platforms. The portions of the test suite that have not yet been migrated over to Apache depend on the names of the old headers [testdefs.h, file.h, environ.h, valcmp.h...] and this causes the test library to fail to compile. Thanks. I'll update the necessary tests in Perforce. I fixed all of these compile errors save one. I'm not sure what to make of it: Awesome. I think we're all good now. tests/include/test.h:80:30: error: rw/rwtest/rwtest.h: No such file or directory I can find no such rwtest.h header in Subversion or Perforce. I must be building the test suite wrong somehow. Any ideas? I see the file in perforce in the //rwtest depot. I believe that the nightly build system pulls in files from this location. Brad.
Issues with the build result pages
There appears to be some kind of error with the x-platform build result pages for 4.3.x and trunk. On 4.2.x the page has only the latest build results as I'd expect. The 4.3.x and trunk pages look like the new results are being placed at the bottom. If you look at the actual html, you'll see that the page actually contains multiple html/html blocks, so I'm guessing that something that is supposed to delete or overwrite the file is just appending. http://stdcxx.apache.org/builds/4.2.x/ http://stdcxx.apache.org/builds/4.3.x/ http://stdcxx.apache.org/builds/trunk/ Another issue is the windows build results on 4.2.x. Many of the columns appear to contain data from the execution times instead of a string representing the exit code of the process or the failed assertions. http://tinyurl.com/5wd3kr [4.2.x] http://tinyurl.com/59kpfq [4.3.x] http://tinyurl.com/63nbm3 [trunk] Travis
RE: Issues with the build result pages
-Original Message- From: Martin Sebor [mailto:[EMAIL PROTECTED] On Behalf Of Martin Sebor Sent: Thursday, June 05, 2008 3:53 PM To: dev@stdcxx.apache.org Subject: Re: Issues with the build result pages Travis Vitek wrote: There appears to be some kind of error with the x-platform build result pages for 4.3.x and trunk. On 4.2.x the page has only the latest build results as I'd expect. The 4.3.x and trunk pages look like the new results are being placed at the bottom. If you look at the actual html, you'll see that the page actually contains multiple html/html blocks, so I'm guessing that something that is supposed to delete or overwrite the file is just appending. http://stdcxx.apache.org/builds/4.2.x/ http://stdcxx.apache.org/builds/4.3.x/ http://stdcxx.apache.org/builds/trunk/ Looks like the fix for this hasn't been merged yet: http://svn.apache.org/viewvc?view=revrevision=661075 Oh, I should have realized that this was the fix. I think that we are still on for merging from 4.2.x to 4.3.x on a weekly basis, so this change will be propigated soon. Another issue is the windows build results on 4.2.x. Many of the the columns appear to contain data from the execution times instead of a string representing the exit code of the process or the failed assertions. http://tinyurl.com/5wd3kr [4.2.x] http://tinyurl.com/59kpfq [4.3.x] http://tinyurl.com/63nbm3 [trunk] I saw it this morning but haven't had time to investigate what's causing it. I'm traveling the next two weeks and I'm not sure I'll get around to it until I get back. It's most likely a problem in the xcomp.awk script if you want to look into it. The way to test it is to download a few logs and running xbuildgen on them like so: (mkdir -p builds/logs cd builds/logs wget http://stdcxx.apache.org/builds/4.2.x/logs/win_xp-1-em64t-msvc- 9.0-12d-win32-663410-log.gz.txt http://stdcxx.apache.org/builds/4.2.x/logs/win_xp-1-em64t-msvc- 9.0-12D-win32-663410-log.gz.txt PATH=~/stdcxx-4.2.x/bin:$PATH ~/stdcxx-4.2.x/bin/xbuildgen -s -o../test.html *-log.gz.txt) This assumes you have a local copy of 4.2.x in stdcxx-4.2.x. Awesome. I'll take a few minutes to look at this problem tomorrow. Martin
RE: [jira] Commented: (STDCXX-901) 26.class.gslice test fails
Martin Sebor commented on STDCXX-901: - This is from the binary incompatible rewrite of {{valarray}} that I've been mentioning for eons (I should finally commit it on trunk). If it fixes this bug it might spark an idea for a compatible fix... Martin, I'm struggling with what appears to a discrepancy between the standard and the two implementations I'm testing with. According to lib.gslice.cons, a default constructed slice specifies no elements. Section lib.class.gslice describes gslices that do have lengths and strides. The example it gives is shown here start = 3 length = { 2, 4, 3 } stride = { 19, 4, 1 } k = 3 + (0,1) * 19 + (0,1,2,3) * 4 + (0,1,2) * 1 i0, i1, i2, k (0, 0, 0, 3 ) // = 3 + (0) * 19 + (0) * 4 + (0) * 1 (0, 0, 1, 4 ) // = 3 + (0) * 19 + (0) * 4 + (1) * 1 (0, 0, 2, 5 ) // = 3 + (0) * 19 + (0) * 4 + (2) * 1 (0, 1, 0, 7 ) // = 3 + (0) * 19 + (1) * 4 + (0) * 1 (0, 1, 1, 8 ) // = 3 + (0) * 19 + (1) * 4 + (1) * 1 (0, 1, 2, 9 ) // = 3 + (0) * 19 + (1) * 4 + (2) * 1 (0, 2, 0, 11) // = 3 + (0) * 19 + (2) * 4 + (0) * 1 (0, 2, 1, 12) // = 3 + (0) * 19 + (2) * 4 + (1) * 1 (0, 2, 2, 13) // = 3 + (0) * 19 + (2) * 4 + (2) * 1 (0, 3, 0, 15) // = 3 + (0) * 19 + (3) * 4 + (0) * 1 (0, 3, 1, 16) // = 3 + (0) * 19 + (3) * 4 + (1) * 1 (0, 3, 2, 17) // = 3 + (0) * 19 + (3) * 4 + (2) * 1 (1, 0, 0, 22) // = 3 + (1) * 19 + (0) * 4 + (0) * 1 (1, 0, 1, 23) // = 3 + (1) * 19 + (0) * 4 + (1) * 1 ... (1, 3, 2, 36) // = 3 + (1) * 19 + (3) * 4 + (2) * 1 Assume for a moment that we have the following gslice... start = 0 length = { 0 } stride = { 0 } So the indices specified by this slice should be k = 0 + () * 0 i0, i1, k (0, (), 0) // = 0 + () * 0 So this slice should be a view of 0th element in a given array. I wrote a quick testcase to make sure that I was understanding this gslice stuff correctly. It creates a valarray and a slice from strings, then assigns 0 to the resulting gslice_array. This zeros out all elements specified by the slice. Here is the set of testcases... int main () { // + length // |+- stride // || // vv test ([EMAIL PROTECTED], 0, , ); test ([EMAIL PROTECTED], 0, 0, 0); test ([EMAIL PROTECTED], 0, 1, 1); test ([EMAIL PROTECTED], 0, 1, 2); test ([EMAIL PROTECTED], 0, 1, 3); test ([EMAIL PROTECTED], 0, 2, 1); test ([EMAIL PROTECTED], 0, 2, 2); test ([EMAIL PROTECTED], 0, 3, 3); test ([EMAIL PROTECTED], 0, 2, 3); test ([EMAIL PROTECTED], 0, 5, 1); test ([EMAIL PROTECTED], 1, 5, 1); test ([EMAIL PROTECTED], 1, 5,2, 1,2); test ([EMAIL PROTECTED], 0, 0,0,0, 1,2,3); return 0; } And here is the output I get with the Dinkum and gnu implementations... {1,1,1,1,1,1,1,1,1,1}[0,{},{}] = 0 = = {1,1,1,1,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{0},{0}] = 0 = {1,1,1,1,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{1},{1}] = 0 = {0,1,1,1,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{1},{2}] = 0 = {0,1,1,1,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{1},{3}] = 0 = {0,1,1,1,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{2},{1}] = 0 = {0,0,1,1,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{2},{2}] = 0 = {0,1,0,1,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{3},{3}] = 0 = {0,1,1,0,1,1,0,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{2},{3}] = 0 = {0,1,1,0,1,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{5},{1}] = 0 = {0,0,0,0,0,1,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[1,{5},{1}] = 0 = {1,0,0,0,0,0,1,1,1,1} {1,1,1,1,1,1,1,1,1,1}[1,{5,2},{1,2}] = 0 = {1,0,0,0,0,0,0,0,1,1} {1,1,1,1,1,1,1,1,1,1}[0,{0,0,0},{1,2,3}] = 0 = {1,1,1,1,1,1,1,1,1,1} The STLPort and RW implementations both get stuck in an infinite loop on the second testcase, so I'm pretty sure that they're broken. I can't find anything in the standard that says this would be unspecified or undefined behavior and I don't see anything that calls this out as a special case. This leads me to believe that this is a bug in both implementations and I should take it into consideration when applying any fix. Travis
RE: [jira] Commented: (STDCXX-901) 26.class.gslice test fails
Okay, I have a fix. It isn't as pretty as I'd like it to be, but it is forward and backward binary compatible. I'm attaching the patch to the issue, which you can find by clicking the link below. Please review when you have a chance. http://issues.apache.org/jira/secure/attachment/12383346/stdcxx-901.patc h Note that I left some commented references to a new inline method gslice::is_empty(). If I submit the fix to 4.2.x I plan to remove these lines. When the fix goes to 4.3.x I'd like to use the clean solution which allows me to eliminate the friendship and direct member access. I also realize that the test is currently incomplete. I will obviously be working to finish up the test before submitting the patch. Travis
RE: [jira] Updated: (STDCXX-955) infinite loop or out of bound access when slicing valarray
Travis Vitek updated STDCXX-955: Attachment: stdcxx-955.patch {noformat} 2008-06-03 Travis Vitek [EMAIL PROTECTED] STDCXX-955 * include/valarray (gslice::ind_numb): Correctly calculate index count when the length array contains a zero. * src/valarray.cpp (next_ind): Correctly calculate next index when the length array contains a zero. * tests/numerics/26.class.gslice.cpp (make_array): Update to handle empty strings or other poorly formatted input. (get_array_size): Correctly calculate index count when the slice has a size array that contains a zero. (next_index): Correctly calculate next index when the length array contains a zero. (test_gslice): Remove unnecessary linefeed from assertion. (run_test): Update degenerate testcase to match comment. {noformat} So I have one tiny issue with this fix that I should bring up before I submit it. The function gslice::ind_numb() is inline and gslice::next_ind() is not. The functions that use ind_numb() are listed below. valarrayT::operator[](const gslice) const valarrayT::valarray(const gslice_arrayT) valarrayT::operator=(const gslice_arrayT) The issue is that these functions use ind_numb() to decide how big an array to allocate, and then they use next_ind() to iterate over those elements assigning values to each of them. So if ind_numb() returns 4, but the iteration terminates after just 2 passes, then there would be 2 elements in the array that are probably not supposed to be there. If the user builds with 4.2.2 headers and links a 4.2.1 library, they will get the same behavior as they did with 4.2.1. Namely their application will hang or crash [under conditions from stdcxx-995] because the gslice iteration code would not contain the fix. If an application built with 4.2.1 linked the 4.2.2 library it would also crash, most likely because the allocated array would have 0 elements but the gslice iteration would try to allow multiple elements to be written. The same app would already crash or hang when linking the 4.2.1 library. So I'm pretty sure that this change is suitable for 4.2.2 as I can't envision a scenerio where it would cause any new problems for the user. Can anyone else? If not I'll submit this change to 4.2.x tomorrow morning. Travis
RE: svn commit: r661873 - /stdcxx/branches/4.2.x/tests/regress/18.limits.traps.stdcxx-624.cpp
-Original Message- From: Martin Sebor [mailto:[EMAIL PROTECTED] On Behalf Of Martin Sebor Sent: Saturday, May 31, 2008 3:18 PM To: dev@stdcxx.apache.org Subject: Re: svn commit: r661873 - /stdcxx/branches/4.2.x/tests/regress/18.limits.traps.stdcxx-624.cpp [EMAIL PROTECTED] wrote: Author: vitek Date: Fri May 30 14:24:06 2008 New Revision: 661873 URL: http://svn.apache.org/viewvc?rev=661873view=rev Log: 2008-05-30 Travis Vitek [EMAIL PROTECTED] STDCXX-833 * tests/regress/18.limits.traps.stdcxx-624.cpp: Add special handling for divide by zero on windows. [...] @@ -66,14 +76,21 @@ if (std::numeric_limitsint::traps) std::signal (SIGFPE, handle_FPE); +bool trapped = false; + // if this traps (generates SIGFPE), verify (in the signal handler) // that integer arithmetic is expected to trap -result = non_zero / zero; -result += non_zero % zero; +TRY { +result = non_zero / zero; +result += non_zero % zero; +} +EXCEPT (1) { +trapped = true; +} // if we get this far, verify that integer arithmetic is known not // to trap Since after this change it's no longer true that the assertions below verify that integer arithmetic does not trap the comment above needs to be updated. (The comment about SIGFPE above could also stand to be updated to explain that the handler is never entered on Windows. Committed in r662468 [http://svn.apache.org/viewvc?view=revrevision=662468] Travis Martin -assert (!std::numeric_limitsint::traps); +assert (trapped == std::numeric_limitsint::traps); (void)result;
RE: [jira] Created: (STDCXX-948) Define substitution variable for current year and automatically replace in all copyright notices.
Eric Lemings wrote: Key: STDCXX-948 URL: https://issues.apache.org/jira/browse/STDCXX-948 Project: C++ Standard Library Issue Type: Sub-task Components: Configuration Reporter: Eric Lemings Priority: Minor Define a substitution variable during configuration (i.e. add {{AC_SUBST(STDCXX_YEAR, `date +%Y`)}} to {{configure.ac}}) and replace this variable in all copyright notices (i.e. change {{Copyright 1994-2008 Rogue Wave Software, Inc.}} to {{Copyright [EMAIL PROTECTED]@ Rogue Wave Software, Inc.}}) -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. I believe that the copyright dates need to be correct for the files by the time they are received by the user. If this is correct, then the substitution would have to happen when the files are submitted to subversion, not after the user has run the configure step. One solution is to write a commit hook that verifies the copyright date is accurate for files as they are committed. This has the disadvantage that the copyrights aren't updated for files that aren't touched. Another solution would be to have a script that runs periodically [say every 24 hours] that checks out the head of a given branch, scans for and updates the copyright, and then commits the result. Travis
RE: type_traits progress
Martin Sebor worte: Eric Lemings wrote: Martin Sebor wrote: Eric Lemings wrote: template class T, T v struct __rw_integral_constant { static const T value = v; typedef T value_type; typedef integral_constantT,v type; } In all cases I've seen, `type' refers to type of self for identity properties. This typedef would not hold up the identity property. IIUC, for every specialization X of integral_constant, this must hold: is_sameX, typename X::type::value == true With integral_constant derived from __rw_integral_constant the condition would fail. Not if it defined its own `type'. template class T, T v struct integral_constant: __rw_integral_constantT, v { typedef integral_constantT, v type; }; Good point! This would effectively break the problematic dependency, wouldn't it, Travis? Yes, it does allow us to use the name 'type' in both contexts. Martin
RE: type_traits progress
Martin Sebor wrote: Travis Vitek wrote: [...] On a related note, I wonder if it would make sense to consolidate some of the implementation headers that we don't expect to be useful in the rest of the library on their own (e.g., all the ctor headers/traits). I think it would. I'd like to consolidate these a little further. I'd like to either put them in headers by category, something like this [those not mentioned would go into their own header]. My initial thought was to group them based on how they are likely to be used in the rest of the library. Another option would be to follow the breakdown used by the standard. Your organization doesn't seem to fall into either of these two categories. What was your rationale for it? I'm just grouping closely related traits. rw/_meta_arr.h * __rw_rank * __rw_extent * __rw_is_array * __rw_remove_extent * __rw_remove_all_extents As an example, the array traits above are all closely related and their implementations are similar. There are five traits, and those traits span three sections of the standard. I'm open to doing some type of grouping, we just need to understand how we want to group them and then how we want to name the files. * Do the trait member (e.g., _C_type, _C_value) need to be privatized or would it make more sense to use the required names? I'm not sure what you're saying here. The types in the public interface all have the required names [from the base integral_constant template]. Everything else is an internal class, and I thought that we always needed to use privatized names for internal classes exposed in the headers. Using names consistent with those in the public interface doesn't buy us anything significant that I can think of, and there is no requirement that I know of saying we should. [snip] One reason why I asked the question was that if we derived the standard traits from the implementation-defined ones we wouldn't need to re-declare these members. (I now see that we don't use derivation). We're not allowed to. In all cases the public type is required to to inherit 'directly or indirectly' from integral_constantT,V. Right. That could be another wrinkle. Our traits won't work with generic code that takes integral_constantT, V by reference. I don't really see the motivation, but it is obvious that the committee thought it was important for the standard traits to do so, so we should probably follow suit in our internal implementation. If we did decide to do this then we would probably want our own write __rw_integral_constant and use that internally to avoid namespace pollution? Then I'd assume we'd want something like the following example for is_const... template class T, T v struct __rw_integral_constant { static const T value = v; typedef T value_type; typedef integral_constantT,v type; }; template class T struct __rw_is_const_impl { enum { _C_value = 0 }; }; template class T struct __rw_is_const_implconst T { enum { _C_value = 1 }; }; template class T struct __rw_is_const : __rw_integral_constantbool, __rw_is_const_implT::_C_value { }; template class T, T v struct integral_constant : __rw_integral_constantT,v { }; template class T struct is_const : integral_constantbool, __rw_is_constT::value { }; Another, and probably far more important reason for keeping the names of the members the same, to make our implementation traits look and feel like standard traits, i.e., conform to the traits requirements. Otherwise the rest of our library won't be able to easily use the private traits. But this should only be an issue if we are passing around traits as template parameters, right? Right. All of the scenerios I can think of we would be using __rw_enable_if or specialization on non-type template parameters. Can you think of any case where the name of the member would be important? I searched the latest draft standard to see if traits were being used anywhere in the spec but didn't get any hits. I hadn't thought too deeply about how the traits could be used, but I have used traits outside of enable_if. I think its should be easy to contrive code that wouldn't work with our approach. Let me try: // transforms T if it satisfies PropertyT // by applying TransformerT, otherwise leaves // T unchanged: template class T, template class Property, template class Transformer struct TransformIf; Yes, if we go with the above approach then this problem just disappears for any trait inheriting from __rw_integral_constant. For the other types I can just expose the names that the standard defines. I'm okay with that if you think that the motivation is there. Martin
RE: type_traits progress
Martin Sebor wrote: Travis Vitek wrote: [...] Right. That could be another wrinkle. Our traits won't work with generic code that takes integral_constantT, V by reference. I don't really see the motivation, but it is obvious that the committee thought it was important for the standard traits to do so, so we should probably follow suit in our internal implementation. Can you think of a reason why this 'feature' would be important? If we did decide to do this then we would probably want our own write __rw_integral_constant and use that internally to avoid namespace pollution? Then I'd assume we'd want something like the following example for is_const... Yes, I think this is close to what we want. The only thing that bugs me about it is... template class T, T v struct __rw_integral_constant { static const T value = v; typedef T value_type; typedef integral_constantT,v type; ...this backward dependency on integral_constant, but I don't see how to break it without template typedefs. I don't think there's a compiler out there that supports them yet. Actually, this was originally a typo on my part, but I do see where this is going. I haven't read about template typedefs, but it seems that there would be a serious problem caused by the cyclic dependency. }; I hadn't thought too deeply about how the traits could be used, but I have used traits outside of enable_if. I think its should be easy to contrive code that wouldn't work with our approach. Let me try: // transforms T if it satisfies PropertyT // by applying TransformerT, otherwise leaves // T unchanged: template class T, template class Property, template class Transformer struct TransformIf; Yes, if we go with the above approach then this problem just disappears for any trait inheriting from __rw_integral_constant. For the other types I can just expose the names that the standard defines. I'm okay with that if you think that the motivation is there. I'm not sure the contrived example I gave qualifies as a motivating use case but it is a use case nonetheless. That said, I don't think consistency with other uglified names is a compelling enough reason for us to dismiss even this contrived use case. I'm starting to think that the above example is not motivating at all. There is no reason that any of our library code would ever need to use the public types because those types are just alternate names for the internal implmentation types. If we are writing code to be used in other parts of our implementation, then we would always use the internal _C_ names. Martin
RE: type_traits progress
Martin Sebor wrote: Travis Vitek wrote: If this is the case I may opt to merge the headers. i.e. _rw_has.h I'd get rid of the _rw prefix and abbreviate the names. My example was flawed. None of the header names begin with the _rw prefix. E.g., use ctor instead of constructor etc. In fact, I wouldn't be at all upset if we abbreviated the names of some the private traits as well, e.g., truncate __rw_add_lvalue_reference to __rw_add_lval_ref or something similar). Not just to spare us the typing a few extra characters but also to reduce the sizes of symbol tables generated for specializations involving these critters (FYI: this was bad enough in C++ 98 that the IA64 ABI put in special cases for the most egregious symbols: std::string and std::wstring). I'm all for cutting down the length of the names of the internal classes. I'll do this in the next pass. On a related note, I wonder if it would make sense to consolidate some of the implementation headers that we don't expect to be useful in the rest of the library on their own (e.g., all the ctor headers/traits). I think it would. I'd like to consolidate these a little further. I'd like to either put them in headers by category, something like this [those not mentioned would go into their own header]. rw/_meta_cv.h * __rw_add_const * __rw_add_volatile * __rw_add_cv * __rw_is_const * __rw_is_volatile * __rw_remove_const * __rw_remove_volatile * __rw_remove_cv rw/_meta_trivial.h * __rw_is_trivial * __rw_has_trivial_ctor * __rw_has_trivial_copy * __rw_has_trivial_assign * __rw_has_trivial_dtor rw/_meta_nothrow.h * __rw_has_nothrow_ctor * __rw_has_nothrow_copy * __rw_has_nothrow_assign * __rw_has_nothrow_dtor rw/_meta_sign.h * __rw_is_signed * __rw_is_unsigned * __rw_make_signed * __rw_make_unsigned rw/_meta_arr.h * __rw_rank * __rw_extent * __rw_is_array * __rw_remove_extent * __rw_remove_all_extents rw/_meta_ptr.h * __rw_add_pointer * __rw_remove_pointer * __rw_is_pointer rw/_meta_ref.h * __rw_is_lval_ref * __rw_is_rval_ref * __rw_is_ref * __rw_add_lval_ref * __rw_add_rval_ref rw/_meta_member.h * __rw_is_mem_ptr * __rw_is_mem_obj_ptr * __rw_is_mem_fun_ptr rw/_meta_align.h * __rw_aligned_storage * __rw_aligned_union rw/_meta_decay.h * __rw_decay rw/_meta_other.h * __rw_enable_if * __rw_conditional What do you think of this? * Do the trait member (e.g., _C_type, _C_value) need to be privatized or would it make more sense to use the required names? I'm not sure what you're saying here. The types in the public interface all have the required names [from the base integral_constant template]. Everything else is an internal class, and I thought that we always needed to use privatized names for internal classes exposed in the headers. Using names consistent with those in the public interface doesn't buy us anything significant that I can think of, and there is no requirement that I know of saying we should. [snip] One reason why I asked the question was that if we derived the standard traits from the implementation-defined ones we wouldn't need to re-declare these members. (I now see that we don't use derivation). We're not allowed to. In all cases the public type is required to to inherit 'directly or indirectly' from integral_constantT,V. Another, and probably far more important reason for keeping the names of the members the same, to make our implementation traits look and feel like standard traits, i.e., conform to the traits requirements. Otherwise the rest of our library won't be able to easily use the private traits. But this should only be an issue if we are passing around traits as template parameters, right? All of the scenerios I can think of we would be using __rw_enable_if or specialization on non-type template parameters. Can you think of any case where the name of the member would be important? Travis