On Sat, Jun 7, 2014 at 11:19 PM, Peter Dimov
Andrey Semashev wrote:
I was thinking you were proposing a replacement for deriving traits from bool_.
More precisely, I was proposing a way for code that dispatches on bool_ to not require derivation from bool_. So that a library can use a core type trait (that does not derive from anything) and core::bool_ to dispatch in the same way it did before.
This is not a magic replacement. It still requires source changes.
Ok. Just for the record, the same can be achieved with mpl::bool_, even without modification: foo(mpl::bool_< is_pointer< int >::value >()); That is not to say we can add the conversion constructor to mpl::bool_.
My point was that your proposed bool_ doesn't fully reflect the current interface, so it can't replace it. In that case, is there a point to it?
Maybe. It depends.
The point is that there are two general types of MPL dependencies: libraries that do use metaprogramming facilities, and libraries that only use bool_, if_, and_, and similar things. If these things exist in Core, a library of the second kind can drop its MPL dependency.
Assuming these things will be in MPL.Core (and I really think we will have it, even for sake of improving dependencies of existing libraries), there is no benefit of having them in Core as well.
Of course, if these facilities are split into 'mpl_core', this will considerably lessen the need for duplication in 'core'.
Duplicating in 'core' has the advantage of not worrying about backward compatibility so we can avoid the no longer necessary workarounds and (ideally) offer the simplest and most straightforward implementation. And not duplicating has the advantage that there's no duplication. :-)
I would definitely vote for avoiding duplication (and for MPL.Core). We can always drop workarounds in MPL.Core, as well as make use of std::integral_constant and add the converting constructor. What other benefits could there be for a set of simple MPL components? OTOH, duplication of these components in Core may cause confusion and subtle errors (i.e. I provided a specialization for core::true_ and not mpl::true_ and my code is silently broken).
TypeTraits will still derive from mpl::bool_.
I'm not sure that our existing type traits need to continue deriving from mpl::bool_. They already derive from boost::integral_constant, which is expected to provide ::type as that's a requirement on std::integral_constant. On the other hand, there are likely many uses of type traits in an MPL context and I'm not sure what places, if any, need the ::tag for instance.
For purposes of tag dispatching and compatibility with standard type traits, it is sufficient to derive mpl::bool_ from boost::integral_constant, which could be an alias or derive from std::integral_constant. mpl::bool_ can add the ::tag typedef. If you want to just drop the mpl::bool_ part of the interface from type traits, that would be a breaking change, and arguably should be done as an alternative implementation of type traits (TypeTraits v2?). This might be a useful thing to do in perspective, but I don't think this is our immediate priority now to improve dependencies. I think MPL.Core and TypeTraits.Core would do better (for all Boost libraries) and simpler to achieve. I'm intentionally not calling TypeTraits v2 as TypeTraits.Core, as I'd really like TypeTraits.Core to not depend (interface-wise) on MPL or std::integral_constant or std:: type traits. I.e. TypeTraits.Core interface should only define a nested type ::type or constant ::value and not derive from any particular primitive (std or MPL). This still allows to implement TypeTraits.Core through std:: type traits.
We don't need another bool_ in Core (yet) and TypeTraits.Core would be enough for us.
Replacing use of TypeTraits with use of core type traits is precisely what demands the use of another bool_, because you can no longer use the old mpl::bool_ for dispatching a core type trait. Either we enhance mpl::bool_ with a converting constructor, or we switch to core::bool_.
In my view, TypeTraits.Core shall not be suitable for tag dispatching. This will be a foundation library, offering only the implementation of the traits. You'll have to use it with MPL.Core (i.e. mpl::bool_) or another (maybe a custom) similar value-to-type transform primitive. For conventional tag dispatching one would use the full TypeTraits, which would derive from mpl::bool_ and essentially provide the complete current interface of type traits. The full TypeTraits library will depend on MPL.Core, at the very least; I'm not sure if we'll need the full MPL there. As for Core, I'm not sure we'll need tag dispatching there at all. The same effect can be achieved with simple template specialization on constants.