Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2004-09-29 19:11:27


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk