RE: static_assert config check
> -Original Message- > From: Eric Lemings [mailto:[EMAIL PROTECTED] > Sent: Thursday, June 12, 2008 4:37 PM > To: dev@stdcxx.apache.org > Subject: RE: static_assert config check > > > > > -Original Message- > > From: Travis Vitek [mailto:[EMAIL PROTECTED] > > Sent: Thursday, June 12, 2008 4:00 PM > > To: dev@stdcxx.apache.org > > Subject: 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 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? > > Or...you could run the negative test _first_ and if that fails (i.e. > does not fire as assertion), run the positive test which will produce > _RWSTD_NO_STATIC_ASSERT only if one or both tests failed. Ehh, to clarify a bit: STATIC_ASSERT_FAIL.cpp: static_assert (false, "Grep for this exact text in the compiler diagnostics"); STATIC_ASSSERT.cpp: (Same as Travis' static assert test posted earlier.) In pseudo-script: compile the negative test if the compile command succeeds, {echo "#define _RWSTD_NO_STATIC_ASSERT" >>$BUILDDIR/include/config.h} else grep the compiler diagnostic output for the text in the static_assert statement if the text is found in the compiler output, compile the STATIC_ASSERT.cpp if the compile command fails, {echo "#define _RWSTD_NO_STATIC_ASSERT" >>$BUILDDIR/include/config.h} endif endif endif I think I got that right. :P Brad.
RE: remove_reference
> -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. :) Brad.
RE: static_assert config check
> -Original Message- > From: Travis Vitek [mailto:[EMAIL PROTECTED] > Sent: Thursday, June 12, 2008 4:00 PM > To: dev@stdcxx.apache.org > Subject: 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 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? Or...you could run the negative test _first_ and if that fails (i.e. does not fire as assertion), run the positive test which will produce _RWSTD_NO_STATIC_ASSERT only if one or both tests failed. 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 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 >> struct S >> { >> static_assert (0 < _N, "fail"); >> }; >> >> template >> void f () >> { >> static_assert (0 < _N, "fail"); >> } >> >> int main () >> { >> S<1> s1; >> f<1>(); >> static_assert (1, "pass"); >> >> return 0; >> } > >
RE: remove_reference
> -Original Message- > From: Travis Vitek > Sent: Thursday, June 12, 2008 3:19 PM > To: Eric Lemings > Cc: 'dev@stdcxx.apache.org' > Subject: 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 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 . > > 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. 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? That's why I was asking if there are some future plans for the internal type traits that will provide some additional value. Otherwise, we really don't need them and they're actually just polluting our internal namespace. Brad.
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 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 . 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_constant, they inherit from >> __rw_integral_constant [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 >> >> >> . That is where all of the standard traits are >> >> >> defined. If you want the internal trait >> >> >> _RW::__rw_remove_reference, you could still include >> >> >> if you wanted, or you could include >> >. >> >> >> >> >> >> 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: remove_reference
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 header? Or do we have some plans for the internal type traits that I'm unaware of? Brad. P.S. Forwarded to stdcxx dev list. > -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_constant, they inherit from > __rw_integral_constant [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 > >> >> . That is where all of the standard traits are > >> >> defined. If you want the internal trait > >> >> _RW::__rw_remove_reference, you could still include > >> >> if you wanted, or you could include > >. > >> >> > >> >> 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: 20.2.2 forward/move helpers
>Eric Lemings wote: > > >Has anyone written or started on the forward/move helpers in 20.2.2 of >the latest draft (n2606)? > I have not. >Brad. > >
20.2.2 forward/move helpers
Has anyone written or started on the forward/move helpers in 20.2.2 of the latest draft (n2606)? Brad.
Re: Empty member initializers
Travis Vitek wrote: 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. I agree with this list with a couple of exceptions: _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 The macro can probably go but we might need to continue to support _RWSTD_NAMESPACE() and add namespace renaming (including std). _RWSTD_NO_LONG_DOUBLE _RWSTD_NO_LONG_LONG This one can't go until the next standard has been ratified and EDG eccp supports long long in strict mode. In general, my feeling is that starting perhaps as early as 4.3 but certainly 5.0 we should feel free to assume a C++ 03 conforming compiler unless there is some value in doing otherwise (e.g., supporting users who wish to compile with exceptions disabled). Martin _RWSTD_NO_WCHAR_T _RWSTD_NO_NATIVE_WCHAR_T Brad.
Re: static_assert config check
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 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. Martin template struct S { static_assert (0 < _N, "fail"); }; template void f () { static_assert (0 < _N, "fail"); } int main () { S<1> s1; f<1>(); static_assert (1, "pass"); return 0; }
Re: NLS Files
Eric Lemings wrote: Do the files in $TOPDIR/etc/nls ever change or need a periodic update? Yes :) Just wonderin. Brad.
Re: static_assert config check
On Jun 11, 2008, at 1:57 PM, Travis Vitek wrote: 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. And the macro can be used the same in all cases regardless of whether it is implemented using the compiler's static_assert or our own static assert? Brad.
Re: type_traits progress
Travis Vitek wrote: Martin Sebor wrote: Travis Vitek wrote: [...] Right. That could be another wrinkle. Our traits won't work with generic code that takes integral_constant 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. I read the proposal for type traits and their motivation for using the base class integral_constant is to avoid having to write out of line definitions as well as inline initialization of the static const member for every trait. Martin Sebor wrote: 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 struct __rw_integral_constant { static const T value = v; typedef T value_type; typedef integral_constant 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. }; 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 Property // by applying Transformer, otherwise leaves // T unchanged: template Property, template 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. As I mentioned in a previous message in this thread, I see no reason why the above wouldn't work with our current approach. template Property, template Transformer> struct __rw_transform_if { typedef typename __rw_conditional::_C_value, T, Transformer::_C_type>::_C_type _C_type; }; It's been some time but I think my point was that TransformIf was an example of a trait that couldn't interoperate with both the standard and our own private traits. Every one of the required traits have internal implementations, so any code that would be be written using required traits could be written using the internal ones. If the trait above was intended to be part of the implementation, then it would appear in the __rw namespace and it would use the internal traits. If it were intended to be part of the public interface, then it would be in the appropriate namespace and it would use the required traits. So I don't see any motivation to use the same names as required by the standard for the internal types. What is the motivation for using the name _C_type rather than just type? The only reason we do it with other names is to avoid clashes with user-defined macros but there can be no such macros named type or value (not without clashing with the standard traits). For the same reasons, I don't understand why integral_constant should interit from __rw_integral_constant. I don't feel terribly strongly about this. If it turns out that the derivation is important we can easily add it later. Martin