
Terje Slettebø wrote:
[...]
I'm glad you like it ! Thanks for all the positive feedback ;+).
I've dropped your has_plus_op version into the operator traits unit test, and it compiles and runs flawlessly on Intel C++ 7.1, MSVC 7.1 and g++ 3.2. As you said in an earlier posting: I guess I had to see it with my own eyes. ;)
Beware! It might be Intel (or EDG) is not 100% supported out of the box. However it's a matter of seconds to find out and likely to be a matter of minutes to adjust it, if necessary. See the "how to port" part in the "readme.txt".
You've certainly done a lot of work, here... The table still has a dent-mark from my jaw. ;)
I see a lot of potential for this approach.
It's really astonishing - I am suprised, too. I refined the 'is_enum' hack I posted (somewhere in this thread) until its behaviour was aequivalent to the Type Traits library as one of the first tests. It turned out to be 20 (msvc, 10 gcc, 4 bcc) times faster, so I expected some speedup. But what I saw yesterday was exceeding all my expectations.
I also see you use inheritance to guide implicit conversions. Clever. :)
Just saying 'integral' means "match whatever integral type" and is a weaker match than 'lvalue<integral>' or 'rvalue<integral>'. Using 'integral_or_enum' is an even weaker match than 'integral' but still stronger than 'object_lvalue', which matches stronger than 'object_lvalue' which in turn is a stronger match than 'object'.... Using multiple inheritance only, would make rule set development very hard and error-prone. This way it's possible to emphasize quite complex rules without running into ambiguity problems. Using an extra argument for disambiguation should _only_ be required when things get extremely tricky, that is the rules _are_ in fact (sematically, that is) ambigous and need prioritization.
It also goes further than the original version, checking for lvalue/rvalue, which might also be useful for concept checking, where these are specified.
This check doesn't cost much - so it was reasonable to have it...
I'm wondering about the "two_way" part of the code, could you say what the name alludes to, and what code that refers to? Also, regarding this part:
The namespace 'two_way' defines the result type for a rule set of a 'two way filter', having two result states 'filter' and 'pass'. There could be a 'three way filter' with three states like "filter and return true", "filter and return false" and "let the delegate decide" for example or an 'n way filter' with a result type template to carry an integral value... In some "macro-ized" form these could be made interchangable... However, it may change and I am not sure on this, yet. Had to place this somewhere, though - and I did not want to obscure 'has_plus_op.hpp' with negligibilities.
type_filter::two_way::eq_pass< ::boost::has_plus_op_local::has_plus_op_prefilter<T,U>::value >
Is "eq_pass" used, to enable other conditions, like "not_eq_pass", or something like that? If not, why not something to this effect:
mpl::bool_< ::boost::has_plus_op_local::has_plus_op_prefilter<T,U>::value==::boost::type _filter::two_way::state_pass>
(The namespace nesting makes this look more complex than it is)
The == operator within an integral constant expression may confuse some compilers, so the comparison is wrapped within a metafunction.
Or, if we let ::boost::has_plus_op_local::has_plus_op_prefilter<T,U> act as mpl::bool_<>, itself (letting state_pass=true and state_filt=false):
I don't think it's a good idea (see below).
Nearly all dependecies are gone - I kept 'mpl::and_' (just because I was too lazy to change things which are likely to change again ;+) - actually we can get rid of this, too. ( For that matter it's probably a good idea to use these "bool_trait_(un)def" headers [boost/type_traits/detail], which seem much more portable than just inheriting from a "bool holder type").
I guess I have to be more precise: The problem is that some compilers do not properly inherit type/template/static-const members. In this case the carrier classes need special care to interoperate nicely with mpl placeholders. The Type Traits library addresses this problem with these def/undef multi-#include headers that define and undefine a set of macros to create the frontend class with all "workaround decorations" needed for the compiler in use. The '_impl' classes do not have to care about it and just publish a 'value' or 'type' member.
That may be an idea. We could go through any remaining dependencies, and see if we can do any reasonable changes to reduce their dependencies, again (and possibly compilation time), and/or improve portability.
There are not too many dependencies left, are there ;+) ? The actual operator tester is very flat. There's nothing to stip in the filter, either. Well, using mpl::and_ is _probably_ breaking a butterfly on a wheel here. On the other hand it's very portable and good readable. I will check on this.
The categorization pipeline was successfully tested with gcc 3.2, 3.3 and 3.4, msvc 13.10.3077, bcc 5.5.1, 5.6.4.
That's great. :)
By the way - I ran the (naiv) benchmark test on BCC and it worked without having to change anything.
I'll contact you off-list for the way forward, but I'd be interested in using this technique in all of the operator/concept traits library (where it makes sense), or some other form of library for operator/concept checking.
Great ! It will need some refinement in terms of wrapping this into a fine modular design supportive to library development. Any suggestions are welcome, of course ! Regards, Tobias