
Hello I am currently actively contributing to STLport. One of my contribution is to make boost and STLport closer. I think STLport can gain a lot in using some of the boost libraries and then boost will be able to count on a robust std lib. For the moment I only use 2 libraries from boost, type_traits and call_traits. I have some issue when I include the boost headers from STLport. I was counting on the BOOST_STD_CONFIG macro to limit the damage but for some platforms this feature is just useless. Under Win32 there is a workaround implemented for MSVC compilers (win32.hpp:60) on the min and max template functions. This workaround require the inclusion of the algorithm standard header which make the STLport lib build process failed. According the comment this workaround has not really been validated so my questions are: - is it require for all MSVC++ versions? Doesn't VC.Net 2003 or even 2002 managed the described cases correctly? - Couldn't this workaround be implemented for the native library only and not when using STLport? STLport looks to me as the right place to handle this case. Bests Francois Dumont

François Dumont <francois.cppdevs@free.fr> writes:
Hello
I am currently actively contributing to STLport. One of my contribution is to make boost and STLport closer. I think STLport can gain a lot in using some of the boost libraries and then boost will be able to count on a robust std lib.
For the moment I only use 2 libraries from boost, type_traits and call_traits. I have some issue when I include the boost headers from STLport. I was counting on the BOOST_STD_CONFIG macro to limit the damage
AFAIK we don't have such a macro, at least not a documented one.
but for some platforms this feature is just useless. Under Win32 there is a workaround implemented for MSVC compilers (win32.hpp:60) on the min and max template functions. This workaround require the inclusion of the algorithm standard header which make the STLport lib build process failed.
I'm not exactly sure what you're referring to, but there's been some recent work on dealing with the horrible min/max macros that some headers define. Please search our mailing list archives for recent postings from Eric Niebler.
According the comment this workaround has not really been
The comment where?
validated so my questions are: - is it require for all MSVC++ versions? Doesn't VC.Net 2003 or even 2002 managed the described cases correctly? - Couldn't this workaround be implemented for the native library only and not when using STLport? STLport looks to me as the right place to handle this case.
I don't think you're giving enough specifics for most of us to understand what you're talking about. Please point to specific source code in the Boost CVS. Thanks, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
François Dumont <francois.cppdevs@free.fr> writes:
but for some platforms this feature is just useless. Under Win32 there is a workaround implemented for MSVC compilers (win32.hpp:60) on the min and max template functions. This workaround require the inclusion of the algorithm standard header which make the STLport lib build process failed.
I'm not exactly sure what you're referring to, but there's been some recent work on dealing with the horrible min/max macros that some headers define. Please search our mailing list archives for recent postings from Eric Niebler.
Before this goes any further, you should get the latest version of boost from CVS. The min/max hack in win32.hpp has been removed, since it was found to silently change program behavior and cause ambiguity errors. It was replaced with a different hack <g> by me. In addition to trying CVS head, you should also follow Dave's suggestion and read my posts regarding the min/max issue. The reasoning for the current hack is all in the archive. -- Eric Niebler Boost Consulting www.boost-consulting.com

François Dumont <francois.cppdevs@free.fr> writes:
Hello
I am currently actively contributing to STLport. One of my contribution is to make boost and STLport closer. I think STLport can gain a lot in using some of the boost libraries and then boost will be able to count on a robust std lib.
This sounds really cool, BTW.
For the moment I only use 2 libraries from boost, type_traits and call_traits.
Take care with call_traits. The documentation isn't very clear about how it behaves in all circumstances (especially on broken compilers). I would be inclined to build my own individual metafunctions (rather than traits "blobs") for doing the kinds of thigs that call_traits tries to address. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

On Jul 5, 2004, at 3:55 PM, David Abrahams wrote:
Take care with call_traits. The documentation isn't very clear about how it behaves in all circumstances (especially on broken compilers). I would be inclined to build my own individual metafunctions (rather than traits "blobs") for doing the kinds of thigs that call_traits tries to address.
Perhaps we should deblobify call_traits (putting the resulting fine-grained traits into the type_traits lib) and deprecate it? Doug

What are the issues with call_traits which make it unusable ? Doug Gregor wrote:
On Jul 5, 2004, at 3:55 PM, David Abrahams wrote:
Take care with call_traits. The documentation isn't very clear about how it behaves in all circumstances (especially on broken compilers). I would be inclined to build my own individual metafunctions (rather than traits "blobs") for doing the kinds of thigs that call_traits tries to address.
Perhaps we should deblobify call_traits (putting the resulting fine-grained traits into the type_traits lib) and deprecate it?

"Edward Diener" <eddielee@tropicsoft.com> writes:
What are the issues with call_traits which make it unusable ?
As far as I can tell, there is no clear documentation of what _precisely_ any partcular member of call_traits<T> is for a given T. It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available. It seems as though the documentation is intended to be a more abstract description of what happens, but it leaves me (at least) feeling very unclear about what I'm actually getting. It's also unclear to me what purpose is served by the "reference" and "const_reference" members. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
What are the issues with call_traits which make it unusable ?
As far as I can tell, there is no clear documentation of what _precisely_ any partcular member of call_traits<T> is for a given T.
The table given after "The following table shows the effect that call_traits has on various types, the table assumes that the compiler supports partial specialization: if it doesn't then all types behave in the same way as the entry for "myclass", and call_traits can not be used with reference or array types" seems to answer that pretty specifically. It gives the values which call_traits will generate for any user defined type and various permutations of a basic type.
It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available.
See quote above. How many compilers without partial specialization, beside VC6, does Boost really want to support anymore. My guess would be 0 and if Boost didn't feel obliged to support VC6, I am sure all Boost developers would be happier. I am not knocking the tremendous effort Boost has made to support VC6, since I have used it myself and am appreciative of it. But if call_traits doesn't largely work with VC6 in any meaningful way, I don't think it is a reason to deprecate it.
It seems as though the documentation is intended to be a more abstract description of what happens, but it leaves me (at least) feeling very unclear about what I'm actually getting.
Seems fairly clear to me. The only possibiliites not listed are other permutations of user-defined types. I would think this latter may be a documentation issue, but an educated guess would be that other permutations of user-defined types would mirror the other permutations of basic types.
It's also unclear to me what purpose is served by the "reference" and "const_reference" members.
In the beginning of the doc it specifies that both are for returning values of reference and const reference respectively, while avoiding the reference to reference problem. I am not defending call_traits itself, which I have not used but which I am thinking about using as part of my calling and returning style, but rather the doc which seems fairly clear to me about what it is and does from a user perspective.

"Edward Diener" <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
What are the issues with call_traits which make it unusable ?
BTW, I should point out that I never claimed it was unusable.
As far as I can tell, there is no clear documentation of what _precisely_ any partcular member of call_traits<T> is for a given T.
The table given after "The following table shows the effect that call_traits has on various types,
But not all types, right? What about pointers and references to functions? What about POD classes the same size as 2 ints?
the table assumes that the compiler supports partial specialization: if it doesn't then all types behave in the same way as the entry for "myclass", and call_traits can not be used with reference or array types" seems to answer that pretty specifically.
Not well enough for me, I'm afraid. What does "can not be used" mean? Will it generate an error? Note also: "If T is a small built in type or a pointer, then param_type is defined as T const, instead of T const&" What is "small"?
It gives the values which call_traits will generate for any user defined type and various permutations of a basic type.
It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available.
See quote above. How many compilers without partial specialization, beside VC6, does Boost really want to support anymore. My guess would be 0 and if Boost didn't feel obliged to support VC6, I am sure all Boost developers would be happier. I am not knocking the tremendous effort Boost has made to support VC6, since I have used it myself and am appreciative of it.
This is probably all irrelevant to the OP because STLPort is trying to support many older compilers, unless something has changed over there.
But if call_traits doesn't largely work with VC6 in any meaningful way, I don't think it is a reason to deprecate it.
Who said anything about deprecating? Not a bad idea, though.
It seems as though the documentation is intended to be a more abstract description of what happens, but it leaves me (at least) feeling very unclear about what I'm actually getting.
Seems fairly clear to me. The only possibiliites not listed are other permutations of user-defined types. I would think this latter may be a documentation issue, but an educated guess would be that other permutations of user-defined types would mirror the other permutations of basic types.
It's also unclear to me what purpose is served by the "reference" and "const_reference" members.
In the beginning of the doc it specifies that both are for returning values of reference and const reference respectively, while avoiding the reference to reference problem.
boost::add_reference<T>::type boost::add_reference<boost::add_const<T>::type>::type
I am not defending call_traits itself, which I have not used but which I am thinking about using as part of my calling and returning style, but rather the doc which seems fairly clear to me about what it is and does from a user perspective.
It's still failing this potential user. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
What are the issues with call_traits which make it unusable ?
BTW, I should point out that I never claimed it was unusable.
As far as I can tell, there is no clear documentation of what _precisely_ any partcular member of call_traits<T> is for a given T.
The table given after "The following table shows the effect that call_traits has on various types,
But not all types, right? What about pointers and references to functions?
Good question but I would assume it is the same as pointers and references to built-in types.
What about POD classes the same size as 2 ints?
It is a user-defined type. I would assume it follows the rule for user-defined type since nothing was said in the doc about passing small user-defined types by value.
the table assumes that the compiler supports partial specialization: if it doesn't then all types behave in the same way as the entry for "myclass", and call_traits can not be used with reference or array types" seems to answer that pretty specifically.
Not well enough for me, I'm afraid. What does "can not be used" mean? Will it generate an error?
I agree with this criticism of it.
Note also: "If T is a small built in type or a pointer, then param_type is defined as T const, instead of T const&"
What is "small"?
I agree with this criticism also. I had assumed it referred to all built-in types, and ignored the "small", but this should definitely be explained.
It gives the values which call_traits will generate for any user defined type and various permutations of a basic type.
It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available.
"Note that for compilers that do not support either partial specialization or member templates, no benefit will occur from using call_traits: the call_traits defined types will always be the same as the existing practice in this case. In addition if only member templates and not partial template specialisation is support by the compiler (for example Visual C++ 6) then call_traits can not be used with array types (although it can be used to solve the reference to reference problem)."
See quote above. How many compilers without partial specialization, beside VC6, does Boost really want to support anymore. My guess would be 0 and if Boost didn't feel obliged to support VC6, I am sure all Boost developers would be happier. I am not knocking the tremendous effort Boost has made to support VC6, since I have used it myself and am appreciative of it.
This is probably all irrelevant to the OP because STLPort is trying to support many older compilers, unless something has changed over there.
But if call_traits doesn't largely work with VC6 in any meaningful way, I don't think it is a reason to deprecate it.
Who said anything about deprecating? Not a bad idea, though.
Mr. Gregor.
It seems as though the documentation is intended to be a more abstract description of what happens, but it leaves me (at least) feeling very unclear about what I'm actually getting.
Seems fairly clear to me. The only possibiliites not listed are other permutations of user-defined types. I would think this latter may be a documentation issue, but an educated guess would be that other permutations of user-defined types would mirror the other permutations of basic types.
It's also unclear to me what purpose is served by the "reference" and "const_reference" members.
In the beginning of the doc it specifies that both are for returning values of reference and const reference respectively, while avoiding the reference to reference problem.
boost::add_reference<T>::type boost::add_reference<boost::add_const<T>::type>::type
Too cryptic for me. Please explain.
I am not defending call_traits itself, which I have not used but which I am thinking about using as part of my calling and returning style, but rather the doc which seems fairly clear to me about what it is and does from a user perspective.
It's still failing this potential user.
I think the areas you pointed out in the doc should be explained better but I still think the idea is a good one.

"Edward Diener" <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
But not all types, right? What about pointers and references to functions?
Good question but I would assume it is the same as pointers and references to built-in types.
One shouldn't have to assume.
What about POD classes the same size as 2 ints?
It is a user-defined type. I would assume it follows the rule for user-defined type since nothing was said in the doc about passing small user-defined types by value.
One shouldn't have to assume.
Not well enough for me, I'm afraid. What does "can not be used" mean? Will it generate an error?
I agree with this criticism of it.
Why is it unacceptable to assume some specifics here, but not in the two other cases I mentioned?
Note also: "If T is a small built in type or a pointer, then param_type is defined as T const, instead of T const&"
What is "small"?
I agree with this criticism also. I had assumed it referred to all built-in types, and ignored the "small", but this should definitely be explained.
It gives the values which call_traits will generate for any user defined type and various permutations of a basic type.
It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available.
I didn't just write this (it's from several posts ago); there's no need to repeat your earlier repetition of what's on the web page ;-)
"Note that for compilers that do not support either partial specialization or member templates, no benefit will occur from using call_traits: the
<snip>
It's also unclear to me what purpose is served by the "reference" and "const_reference" members.
In the beginning of the doc it specifies that both are for returning values of reference and const reference respectively, while avoiding the reference to reference problem.
boost::add_reference<T>::type boost::add_reference<boost::add_const<T>::type>::type
Too cryptic for me. Please explain.
These constructs do what you just described above and in fact they work even on compilers without partial specialization.
I am not defending call_traits itself, which I have not used but which I am thinking about using as part of my calling and returning style, but rather the doc which seems fairly clear to me about what it is and does from a user perspective.
It's still failing this potential user.
I think the areas you pointed out in the doc should be explained better but I still think the idea is a good one.
The basic idea might be OK but I think the execution is now very out-of-date. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
But not all types, right? What about pointers and references to functions?
Good question but I would assume it is the same as pointers and references to built-in types.
One shouldn't have to assume.
By assume I meant that the documentation basically divides its explanation between user-defined types and built-in types. Since pointers and references to functions fall under built-in types, I follow the documentation about built-in types and I have my answer. There is a question of interpretation. So you ask the question and hopefully one of the original implementors gives you an answer.
What about POD classes the same size as 2 ints?
It is a user-defined type. I would assume it follows the rule for user-defined type since nothing was said in the doc about passing small user-defined types by value.
One shouldn't have to assume.
Here it is even clearer from the documentation that a POD class follows the rules of a user-defined type. You are attempting to twist the word "assume" for your own purposes.
Not well enough for me, I'm afraid. What does "can not be used" mean? Will it generate an error?
I agree with this criticism of it.
Why is it unacceptable to assume some specifics here, but not in the two other cases I mentioned?
You are trying to win debates instead of finding out answers.
Note also: "If T is a small built in type or a pointer, then param_type is defined as T const, instead of T const&"
What is "small"?
I agree with this criticism also. I had assumed it referred to all built-in types, and ignored the "small", but this should definitely be explained.
It gives the values which call_traits will generate for any user defined type and various permutations of a basic type.
It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available.
I didn't just write this (it's from several posts ago); there's no need to repeat your earlier repetition of what's on the web page ;-)
"Note that for compilers that do not support either partial specialization or member templates, no benefit will occur from using call_traits: the
<snip>
It's also unclear to me what purpose is served by the "reference" and "const_reference" members.
In the beginning of the doc it specifies that both are for returning values of reference and const reference respectively, while avoiding the reference to reference problem.
boost::add_reference<T>::type boost::add_reference<boost::add_const<T>::type>::type
Too cryptic for me. Please explain.
These constructs do what you just described above and in fact they work even on compilers without partial specialization.
How does one work with them in the context of call traits ?

"Edward Diener" <eddielee@tropicsoft.com> writes:
You are trying to win debates instead of finding out answers.
Please don't. I could easily make the same assertion about you. I'm doing neither. I'm trying to illustrate why I have a hard time with the documentation of this library.
In the beginning of the doc it specifies that both are for returning values of reference and const reference respectively, while avoiding the reference to reference problem.
boost::add_reference<T>::type boost::add_reference<boost::add_const<T>::type>::type
Too cryptic for me. Please explain.
These constructs do what you just described above and in fact they work even on compilers without partial specialization.
How does one work with them in the context of call traits ?
Huh? I'm just saying these members of call_traits are redundant and not even as portable as the ones in type_traits. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

On Jul 5, 2004, at 7:46 PM, David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
What are the issues with call_traits which make it unusable ?
As far as I can tell, there is no clear documentation of what _precisely_ any partcular member of call_traits<T> is for a given T. It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available.
It seems as though the documentation is intended to be a more abstract description of what happens, but it leaves me (at least) feeling very unclear about what I'm actually getting.
It's also unclear to me what purpose is served by the "reference" and "const_reference" members.
As I recall, call_traits was intended to work around the "reference to reference" problem for both parameters and return types. This problem has since been solved by cwg #106 ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 ). Though I'm unsure how widely implemented this dr is in current compilers. I initially viewed call_traits as a way to optimize whether a type should be passed by const ref or by value. But I was mistaken. The real value was in passing/returning reference types without bumping into the reference-to-reference problem. -Howard

Howard Hinnant <hinnant@twcny.rr.com> writes:
On Jul 5, 2004, at 7:46 PM, David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
What are the issues with call_traits which make it unusable ?
As far as I can tell, there is no clear documentation of what _precisely_ any partcular member of call_traits<T> is for a given T. It's even less clear what fallback the library uses when a full implementation of call_traits would require partial specialization that isn't available.
It seems as though the documentation is intended to be a more abstract description of what happens, but it leaves me (at least) feeling very unclear about what I'm actually getting.
It's also unclear to me what purpose is served by the "reference" and "const_reference" members.
As I recall, call_traits was intended to work around the "reference to reference" problem for both parameters and return types. This problem has since been solved by cwg #106 ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 ).
Or by boost::add_reference ;-)
Though I'm unsure how widely implemented this dr is in current compilers. I initially viewed call_traits as a way to optimize whether a type should be passed by const ref or by value. But I was mistaken. The real value was in passing/returning reference types without bumping into the reference-to-reference problem.
Well that one's neatly handled by the Type Traits library. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Howard Hinnant <hinnant@twcny.rr.com> writes:
As I recall, call_traits was intended to work around the "reference to reference" problem for both parameters and return types. This problem has since been solved by cwg #106 ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 ).
Or by boost::add_reference ;-)
Out of interest, when did call_traits came into existence? Was it prior to type_traits? When was it reviewed? It seems that we are re-reviewing call_traits again? Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

On Jul 6, 2004, at 11:02 PM, Joel de Guzman wrote:
David Abrahams wrote:
Howard Hinnant <hinnant@twcny.rr.com> writes:
As I recall, call_traits was intended to work around the "reference to reference" problem for both parameters and return types. This problem has since been solved by cwg #106 ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 ). Or by boost::add_reference ;-)
Out of interest, when did call_traits came into existence? Was it prior to type_traits? When was it reviewed? It seems that we are re-reviewing call_traits again?
Sorry, it's my fault. I sometimes look at Boost and see these little libraries and wonder if they really belong at the same level as the Python lib, or Spirit, or the Graph lib, etc. Call traits seems like a trivial application of type traits, but hasn't been maintained with the same vigor. Being accepted doesn't mean that a library stays in Boost forever... for instance, my previous rampage resulted in having Compose removed from Boost, because we have better libraries (Bind, Lambda, Phoenix) now. Doug

Doug Gregor <dgregor@cs.indiana.edu> writes:
On Jul 6, 2004, at 11:02 PM, Joel de Guzman wrote:
David Abrahams wrote:
Howard Hinnant <hinnant@twcny.rr.com> writes:
As I recall, call_traits was intended to work around the "reference to reference" problem for both parameters and return types. This problem has since been solved by cwg #106 ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 ). Or by boost::add_reference ;-)
Out of interest, when did call_traits came into existence? Was it prior to type_traits? When was it reviewed? It seems that we are re-reviewing call_traits again?
Sorry, it's my fault. I sometimes look at Boost and see these little libraries and wonder if they really belong at the same level as the Python lib, or Spirit, or the Graph lib, etc. Call traits seems like a trivial application of type traits, but hasn't been maintained with the same vigor.
That very trivialness is one of the things that makes the docs hard for me to understand. add_reference<add_const<T>::type>::type is really easy to grasp once you know the type traits library a little bit, but the amount of verbiage required to explain call_traits (not even very well) hardly justifies its functionality. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

"Howard Hinnant" <hinnant@twcny.rr.com> wrote in message news:D131A1F4-CEE6-11D8-ACE3-003065D18932@twcny.rr.com...
[...] I initially viewed call_traits as a way to optimize whether a type should be passed by const ref or by value. But I was mistaken. The real value was in passing/returning reference types without bumping into the reference-to-reference problem.
So are you saying that call_traits is *not* useful for said optimization? If so, why not? Dave --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.710 / Virus Database: 466 - Release Date: 6/23/2004

On Jul 6, 2004, at 11:37 AM, David B. Held wrote:
"Howard Hinnant" <hinnant@twcny.rr.com> wrote in message news:D131A1F4-CEE6-11D8-ACE3-003065D18932@twcny.rr.com...
[...] I initially viewed call_traits as a way to optimize whether a type should be passed by const ref or by value. But I was mistaken. The real value was in passing/returning reference types without bumping into the reference-to-reference problem.
So are you saying that call_traits is *not* useful for said optimization? If so, why not?
For it to make a significant difference in performance, say for passing a parameter, the function would have to be very short - short enough that it should be inlined. On Metrowerks Pro 9.2 / Mac I've just run the following experiment: inline int foo1(int i) { return i; } inline int foo2(const int& i) { return i; } int main() { int i = 1; return foo1(i); } I've looked at the generated (optimized) assembly of main, using both foo1 and foo2. The assembly is identical in both cases. No doubt I could come up with examples where the assembly is different. But I'm having more trouble coming up with a situation where the performance difference is enough that I'd want to start lacing my generic code with call_traits for this purpose. However if you have such examples, I'm interested in pursuing this further. -Howard

"Howard Hinnant" wrote:
So are you saying that call_traits is *not* useful for said optimization? If so, why not?
For it to make a significant difference in performance, say for passing a parameter, the function would have to be very short - short enough that it should be inlined.
...
On Metrowerks Pro 9.2 / Mac I've just run the following experiment:
I've looked at the generated (optimized) assembly of main, using both foo1 and foo2. The assembly is identical in both cases. No doubt I could come up with examples where the assembly is different.
More complex programs may not inline the function and difference will show up. Experimental version of STLport with call_traits like optimisation got ~5% speedup for vector<int>::push_back(). /Pavel

"Howard Hinnant" <hinnant@twcny.rr.com> wrote in message news:FAEED0B1-CF6E-11D8-8C1A-003065D18932@twcny.rr.com...
[...] For it to make a significant difference in performance, say for passing a parameter, the function would have to be very short - short enough that it should be inlined. [...] But I'm having more trouble coming up with a situation where the performance difference is enough that I'd want to start lacing my generic code with call_traits for this purpose. However if you have such examples, I'm interested in pursuing this further.
Well, I started using it in policy_ptr, where basically all the functions *are* very short and inlined, where performance matters, and where the library doesn't know what types are going to be passed to it. I think in the vast majority of cases, it won't make a difference, because a fundamental pointer type will be used; but I like to think that I'm improving the QoI by using it anyway. Dave --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.710 / Virus Database: 466 - Release Date: 6/23/2004

"David B. Held" <dheld@codelogicconsulting.com> writes:
"Howard Hinnant" <hinnant@twcny.rr.com> wrote in message news:FAEED0B1-CF6E-11D8-8C1A-003065D18932@twcny.rr.com...
[...] For it to make a significant difference in performance, say for passing a parameter, the function would have to be very short - short enough that it should be inlined. [...] But I'm having more trouble coming up with a situation where the performance difference is enough that I'd want to start lacing my generic code with call_traits for this purpose. However if you have such examples, I'm interested in pursuing this further.
Well, I started using it in policy_ptr, where basically all the functions *are* very short and inlined, where performance matters, and where the library doesn't know what types are going to be passed to it. I think in the vast majority of cases, it won't make a difference, because a fundamental pointer type will be used; but I like to think that I'm improving the QoI by using it anyway.
This might well be premature optimization. I'm not sure added complexity is ever a QOI improvement unless it is proven to improve usability or performance. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

I've looked at the generated (optimized) assembly of main, using both foo1 and foo2. The assembly is identical in both cases. No doubt I could come up with examples where the assembly is different. But I'm having more trouble coming up with a situation where the performance difference is enough that I'd want to start lacing my generic code with call_traits for this purpose. However if you have such examples, I'm interested in pursuing this further.
It started out as an optimisation, but even where the assembly is different, current processors are so fast at loads and stores, that the difference between pass by reference (involving one extra load in some cases) and pass by value is minimal. Except possibly in one case: if the value passed is used inside a loop, then passing by value may suppress the "aliasing issue" that "restrict" also addresses: template <class T> void fill_n(T* data, int len, call_traits<T>::call_type val) { while(len) { data[len--] == val; // if val is a reference it gets re-loaded every time rather than cached in a register } } John.

John Maddock wrote: [...]
template <class T> void fill_n(T* data, int len, call_traits<T>::call_type val) { while(len) { data[len--] == val; // if val is a reference it gets re-loaded every time rather than cached in a register } }
fill_n should just take val by value. There are "len" assignments in the loop; the additional cost of one copy is insignificant. No point on relying on heuristics here.
participants (11)
-
David Abrahams
-
David B. Held
-
Doug Gregor
-
Edward Diener
-
Eric Niebler
-
François Dumont
-
Howard Hinnant
-
Joel de Guzman
-
John Maddock
-
Pavel Vozenilek
-
Peter Dimov