Re: [boost] dangerous_cast
Gabriel Dos Reis writes: Peter Dimov [EMAIL PROTECTED] writes: | From: Gabriel Dos Reis [EMAIL PROTECTED] | David Abrahams [EMAIL PROTECTED] writes: | | | Gabriel Dos Reis [EMAIL PROTECTED] writes: | | | | Hmm, I have a couple of questions answers to which will help me | | get your point. | | | | 1) Why can't you do that with reinterpret_cast? | | | | You can, but the results are non-portable | | No more non-portable than with dangerous_cast. | | I think that Dave's point is that in | | new(h.storage) Foo; | | there is a char* - void* implicit conversion as placement new takes a | void*. So the placement new performs char* - void* - Foo* (by constructing | a Foo at (void*)h.storage), which - in theory - might not be the same as | char* - Foo*. But then, that theoretical implementation can remember the type from which the conversion to void* was made and may issue an error when an attempt is made to dereference the pointer obtained by recasting the result of static_castvoid*(h.storage) to Foo*. Practical notes: Historically, char* was used as the type of raw memory until void* was invented. And since then char* and void* continues to have the same properties as raw-memory issues are concerned. unsigned char* has _additional_ properties to void* --- you can access the object representation of _any_ object through an unsigned char* (and for PODs, you can copy them around using this) 3.9p4: The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T). 3.10p15: If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined: - the dynamic type of the object, ... - a char or unsigned char type. So given a Foo object foo, static_castchar*(static_castvoid*(foo)) is legal, and can be used to access the object representation of the object. Also, 3.9.2p4 says: Objects of cvqualified (3.9.3) or cvunqualified type void* (pointer to void), can be used to point to objects of unknown type. A void* shall be able to hold any object pointer. A cvqualified or cvunqualified (3.9.3) void* shall have the same representation and alignment requirements as a cvqualified or cvunqualified char*. So casting a void* to/from a char* is a no-op. 3.8p1: The lifetime of an object is a runtime property of the object. The lifetime of an object of type T begins when: - storage with the proper alignment and size for type T is obtained, and - if T is a class type with a nontrivial constructor (12.1), the constructor call has completed. Thus, given that h.storage is properly aligned, (which is the purpose of the other union member), after new(h.storage) Foo, h.storage contains a Foo object. Thus accessing it through a pointer-to-Foo is legal, as Foo is the dynamic type of the object. The question is: is the Foo* returned by the placement new expression (which is usable) the same as the Foo* returned from static_castFoo*(static_castvoid*(h.storage))? The object representation of the Foo object is the sizeof(T) bytes starting at static_castvoid*(h.storage) (since that is what was passed to placement new), so static_castvoid*(pfoo)==static_castvoid*(h.storage) if pfoo is the value returned from the new expression. Thus static_castFoo*(static_castvoid*(pfoo)) ==static_castFoo*(static_castvoid*(h.storage)) ==pfoo and we're legal. Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] dangerous_cast
Gabriel Dos Reis writes: Hi, Hi Anthony Williams [EMAIL PROTECTED] writes: [...] | 3.10p15: | If a program attempts to access the stored value of an object through an | lvalue of other than one of the following types the behavior is undefined: | | - the dynamic type of the object, | | ... | | - a char or unsigned char type. | | So given a Foo object foo, static_castchar*(static_castvoid*(foo)) is | legal, and can be used to access the object representation of the object. There is no question that the above cast is legal. I thin the issue is elsewhere. The key question is whether that may be different from reinterpret_castvoid*(foo); I thought the issue was whether the pair of static_casts in dangerous_cast was as implementation defined as a reintepret_cast would be. If you read my mail to the end, hopefully I have explained that I think that the static_cast pair is legal and well-defined, as opposed to using reinterpret_cast, which is implementation-defined. If I haven't made myself clear, I apologise, and will try again. Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] BOOST_NO_CONFIG
On Wednesday 04 December 2002 08:53 am, David Abrahams wrote: It looks like some people (ahem! wink) have been using BOOST_NO_CONFIG where they should be using BOOST_STRICT_CONFIG. See boost/function/function_base.hpp. Oops. Fixed now. Doug ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] dangerous_cast
Gabriel Dos Reis writes: Anthony Williams [EMAIL PROTECTED] writes: | Anthony Williams [EMAIL PROTECTED] writes: | | [...] | | | 3.10p15: | | If a program attempts to access the stored value of an object through an | | lvalue of other than one of the following types the behavior is undefined: | | | | - the dynamic type of the object, | | | | ... | | | | - a char or unsigned char type. | | | | So given a Foo object foo, static_castchar*(static_castvoid*(foo)) is | | legal, and can be used to access the object representation of the object. | | There is no question that the above cast is legal. I thin the issue | is elsewhere. The key question is whether that may be different from | | reinterpret_castvoid*(foo); | | I thought the issue was whether the pair of static_casts in dangerous_cast | was as implementation defined as a reintepret_cast would be. If you read my | mail to the end, hopefully I have explained that I think that the | static_cast pair is legal and well-defined, as opposed to using | reinterpret_cast, which is implementation-defined. If I haven't made myself | clear, I apologise, and will try again. You made youself clear. However, there are two running issues originating from a claim of Dave that dangerous_cast might be better than reinterpret_cast in casting from U* to T* (dangerous_cast uses the intermediate step void* via static_cast). 1) is dangerous_cast better than reinterpret_cast? 2) is it well-defined to dereference the value obtained from U* - void* - T* ? You've showed that si U == char, (the case in Dave's example) then it is well-formed. The other cases are left undefined. So the key question (1) is still unanswered. Well, given that we have a valid use when U==(unsigned) char, I think it is certainly better than reinterpret_cast in that case. However, for (2), it is only safe to dereference the resulting pointer if there is a T at the location that the final T* points to. This is true irrespective of what U is. However, there are very few cases in which you are guaranteed to be able to get a valid U* that holds a valid T* --- given that U and T may have different alignment requirements, and an implementation is permitted to drop any unnecessary info from pointers, so T* and U* may only store addresses which are valid multiples of the alignment for T and U respectively, so it is unlikely that you would get a valid case, unless there was special dispensation. One of these is U==char or void, as I showed. Another case to consider is when U is a POD-struct and T is the type of the first data member (or vice-versa). In this case, reinterpret_cast is guaranteed to work (9.2p17), so what about dangerous_cast? IMO, there is no guarantee, though I would be surprised if it didn't work. Indeed, I read the note on that paragraph to indicate that the intent is that the address is the same, and thus static_castvoid* will yield the same result. However, I can't find any normative guarantee. A third case to consider is when T and U are the types of members of the same union. In this case, reinterpret_cast to a pointer to the union type and back is guaranteed (since the members are to be allocated as if they were the only member of a struct), and I would be surprised if it didn't work, but I can't find a normative guarantee. If these last two cases are guaranteed to be OK, then I think we have sufficient to indicate that dangerous_cast can be useful. If not, then it ought to be renamed, and only defined for char types. Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] BOOST_NO_CONFIG
On Thursday 05 December 2002 08:51 am, David Abrahams wrote: Douglas Gregor [EMAIL PROTECTED] writes: F On Wednesday 04 December 2002 08:53 am, David Abrahams wrote: It looks like some people (ahem! wink) have been using BOOST_NO_CONFIG where they should be using BOOST_STRICT_CONFIG. See boost/function/function_base.hpp. Oops. Fixed now. Well, now John Maddock may be quarrelling with you over the correct approach. We need to decide how this will work. -Dave It seems like places that need BOOST_(STRICT|NO)_CONFIG in the source don't fit the documentation for either macro. BOOST_STRICT_CONFIG just tells the config system how pessimistic to be w.r.t. new compiler versions. BOOST_NO_CONFIG tells the config system not to include any of its configuration headers (i.e., don't define any defect/extension macros). As it stands now, I think the right way to write compiler/library/platform-dependent workarounds is to check for _both_ BOOST_STRICT_CONFIG and BOOST_NO_CONFIG. BOOST_STRICT_CONFIG disables the workaround when dealing with a new compiler version, whereas BOOST_NO_CONFIG disables the workaround when the user has asked not to configure for the compiler. Maybe BOOST_NO_CONFIG (actually, BOOST_NO_COMPILER_CONFIG) should define BOOST_STRICT_CONFIG? Doug ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [MPL] Making Generators
David A. Greene [EMAIL PROTECTED] writes: template class T, class U, class V struct my_type_generator { typedef my_typeT,U,V type; }; lambdamy_type_generator does it Oops, I meant lambdamy_type_generatorBound,mpl::_1,mpl::_2 of course! , unless of course your compiler needs BOOST_MPL_AUX_LAMDA_SUPPORT. I don't think it's much of a savings, though. Not for one class, no, but when we're talking several classes with several binding requirements, I think there's a significant savings to be had. So do you feel you need an additional library feature? Plus your solution here doesn't bind T to a type. :) Are you just pointing out my error? I thought lambda might do the trick, but apparently not: typedef my_typeint, mpl::_1, mpl::_2 my_type_generator; (This will be passed to an MPL algorithm so I didn't bother with lambda). This causes a static assertion in mpl::arg2 where it sees a void type for V (I think). Is the problem that my_type doesn't contain a ::type member? Maybe. What compiler are you using? g++ 3.2. The MPL paper and docs don't say anything about using placeholders or binders with classes that aren't metafunctions. How would the binders know what to typedef as apply::type? I don't know... well, it could detect whether there was a ::type member, and if it were not present, it could just give you the outer class. I think that's a bit of a hack, though. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: [MPL] Making Generators
David Abrahams [EMAIL PROTECTED] wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... [...] I don't know... well, it could detect whether there was a ::type member, [...] Really??? Is it possible to detect the presence of a typedef without generating an error? How do you do this? I think this is a very useful feature! Dave ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [MPL] Making Generators
David Abrahams wrote: template class T, class U, class V struct my_type_generator { typedef my_typeT,U,V type; }; lambdamy_type_generator does it Oops, I meant lambdamy_type_generatorBound,mpl::_1,mpl::_2 of course! Ok, that makes more sense now. :) , unless of course your compiler needs BOOST_MPL_AUX_LAMDA_SUPPORT. I don't think it's much of a savings, though. Not for one class, no, but when we're talking several classes with several binding requirements, I think there's a significant savings to be had. So do you feel you need an additional library feature? That's what I'm trying to find out. It seems like most of the stuff is there already in MPL placeholders and binders. Plus your solution here doesn't bind T to a type. :) Are you just pointing out my error? Well...yeah. :) It wasn't meant as an attack. I honestly was confused about what you presented. Your correction above makes everything clear to me now. g++ 3.2. The MPL paper and docs don't say anything about using placeholders or binders with classes that aren't metafunctions. How would the binders know what to typedef as apply::type? I don't know... well, it could detect whether there was a ::type member, and if it were not present, it could just give you the outer class. I think that's a bit of a hack, though. Agreed. Urk...I'm not sure how to get around this problem without requiring template template parameters (beyond what's used for placeholders currently). -Dave -- Some little people have music in them, but Fats, he was all music, and you know how big he was. -- James P. Johnson ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] [Config] Testing instructions for compiler vendors
David Abrahams wrote: I'm trying to come up with instructions for compiler vendors who want to use Boost to test their compilers. What preprocessor symbols do they need to define? So far, it looks like: - BOOST_NO_COMPILER_CONFIG - BOOST_NO_STDLIB_CONFIG - if they want to check the library - BOOST_STRICT_CONFIG - to disable some checks in source code - macros for any known-not-implemented features, e.g. BOOST_NO_TEMPLATE_TEMPLATES. Right? As far as I understand, defining BOOST_STRICT_CONFIG only should be sufficient (for compiler tests) - given that the compiler being tested has a bumped up version number. 2. What about all the places we make compiler-specific checks in Boost code? Could we define some macros which make it easier and less error-prone to write these, and which can be globally turned off when needed? # if BOOST_COMPILER_WORKAROUND(__SUNPRO_CC, = 0x540) ... #else ... #endif The checks for the past versions of the compiler, e.g. #if defined(BOOST_MSVC) BOOST_MSVC = 1300 # define BOOST_MPL_MSVC_ETI_BUG #endif are harmless for the beta-testing of the new one. As for checks for current bugs, I think it's our current convention that they should be guarded by BOOST_STRICT_CONFIG, like this: #if defined(__BORLANDC__) \ (__BORLANDC__ = 0x570 || !defined(BOOST_STRICT_CONFIG)) # define BOOST_MPL_BROKEN_OVERLOAD_RESOLUTION #endif so defining BOOST_STRICT_CONFIG would disable them. I am afraid it's not thoroughly enforced, though. If we come up with a way to simplify the above, personally I would be more than happy. Aleksey ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: [MPL] Making Generators
-Original Message- From: David B. Held [mailto:[EMAIL PROTECTED]] Sent: Thursday, December 05, 2002 10:56 AM To: [EMAIL PROTECTED] Subject: [boost] Re: [MPL] Making Generators David Abrahams [EMAIL PROTECTED] wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... [...] I don't know... well, it could detect whether there was a ::type member, [...] Really??? Is it possible to detect the presence of a typedef without generating an error? How do you do this? I think this is a very useful feature! Dave Vandevoorde and Josuttis call it SFINAE, substitution failute is not an error. In C++ Templates: The Complete Guide (Recommended), they give this example on pages 106-107: typedef char RT1; typedef struct {char a[2];} RT2; templatetypename T RT1 test(typename T::X const*); templatetypename T RT2 test(...); #define type_has_member_type_X(T) \ (sizeof(testT(0) == 1) ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [MPL] Making Generators
David A. Greene [EMAIL PROTECTED] writes: So do you feel you need an additional library feature? That's what I'm trying to find out. It seems like most of the stuff is there already in MPL placeholders and binders. Plus your solution here doesn't bind T to a type. :) Are you just pointing out my error? Well...yeah. :) It wasn't meant as an attack. Wasn't taken that way. I honestly was confused about what you presented. Understandably. Your correction above makes everything clear to me now. So do you feel you need an additional library feature? ;-) g++ 3.2. The MPL paper and docs don't say anything about using placeholders or binders with classes that aren't metafunctions. How would the binders know what to typedef as apply::type? I don't know... well, it could detect whether there was a ::type member, and if it were not present, it could just give you the outer class. I think that's a bit of a hack, though. Agreed. Urk...I'm not sure how to get around this problem without requiring template template parameters (beyond what's used for placeholders currently). There's no way. So what? Your compiler supports them. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [Config] Testing instructions for compiler vendors
Aleksey Gurtovoy [EMAIL PROTECTED] writes: David Abrahams wrote: I'm trying to come up with instructions for compiler vendors who want to use Boost to test their compilers. What preprocessor symbols do they need to define? So far, it looks like: - BOOST_NO_COMPILER_CONFIG - BOOST_NO_STDLIB_CONFIG - if they want to check the library - BOOST_STRICT_CONFIG - to disable some checks in source code - macros for any known-not-implemented features, e.g. BOOST_NO_TEMPLATE_TEMPLATES. Right? As far as I understand, defining BOOST_STRICT_CONFIG only should be sufficient (for compiler tests) - given that the compiler being tested has a bumped up version number. That's a big assumption. Some vendors will want to check their current release, and sometimes we begin to set up configuration for pre-released compilers. 2. What about all the places we make compiler-specific checks in Boost code? Could we define some macros which make it easier and less error-prone to write these, and which can be globally turned off when needed? # if BOOST_COMPILER_WORKAROUND(__SUNPRO_CC, = 0x540) ... #else ... #endif The checks for the past versions of the compiler, e.g. #if defined(BOOST_MSVC) BOOST_MSVC = 1300 # define BOOST_MPL_MSVC_ETI_BUG #endif are harmless for the beta-testing of the new one. I suppose. I can see it being useful to be able to demonstrate bugs in any version of a compiler, though. As for checks for current bugs, I think it's our current convention that they should be guarded by BOOST_STRICT_CONFIG, like this: #if defined(__BORLANDC__) \ (__BORLANDC__ = 0x570 || !defined(BOOST_STRICT_CONFIG)) # define BOOST_MPL_BROKEN_OVERLOAD_RESOLUTION #endif so defining BOOST_STRICT_CONFIG would disable them. I'm not sure there's universal agreement about that, but now that Doug has fixed the function headers, the code says otherwise. I am afraid it's not thoroughly enforced, though. If we come up with a way to simplify the above, personally I would be more than happy. I propose: #ifndef BOOST_STRICT_CONFIG # define BOOST_WORKAROUND(symbol, test) (defined(symbol) symbol test) #else # define BOOST_WORKAROUND(symbol, test) 0 #endif Comments? -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: unicode support
Vladimir Prus wrote: First interpretation is that you're interested in support for different Unicode encodings, via appropriate facets. Then Alberto Barbati is the last person who touches this matter, in news://news.gmane.org:119/aq72e4$pog$[EMAIL PROTECTED] I assume he's holding a lock on implementation work. Alberto, did you get anywhere? Yes, despite the clear lack of interest from Boosters about this issue, I'm still working on it ( but I don't have any lock ;) ). I had a few problems with the interpretation of the standard, but thanks to a few guys from comp.std.c++ I can now say that I have a working implementation of facets to converts from UTF-8/16/32 (external) to UTF-16/32 (internal), with endian variants, a total of 10 facets. The implementation fulfill a basic suite of tests on VS.NET with both the native STL and STLport. The facets are conformant to Unicode 3.2 requirements about non-characters, use of surrogates and non-shortest UTF-8 sequences. After a private discussion with a field expert, I decided to drop the UCS-2 facets, so surrogate support is no longer optional. I also decided to drop facets with UTF-8 as the internal encoding because they are not very useful and the current wording of the C++ standard de facto disallows a portable implementation :(. I hope the LWG would consider clarifying the issue. My next steps would be to polish the code, write the docs and prepare a more complete test suite. If everything goes well, I think I could submit the library for review by the end of the month. Second interpretation is conversion between all the 8-bit encodings out there. E.g. from koi8-r to windows-1251. Since there's GNU iconv already, I'd rather see a tiny wrapper over it. (GNU iconv works on Windows, too). Here things become more complex. UTF conversions are just algorithmic stuff, easy to do. Other conversions like koi8-r o windows-1251 require look-up tables and simply gathering the data for all of them will be equivalent to rewriting a part of ICU, which is a huge piece of work. The idea of wrapping ICU is very interesting. However the Boost policy explictly disallows dependencies from external libraries, so this solution is out of discussion. Moreover, the only things ICU is missing are the conversion facets. I don't see any reason to wrap anything else. Unfortunately, as I said before, not all conversions can be portably expressed as a facet with the current C++ standard, so even writing wrapping facets has little meaning. Alberto Barbati ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [Config] Testing instructions for compiler vendors
--- David Abrahams [EMAIL PROTECTED] wrote: [...] I propose: #ifndef BOOST_STRICT_CONFIG # define BOOST_WORKAROUND(symbol, test) (defined(symbol) symbol test) #else # define BOOST_WORKAROUND(symbol, test) 0 #endif Comments? Sorry for jumping in without really following this thread. I'm busy and just trying to read the posts quickly. This example struck me though. Please take a look at this: http://groups.google.com/groups?threadm=m4TT8.211653%24nZ3.100438%40rwcrnsc53 Genny. __ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [Config] Testing instructions for compiler vendors
- Original Message - From: David Abrahams [EMAIL PROTECTED] To: boost [EMAIL PROTECTED] Sent: Wednesday, December 04, 2002 9:27 PM Subject: [boost] [Config] Testing instructions for compiler vendors Hi, I'm trying to come up with instructions for compiler vendors who want to use Boost to test their compilers. What preprocessor symbols do they need to define? So far, it looks like: - BOOST_NO_COMPILER_CONFIG - BOOST_NO_STDLIB_CONFIG - if they want to check the library - BOOST_STRICT_CONFIG - to disable some checks in source code - macros for any known-not-implemented features, e.g. BOOST_NO_TEMPLATE_TEMPLATES. Right? Questions: 1. Should we do something to make this easier for them? No. We should focus on serving our users. 2. What about all the places we make compiler-specific checks in Boost code? Could we define some macros which make it easier and less error-prone to write these, and which can be globally turned off when needed? # if BOOST_COMPILER_WORKAROUND(__SUNPRO_CC, = 0x540) ... #else ... #endif I'm sometimes not even able to decide who is wrong ;-( Best regards Joerg ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [Config] Testing instructions for compiler vendors
- Original Message - From: David Abrahams [EMAIL PROTECTED] To: Boost mailing list [EMAIL PROTECTED] Sent: Thursday, December 05, 2002 9:38 PM Subject: Re: [boost] [Config] Testing instructions for compiler vendors [EMAIL PROTECTED] (Joerg Walter) writes: 1. Should we do something to make this easier for them? No. We should focus on serving our users. Our users will be happy and our lives will be easier if their compilers finally start working. Didn't they have enough time and resources to work this out 'til now? Best regards Joerg ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [MPL] Making Generators
David Abrahams wrote: Your correction above makes everything clear to me now. So do you feel you need an additional library feature? ;-) I suppose not. What I really wanted was the ability to take a regular old template class and create a generator out of it: templatetypename T, typename U, typename V struct my_type { ... } // Note: no ::type member typedef SHAZAMmy_typeint, _1, _2 generator; typedef generator::template applychar, float::type my_type_inst; I want SHAZAM to be generic enough to take any template class, not just my_type. If I understand your solution correctly, it requires a manually-constructed generator for my_type: templatetypename T, typename U, typename V struct my_type_generator { typedef my_typeT, U, V type; }; SHAZAM then becomes mpl::lambda. The problem is, I'll have to create these trivial generators (I hesitate to even call it that) many times over, once for each class I want to bind. But I can construct a generic trivial generator: templatetemplatetypename A, typename B, typename C class Base, typename T, typename U, typename V struct trivial_generator { typedef BaseT, U, V type; }; Then I can use MPL lambda facilities. Unfortunately, I need a trivial_generator for every arity of class template. But I don't think there's any way around that. MPL needs the same thing for its placeholders. It just seems a shame that this enumeration needs to be repeated for this special case when it already exists for _1, _2, etc. I don't know... well, it could detect whether there was a ::type member, and if it were not present, it could just give you the outer class. I think that's a bit of a hack, though. Agreed. Urk...I'm not sure how to get around this problem without requiring template template parameters (beyond what's used for placeholders currently). There's no way. So what? Your compiler supports them. Of course. But others don't. I'm more concerned about the duplication of effort described above. But again, I don't think there's any way around that. -Dave -- Some little people have music in them, but Fats, he was all music, and you know how big he was. -- James P. Johnson ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [Config] Testing instructions for compiler vendors
On Thursday 05 December 2002 02:41 pm, David Abrahams wrote: I propose: #ifndef BOOST_STRICT_CONFIG # define BOOST_WORKAROUND(symbol, test) (defined(symbol) symbol test) #else # define BOOST_WORKAROUND(symbol, test) 0 #endif Comments? I'm still not sure that BOOST_STRICT_CONFIG is the right macro to determine if workarounds are enabled or not, but if John agrees then I'm happy with it. Regardless of what macro determines which BOOST_WORKAROUND is used, I like the above definition (+ dumb compiler workarounds). Doug ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: [MPL] Making Generators
- Original Message - From: David B. Held [EMAIL PROTECTED] Jon Kalb [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] icrosoft.com... [...] Vandevoorde and Josuttis call it SFINAE, substitution failute is not an error. Ah, I've heard of this, but didn't realize what it was all about. In C++ Templates: The Complete Guide (Recommended), they give this example on pages 106-107: typedef char RT1; typedef struct {char a[2];} RT2; templatetypename T RT1 test(typename T::X const*); templatetypename T RT2 test(...); #define type_has_member_type_X(T) \ (sizeof(testT(0) == 1) This is cool. What compilers are known to support it? Comeau C++ certainly supports it (what a surprise...). BTW, this is nothing new. It was discovered a while back based on an is_enum implementation, which was converted to an is_class implementation, which, finally, was converted to a has_member_... implementation. (I think by Rani Sharoni, but I'm not sure.) The bad part about it is that there is no way, given the nature of the solution, to parametize the member name. Also, SFINAE, according to the standard does not apply to expression errors, and is very unclear about what happens, for example in the code above, if X is a template instead of a regular type. I talked to Daveed Vandevoorde about this issue this past week. Supposedly, the SFINAE principle used to be very broad, but compilers were having difficulty implementing it robustly, so they (as in core-3) dumbed it down to only include the list of ways that deduction/substitution can fail in 14.8.2. This list is, in effect, a list of negatives--which IMO is a bad idea. Apparently, they've added things to this list in each of the last three core-3 meetings (or whatever they are). Personally, I believe the SFINAE principle should be significantly broader. The original argument about the difficulty of a robust implementation is pretty bogus considering that most compilers won't handle just the invalid type-creation attempts listed in 14.8.2 anyway. Also, the line between invalid type and invalid expression is significantly blurred because of the sizeof and typeid operators (not to mention invalid templates). Consider again how brittle the above might be: templateclass T char test(typename T::X const*); templateclass T char ( test(...))[2]; #define has_member_type_X(T) \ (sizeof( testT(0) ) == 1) struct Y { templateclass struct X { }; }; has_member_type_X(Y) // ? Paul Mensonides ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [MPL] Making Generators
David A. Greene [EMAIL PROTECTED] writes: David Abrahams wrote: Your correction above makes everything clear to me now. So do you feel you need an additional library feature? ;-) I suppose not. What I really wanted was the ability to take a regular old template class and create a generator out of it: templatetypename T, typename U, typename V struct my_type { ... } // Note: no ::type member typedef SHAZAMmy_typeint, _1, _2 generator; typedef generator::template applychar, float::type my_type_inst; I want SHAZAM to be generic enough to take any template class, not just my_type. You can do that, up to N arguments, for some N. If I understand your solution correctly, it requires a manually-constructed generator for my_type: templatetypename T, typename U, typename V struct my_type_generator { typedef my_typeT, U, V type; }; SHAZAM then becomes mpl::lambda. The problem is, I'll have to create these trivial generators (I hesitate to even call it that) many times over, once for each class I want to bind. But I can construct a generic trivial generator: templatetemplatetypename A, typename B, typename C class Base, typename T, typename U, typename V struct trivial_generator { typedef BaseT, U, V type; }; Then I can use MPL lambda facilities. Unfortunately, I need a trivial_generator for every arity of class template. Only as part of the implementation. You just need a nice wrapper over the top to hide it all. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost