I've taken care of the mpl -> detail detail -> iterator utility -> iterator critical dependencies, which improved things a bit. The new report is at http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html It includes reverse dependencies for each module and has been generated from the develop branch of the super-project.
On Wed, Jun 4, 2014 at 9:31 PM, Peter Dimov
I've taken care of the
mpl -> detail detail -> iterator utility -> iterator
critical dependencies, which improved things a bit. The new report is at
http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html
I've been watching system and filesystem, and they are improved dramatically from where they were when the Core project started! Good job! --Beman
Beman Dawes wrote:
I've been watching system and filesystem, and they are improved dramatically from where they were when the Core project started! Good job!
Thanks, on behalf of the whole Core team and friends. Separately compiled libraries have an 'unfair' advantage over header-based ones in the report, which is only based on the contents of the include/ directory. They don't seem to exploit this fully though. :-) PS. Beman, did you get my mail about a possible Filesystem TS issue?
On Thu, Jun 5, 2014 at 10:59 AM, Peter Dimov
Beman Dawes wrote:
I've been watching system and filesystem, and they are improved
dramatically from where they were when the Core project started! Good job!
Thanks, on behalf of the whole Core team and friends.
Separately compiled libraries have an 'unfair' advantage over header-based ones in the report, which is only based on the contents of the include/ directory. They don't seem to exploit this fully though. :-)
PS. Beman, did you get my mail about a possible Filesystem TS issue?
Yes, but haven't processed it yet. --Beman
El 05/06/2014 3:31, Peter Dimov escribió:
I've taken care of the
mpl -> detail detail -> iterator utility -> iterator
critical dependencies, which improved things a bit. The new report is at
http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html
Many thanks Peter. An extremely useful report. Could we add this type of information to the regression report in the future? Best, Ion
On 5 June 2014 12:48, Ion Gaztañaga
El 05/06/2014 3:31, Peter Dimov escribió:
I've taken care of the
mpl -> detail detail -> iterator utility -> iterator
critical dependencies, which improved things a bit. The new report is at
http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html
Many thanks Peter. An extremely useful report. Could we add this type of information to the regression report in the future?
It would be nice to have a more unified approach to the various reports we're creating (pull requests, inspect, dependencies, etc.). Perhaps a new website would be appropriate, it's a bit awkward integrating these things into the main site.
Ion Gaztañaga wrote:
Many thanks Peter. An extremely useful report. Could we add this type of information to the regression report in the future?
I can add the program that generates it as a submodule in tools/boostdep (say), when I finish polishing it. I don't have a convenient way to script it to run regularly and unattended though. Someone else would need to take care of that part. :-)
El 05/06/2014 17:03, Peter Dimov escribió:
Ion Gaztañaga wrote:
Many thanks Peter. An extremely useful report. Could we add this type of information to the regression report in the future?
I can add the program that generates it as a submodule in tools/boostdep (say), when I finish polishing it. I don't have a convenient way to script it to run regularly and unattended though. Someone else would need to take care of that part. :-)
Ok, understood. We'll think about scripting it once you think it's polished enough then. Best, Ion
2014-06-05 5:31 GMT+04:00 Peter Dimov
I've taken care of the
mpl -> detail detail -> iterator utility -> iterator
critical dependencies, which improved things a bit. The new report is at
http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html
It includes reverse dependencies for each module and has been generated from the develop branch of the super-project.
Great thanks!
Would it be good to move a single
On Thu, Jun 5, 2014 at 5:37 PM, Antony Polukhin
Would it be good to move a single
header into the Boost.Core? This header depends only on Boost.Config. It adds dependency to a whole Boost.Functional library for the following libraries: array, container, filesystem, multiindex, thread, type_index, variant.
Hmm, although I can see benefits of it, I don't like tearing forward declarations from definitions.
Andrey Semashev wrote:
On Thu, Jun 5, 2014 at 5:37 PM, Antony Polukhin
wrote: Would it be good to move a single
header into the Boost.Core? This header depends only on Boost.Config. It adds dependency to a whole Boost.Functional library for the following libraries: array, container, filesystem, multiindex, thread, type_index, variant. Hmm, although I can see benefits of it, I don't like tearing forward declarations from definitions.
I don't think it should go Core. On the other hand, the whole purpose of forward declarations is to let you not depend on the definition. This is still valuable when the _fwd header is in the same module, as it decreases the actual dependencies in terms of headers included, but this decrease doesn't show up in a module dependency report. Neither will it affect a module-based automatic downloader. Therefore, it might be worth thinking about a separate module that hosts just forward declarations. The danger of declarations and definitions going out of sync can be avoided by having tests (in the 'forward' module) that include both the declaration and the actual definition. Incidentally, 'functional/hash' has always bothered me. What was wrong with just 'hash'? Hierarchies do have its place but hash is hash, nothing particularly functional about it.
On 5 June 2014 15:40, Peter Dimov
On the other hand, the whole purpose of forward declarations is to let you not depend on the definition. This is still valuable when the _fwd header is in the same module, as it decreases the actual dependencies in terms of headers included, but this decrease doesn't show up in a module dependency report. Neither will it affect a module-based automatic downloader.
Someone suggested having dependencies on a subset of a module. Could set one up so that not all the headers are soft-linked.
Incidentally, 'functional/hash' has always bothered me. What was wrong with just 'hash'? Hierarchies do have its place but hash is hash, nothing particularly functional about it.
It was because std::hash is part of the functional header.
Antony Polukhin wrote:
Would it be good to move a single
header into the Boost.Core? This header depends only on Boost.Config. It adds dependency to a whole Boost.Functional library for the following libraries: array, container, filesystem, multiindex, thread, type_index, variant.
While the general subject of forwarding headers still deserves consideration, in this specific case I wonder if moving funcional/hash into its own 'hash' module would not alleviate most of the problem. I know that std::hash is in <functional>, but it still feels wrong having boost::hash in boost/functional/hash.hpp.
On 7 June 2014 17:41, Peter Dimov
Antony Polukhin wrote:
Would it be good to move a single
header into the Boost.Core? This header depends only on Boost.Config. It adds dependency to a whole Boost.Functional library for the following libraries: array, container, filesystem, multiindex, thread, type_index, variant. While the general subject of forwarding headers still deserves consideration, in this specific case I wonder if moving funcional/hash into its own 'hash' module would not alleviate most of the problem.
The point of the forwarding header was to be a lightweight header, because the main header is quite heavy, so separating out the forwarding header is probably the right thing to do. I can't guarantee that I won't add any new dependencies to hash, so if you rely on hash having less dependencies, then this problem might resurface in the future. Looking at your report, many of functional's dependencies seem to be caused by problems elsewhere, e.g. boost/functional/factory.hpp includes boost/pointee.hpp from iterator, which pulls in a lot of modules. I think the problem there is with boost/pointee.hpp.
Daniel James wrote:
On 7 June 2014 17:41, Peter Dimov
wrote: While the general subject of forwarding headers still deserves consideration, in this specific case I wonder if moving funcional/hash into its own 'hash' module would not alleviate most of the problem.
The point of the forwarding header was to be a lightweight header, because the main header is quite heavy, so separating out the forwarding header is probably the right thing to do.
It's definitely the right thing to do. This doesn't mean that splitting 'hash' into its own module isn't also the right thing to do. That's what modularization means - to isolate independent components. 'hash' is completely independent of the rest of the functional library, it's even of a different kind.
Looking at your report, many of functional's dependencies seem to be caused by problems elsewhere, e.g. boost/functional/factory.hpp includes boost/pointee.hpp from iterator, which pulls in a lot of modules. I think the problem there is with boost/pointee.hpp.
boost/pointee.hpp, along with boost/indirect_reference.hpp and boost/detail/is_incrementable.hpp, are an obvious target, one that I've already identified. If you look at them, however, you'll see that they can't go to Core in their present form, as they have dependencies on MPL and TypeTraits. They will be dealt with, in due time. At the moment, I've been concentrating on (a) low-hanging fruits that (b) don't have potential to break code. 'pointee' and friends are neither. Splitting 'hash' into its own module is both. Separating hash_fwd could be, if we figure out where to put it, which I estimate will take time.
On 8 June 2014 12:33, Peter Dimov
Daniel James wrote:
On 7 June 2014 17:41, Peter Dimov
wrote: While the general subject of forwarding headers still deserves > consideration, in this specific case I wonder if moving funcional/hash > into its own 'hash' module would not alleviate most of the problem.
The point of the forwarding header was to be a lightweight header, because the main header is quite heavy, so separating out the forwarding header is probably the right thing to do.
It's definitely the right thing to do.
This doesn't mean that splitting 'hash' into its own module isn't also the right thing to do.
I didn't make that inference. If you look in the archives I wanted hash to be a separate module before the conversion.
That's what modularization means - to isolate independent components.
Well, I never! And I thought it meant arguing on mailing lists.
'hash' is completely independent of the rest of the functional library, it's even of a different kind.
Functional includes several disparate libraries.
Looking at your report, many of functional's dependencies seem to be caused by problems elsewhere, e.g. boost/functional/factory.hpp includes boost/pointee.hpp from iterator, which pulls in a lot of modules. I think the problem there is with boost/pointee.hpp.
boost/pointee.hpp, along with boost/indirect_reference.hpp and boost/detail/is_incrementable.hpp, are an obvious target, one that I've already identified. If you look at them, however, you'll see that they can't go to Core in their present form, as they have dependencies on MPL and TypeTraits. They will be dealt with, in due time.
At the moment, I've been concentrating on (a) low-hanging fruits that (b) don't have potential to break code. 'pointee' and friends are neither. Splitting 'hash' into its own module is both. Separating hash_fwd could be, if we figure out where to put it, which I estimate will take time.
Why the rush? I've got enough things to deal with in this release, I don't want to add another.
Daniel James:
Why the rush? I've got enough things to deal with in this release, I don't want to add another.
There is no rush. I had misinterpreted your responses as your being opposed to 'hash' being its own module. Expecting me to scan the archives each time is a high bar. Perhaps others are capable of that; I am not. Had you just said "I agree that splitting 'hash' is a good idea, but I don't have time for that before the release", that would have been that.
On 8 June 2014 13:22, Peter Dimov
Had you just said "I agree that splitting 'hash' is a good idea, but I don't have time for that before the release", that would have been that.
But that isn't what I think. I want to wait and see how the current crop of changes work out before making a decision.
Le 05/06/14 03:31, Peter Dimov a écrit :
I've taken care of the
mpl -> detail detail -> iterator utility -> iterator
critical dependencies, which improved things a bit. The new report is at
http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html
It includes reverse dependencies for each module and has been generated from the develop branch of the super-project.
Hi Peter, from my point of view there is something wrong on the levels report. mpl and type_traits cannot be on level 3 as they depend mutually (on libraries on level 3). typeof and utility can not be either as it depends on mpl and type_traits. The definition of level must be strict otherwise we introduce cycles. Level 3 * bind http://www.pdimov.com/tmp/report-6d1f271/bind.html ? config core static_assert * logic http://www.pdimov.com/tmp/report-6d1f271/logic.html ? config core * mpl http://www.pdimov.com/tmp/report-6d1f271/mpl.html ? config core predef preprocessor static_assert type_traits utility * system http://www.pdimov.com/tmp/report-6d1f271/system.html ? assert config core predef * type_traits http://www.pdimov.com/tmp/report-6d1f271/type_traits.html ? config core mpl preprocessor static_assert typeof utility * typeof http://www.pdimov.com/tmp/report-6d1f271/typeof.html ? config core mpl preprocessor type_traits * utility http://www.pdimov.com/tmp/report-6d1f271/utility.html ? config core mpl preprocessor static_assert throw_exception type_traits * If we create as I suggested a module that contains mpl + type_traits, as I suggested, we could have this module at level 3 and the others typeof and utility at level 4. This could be temporary, the time we reach to manage with the mpl<->type_traits dependency cycle. You proposition of making a type_traits -> mpl -> core_type_traits would break the cycle but this would take some time. I think that doing this kind of things could be useful to see clearer, where do we have cycles that must be resolved in some way. Best, Vicente
Vicente J. Botet Escriba wrote:
Hi Peter,
from my point of view there is something wrong on the levels report. mpl and type_traits cannot be on level 3 as they depend mutually (on libraries on level 3). typeof and utility can not be either as it depends on mpl and type_traits.
The definition of level must be strict otherwise we introduce cycles.
I didn't introduce the cycles, they were already there. :-) It is impossible to have a strict level definition, X depends on Y implies level(X) > level(Y) when there are cycles. That should be obvious: level(X) can't be both less than, and greater than, level(Y). So the best we can possibly do is weak level assignment, X depends on Y implies level(X) >= level(Y) from which it follows that when X and Y depend on each other, level(X) == level(Y). Basic mathematics. :-) And when you have type_traits -> mpl -> utility -> type_traits, this also implies that those three are on the same level. There is no other way that could possibly satisfy the definition. The current level assignments are slightly stronger than that, they satisfy the property that level(X) == level(Y) only when X and Y form a dependency cycle. It's not possible to do better, I'm afraid.
If we create as I suggested a module that contains mpl + type_traits, as I suggested, we could have this module at level 3 and the others typeof and utility at level 4.
No, because type_traits depends on typeof: http://www.pdimov.com/tmp/report-6d1f271/type_traits.html#typeof and mpl depends on utility: http://www.pdimov.com/tmp/report-6d1f271/mpl.html#utility You can't have level 3 libraries depending on level 4.
Le 05/06/14 19:15, Peter Dimov a écrit :
Vicente J. Botet Escriba wrote:
Hi Peter,
from my point of view there is something wrong on the levels report. mpl and type_traits cannot be on level 3 as they depend mutually (on libraries on level 3). typeof and utility can not be either as it depends on mpl and type_traits.
The definition of level must be strict otherwise we introduce cycles.
I didn't introduce the cycles, they were already there. :-)
It is impossible to have a strict level definition,
X depends on Y implies level(X) > level(Y)
when there are cycles. That should be obvious: level(X) can't be both less than, and greater than, level(Y).
So the best we can possibly do is weak level assignment,
X depends on Y implies level(X) >= level(Y)
from which it follows that when X and Y depend on each other, level(X) == level(Y).
Basic mathematics. :-)
And when you have type_traits -> mpl -> utility -> type_traits, this also implies that those three are on the same level. There is no other way that could possibly satisfy the definition.
The current level assignments are slightly stronger than that, they satisfy the property that level(X) == level(Y) only when X and Y form a dependency cycle. It's not possible to do better, I'm afraid.
If we create as I suggested a module that contains mpl + type_traits, as I suggested, we could have this module at level 3 and the others typeof and utility at level 4.
No, because type_traits depends on typeof:
http://www.pdimov.com/tmp/report-6d1f271/type_traits.html#typeof
and mpl depends on utility:
http://www.pdimov.com/tmp/report-6d1f271/mpl.html#utility
You can't have level 3 libraries depending on level 4.
A gree that we can not assign the strict level until all the cycles are broken. What I'm just suggesting is to put all the libraries that form a cycle into the same strict module For what you report I would create a module type_traits<=>mpl<=>utility<=>typeof This macro-module can be at level 4. The libraries that depends on one of this library would depend on this macro-module. We will see what needs to be done to break this cycle. If declval moves from utility to type_traits we break the type_traits->utility dependency. I would also move typeof to type_traits. After this changes we will have a macro-module type_traits<=>mpl. Other cycles will appear on higher levels, and I propose to take care of them in the same way. Best, Vicente
Le 05/06/14 19:46, Peter Dimov a écrit :
Vicente J. Botet Escriba wrote:
If declval moves from utility to type_traits we break the type_traits->utility dependency.
That's already done. Great, the dependency type_traits->utility dependency is broken then.
I would also move typeof to type_traits.
I'd actually handle this in the opposite way, by moving common_type to typeof.
typeof is an emulation/workaround of a missing C++98 feature. It seems to me natural that this library should be quite close to the Core module. Anyway, here are the alternatives: A- Create a macro-module common_type <=> typeof B- Extract common_type from type_trais in an isolated module. C- Add typeof to type_traits. A- Peter? B- C- Vicente What do other think? Best, Vicente
On Thursday 05 June 2014 20:46:58 Peter Dimov wrote:
Vicente J. Botet Escriba wrote:
If declval moves from utility to type_traits we break the type_traits->utility dependency.
That's already done.
I can see that its docs are still in Utility. Is this an oversight?
On Thursday 12 June 2014 01:36:27 you wrote:
On Thursday 05 June 2014 20:46:58 Peter Dimov wrote:
Vicente J. Botet Escriba wrote:
If declval moves from utility to type_traits we break the type_traits->utility dependency.
That's already done.
I can see that its docs are still in Utility. Is this an oversight?
On a related note, I can see addressof, checked_delete, enable_if, noncopyable, ref, value_init tests and some docs in Utility as well. I think these should be moved to Core or removed, if the tests in Core already cover these cases.
Andrey Semashev wrote:
On a related note, I can see addressof, checked_delete, enable_if, noncopyable, ref, value_init tests and some docs in Utility as well.
value_init is still in Utility, I think.
I think these should be moved to Core or removed, if the tests in Core already cover these cases.
On the one hand, test duplication wastes resources. On the other, I prefer leaving the old tests there for a release or two, to be on the safe side, because it'd be possible for the new tests to diverge and no longer test previously valid functionality. (An obvious example would be testing boost/core/header.hpp instead of boost/utility/header.hpp.)
On Thursday 12 June 2014 01:01:40 Peter Dimov wrote:
Andrey Semashev wrote:
On a related note, I can see addressof, checked_delete, enable_if, noncopyable, ref, value_init tests and some docs in Utility as well.
value_init is still in Utility, I think.
Oh, right, I got ahead of time. :)
I think these should be moved to Core or removed, if the tests in Core already cover these cases.
On the one hand, test duplication wastes resources.
On the other, I prefer leaving the old tests there for a release or two, to be on the safe side, because it'd be possible for the new tests to diverge and no longer test previously valid functionality. (An obvious example would be testing boost/core/header.hpp instead of boost/utility/header.hpp.)
I think everything that needs to be tested, needs to be tested in Core. That includes legacy forwarding headers, if needed, although I wouldn't say that such a test is very useful. Duplicating tests just adds confusion (and wastes resources, as you said). Even if we don't forget about them, which is possible, when the time comes it'll be more difficult to get rid of them. One would have to analyze both Core and Utility tests to see if anything needs to be pulled from Utility before removal. It's easier and safer to do everything once now, when the context is not lost.
Andrey, The copyright comments you've added in Core are incorrect. The copyright in the documentation files should reflect the copyright of the documentation. The copyright in the source files should reflect the copyright of the source files. The two are independent. Adding a line to a source file does not make one hold copyright on the documentation, and vice versa. Please revise accordingly, or revert.
On Thursday 12 June 2014 01:43:17 Peter Dimov wrote:
Andrey,
The copyright comments you've added in Core are incorrect.
The copyright in the documentation files should reflect the copyright of the documentation. The copyright in the source files should reflect the copyright of the source files. The two are independent. Adding a line to a source file does not make one hold copyright on the documentation, and vice versa. Please revise accordingly, or revert.
Ok, will do.
On Thursday 12 June 2014 02:48:22 you wrote:
On Thursday 12 June 2014 01:43:17 Peter Dimov wrote:
Andrey,
The copyright comments you've added in Core are incorrect.
The copyright in the documentation files should reflect the copyright of the documentation. The copyright in the source files should reflect the copyright of the source files. The two are independent. Adding a line to a source file does not make one hold copyright on the documentation, and vice versa. Please revise accordingly, or revert.
Ok, will do.
I've corrected the copyrights in the docs, based on git log. Let me know if you think anything is still incorrect. The copyrights in the source code were only added for the forwarding headers Glen and I created. I think they are correct.
Andrey Semashev wrote:
I think everything that needs to be tested, needs to be tested in Core. That includes legacy forwarding headers, if needed, although I wouldn't say that such a test is very useful.
Duplicating tests just adds confusion (and wastes resources, as you said). Even if we don't forget about them, which is possible, when the time comes it'll be more difficult to get rid of them. One would have to analyze both Core and Utility tests to see if anything needs to be pulled from Utility before removal. It's easier and safer to do everything once now, when the context is not lost.
That's a good point. OK, I agree that tests that are now in Core can be removed from Utility. The old documentation probably needs to link to the new one so that people can "find their stuff". :-)
On Thursday 12 June 2014 01:59:22 Peter Dimov wrote:
Andrey Semashev wrote:
I think everything that needs to be tested, needs to be tested in Core. That includes legacy forwarding headers, if needed, although I wouldn't say that such a test is very useful.
Duplicating tests just adds confusion (and wastes resources, as you said). Even if we don't forget about them, which is possible, when the time comes it'll be more difficult to get rid of them. One would have to analyze both Core and Utility tests to see if anything needs to be pulled from Utility before removal. It's easier and safer to do everything once now, when the context is not lost.
That's a good point.
OK, I agree that tests that are now in Core can be removed from Utility.
Do you mean that all tests are in Core already and the tests in Utility can be safely removed? I didn't see your commit in Core. Will you remove the tests or shall I do this?
The old documentation probably needs to link to the new one so that people can "find their stuff". :-)
Agreed.
Andrey Semashev wrote:
Do you mean that all tests are in Core already and the tests in Utility can be safely removed?
If they aren't, it would be because we've missed something. All of the components that have been moved should have had their tests moved as well. Let me know if a test is missing.
On Thursday 12 June 2014 02:41:26 Peter Dimov wrote:
Andrey Semashev wrote:
Do you mean that all tests are in Core already and the tests in Utility can be safely removed?
If they aren't, it would be because we've missed something. All of the components that have been moved should have had their tests moved as well. Let me know if a test is missing.
I've moved the missing bits and removed the duplicate tests and docs from Utility. I didn't move declval docs as I don't have access to TypeTraits. I think you and John will have to do it.
Andrey Semashev wrote:
On Thursday 05 June 2014 20:46:58 Peter Dimov wrote:
Vicente J. Botet Escriba wrote:
If declval moves from utility to type_traits we break the type_traits->utility dependency.
That's already done.
I can see that its docs are still in Utility. Is this an oversight?
Yes, I think that declval's docs need to be moved, or at least copied, to TypeTraits. That would probably imply moving the header to boost/type_traits as well.
On Thursday 05 June 2014 19:39:21 Vicente J. Botet Escriba wrote:
What I'm just suggesting is to put all the libraries that form a cycle into the same strict module For what you report I would create a module
type_traits<=>mpl<=>utility<=>typeof
This macro-module can be at level 4. The libraries that depends on one of this library would depend on this macro-module. We will see what needs to be done to break this cycle.
I don't think we should place components together just on dependency basis. Modules now roughly correspond to libraries that serve different purposes. I like the separation. Merging libraries together is a step backward to monolithic Boost, IMO. It doesn't remove any dependencies, it simply hides them.
Le 05/06/14 19:56, Andrey Semashev a écrit :
What I'm just suggesting is to put all the libraries that form a cycle into the same strict module For what you report I would create a module
type_traits<=>mpl<=>utility<=>typeof
This macro-module can be at level 4. The libraries that depends on one of this library would depend on this macro-module. We will see what needs to be done to break this cycle. I don't think we should place components together just on dependency basis. Modules now roughly correspond to libraries that serve different purposes. I
On Thursday 05 June 2014 19:39:21 Vicente J. Botet Escriba wrote: like the separation. Merging libraries together is a step backward to monolithic Boost, IMO. It doesn't remove any dependencies, it simply hides them.
This is temporary, and allows to help to go on the level identification.
Anyway, here is my proposal to break the mpl -> type_traits dependency
(following the Peter suggestion)
- Move to a new core_type_traits everything that make mpl depend on
type_traits
*|boost/type_traits/detail/bool_trait_def.hpp||
* boost/type_traits/detail/bool_trait_undef.hpp||
* boost/type_traits/is_class.hpp||
* boost/type_traits/is_empty.hpp||
* boost/type_traits/is_reference.hpp||
* boost/type_traits/is_same.hpp|
* boost/mpl/bool.hpp
* boost/mpl/aux_/lambda_support.hpp
* boost/mpl/bool_fwd.hpp
* boost/mpl/integral_c_tag.hpp
* boost/mpl/aux_/config/static_constant.hpp
| * boost/mpl/aux_/adl_barrier.hpp
* boost/mpl/aux_/config/adl.hpp
* boost/mpl/aux_/config/gcc.hpp
* boost/mpl/aux_/config/msvc.hpp
* boost/mpl/aux_/config/intel.hpp
* boost/mpl/aux_/config/workaround.hpp
|
|- Replace the use of boost/type_traits/same_traits.hpp by
2014-06-05 23:45 GMT+04:00 Vicente J. Botet Escriba < vicente.botet@wanadoo.fr>:
Anyway, here is my proposal to break the mpl -> type_traits dependency (following the Peter suggestion)
- Move to a new core_type_traits everything that make mpl depend on type_traits *|boost/type_traits/detail/bool_trait_def.hpp|| * boost/type_traits/detail/bool_trait_undef.hpp|| * boost/type_traits/is_class.hpp|| * boost/type_traits/is_empty.hpp|| * boost/type_traits/is_reference.hpp|| * boost/type_traits/is_same.hpp| * boost/mpl/bool.hpp * boost/mpl/aux_/lambda_support.hpp * boost/mpl/bool_fwd.hpp * boost/mpl/integral_c_tag.hpp * boost/mpl/aux_/config/static_constant.hpp | * boost/mpl/aux_/adl_barrier.hpp * boost/mpl/aux_/config/adl.hpp * boost/mpl/aux_/config/gcc.hpp * boost/mpl/aux_/config/msvc.hpp * boost/mpl/aux_/config/intel.hpp * boost/mpl/aux_/config/workaround.hpp
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library? Those classes are already mostly the part of C++, they are very simple and very widely used. Such reorganization will remove the dependency to MPL from many libraries. -- Best regards, Antony Polukhin
Antony Polukhin wrote:
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library?
No, a header called boost/mpl/something.hpp will never be part of Core, and neither will a component boost::mpl::something. We might duplicate these as boost/core/something.hpp and boost::core::something, but they will not be quite the same as their mpl counterparts, and will not magically make a module that includes a boost/mpl/ header drop its dependency to MPL. As John said, let's not get carried away. Module names, header directories, namespaces should match. boost/, boost/detail/, boost/pending/ headers that do not obviously belong to a specific module can arguably be considered fair game.
El 06/06/2014 13:17, Peter Dimov escribió:
Antony Polukhin wrote:
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library?
No, a header called boost/mpl/something.hpp will never be part of Core, and neither will a component boost::mpl::something. We might duplicate these as boost/core/something.hpp and boost::core::something, but they will not be quite the same as their mpl counterparts, and will not magically make a module that includes a boost/mpl/ header drop its dependency to MPL.
An option is to implement them into boost::core namespace and inject them into boost::mpl namespace in boost/mpl/. Then each library can break mpl dependencies incluing core headers and namespaces instead of mpl ones. But this is not trivial. Best, Ion
On Friday 06 June 2014 13:43:37 Ion Gaztañaga wrote:
El 06/06/2014 13:17, Peter Dimov escribió:
Antony Polukhin wrote:
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library?
No, a header called boost/mpl/something.hpp will never be part of Core, and neither will a component boost::mpl::something. We might duplicate these as boost/core/something.hpp and boost::core::something, but they will not be quite the same as their mpl counterparts, and will not magically make a module that includes a boost/mpl/ header drop its dependency to MPL.
An option is to implement them into boost::core namespace and inject them into boost::mpl namespace in boost/mpl/. Then each library can break mpl dependencies incluing core headers and namespaces instead of mpl ones. But this is not trivial.
From dependencies standpoint, MPL does not add much, see our earlier exchange [1]. I think value_init can be moved to Core and changed to depend on TypeTraits.Core once it's ready. detail/endian.hpp has been handled already.
Even now, looking at the report [2], the situation is much better than it was before, when we discussed it. MPL decomposition is also pending, but it's probably better to split it into two modules MPL and MPL.Core, similar to TypeTraits. For many cases dependency on MPL.Core would be enough. [1] http://lists.boost.org/Archives/boost/2014/06/213916.php [2] http://www.pdimov.com/tmp/report-6d1f271/mpl.html
2014-06-06 16:04 GMT+04:00 Andrey Semashev
MPL decomposition is also pending, but it's probably better to split it into two modules MPL and MPL.Core, similar to TypeTraits. For many cases dependency on MPL.Core would be enough.
Yes, it's much better than moving parts of the MPL into the Core. Looks like MPL.Core could depend only on libraries from level0 and I love it this way! -- Best regards, Antony Polukhin
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library?
No, a header called boost/mpl/something.hpp will never be part of Core, and neither will a component boost::mpl::something. We might duplicate these as boost/core/something.hpp and boost::core::something, but they will not be quite the same as their mpl counterparts, and will not magically make a module that includes a boost/mpl/ header drop its dependency to MPL.
An option is to implement them into boost::core namespace and inject them into boost::mpl namespace in boost/mpl/. Then each library can break mpl dependencies incluing core headers and namespaces instead of mpl ones. But this is not trivial.
From dependencies standpoint, MPL does not add much, see our earlier exchange [1]. I think value_init can be moved to Core and changed to depend on TypeTraits.Core once it's ready. detail/endian.hpp has been handled already.
Even now, looking at the report [2], the situation is much better than it was before, when we discussed it.
MPL decomposition is also pending, but it's probably better to split it into two modules MPL and MPL.Core, similar to TypeTraits. For many cases dependency on MPL.Core would be enough.
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of
MPL full, either to core, or to some mpl_core, then there's no need to
split type_traits anymore.
Indeed I suspect there's a huge amount of obfuscated code inherited from
mpl's broken-compiler-workarounds that can now be removed: not only do
we not support those compilers any more, but given that they haven't
been tested in heaven knows how long they're unlikely to compile *any*
of modern Boost anyway.
In fact in C++11 it makes sense to me have:
namespace boost{ namespace mpl{
template <bool b>
using bool_ = std::integral_constant
On Friday 06 June 2014 16:39:13 John Maddock wrote:
MPL decomposition is also pending, but it's probably better to split it into two modules MPL and MPL.Core, similar to TypeTraits. For many cases dependency on MPL.Core would be enough.
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of MPL full, either to core, or to some mpl_core, then there's no need to split type_traits anymore.
Yes, that's one way to do it. However, TypeTraits.Core could have no dependency on MPL at all an be sufficient for things like value_init.hpp and blank.hpp. Arguably this way has more potential.
Indeed I suspect there's a huge amount of obfuscated code inherited from mpl's broken-compiler-workarounds that can now be removed: not only do we not support those compilers any more, but given that they haven't been tested in heaven knows how long they're unlikely to compile *any* of modern Boost anyway.
In fact in C++11 it makes sense to me have:
namespace boost{ namespace mpl{
template <bool b> using bool_ = std::integral_constant
; template <int i> using int_ = std::integral_constant ; }
// replaces boost::integral_constant: using std::integral_constant;
}
Now any function or template that's overloaded/specialized on mpl::bool_ or int_ will also "just work" with std:: type_traits as well as boost ones.
Yes, that's something to consider when working on MPL.Core.
On 6/6/2014 11:39 AM, John Maddock wrote:
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library?
No, a header called boost/mpl/something.hpp will never be part of Core, and neither will a component boost::mpl::something. We might duplicate these as boost/core/something.hpp and boost::core::something, but they will not be quite the same as their mpl counterparts, and will not magically make a module that includes a boost/mpl/ header drop its dependency to MPL.
An option is to implement them into boost::core namespace and inject them into boost::mpl namespace in boost/mpl/. Then each library can break mpl dependencies incluing core headers and namespaces instead of mpl ones. But this is not trivial.
From dependencies standpoint, MPL does not add much, see our earlier exchange [1]. I think value_init can be moved to Core and changed to depend on TypeTraits.Core once it's ready. detail/endian.hpp has been handled already.
Even now, looking at the report [2], the situation is much better than it was before, when we discussed it.
MPL decomposition is also pending, but it's probably better to split it into two modules MPL and MPL.Core, similar to TypeTraits. For many cases dependency on MPL.Core would be enough.
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of MPL full, either to core, or to some mpl_core, then there's no need to split type_traits anymore.
Indeed I suspect there's a huge amount of obfuscated code inherited from mpl's broken-compiler-workarounds that can now be removed: not only do we not support those compilers any more, but given that they haven't been tested in heaven knows how long they're unlikely to compile *any* of modern Boost anyway.
Based on Stephen Kelly's recommendations I actually removed a bunch of old workarounds in MPL for compilers which we don't support anymore. I even posted about it on this mailing list. But Daniel james objected to this being done for the 'develop' branch of MPL so I posted the change to a remote branch of MPL called 'remotes/origin/mfixes'. Looking through code in MPL, and other long-standing libraries may be similar, the need to keep compiler workarounds in the code for compilers which are obsolete, or do not implement basic parts of even the C++ 98 standard, makes understanding and updating code fairly difficult in many cases. I believe that Boost has a right to say to those who still want to use some of these compilers with Boost that they will have to stick to previous versions. It really becomes difficult for a number of Boost libraries to move forward if they have to continually support poorly conforming compilers. As obvious examples I would not bother trying to support VC++ versions prior to VS2005/VC8 and I would not bother trying to support gcc versions prior to 4.0 etc.
Edward Diener wrote:
Based on Stephen Kelly's recommendations I actually removed a bunch of old workarounds in MPL for compilers which we don't support anymore. I even posted about it on this mailing list. But Daniel james objected to this being done for the 'develop' branch of MPL so I posted the change to a remote branch of MPL called 'remotes/origin/mfixes'.
I'm interested in your changes, but can't find them. The diff between mfixes..develop shows some GPU-related stuff and other things done to the develop branch. I'm not seeing any workaround removals.
On 6/6/2014 4:52 PM, Peter Dimov wrote:
Edward Diener wrote:
Based on Stephen Kelly's recommendations I actually removed a bunch of old workarounds in MPL for compilers which we don't support anymore. I even posted about it on this mailing list. But Daniel james objected to this being done for the 'develop' branch of MPL so I posted the change to a remote branch of MPL called 'remotes/origin/mfixes'.
I'm interested in your changes, but can't find them. The diff between mfixes..develop shows some GPU-related stuff and other things done to the develop branch. I'm not seeing any workaround removals.
I gave the wrong information. The changes were actually pushed on MPL to 'remotes/origin/SKChanges'. At one point there were in MPL 'develop' and having watched the regression tests I wanted to merge them into MPL 'master'. I believe Daniel James reverted them on 'develop'. My 'remotes/origin/mfixes' was something else related to testing clang on Windows with VC++ RTL.
On 6 June 2014 21:41, Edward Diener
Looking through code in MPL, and other long-standing libraries may be similar, the need to keep compiler workarounds in the code for compilers which are obsolete, or do not implement basic parts of even the C++ 98 standard, makes understanding and updating code fairly difficult in many cases. I believe that Boost has a right to say to those who still want to use some of these compilers with Boost that they will have to stick to previous versions. It really becomes difficult for a number of Boost libraries to move forward if they have to continually support poorly conforming compilers. As obvious examples I would not bother trying to support VC++ versions prior to VS2005/VC8 and I would not bother trying to support gcc versions prior to 4.0 etc.
It would be nice if you responded to what I wrote rather than what you imagined I wrote. The problem with the MPL changes was that they were non-trivial, and for a library which is very arcane (with or without workarounds), has little maintenance and a lot of dependants, some of which are unmaintained. Also, many of the dependants hadn't merged Stephen Kelly's changes (some still haven't) and it wasn't clear if it was safe to merge MPL before them. It was nothing to do with maintaining support for Visual C++ 7.0.
On 6/6/2014 5:23 PM, Daniel James wrote:
On 6 June 2014 21:41, Edward Diener
wrote: Looking through code in MPL, and other long-standing libraries may be similar, the need to keep compiler workarounds in the code for compilers which are obsolete, or do not implement basic parts of even the C++ 98 standard, makes understanding and updating code fairly difficult in many cases. I believe that Boost has a right to say to those who still want to use some of these compilers with Boost that they will have to stick to previous versions. It really becomes difficult for a number of Boost libraries to move forward if they have to continually support poorly conforming compilers. As obvious examples I would not bother trying to support VC++ versions prior to VS2005/VC8 and I would not bother trying to support gcc versions prior to 4.0 etc.
It would be nice if you responded to what I wrote rather than what you imagined I wrote. The problem with the MPL changes was that they were non-trivial, and for a library which is very arcane (with or without workarounds), has little maintenance and a lot of dependants, some of which are unmaintained. Also, many of the dependants hadn't merged Stephen Kelly's changes (some still haven't) and it wasn't clear if it was safe to merge MPL before them. It was nothing to do with maintaining support for Visual C++ 7.0.
What does the quoted contents above have anything to do to what you wrote anywhere ? In other words my response was to a post by John Maddock and has nothing to do with anything you wrote on this thread.
On 7 June 2014 05:47, Edward Diener
On 6/6/2014 5:23 PM, Daniel James wrote:
On 6 June 2014 21:41, Edward Diener
wrote: Looking through code in MPL, and other long-standing libraries may be similar, the need to keep compiler workarounds in the code for compilers which are obsolete, or do not implement basic parts of even the C++ 98 standard, makes understanding and updating code fairly difficult in many cases. I believe that Boost has a right to say to those who still want to use some of these compilers with Boost that they will have to stick to previous versions. It really becomes difficult for a number of Boost libraries to move forward if they have to continually support poorly conforming compilers. As obvious examples I would not bother trying to support VC++ versions prior to VS2005/VC8 and I would not bother trying to support gcc versions prior to 4.0 etc.
It would be nice if you responded to what I wrote rather than what you imagined I wrote. The problem with the MPL changes was that they were non-trivial, and for a library which is very arcane (with or without workarounds), has little maintenance and a lot of dependants, some of which are unmaintained. Also, many of the dependants hadn't merged Stephen Kelly's changes (some still haven't) and it wasn't clear if it was safe to merge MPL before them. It was nothing to do with maintaining support for Visual C++ 7.0.
What does the quoted contents above have anything to do to what you wrote anywhere ? In other words my response was to a post by John Maddock and has nothing to do with anything you wrote on this thread.
It's do with what I wrote in objection to Stephen Kelly's changes to
MPL, this would have been clearer if I hadn't cut my reply to the
previous paragraph:
On 6 June 2014 21:41, Edward Diener
Based on Stephen Kelly's recommendations I actually removed a bunch of old workarounds in MPL for compilers which we don't support anymore. I even posted about it on this mailing list. But Daniel james objected to this being done for the 'develop' branch of MPL so I posted the change to a remote branch of MPL called 'remotes/origin/mfixes'.
I removed the quote and my reply because you clarified in your other
mail that it was wrong:
On 6 June 2014 22:20, Edward Diener
I gave the wrong information. The changes were actually pushed on MPL to 'remotes/origin/SKChanges'. At one point there were in MPL 'develop' and having watched the regression tests I wanted to merge them into MPL 'master'. I believe Daniel James reverted them on 'develop'. My 'remotes/origin/mfixes' was something else related to testing clang on Windows with VC++ RTL.
In both emails you named me as the person objecting to changes. So,
you're arguing for changes I reverted, and making clear that I
reverted them. That does suggest that this what you're writing has a
lot to do with my objections to them. If it didn't, why mention me
twice? The implication of your mail is that the changes were reverted
in order to keep support for compilers such as Visual C++ 7.0, which
is not true. This is what I wrote back in March:
On 20 March 2014 22:39, Daniel James
I think the best thing to do for MPL is to revert Stephen Kelly's changes, and put them on a branch so that they can be reconsidered later. I'm not saying they're bad - at the very least, removing support for old versions of Visual C++ is a good idea. But I think we need to sort out the libraries' dependants first. I'm going to try to start on some of these soon, but it'll take a while.
On 6/7/2014 5:23 AM, Daniel James wrote:
On 7 June 2014 05:47, Edward Diener
wrote: On 6/6/2014 5:23 PM, Daniel James wrote:
On 6 June 2014 21:41, Edward Diener
wrote: Looking through code in MPL, and other long-standing libraries may be similar, the need to keep compiler workarounds in the code for compilers which are obsolete, or do not implement basic parts of even the C++ 98 standard, makes understanding and updating code fairly difficult in many cases. I believe that Boost has a right to say to those who still want to use some of these compilers with Boost that they will have to stick to previous versions. It really becomes difficult for a number of Boost libraries to move forward if they have to continually support poorly conforming compilers. As obvious examples I would not bother trying to support VC++ versions prior to VS2005/VC8 and I would not bother trying to support gcc versions prior to 4.0 etc.
It would be nice if you responded to what I wrote rather than what you imagined I wrote. The problem with the MPL changes was that they were non-trivial, and for a library which is very arcane (with or without workarounds), has little maintenance and a lot of dependants, some of which are unmaintained. Also, many of the dependants hadn't merged Stephen Kelly's changes (some still haven't) and it wasn't clear if it was safe to merge MPL before them. It was nothing to do with maintaining support for Visual C++ 7.0.
What does the quoted contents above have anything to do to what you wrote anywhere ? In other words my response was to a post by John Maddock and has nothing to do with anything you wrote on this thread.
It's do with what I wrote in objection to Stephen Kelly's changes to MPL, this would have been clearer if I hadn't cut my reply to the previous paragraph:
On 6 June 2014 21:41, Edward Diener
wrote: Based on Stephen Kelly's recommendations I actually removed a bunch of old workarounds in MPL for compilers which we don't support anymore. I even posted about it on this mailing list. But Daniel james objected to this being done for the 'develop' branch of MPL so I posted the change to a remote branch of MPL called 'remotes/origin/mfixes'.
I removed the quote and my reply because you clarified in your other mail that it was wrong:
On 6 June 2014 22:20, Edward Diener
wrote: I gave the wrong information. The changes were actually pushed on MPL to 'remotes/origin/SKChanges'. At one point there were in MPL 'develop' and having watched the regression tests I wanted to merge them into MPL 'master'. I believe Daniel James reverted them on 'develop'. My 'remotes/origin/mfixes' was something else related to testing clang on Windows with VC++ RTL.
In both emails you named me as the person objecting to changes.
Which was true, you objected to the changes and therefore I did not follow through by updating 'master' from those changes in 'develop'.
So, you're arguing for changes I reverted, and making clear that I reverted them. That does suggest that this what you're writing has a lot to do with my objections to them. If it didn't, why mention me twice?
I just mentioned what factually occurred.
The implication of your mail is that the changes were reverted in order to keep support for compilers such as Visual C++ 7.0, which is not true.
You are reading into my current replies to John Maddock and Peter Dimov things which are not there and then accusing me of not replying "to what I wrote rather than what you imagined I wrote". Please do not do that. I was not replying to you in either situation. I was just giving my opinion about supporting obsolete compilers in the first instance and factually giving information about MPL changes in the second instance. I did not offer criticism of you in either case.
This is what I wrote back in March:
On 20 March 2014 22:39, Daniel James
wrote: I think the best thing to do for MPL is to revert Stephen Kelly's changes, and put them on a branch so that they can be reconsidered later.
And indeed I put them on a branch and brought that to Peter Dimov's notice recently in reply to his current posts.
I'm not
saying they're bad - at the very least, removing support for old versions of Visual C++ is a good idea. But I think we need to sort out the libraries' dependants first. I'm going to try to start on some of these soon, but it'll take a while.
On 7 June 2014 13:19, Edward Diener
On 6/7/2014 5:23 AM, Daniel James wrote:
On 7 June 2014 05:47, Edward Diener
wrote: So, you're arguing for changes I reverted, and making clear that I reverted them. That does suggest that this what you're writing has a lot to do with my objections to them. If it didn't, why mention me twice? I just mentioned what factually occurred.
But you choose what to mention. You left out why I reverted the changes, and that I'd said they would be more appropriate in the future, which makes it look like I was blocking them indefinitely.
The implication of your mail is that the changes were reverted in order to keep support for compilers such as Visual C++ 7.0, which is not true.
You are reading into my current replies to John Maddock and Peter Dimov things which are not there and then accusing me of not replying "to what I wrote rather than what you imagined I wrote". Please do not do that.
I'm sorry about that line, it would have made more sense if I'd included the reply to your original inaccurate description of what happened, which is what annoyed me. I should have edited more carefully before sending.
John Maddock wrote:
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of MPL full, either to core, or to some mpl_core, then there's no need to split type_traits anymore.
The question is: what is the minimal conforming implementation of a type trait? Is it template<class T> struct something { bool const value = false; } or is it, instead, template<class T> struct something: mpl::false_ { }; For C++11, the answer to this question determines whether the std type traits are conforming type traits for us. In other words, whether "using std::is_pointer;" is a conforming implementation of boost::is_pointer. For C++03, the answer determines whether I can specialize a type trait for my type without including the header that defines mpl::true_ and mpl::false_. I prefer the first definition for reasons already stated. This doesn't mean however that going with the second, along with a lean and mean mpl::bool_, will not going to be a considerable improvement as well. Far from it.
Indeed I suspect there's a huge amount of obfuscated code inherited from mpl's broken-compiler-workarounds that can now be removed: not only do we not support those compilers any more, but given that they haven't been tested in heaven knows how long they're unlikely to compile *any* of modern Boost anyway.
That's certainly true. If we remove the obsolete workarounds from MPL and TypeTraits things will start looking much better.
In fact in C++11 it makes sense to me have:
namespace boost{ namespace mpl{
template <bool b> using bool_ = std::integral_constant
;
Interesting. This makes the std type traits conform to my second definition above, so that "using std::is_member_pointer;" (say) is a legitimate implementation of boost::is_member_pointer even when derivation from mpl::bool_ is required. I'm not sure that this is a conforming mpl::bool_ though. It almost is. But mpl integral constants need to have a nested ::tag (integral_c_tag), and std::integral_constant doesn't have one. Maybe this requirement can be dropped. Maybe it can't. I don't know.
Le 06/06/14 23:40, Peter Dimov a écrit :
John Maddock wrote:
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of MPL full, either to core, or to some mpl_core, then there's no need to split type_traits anymore.
The question is: what is the minimal conforming implementation of a type trait? Is it
template<class T> struct something { bool const value = false; }
or is it, instead,
template<class T> struct something: mpl::false_ { };
The answer as for the documentation * for TypeTraits trais is template <class T> struct is_abstract : public /|true_type http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetra...-or-false_type http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetra...|/ {}; I interpret these are the ones on boost namesapce. * for MPL traits is template< typename T1 , typename T2 > structless http://www.boost.org/doc/libs/1_55_0/libs/mpl/doc/refmanual/less.html { typedef/unspecified/ type; }; Returns a true-valuedIntegral Constant http://www.boost.org/doc/libs/1_55_0/libs/mpl/doc/refmanual/integral-constan... ifT1 is less thanT2. Here an integral constant has some constraints not satisfied by boost::integral_constant, as tag, next, prior. I think that TypeTraits shouldn't require the MPL constraints. In order to be compatible with C++11 we should provide the same interface than std::integral_constant.
For C++11, the answer to this question determines whether the std type traits are conforming type traits for us. In other words, whether "using std::is_pointer;" is a conforming implementation of boost::is_pointer.
For C++03, the answer determines whether I can specialize a type trait for my type without including the header that defines mpl::true_ and mpl::false_. Well, you could include a header that defines boost::true_type and boost::false_type ;-) Or you could define the traits defining every_thing integral_constant defines.
I prefer the first definition for reasons already stated. This doesn't mean however that going with the second, along with a lean and mean mpl::bool_, will not going to be a considerable improvement as well. Far from it.
I prefer to conform to the standard traits as much as possible. The moving from Boost to the standard is easier. The porting of C++11 libraries to Boost for non-conforming C++11 compilers also.
Indeed I suspect there's a huge amount of obfuscated code inherited from mpl's broken-compiler-workarounds that can now be removed: not only do we not support those compilers any more, but given that they haven't been tested in heaven knows how long they're unlikely to compile *any* of modern Boost anyway.
That's certainly true. If we remove the obsolete workarounds from MPL and TypeTraits things will start looking much better.
In fact in C++11 it makes sense to me have:
namespace boost{ namespace mpl{
template <bool b> using bool_ = std::integral_constant
; Interesting. This makes the std type traits conform to my second definition above, so that "using std::is_member_pointer;" (say) is a legitimate implementation of boost::is_member_pointer even when derivation from mpl::bool_ is required.
I'm not sure that this is a conforming mpl::bool_ though. It almost is. But mpl integral constants need to have a nested ::tag (integral_c_tag), and std::integral_constant doesn't have one. Maybe this requirement can be dropped. Maybe it can't. I don't know.
We agree here. The preceding bool_ definition is no equivalent to the
MPL current definition.
The question is whether we need tag dispatching for the result of a
trait. IMHO not.
mpl::bool_could be defined
template <bool b>
struct bool_ : std::integral_constant
On 06/06/2014 22:40, Peter Dimov wrote:
John Maddock wrote:
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of MPL full, either to core, or to some mpl_core, then there's no need to split type_traits anymore.
The question is: what is the minimal conforming implementation of a type trait? Is it
template<class T> struct something { bool const value = false; }
or is it, instead,
template<class T> struct something: mpl::false_ { };
For C++11, the answer to this question determines whether the std type traits are conforming type traits for us. In other words, whether "using std::is_pointer;" is a conforming implementation of boost::is_pointer.
For C++03, the answer determines whether I can specialize a type trait for my type without including the header that defines mpl::true_ and mpl::false_.
I prefer the first definition for reasons already stated. This doesn't mean however that going with the second, along with a lean and mean mpl::bool_, will not going to be a considerable improvement as well. Far from it.
For me it seems there are relatively few uses of type_traits that don't end up requiring either mpl::if_ or mpl::bool_ anyway?
Indeed I suspect there's a huge amount of obfuscated code inherited from mpl's broken-compiler-workarounds that can now be removed: not only do we not support those compilers any more, but given that they haven't been tested in heaven knows how long they're unlikely to compile *any* of modern Boost anyway.
That's certainly true. If we remove the obsolete workarounds from MPL and TypeTraits things will start looking much better.
In fact in C++11 it makes sense to me have:
namespace boost{ namespace mpl{
template <bool b> using bool_ = std::integral_constant
; Interesting. This makes the std type traits conform to my second definition above, so that "using std::is_member_pointer;" (say) is a legitimate implementation of boost::is_member_pointer even when derivation from mpl::bool_ is required.
I'm not sure that this is a conforming mpl::bool_ though. It almost is. But mpl integral constants need to have a nested ::tag (integral_c_tag), and std::integral_constant doesn't have one. Maybe this requirement can be dropped. Maybe it can't. I don't know.
Ah, good point, clearly we can't do that then. John.
John Maddock wrote:
For me it seems there are relatively few uses of type_traits that don't end up requiring either mpl::if_ or mpl::bool_ anyway?
Depends. smart_ptr doesn't (and will never) require anything mpl. And we can always duplicate mpl::if_ in core::, if there's demand. It's not hard to avoid mpl::if_ and mpl::bool_ in our brave post-VC++6 world.
John Maddock wrote:
In fact in C++11 it makes sense to me have:
namespace boost{ namespace mpl{
template <bool b> using bool_ = std::integral_constant
;
I have another solution, which appears good enough to go into Core. We could
also enhance mpl::bool_ in the same way. Note that the trait knows nothing
about bool_, but dispatch still works.
#include
On Saturday 07 June 2014 18:46:19 Peter Dimov wrote:
I have another solution, which appears good enough to go into Core. We could also enhance mpl::bool_ in the same way. Note that the trait knows nothing about bool_, but dispatch still works.
template< class T > struct is_pointer { BOOST_STATIC_CONSTANT( bool, value = false ); };
template< class T > struct is_pointer< T* > { BOOST_STATIC_CONSTANT( bool, value = true ); };
int f( true_ ) { return 5; }
int f( false_ ) { return 11; }
int main() { BOOST_TEST( f( is_pointer< int* >() ) == 5 ); BOOST_TEST( f( is_pointer< int >() ) == 11 );
return boost::report_errors(); }
It's still a partial solution since f(is_pointer< int >::type()); is also valid with the current implementation. We can add the conversion constructor to mpl::bool_ but that is not a replacement for the current mechanism, at least not a backward compatible one. I think our previous plan with TypeTraits.Core is better. Pulling type traits to Core doesn't sound good, it's better to create a separate submodule for it.
Andrey Semashev wrote:
Pulling type traits to Core doesn't sound good, it's better to create a separate submodule for it.
I think that you misunderstand. I do not intend to put type traits in Core. The is_pointer definition in the example is part of the test for bool_. It demonstrates that bool_ can dispatch without it being coupled to the definition of the trait - which can come from core_type_traits, from std, or from a user specialization.
It's still a partial solution...
When you say that it is a partial solution, what problem do you have in mind it is a partial solution for?
... since
f(is_pointer< int >::type());
is also valid with the current implementation.
Well, so is is_pointer<int>::value_type x = is_pointer<int>::type::type(); but I'm not sure what is the practical impact of these examples.
On Sat, Jun 7, 2014 at 10:00 PM, Peter Dimov
Andrey Semashev wrote:
Pulling type traits to Core doesn't sound good, it's better to create a separate submodule for it.
I think that you misunderstand. I do not intend to put type traits in Core. The is_pointer definition in the example is part of the test for bool_. It demonstrates that bool_ can dispatch without it being coupled to the definition of the trait - which can come from core_type_traits, from std, or from a user specialization.
You're right, I did misunderstood. So you're proposing to add bool_ to Core?
It's still a partial solution...
When you say that it is a partial solution, what problem do you have in mind it is a partial solution for?
I was thinking you were proposing a replacement for deriving traits from bool_.
... since
f(is_pointer< int >::type());
is also valid with the current implementation.
Well, so is
is_pointer<int>::value_type x = is_pointer<int>::type::type();
but I'm not sure what is the practical impact of these examples.
Well, I surely did use the nested ::type type somewhere. 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? TypeTraits will still derive from mpl::bool_. We don't need another bool_ in Core (yet) and TypeTraits.Core would be enough for us. And if we need bool_ I'd probably prefer it in MPL.Core, and it should be the same bool_ TypeTraits derive from. I wouldn't like us having multiple different bool_s in multiple libraries.
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.
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. 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. :-)
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.
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_.
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.
Andrey Semashev wrote:
Ok. Just for the record, the same can be achieved with mpl::bool_, even without modification:
foo(mpl::bool_< is_pointer< int >::value >());
Yes, I know. I even said so a few days ago. That's a bit inconvenient and considerably less readable though, so people might be reluctant to switch to it.
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.
When you say "we will have it", what specific procedure do you imagine that will cause MPL.Core to come into existence? I'm not saying that we _should_ not have it. I'm saying that there is a certain gap between "should" and "will". Who will actually bridge that gap and accept the responsibility for creating and maintaining MPL.Core?
We can always drop workarounds in MPL.Core, ...
I'm not sure that it will be that simple, as MPL.Core will be required to maintain backward compatibility with existing uses of MPL. Those existing uses are not confined to Boost. Part of the responsibility to which I allude above will be to not break code without a good reason and to address user complaints that their code did indeed break as a consequence of the refactoring. So this is a bit of a constraint. It will not prevent a significant cleanup, but it will serve as a limitation.
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).
Well, maybe. I'd say that people need to realize that there's more than one
bool_. At present, we have at least four - mpl::bool_<B>,
mpl::integral_c
If you want to just drop the mpl::bool_ part of the interface from type traits, that would be a breaking change, ...
It will be a breaking change in theory, but it need not break any actual code in practice. But that's not particularly relevant, so no point in digging into it.
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.
I'm not sure what you're talking about here.
On Sunday 08 June 2014 01:18:10 Peter Dimov wrote:
Andrey Semashev wrote:
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.
When you say "we will have it", what specific procedure do you imagine that will cause MPL.Core to come into existence?
I'm not saying that we _should_ not have it. I'm saying that there is a certain gap between "should" and "will". Who will actually bridge that gap and accept the responsibility for creating and maintaining MPL.Core?
Yes, I probably made that statement overly confident. I'm not the maintainer of MPL nor I have rights to create submodules, so I clearly don't have the upper hand. However, I do think this is the right way to go, and should we take that route I'd be willing to participate in that work.
We can always drop workarounds in MPL.Core, ...
I'm not sure that it will be that simple, as MPL.Core will be required to maintain backward compatibility with existing uses of MPL. Those existing uses are not confined to Boost. Part of the responsibility to which I allude above will be to not break code without a good reason and to address user complaints that their code did indeed break as a consequence of the refactoring. So this is a bit of a constraint. It will not prevent a significant cleanup, but it will serve as a limitation.
Surely we will have to maintain interface compatibility of the components we move to MPL.Core (if it is created). But is it that much of a constrain? What kind of changes do you think will be needed and not possible without breaking compatibility? If you're concerned with supporting ancient compilers, then I'd say you shouldn't be as noone requires us to keep the support forever. I think, at first it will be simply enough to just move the components to the new submodule. This alone will reduce dependencies.
I'd say that people need to realize that there's more than one bool_.
I'm on the opposite end. I think it's better to reduce the fragmentation, it does no good in practice. It's the same as with std::shared_ptr vs boost::shared_ptr - both work and available, used in different places and yet incompatible.
what if MPL.Core never actually materializes?
Let's make it happen then. :)
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.
I'm not sure what you're talking about here.
If you have a tag dispatching code such as: void foo(mpl::true_); void foo(mpl::false_); foo(is_pointer< T >()); you can always replace it with template specializations: template<bool> struct foo { void call(); }; template<> struct foo<false> { void call(); }; foo< is_pointer< T >::value >::call(); Yes, it's more awkward but it allows to avoid dependencies on MPL and use TypeTraits.Core. However, I don't see tag dispatching in Core now and I'm not sure it will appear (and need refactoring such as above) in the near future.
On Sunday 08 June 2014 04:15:54 you wrote:
On Sunday 08 June 2014 01:18:10 Peter Dimov wrote:
Andrey Semashev wrote:
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.
When you say "we will have it", what specific procedure do you imagine that will cause MPL.Core to come into existence?
I'm not saying that we _should_ not have it. I'm saying that there is a certain gap between "should" and "will". Who will actually bridge that gap and accept the responsibility for creating and maintaining MPL.Core?
Yes, I probably made that statement overly confident. I'm not the maintainer of MPL nor I have rights to create submodules, so I clearly don't have the upper hand. However, I do think this is the right way to go, and should we take that route I'd be willing to participate in that work.
We can always drop workarounds in MPL.Core, ...
I'm not sure that it will be that simple, as MPL.Core will be required to maintain backward compatibility with existing uses of MPL. Those existing uses are not confined to Boost. Part of the responsibility to which I allude above will be to not break code without a good reason and to address user complaints that their code did indeed break as a consequence of the refactoring. So this is a bit of a constraint. It will not prevent a significant cleanup, but it will serve as a limitation.
Surely we will have to maintain interface compatibility of the components we move to MPL.Core (if it is created). But is it that much of a constrain? What kind of changes do you think will be needed and not possible without breaking compatibility? If you're concerned with supporting ancient compilers, then I'd say you shouldn't be as noone requires us to keep the support forever.
I think, at first it will be simply enough to just move the components to the new submodule. This alone will reduce dependencies.
I'd say that people need to realize that there's more than one bool_.
I'm on the opposite end. I think it's better to reduce the fragmentation, it does no good in practice. It's the same as with std::shared_ptr vs boost::shared_ptr - both work and available, used in different places and yet incompatible.
what if MPL.Core never actually materializes?
Let's make it happen then. :)
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.
I'm not sure what you're talking about here.
If you have a tag dispatching code such as:
void foo(mpl::true_); void foo(mpl::false_);
foo(is_pointer< T >());
you can always replace it with template specializations:
template<bool> struct foo { void call(); }; template<> struct foo<false> { void call(); };
Uh, these two call() declarations should be static.
foo< is_pointer< T >::value >::call();
Yes, it's more awkward but it allows to avoid dependencies on MPL and use TypeTraits.Core.
However, I don't see tag dispatching in Core now and I'm not sure it will appear (and need refactoring such as above) in the near future.
Andrey Semashev wrote:
What kind of changes do you think will be needed and not possible without breaking compatibility?
I don't know enough to answer this question. MPL is somewhat complicated. It's not quite clear, from a brief look, which parts are essential and which parts are workarounds.
I think, at first it will be simply enough to just move the components to the new submodule.
Even that is going to not be as easy as it sounds. Look at boost/mpl/and.hpp, for example. And it's not clear whether, if we move a component into MPL.Core and remove all workarounds, this will not break components in MPL that depend on those workarounds for some reason. In short, it looks like a nontrivial project. Maybe it's easier than it appears. I don't know.
Yes, I probably made that statement overly confident. I'm not the maintainer of MPL nor I have rights to create submodules, so I clearly don't have the upper hand.
MPL doesn't have an official maintainer at the moment, I think. And creating a submodule is the least of our worries. I do have that right. That's not the issue at all. :-)
However, I don't see tag dispatching in Core now and I'm not sure it will appear (and need refactoring such as above) in the near future.
No, there isn't any tag dispatching in Core; the intent was to provide the infrastructure for tag dispatching to libraries that do tag dispatching and wish to avoid the dependency on MPL.
On Sat, Jun 7, 2014 at 6:12 PM, Peter Dimov
In short, it looks like a nontrivial project. Maybe it's easier than it appears. I don't know.
Is there any tool that can be used to visually display and help analyze complex dependency structures? I know there are tools that can generate text files and stuff, but that isn't sufficient. -- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
On Sunday 08 June 2014 04:12:26 Peter Dimov wrote:
Andrey Semashev wrote:
I think, at first it will be simply enough to just move the components to the new submodule.
Even that is going to not be as easy as it sounds. Look at boost/mpl/and.hpp, for example. And it's not clear whether, if we move a component into MPL.Core and remove all workarounds, this will not break components in MPL that depend on those workarounds for some reason.
In short, it looks like a nontrivial project. Maybe it's easier than it appears. I don't know.
Eyes are afraid, hands are doing. :) Here is my first take on this: https://github.com/Lastique/mpl_core/tree/develop https://github.com/Lastique/mpl/tree/develop I moved the files required for the root headers listed in root_list.txt to MPL.Core. Basically, its all numeric wrappers (bool_, int_, etc.), operations on them, if_, eval_if, void_ and a few utils that are likely used in libraries: assert.hpp, print.hpp and identity.hpp. The complete list of what was moved is in move_headers.txt. The resulting MPL.Core depends on Config, Preprocessor and TypeTraits. From TypeTraits it only needs is_class.hpp in mpl/has_xxx.hpp. That dependency is only used to work around Borland bugs. I'm inclined to just remove that workaround. Alternatively, this trait could be replicated in MPL.Core just for this one compiler. Not a bad starting point, IMHO.
Andrey Semashev wrote:
Eyes are afraid, hands are doing. :) Here is my first take on this:
https://github.com/Lastique/mpl_core/tree/develop https://github.com/Lastique/mpl/tree/develop
Thanks for doing this work. Did you run the MPL tests on the new structure? (And if so, how - I'd like to do the same.) I think that in this case a better way to move the files into the new repo will be to clone mpl into mpl_core and then 'git rm' the extra files. This will likely preserve the history better, and it has the additional advantage that you can at a later date move another file by just undeleting it. Assuming that the tests are fine, I wonder what is the best way to proceed from here. Do people have objections to splitting these headers into a new submodule, mpl_core? My initial thought is that we can create the new submodule on a feature branch in the superproject, so as to not affect develop and master at this time. The feature branch will not automatically pick up any further 'develop' changes in other modules, but that's probably not a problem. (The changes to the existing MPL module will need to also be done on a branch, of course.)
On Sunday 08 June 2014 16:54:07 Peter Dimov wrote:
Andrey Semashev wrote:
Eyes are afraid, hands are doing. :) Here is my first take on this:
https://github.com/Lastique/mpl_core/tree/develop https://github.com/Lastique/mpl/tree/develop
Thanks for doing this work.
Did you run the MPL tests on the new structure? (And if so, how - I'd like to do the same.)
Yes, all passed (with a lot of warnings though; I assume this is normal). Not surprising, given that I didn't touch the code. I'm on Linux, so it may be easier for me if you're on Windows. What I did was: 1. Checkout my fork of MPL and MPL.Core. 2. Move BOOST_ROOT/libs/mpl somewhere else, out of the Boost tree. 3. ln -s ../../boost-mpl_core mpl_core; ln -s ../../boost-mpl mpl; I.e. create symlinks in BOOST_ROOT/libs for the replacement modules. 4. In BOOST_ROOT, remove boost directory and run b2 headers. It should create symlinks to the submodules. 5. In BOOST_ROOT, run bjam -j 8 --toolset=gcc cxxflags="-std=gnu++0x" variant=debug threading=multi runtime-link=shared link=shared libs/mpl/test. Don't run it in libs/mpl/test, bjam won't find Boost root. I'd be curious to see a report of your boostdep tool, just in case I missed some dependencies in my scripts.
I think that in this case a better way to move the files into the new repo will be to clone mpl into mpl_core and then 'git rm' the extra files. This will likely preserve the history better, and it has the additional advantage that you can at a later date move another file by just undeleting it.
Maybe, although it would complicate scripting as I work down from the headers that I want to move, not the ones I want to delete.
Assuming that the tests are fine, I wonder what is the best way to proceed from here.
Do people have objections to splitting these headers into a new submodule, mpl_core?
My initial thought is that we can create the new submodule on a feature branch in the superproject, so as to not affect develop and master at this time. The feature branch will not automatically pick up any further 'develop' changes in other modules, but that's probably not a problem. (The changes to the existing MPL module will need to also be done on a branch, of course.)
I think we're safe to do this in develop. The extraction doesn't require code changes (yet, until we solve that TypeTraits dependency problem). However, I'd be fine if we do this in a separate branch and merge it after 1.56.
Andrey Semashev wrote:
I'd be curious to see a report of your boostdep tool, just in case I missed some dependencies in my scripts.
It's in tools/boostdep in develop now, so you can run it yourself. MPL includes via macros occasionally though, so it might not catch everything. One reliable way to test that mpl_core doesn't include mpl will be to set up an environment in which mpl is missing and run the mpl_core tests there.
On Sunday 08 June 2014 18:15:39 you wrote:
On Sunday 08 June 2014 16:54:07 Peter Dimov wrote:
Assuming that the tests are fine, I wonder what is the best way to proceed from here.
Do people have objections to splitting these headers into a new submodule, mpl_core?
My initial thought is that we can create the new submodule on a feature branch in the superproject, so as to not affect develop and master at this time. The feature branch will not automatically pick up any further 'develop' changes in other modules, but that's probably not a problem. (The changes to the existing MPL module will need to also be done on a branch, of course.)
I think we're safe to do this in develop. The extraction doesn't require code changes (yet, until we solve that TypeTraits dependency problem). However, I'd be fine if we do this in a separate branch and merge it after 1.56.
So what shall we decide? FWIW, since there are no code changes, only file moves, it's safe to add the submodule to both develop and master. We can defer the code modifications until after release or make them in develop only or a separate branch, but this won't be possible if we don't create the submodule.
I'd say that people need to realize that there's more than one bool_.
I'm on the opposite end. I think it's better to reduce the fragmentation, it does no good in practice. It's the same as with std::shared_ptr vs boost::shared_ptr - both work and available, used in different places and yet incompatible.
I'm strongly against fragmentation like this, I feel it will simply confuse and frustrate users in equal measure: well it'll confuse and frustrate me anyway ;-) Ultimately though, this argument will be only be settled by someone doing some hacking. John.
Le 07/06/14 20:00, Peter Dimov a écrit :
Andrey Semashev wrote:
Pulling type traits to Core doesn't sound good, it's better to create a separate submodule for it.
I think that you misunderstand. I do not intend to put type traits in Core. The is_pointer definition in the example is part of the test for bool_. It demonstrates that bool_ can dispatch without it being coupled to the definition of the trait - which can come from core_type_traits, from std, or from a user specialization.
Which library needs bool_ in Core? IMO, what we need is integral_constant in Core and import it to Boost. //boost/core/intergral_constant.hpp namespace boost { namespace core { template <..> struct integral_constant {... }; } } //boost/type_traits/intergral_constant.hpp namespace boost { using core::integral_constant; } Note that the current implementation of integral_constant using mpl::integral_c is not documented, so the changes are backward compatible (Of course, the user or Boost code that is using the implementation detail would be broken). This doesn't needs a change in MPL at all. What are the drawbacks of this solution? Vicente
El 08/06/2014 8:23, Vicente J. Botet Escriba escribió:
Which library needs bool_ in Core?
IMO, what we need is integral_constant in Core and import it to Boost.
//boost/core/intergral_constant.hpp namespace boost { namespace core { template <..> struct integral_constant {... }; } }
//boost/type_traits/intergral_constant.hpp namespace boost { using core::integral_constant; }
Note that the current implementation of integral_constant using mpl::integral_c is not documented, so the changes are backward compatible (Of course, the user or Boost code that is using the implementation detail would be broken).
This doesn't needs a change in MPL at all.
I think you are pointing to the right solution. I'm strongly against using MPL::bool_ as a basic building block for traits. If possible we should have a boost::core::integral_type and boost::core::true_type/false_type. I would even define them directly into the boost namespace in Core. TypeTraits and MPL should depend on the core integral_constant. MPL integral_c has additional features so it could derive from core integral_constant and add the needed features. Ideally, TypeTraits should not depend on MPL, but this could break a lot of code, so we need to maintain interoperability without adding an explicit dependency. So to refine Vicente's idea, how about defining boost::integral_constant boost::true_type / boost::false_type in core, with mpl's requirements: http://www.boost.org/doc/libs/1_55_0/libs/mpl/doc/refmanual/integral-constan... then inject it into MPL and type_traits namespaces in each library. This way, when defining our own trait, we only depend on Core but we are still interoperable with MPL/TypeTraits. TypeTraits would not be MPL dependant. MPL could depend on TypeTraits and Core. Best, Ion
On Sunday 08 June 2014 23:53:41 Ion Gaztañaga wrote:
TypeTraits would not be MPL dependant. MPL could depend on TypeTraits and Core.
mpl::bool_ is not the only thing TypeTraits uses from MPL, so this dependency won't go that easily. This is arguably true for other libraries as well. Pulling more things from MPL to Core will make it heavier. I'd like to keep MPL stuff localized and IMHO Core is not the right place for it.
Andrey Semashev wrote
mpl::bool_ is not the only thing TypeTraits uses from MPL, so this dependency won't go that easily.
The list appears long, ... http://www.pdimov.com/tmp/report-b932921/type_traits.html#mpl ... but most of the nontrivial metaprogramming is done by common_type. The other contenders are floating_point_promotion and detail/template_arity_spec. The reverse, http://www.pdimov.com/tmp/report-b932921/mpl.html#type_traits looks breakable as well.
Le 09/06/14 00:46, Peter Dimov a écrit :
Andrey Semashev wrote
mpl::bool_ is not the only thing TypeTraits uses from MPL, so this dependency won't go that easily.
The list appears long, ...
http://www.pdimov.com/tmp/report-b932921/type_traits.html#mpl
... but most of the nontrivial metaprogramming is done by common_type. The other contenders are floating_point_promotion and detail/template_arity_spec. |The floating_point_promotion dependency is only if BOOST_NO_CV_SPECIALIZATIONS is defined. Do we support compiler defining this?
$ grep -r BOOST_NO_CV_SPECIALIZATIONS *
boost/config/compiler/borland.hpp:# define BOOST_NO_CV_SPECIALIZATIONS
boost/config/compiler/mpw.hpp:# define BOOST_NO_CV_SPECIALIZATIONS
boost/config/suffix.hpp:# if defined(BOOST_NO_CV_SPECIALIZATIONS) \
The detail/template_arity_spec dependency more complex.
The reverse,
http://www.pdimov.com/tmp/report-b932921/mpl.html#type_traits
looks breakable as well.
How do you want to break it? Duplicating what is used? Best, Vicente
El 09/06/2014 0:24, Andrey Semashev escribió:
On Sunday 08 June 2014 23:53:41 Ion Gaztañaga wrote:
TypeTraits would not be MPL dependant. MPL could depend on TypeTraits and Core.
mpl::bool_ is not the only thing TypeTraits uses from MPL, so this dependency won't go that easily. This is arguably true for other libraries as well. Pulling more things from MPL to Core will make it heavier. I'd like to keep MPL stuff localized and IMHO Core is not the right place for it.
Sorry, I missed the rest of dependencies. The circular dependency between MPL and TypeTraits doesn't sound very good from a a design point of view. However, from other libraries' point of view, integral_constant/true_type/false_type seems to be a very general concept that could be in Core. Best, Ion
Ion Gaztañaga wrote:
El 09/06/2014 0:24, Andrey Semashev escribió:
On Sunday 08 June 2014 23:53:41 Ion Gaztañaga wrote:
TypeTraits would not be MPL dependant. MPL could depend on TypeTraits and Core.
mpl::bool_ is not the only thing TypeTraits uses from MPL, so this dependency won't go that easily. This is arguably true for other libraries as well. Pulling more things from MPL to Core will make it heavier. I'd like to keep MPL stuff localized and IMHO Core is not the right place for it.
Sorry, I missed the rest of dependencies. The circular dependency between MPL and TypeTraits doesn't sound very good from a a design point of view.
If separate modules are so tightly coupled that they are inseparable, they are "incidentally" a single module (think 'incidental data structures'). Neither can exist without the other. Typeof and Core also participate in a closed dependency loop with MPL and TypeTraits. The four form one 'incidental module'. You could decide whether absence of incidental modules is a design goal. If it is, then you can merge those four together when it is no longer possible to remove edges between them. Thanks, Steve.
El 09/06/2014 7:12, Stephen Kelly escribió:
Ion Gaztañaga wrote:
El 09/06/2014 0:24, Andrey Semashev escribió:
On Sunday 08 June 2014 23:53:41 Ion Gaztañaga wrote:
TypeTraits would not be MPL dependant. MPL could depend on TypeTraits and Core.
mpl::bool_ is not the only thing TypeTraits uses from MPL, so this dependency won't go that easily. This is arguably true for other libraries as well. Pulling more things from MPL to Core will make it heavier. I'd like to keep MPL stuff localized and IMHO Core is not the right place for it.
Sorry, I missed the rest of dependencies. The circular dependency between MPL and TypeTraits doesn't sound very good from a a design point of view.
If separate modules are so tightly coupled that they are inseparable, they are "incidentally" a single module (think 'incidental data structures'). Neither can exist without the other. Typeof and Core also participate in a closed dependency loop with MPL and TypeTraits. The four form one 'incidental module'.
You could decide whether absence of incidental modules is a design goal. If it is, then you can merge those four together when it is no longer possible to remove edges between them.
That would remove the number of dependencies to one giant dependency. Not very useful to reduce coupling and compilation times. Using mpl::and_/mpl::not_ instead of "&&" and "!" in TypeTraits does seem avoidable. Only CommonType seems a bit more complicated to break from MPL. But it's relatively easy to implement without MPL. Ideally in my mind: MPL --- depends on --> TTraits--- depends on --> (Traits)Core. Or even: MPL --- depends on --> TTraits--- depends on --> (Traits)Core. I think all TypeTraits dependencies on MPL are avoidable and makes Boost more layered and maintainable. Makes a lot of Boost libraries directly or indirectly independent form MPL. I haven't studied Typeof source code so I can speak about its dependencies. However, breaking dependencies will need code changes in several libraries, so we must do this with care. Best, Ion
El 09/06/2014 11:31, Ion Gaztañaga escribió:
MPL. But it's relatively easy to implement without MPL. Ideally in my mind:
MPL --- depends on --> TTraits--- depends on --> (Traits)Core.
Or even:
MPL --- depends on --> TTraits--- depends on --> (Traits)Core.
Sorry, I pasted twice the same, forget the second repeticion. Ctrl+V problems, you know. Ion
Ion Gaztañaga wrote:
MPL. But it's relatively easy to implement without MPL. Ideally in my mind:
MPL --- depends on --> TTraits--- depends on --> (Traits)Core.
Or even:
MPL --- depends on --> TTraits--- depends on --> (Traits)Core.
Sorry, I pasted twice the same, forget the second repeticion. Ctrl+V problems, you know.
MPL -> TypeTraits is also breakable. Outside of workarounds, the genuine dependency is in mpl/empty_base.hpp, which is another example (like blank.hpp) that illustrates that it is at present not possible to define a new type trait (is_empty_base) or to specialize an existing one (is_empty) without including a TypeTraits header. http://www.boost.org/doc/libs/1_55_0/boost/mpl/empty_base.hpp
El 06/06/2014 23:40, Peter Dimov escribió:
John Maddock wrote:
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of MPL full, either to core, or to some mpl_core, then there's no need to split type_traits anymore.
The question is: what is the minimal conforming implementation of a type trait? Is it
template<class T> struct something { bool const value = false; }
or is it, instead,
template<class T> struct something: mpl::false_ { };
I would say the first one. I use my own true_/false_ wrappers in my
libraries just to avoid MPL dependencies.
To be standard conforming, we would need to add
"std::integral_constant
Le 07/06/14 17:13, Ion Gaztañaga a écrit :
El 06/06/2014 23:40, Peter Dimov escribió:
John Maddock wrote:
I'm tied of saying this.... but if mpl::bool_ and int_ were moved out of MPL full, either to core, or to some mpl_core, then there's no need to split type_traits anymore.
The question is: what is the minimal conforming implementation of a type trait? Is it
template<class T> struct something { bool const value = false; }
or is it, instead,
template<class T> struct something: mpl::false_ { };
I would say the first one. I use my own true_/false_ wrappers in my libraries just to avoid MPL dependencies.
To be standard conforming, we would need to add "std::integral_constant
" as "type" member. But IMHO this seems a bit redundant.
Well, currently something more
template
El 07/06/2014 17:37, Vicente J. Botet Escriba escribió:
To be standard conforming, we would need to add "std::integral_constant
" as "type" member. But IMHO this seems a bit redundant. Well, currently something more
template
struct integral_constant { static constexpr T value = v; typedef T value_type; typedef integral_constant
type; constexpr operator value_type() const { return value; } constexpr value_type operator()() const { return value; } };
Vicente C++ International Standard
Yes. The issue is not about deriving from integral_constant if it's a very simple header with no dependencies. Currently if deriving from integral_constant: 1) We need to depend on another Boost library (type_traits and its dependencies, boost::integral_constant derives from mpl::integral_c so we start adding dependencies) 2) In C++11 compilers we need to choose between boost::integral_constant or std::integral_constant. A standard conforming trait is not convertible to boost::true_type. On the other hand: static const bool value = true/false seems very lightweight and portable. An alternative is to inject std::integral_constant into the boost namespace or derive boost::integral_constant from std::integral_constant if it adds more operations. If integral_constant is needed to define a simple trait, then integral_constant should be: - compatible with C++11. - extremely simple, without any further dependencies, and live in core (not in type_traits, mpl or any other library). Just my 2 cents, Ion
On 06/06/2014 02:40 PM, Peter Dimov wrote:
I'm not sure that this is a conforming mpl::bool_ though. It almost is. But mpl integral constants need to have a nested ::tag (integral_c_tag), and std::integral_constant doesn't have one. Maybe this requirement can be dropped. Maybe it can't. I don't know.
Well, mpl can be fixed to not require ::tag, and in fact it should, IMO. I am in favor of adding an mpl::tag_of metafunction which retrieves the tag type of the passed mpl entity. It can be specialized for std::integral_constant to do the right thing. In addition, it would fix the issues raised here: http://lists.boost.org/Archives/boost/2009/01/147045.php and here: https://svn.boost.org/trac/boost/ticket/7192 I think in the C++11 world, boost type_traits should *all* inherit from std::true_type. That's easily accomplished by aliasing mpl::true_ to std::true_type. It fixes everything. Eric
On Friday 13 June 2014 09:27:04 Eric Niebler wrote:
I am in favor of adding an mpl::tag_of metafunction which retrieves the tag type of the passed mpl entity.
I think, mpl::tag already implements that. See mpl/tag.hpp.
It can be specialized for std::integral_constant to do the right thing. In addition, it would fix the issues raised here:
http://lists.boost.org/Archives/boost/2009/01/147045.php
and here:
https://svn.boost.org/trac/boost/ticket/7192
I think in the C++11 world, boost type_traits should *all* inherit from std::true_type. That's easily accomplished by aliasing mpl::true_ to std::true_type. It fixes everything.
Well, technically that would still be a breaking change, even though a relatively safe one. I think if the goal is to add support for std::integral_constant to MPL, it can be achieved with a less radical solution.
On 06/13/2014 09:42 AM, Andrey Semashev wrote:
On Friday 13 June 2014 09:27:04 Eric Niebler wrote:
I am in favor of adding an mpl::tag_of metafunction which retrieves the tag type of the passed mpl entity.
I think, mpl::tag already implements that. See mpl/tag.hpp.
It can be specialized for std::integral_constant to do the right thing. In addition, it would fix the issues raised here:
http://lists.boost.org/Archives/boost/2009/01/147045.php
and here:
https://svn.boost.org/trac/boost/ticket/7192
I think in the C++11 world, boost type_traits should *all* inherit from std::true_type. That's easily accomplished by aliasing mpl::true_ to std::true_type. It fixes everything.
Well, technically that would still be a breaking change, even though a relatively safe one. I think if the goal is to add support for std::integral_constant to MPL, it can be achieved with a less radical solution.
There are a great many goals that this change would address: * Make the minimum requirements for type traits sensible in C++11 by using std:: facilities where appropriate * Breaking the dependency of TypeTraits on MPL.[^1] * Making boost type traits play nicely with code written for C++11 that dispatches to std::true_type or std::false_type * Make the mpl meta-functions work with std::integral_constants * Make it possible to define mpl Sequence types without reserving a very generic and common identifier like "tag". This solution is not radical. It's a matter of grepping the source for "::tag" and replacing with uses of mpl::tag. Eric [^1]: TypeTraits has other mpl dependencies like if_ and friends. Those would need to be addressed regardless of this change. <sigh>
On Fri, Jun 13, 2014 at 1:49 PM, Eric Niebler
On 06/13/2014 09:42 AM, Andrey Semashev wrote:
On Friday 13 June 2014 09:27:04 Eric Niebler wrote:
[snip]
There are a great many goals that this change would address:
* Make the minimum requirements for type traits sensible in C++11 by using std:: facilities where appropriate
* Breaking the dependency of TypeTraits on MPL.[^1]
* Making boost type traits play nicely with code written for C++11 that dispatches to std::true_type or std::false_type
* Make the mpl meta-functions work with std::integral_constants
* Make it possible to define mpl Sequence types without reserving a very generic and common identifier like "tag".
This solution is not radical. It's a matter of grepping the source for "::tag" and replacing with uses of mpl::tag.
I agree this is the best solution. I'd hate to have to know which false_type a template metafunction returns. Also, it goes with the idea of separating multiple member typedefs in specific metafunctions that are considered best practices nowadays. I can volunteer to do this change over this weekend if nobody else volunteers.
Eric
[^1]: TypeTraits has other mpl dependencies like if_ and friends. Those would need to be addressed regardless of this change. <sigh>
Regards, -- Felipe Magno de Almeida
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 06/13/2014 10:50 AM, Peter Dimov wrote:
Eric Niebler wrote:
This solution is not radical. It's a matter of grepping the source for "::tag" and replacing with uses of mpl::tag.
::tag is part of the documented requirements for an MPL integral constant. There's probably code outside Boost taking advantage of that.
It's a breaking change, no question. And I don't know how much code would be effected, but I imagine it to be pretty small, and in all cases, the fix is to use mpl::tag instead of accessing ::tag directly. Then again, maybe leave it alone, and eventually deprecate all of mpl for something more modern? If we eventually migrate boost code away from mpl, it seems we'll have to take breaking changes eventually. Eric -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJTmzzpAAoJEAeJsEDfjLbX1mIH/14TE94pp/TYQhCGoNpz5hak PHYGGRXAb/hwfcs34uW8BoAIERACqcyOcm6ugZ/hCfKPRO8TUnfDDJqZ1BP6y2EO pIMv7847mxMmSwa49PyA0E40LPmxXr2grYMemVc06P7wNAFnW3rBvvSCVCsR+eye dPs0HoBo50OBCd6a4NrJRvTZ4x73DKr9wNdTobXFDMMcxhyDIomZb9wGipJqnR3l sVMbZmTQ3kifAgqal3VqYEgYAaqZLzeWZDV7JJ6RVnat1ATYy0hbqajzUqyGCmr6 RiKBlee8tPp0HKqR2cTGzGzyI/IrlHbaKucmhtsLZp2ybTzlEB7ce6GlMHRC3ug= =R6v8 -----END PGP SIGNATURE-----
Eric Niebler wrote:
I think in the C++11 world, boost type_traits should *all* inherit from std::true_type. That's easily accomplished by aliasing mpl::true_ to std::true_type. It fixes everything.
I can't help but note that you're focusing on the wrong aspect of the problem. In the C++11 world, we have type traits in std and none of this matters. Use of Boost type traits is motivated by the need to support C++03.
On 06/13/2014 10:48 AM, Peter Dimov wrote:
Eric Niebler wrote:
I think in the C++11 world, boost type_traits should *all* inherit from std::true_type. That's easily accomplished by aliasing mpl::true_ to std::true_type. It fixes everything.
I can't help but note that you're focusing on the wrong aspect of the problem. In the C++11 world, we have type traits in std and none of this matters. Use of Boost type traits is motivated by the need to support C++03.
I'm focusing on a larger set of problems. And use use of mpl isn't restricted to C++03 code. Nor is boost.type_traits for that matter; it's used in code that must be portable, like boost libraries. Anyone using a boost library with a C++11 compiler is getting old-style type traits whether they like it or not, and these implementation details can sometimes bubble out in annoying ways. If the user of a lib has to specialize a type trait, they'll be surprised when they use std::true_type and find their specialization doesn't meet the lib's requirements, for instance. Eric
I think in the C++11 world, boost type_traits should *all* inherit from std::true_type. That's easily accomplished by aliasing mpl::true_ to std::true_type. It fixes everything.
I can't help but note that you're focusing on the wrong aspect of the problem. In the C++11 world, we have type traits in std and none of this matters. Use of Boost type traits is motivated by the need to support C++03.
I'm focusing on a larger set of problems. And use use of mpl isn't restricted to C++03 code. Nor is boost.type_traits for that matter; it's used in code that must be portable, like boost libraries. Anyone using a boost library with a C++11 compiler is getting old-style type traits whether they like it or not, and these implementation details can sometimes bubble out in annoying ways. If the user of a lib has to specialize a type trait, they'll be surprised when they use std::true_type and find their specialization doesn't meet the lib's requirements, for instance.
Plus there are type traits in Boost that aren't in the std.
Can we not use inheritance:
boost::integral_constant<bool b> from mpl::bool_<b> from
std::integral_constant
Eric Niebler wrote:
On 06/13/2014 10:48 AM, Peter Dimov wrote:
Eric Niebler wrote:
I think in the C++11 world, boost type_traits should *all* inherit from std::true_type. That's easily accomplished by aliasing mpl::true_ to std::true_type. It fixes everything.
I can't help but note that you're focusing on the wrong aspect of the problem. In the C++11 world, we have type traits in std and none of this matters. Use of Boost type traits is motivated by the need to support C++03.
I'm focusing on a larger set of problems. And use use of mpl isn't restricted to C++03 code. Nor is boost.type_traits for that matter; it's used in code that must be portable, like boost libraries.
That's exactly what I said. Boost type traits are used in code that needs to compile under C++03. I agree with you that ::tag as a requirement for the integral constant concept is a terrible idea. I do not agree with your C++11-based arguments, neither do I agree that type traits should inherit from std::true_type. Type traits should NOT inherit from anything. The only requirement for a type trait (or a metaprogramming predicate, in general) should be to have a ::value with a value of 0 or 1. Nothing more. No ::tags. No required base classes. No mandatory dependencies of any kind. If you want to dispatch, type traits with a ::value == 0 should be _convertible_ to false_type, and type traits with a ::value == 1 should be convertible to true_type, but they should not be required to derive from them. This convertibility can be achieved from the true_type/false_type side. The base classes in the standard are a mistake. The base classes in Boost are a mistake.
El 13/06/2014 20:27, Peter Dimov escribió:
If you want to dispatch, type traits with a ::value == 0 should be _convertible_ to false_type, and type traits with a ::value == 1 should be convertible to true_type, but they should not be required to derive from them. This convertibility can be achieved from the true_type/false_type side.
+1. Best, Ion
On 6/13/2014 11:29 AM, Ion Gaztañaga wrote:
El 13/06/2014 20:27, Peter Dimov escribió:
If you want to dispatch, type traits with a ::value == 0 should be _convertible_ to false_type, and type traits with a ::value == 1 should be convertible to true_type, but they should not be required to derive from them. This convertibility can be achieved from the true_type/false_type side.
+1.
Whether the base classes are a mistake or not, they're a fact. And without changing std::integral_constant, we cannot make type traits as you describe them play nicely with code that dispatches to std::true_type/std::false_type. That said, I think your idea is intriguing, even if it doesn't solve all the problems. -- Eric Niebler Boost.org http://www.boost.org
Eric Niebler wrote:
Whether the base classes are a mistake or not, they're a fact. And without changing std::integral_constant, we cannot make type traits as you describe them play nicely with code that dispatches to std::true_type/std::false_type.
I don't see why code that uses a Boost type trait should dispatch to std::true_type and expect that to work. Dispatch to std::true_type makes sense when using an std:: type trait. When using a Boost type trait, dispatch to boost::true_type seems the most logical approach. Removing the base classes of the existing Boost type traits is obviously a breaking change, of course.
On 06/13/2014 05:12 PM, Peter Dimov wrote:
Eric Niebler wrote:
Whether the base classes are a mistake or not, they're a fact. And without changing std::integral_constant, we cannot make type traits as you describe them play nicely with code that dispatches to std::true_type/std::false_type.
I don't see why code that uses a Boost type trait should dispatch to std::true_type and expect that to work. Dispatch to std::true_type makes sense when using an std:: type trait. When using a Boost type trait, dispatch to boost::true_type seems the most logical approach.
Removing the base classes of the existing Boost type traits is obviously a breaking change, of course.
Then I defer to you. Just wanted to make sure you were aware of all the options, and of the outstanding issues that we could address in one go. As always in open source, the decision lies with the person motivated to actually do the work. :-) \e
Le 13/06/14 20:27, Peter Dimov a écrit :
Eric Niebler wrote:
Eric Niebler wrote:
I think in the C++11 world, boost type_traits should *all* inherit from >> std::true_type. That's easily accomplished by aliasing mpl::true_ to >> std::true_type. It fixes everything.
I can't help but note that you're focusing on the wrong aspect of
On 06/13/2014 10:48 AM, Peter Dimov wrote: the > problem. In the C++11 world, we have type traits in std and none of this > matters. Use of Boost type traits is motivated by the need to support > C++03.
I'm focusing on a larger set of problems. And use use of mpl isn't restricted to C++03 code. Nor is boost.type_traits for that matter; it's used in code that must be portable, like boost libraries.
That's exactly what I said. Boost type traits are used in code that needs to compile under C++03.
I agree with you that ::tag as a requirement for the integral constant concept is a terrible idea. I do not agree with your C++11-based arguments, neither do I agree that type traits should inherit from std::true_type. Type traits should NOT inherit from anything.
The only requirement for a type trait (or a metaprogramming predicate, in general) should be to have a ::value with a value of 0 or 1. Nothing more. No ::tags. No required base classes. No mandatory dependencies of any kind. What should be and what it is a quite different concern. The current documentation says that a boolean type traits inherits from boost::true_type or boost::false_type.
If you want to dispatch, type traits with a ::value == 0 should be _convertible_ to false_type, and type traits with a ::value == 1 should be convertible to true_type, but they should not be required to derive from them. This convertibility can be achieved from the true_type/false_type side. I don't see how.
The base classes in the standard are a mistake. The base classes in Boost are a mistake.
You are surely right, but the status is that these traits inherits. I think that the issue is not a major one and that compatibility between the Boost type traits and the standard ones is more important. Just my 2 cts, Vicente
On Sunday 15 June 2014 12:07:44 Vicente J. Botet Escriba wrote:
Le 13/06/14 20:27, Peter Dimov a écrit :
The only requirement for a type trait (or a metaprogramming predicate, in general) should be to have a ::value with a value of 0 or 1. Nothing more. No ::tags. No required base classes. No mandatory dependencies of any kind.
What should be and what it is a quite different concern. The current documentation says that a boolean type traits inherits from boost::true_type or boost::false_type.
If you read some earlier posts, you will find discussion about TypeTraits.Core submodule. I think no one in good consciousness considers to break TypeTraits backward compatibility in such a radical way.
If you want to dispatch, type traits with a ::value == 0 should be _convertible_ to false_type, and type traits with a ::value == 1 should be convertible to true_type, but they should not be required to derive from them. This convertibility can be achieved from the true_type/false_type side.
I don't see how.
Le 15/06/14 13:04, Andrey Semashev a écrit :
On Sunday 15 June 2014 12:07:44 Vicente J. Botet Escriba wrote:
Le 13/06/14 20:27, Peter Dimov a écrit :
The only requirement for a type trait (or a metaprogramming predicate, in general) should be to have a ::value with a value of 0 or 1. Nothing more. No ::tags. No required base classes. No mandatory dependencies of any kind. What should be and what it is a quite different concern. The current documentation says that a boolean type traits inherits from boost::true_type or boost::false_type. If you read some earlier posts, you will find discussion about TypeTraits.Core submodule. I think no one in good consciousness considers to break TypeTraits backward compatibility in such a radical way. Glad to see we agree we don't want to break backward compatibility.
If you want to dispatch, type traits with a ::value == 0 should be _convertible_ to false_type, and type traits with a ::value == 1 should be convertible to true_type, but they should not be required to derive from them. This convertibility can be achieved from the true_type/false_type side. I don't see how. http://lists.boost.org/Archives/boost/2014/06/214248.php
Agreed I missed this post :( Let me know IIUC: are you proposing Core true_, false_ types that can be used by TypeTraits and MPL preserving backward compatibility? Just to clarify my concern, the documentation of TypeTraits doens't preclule any dependency to MPL types and any module using this implementation detail should be fixed or we need to update the TypeTraits documentation. Sorry if my comments could be of non-sense, and everything is clear for every people. Best, Vicente
On Sunday 15 June 2014 13:47:22 Vicente J. Botet Escriba wrote:
Let me know IIUC: are you proposing Core true_, false_ types that can be used by TypeTraits and MPL preserving backward compatibility?
My personal preference is slightly different. I'll rehash: 1. Separate MPL into MPL and MPL.Core, as I've done in my private repos. 2. Make MPL.Core not depend on TypeTraits. There is only one dependency now, which is only needed to work around Borland bugs. 3. Separate TypeTraits into TypeTraits and TypeTraits.Core. TypeTraits.Core should ideally not depend on MPL and MPL.Core. It may require MPL.Core for things like mpl::if_, mpl::and_, etc, although the necessary components may be duplicated or implemented differently. At this moment, I have no strong opinion whether the dependency on MPL.Core should be strictly avoided. I'm certain though that TypeTraits.Core will not derive from any primitives, std:: or MPL.Core. TypeTraits will depend on MPL (this will be needed for common_type). At least initially, TypeTraits will still derive from MPL.Core primitives and provide backward compatibility. 4. Further improve MPL.Core for compatibility with std::integral_constant and also support Peter's proposed conversion constructor in mpl::bool_. I would prefer not to put anything from MPL into Core. I would accept a re- implementation of std::integral_constant in Core (for compatibility with C++03 compilers); a simple using std::integral_constant; into boost:: would be one possible implementation. MPL.Core then could derive its primitives from boost::integral_constant, this way providing compatibility with std:: numeric constants. Note that TypeTraits would gain support for tag dispatching on std::true_type and false_type as soon as this is done. I think that any version of TypeTraits that does not derive from MPL.Core primitives has to be announced as an alternative implementation (I call it TypeTraits v2), possibly deprecating the current one. This means that the two versions will have to coexist in Boost for some time. Arguably, both can be based in TypeTraits.Core.
Just to clarify my concern, the documentation of TypeTraits doens't preclule any dependency to MPL types and any module using this implementation detail should be fixed or we need to update the TypeTraits documentation.
Deriving from MPL primitives is documented. http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetra... Note that my above plan implies swapping integral_constant and MPL primitives in the inheritance chain. This alone can be viewed as a breaking change on its own, although I'd say it's a relatively safe one.
Le 15/06/14 14:17, Andrey Semashev a écrit :
On Sunday 15 June 2014 13:47:22 Vicente J. Botet Escriba wrote:
Just to clarify my concern, the documentation of TypeTraits doens't preclule any dependency to MPL types and any module using this implementation detail should be fixed or we need to update the TypeTraits documentation. Deriving from MPL primitives is documented.
http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetra... I was not aware of this section. It would be better if this information were on the reference manual section.
IMO, this is in contradiction with the reference documentation
http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetra...
From mpl.html "Purely as an implementation detail, this means that
|true_type| inherits from |boost::mpl::true_|"
From integral_constant.html "typedef integral_constant
On Sunday 15 June 2014 16:17:07 you wrote:
On Sunday 15 June 2014 13:47:22 Vicente J. Botet Escriba wrote:
Let me know IIUC: are you proposing Core true_, false_ types that can be used by TypeTraits and MPL preserving backward compatibility?
My personal preference is slightly different. I'll rehash:
1. Separate MPL into MPL and MPL.Core, as I've done in my private repos. 2. Make MPL.Core not depend on TypeTraits. There is only one dependency now, which is only needed to work around Borland bugs. 3. Separate TypeTraits into TypeTraits and TypeTraits.Core. TypeTraits.Core should ideally not depend on MPL and MPL.Core. It may require MPL.Core for things like mpl::if_, mpl::and_, etc, although the necessary components may be duplicated or implemented differently. At this moment, I have no strong opinion whether the dependency on MPL.Core should be strictly avoided. I'm certain though that TypeTraits.Core will not derive from any primitives, std:: or MPL.Core. TypeTraits will depend on MPL (this will be needed for common_type). At least initially, TypeTraits will still derive from MPL.Core primitives and provide backward compatibility.
I forgot to add: 3.5. Make MPL depend on TypeTraits.Core. This way we break circular dependency between the current MPL and TypeTraits. Note that the circular dependency is broken even if TypeTraits.Core depends on MPL.Core.
4. Further improve MPL.Core for compatibility with std::integral_constant and also support Peter's proposed conversion constructor in mpl::bool_.
I would prefer not to put anything from MPL into Core. I would accept a re- implementation of std::integral_constant in Core (for compatibility with C++03 compilers); a simple using std::integral_constant; into boost:: would be one possible implementation. MPL.Core then could derive its primitives from boost::integral_constant, this way providing compatibility with std:: numeric constants. Note that TypeTraits would gain support for tag dispatching on std::true_type and false_type as soon as this is done.
I think that any version of TypeTraits that does not derive from MPL.Core primitives has to be announced as an alternative implementation (I call it TypeTraits v2), possibly deprecating the current one. This means that the two versions will have to coexist in Boost for some time. Arguably, both can be based in TypeTraits.Core.
Just to clarify my concern, the documentation of TypeTraits doens't preclule any dependency to MPL types and any module using this implementation detail should be fixed or we need to update the TypeTraits documentation.
Deriving from MPL primitives is documented.
http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetra its/mpl.html
Note that my above plan implies swapping integral_constant and MPL primitives in the inheritance chain. This alone can be viewed as a breaking change on its own, although I'd say it's a relatively safe one.
2014-06-06 15:17 GMT+04:00 Peter Dimov
Antony Polukhin wrote:
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library?
<...>
We might duplicate these as boost/core/something.hpp and boost::core::something, but they will not be quite the same as their mpl counterparts, and will not magically make a module that includes a boost/mpl/ header drop its dependency to MPL.
Yes, I what to do something close to "duplicate them in boost::core::". And
no, they won't differ from boost::mpl:: at all.
For example if we take a look at the
namespaces should match. boost/, boost/detail/, boost/pending/ headers that do not obviously belong to a specific module can arguably be considered fair game.
Totally agree. But some parts of the MPL look more like Core parts for Boost (and C++ Standard library), rather than MPL parts. It's strange to see that implicit_cast/algorithm/sync "uses meta-programming library", however they only use identity<>/bool_. I know that the idea is arguable, but there's something wrong with having dependency to MPL in each Boost library. -- Best regards, Antony Polukhin
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library? Those classes are already mostly the part of C++, they are very simple and very widely used. Such reorganization will remove the dependency to MPL from many libraries.
+1 from me, in fact I already suggested that but folks seemed to not like it :-( It does "fix" a huge number of dependencies though... John.
On 6 June 2014 14:30, John Maddock
May be it would be better to move boost/mpl/bool.hpp, boost/mpl/bool_fwd.hpp, boost/mpl/integral_c.hpp, mpl/or.hpp, mpl/identity.hpp, mpl/and.hpp into the Core library? Those classes are already mostly the part of C++, they are very simple and very widely used. Such reorganization will remove the dependency to MPL from many libraries.
+1 from me, in fact I already suggested that but folks seemed to not like it
FWIW I'd like to have these things in core, whether they're duplicated or moved.
Le 05/06/14 03:31, Peter Dimov a écrit :
I've taken care of the
mpl -> detail detail -> iterator utility -> iterator
critical dependencies, which improved things a bit. The new report is at
http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html
It includes reverse dependencies for each module and has been generated from the develop branch of the super-project.
yes, the section Reverse dependencies in the module-overview report is very useful. Thanks, Vicente
2014-06-05 5:31 GMT+04:00 Peter Dimov
I've taken care of the
mpl -> detail detail -> iterator utility -> iterator
critical dependencies, which improved things a bit. The new report is at
http://www.pdimov.com/tmp/report-6d1f271/module-overview.html http://www.pdimov.com/tmp/report-6d1f271/module-levels.html
BTW, do we really want to have modules that contain only a single header file with 1-2 functions? How about moving assert, static_assert, throw_exception into the Core library? -- Best regards, Antony Polukhin
Le 06/06/14 19:47, Antony Polukhin a écrit :
BTW, do we really want to have modules that contain only a single header file with 1-2 functions? I don't think this is a good criteria. How about moving assert, static_assert, throw_exception into the Core library? Make sense. As a consequence Integer moves to level 3 ;-)
Vicente
Vicente J. Botet Escriba wrote:
Le 06/06/14 19:47, Antony Polukhin a écrit :
How about moving assert, static_assert, throw_exception into the Core library?
I'd thought about that. assert and static_assert predate core. I could have put throw_exception into core, but having it as its own module was more convenient because I wanted Emil to own it.
Make sense. As a consequence Integer moves to level 3 ;-)
Actually, core will drop to level 1. But that's just accounting.
participants (13)
-
Andrey Semashev
-
Antony Polukhin
-
Beman Dawes
-
Daniel James
-
Edward Diener
-
Emil Dotchevski
-
Eric Niebler
-
Felipe Magno de Almeida
-
Ion Gaztañaga
-
John Maddock
-
Peter Dimov
-
Stephen Kelly
-
Vicente J. Botet Escriba