
David Abrahams wrote:
on Thu Oct 29 2009, Joel de Guzman <joel-AT-boost-consulting.com> wrote:
So +1 for a mpl/type_traits style of organization from me too, For the record, I am not against this. It is in IMO the logical choice for most libraries. What I am saying is that for bigger libraries, it is logical to organize in modules.
As I've been saying, that practice doesn't have to be incompatible with the mpl/type_traits style of organization
When you have modules then that flat organization will start to break. E.g. if "x.hpp" is a header of module "foo" of library "lib", then, the logical structure is:
boost/ lib/ foo/ a.hpp foo.hpp lib.hpp
Notice that the header for module has the correct header:
<boost/lib/foo.hpp>
I don't even see x.hpp there.
Ooops. I meant a.hpp, of course :)
However, components of foo (a.hpp) cannot be hoisted outside its module. Thus, in this case, this is wrong:
<boost/lib/a.hpp>
Your example is a prime symptom of the breakage: "That said there may be a case to be made for splitting into sub-libraries - we did that with Boost.Math to avoid confusion between a distribution called X and a special function called X.".
When a library is modular, clashes are typical, e.g.:
boost/ lib/ foo/ a.hpp bar/ a.hpp foo.hpp bar.hpp lib.hpp
So, now you have two headers "a.hpp" under different modules, sharing the same name. It then becomes obvious why this is wrong:
<boost/lib/a.hpp>
There are several ways to deal with that. Aside from renaming one of the submodules, you could also have boost/lib/a.hpp #include boost/lib/foo/a.hpp and boost/lib/bar/a.hpp. It's not aesthetically ideal, but it's consistent and easier for users. Those who want to be more selective can still always reach for boost/lib/bar/a.hpp, for example.
Have you actually got a name clash situation like that one, BTW?
Yes. Spirit2 includes both "classic" and "qi" in there as well as "karma". There are lots of similar names such as rule.hpp, grammar.hpp that are found in each of the modules. In our flat include, we have to prepend them with "classic", "qi" and "karma" to disambiguate. Compare these (flat vs. modular) files for instance: #include <boost/spirit/qi/nonterminal/grammar.hpp> #include <boost/spirit/include/qi_grammar.hpp> And this: #include <boost/spirit/karma/nonterminal/grammar.hpp> #include <boost/spirit/include/karma_grammar.hpp> Such a workaround is reminiscent of pre namespace C++. John Maddock hints at a similar scenario that prompted them to make Boost.Math modular "to avoid confusion between a distribution called X and a special function called X". The same underlying reasons why we use namespaces apply to header files. IMHO, it is for the best interest of Boost to evolve from being flat to being more modular. I am lobbying for that. It's just the "right" way to go! :-) Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon