Discussion:
[boost] [Config] Support for switching between std:: and boost:: equivalents.
John Maddock
2015-06-05 07:41:25 UTC
Permalink
There is a pull-request for Config to provide support for switching
between boost:: and std:: library equivalents:
https://github.com/boostorg/config/pull/63

My questions are:

* Is this the right approach? And,
* Is Boost.Config the right place for it?

Thanks for your comments, John.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-05 09:30:03 UTC
Permalink
On 6/5/2015 3:41 AM, John Maddock wrote:
> There is a pull-request for Config to provide support for switching
> between boost:: and std:: library equivalents:
> https://github.com/boostorg/config/pull/63
>
> My questions are:
>
> * Is this the right approach? And,
> * Is Boost.Config the right place for it?
>
> Thanks for your comments, John.

That is my pull request so I will comment now that you have so
graciously provided a forum for my idea.

I don't know what "the right approach" would be but this is one approach
that does work easily, following the documentation I have written about
it and added to the Boost.config documentation.

I have written and added tests for all the Boost libraries involved
which have a C++ standard version which may be interoperably used
instead of the Boost version in code. These tests I would add as PRs to
the particular libraries once this config PR is pushed to 'develop'. The
tests are largely proof of concept tests that show that code does work.
The tests are not meant to be extensive tests for each library's
functionality.

I have also used the code successfully in this PR for a library I am
developing.

It is very easy to use. For library 'XXX':

1) Just include the particular Boost.config header provided for a
particular interoperable library XXX:

#include <boost/config/cpp/XXX.hpp>

2) Include that library's main header file using the macro provided for
that library:

#include BOOST_CPP_XXX_HDR

3) In code for that library's functionality use the namespace macro
provided for accessing the library's functionality:

BOOST_CPP_XXX_NS::some_functionality etc.

If you need to do anything different depending on whether you are using
the C++ standard version of the library or the Boost version of the
library you can test the BOOST_CPP_HAS_XXX macro, which is 1 for the C++
standard version existing in the compiler implementation and is 0 for
only the Boost version existing in the compiler implementation.

That's it for any given library supported. You are using the C++
standard version of the library if it exists in the compiler
implementation or the Boost version of the library if it does not exists
in the compiler implementation.

The Boost implementations supported are:

array
atomic
bind
chrono
function
hash
mem_fn
random
ratio
reg/creg
regex
shared_ptr
thread
tuple
type_index
type_traits
unordered_map
unordered_multimap
unordered_set
unordered_multiset

If I have missed any Boost libraries which have a close C++ standard
equivalent just tell me and I will add it with some added tests for that
particular library.

I give a basic example how the macros are used using regex in the
documentation.

Of course there may be differences between the C++ standard library
equivalent of a Boost library and the Boost library itself. But for the
most part the system I have provided will work and when it does not work
because of differences, at the very least you can use the
BOOST_CPP_HAS_XXX form of macro to decide what you want to do.

As to whether or not it belongs in Boost.config:

1) The macros for any given library 'XXX" are not automatically brought
in by the normal 'include <boost/config.h>', so they affect nothing in
Boost.config.

2) The system is based directly on Boost.config detection macros in
order to determine whether or not a particular 'XXX' equivalent library
exists.

3) The macros do "configure" the ability to use either a Boost library
or its C++ standard equivalent using the same syntax.

4) The system could be put in its own library with a dependency on
Boost.config only, but it is such a simple system already dependent on
Boost.config that I felt it would easily fit as part of Boost.config
than as its own separate library.

5) I wanted to push it to 'develop' and let others use it and add the
per library PR's to test it. If it was found to be flawed or could be
better in any way I could then change it on 'develop', and if people
were satisfied with it as a workable solution it could eventually be
merged to 'master'. If not it could be easily removed if necessary since
it exists in its own header files apart from the rest of Boost.config.
Even its documentation is a separate Boost.config .qbk file.

I know these macros work and provide an easy transition between using
the C++ standard equivalent of a Boost library if it exists in a
compiler implementation or the Boost version if it does not. I made no
attempt to create a per XXX library bridge between functionality of the
C++ standard equivalent of a Boost library and the Boost library itself
when the functionality differs because one has functionality that the
other does not or, in the rarer case, when the same syntactical
functionality works differently. I feel that such an attempt at
interoperability is outside the purpose of the system I provide. For
many of the mainstream Boost libraries which are now in the C++11
standard as libraries the system I have created, via macros, of
including the correct header and use the correct namespace works largely
flawlessly without having to consider differences. I am thinking of such
closely equivalent and highly used libraries as 'function', 'bind',
'ref/cref', 'regex' etc. The system I have provided is meant to make
writing code much easier without having to worry about which library I
am using, the C++ standard version or the Boost version.

If there are better interoperable systems I would love to hear about
them. But for me personally any system where I have to jump through
hoops simply to be able to write code which works whether I am using a
Boost library or its C++ standard library equivalent, will not be worth it.

The fork of config on which this PR is based is under my own account at
https://github.com/eldiener/config.git if anyone wants to play around
with it. The documentation I added to the Boost.config docs explain
everything better than I have here. I am of course willing to support
this work. My local tests I can push to forks of each XXX Boost library
supported by these macros, since I have already made local branches for
each XXX library with tests added for these Boost.config macros to show
that they work.

Questions, concerns etc are welcome.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Sylvester-Bradley, Gareth
2015-06-05 10:15:16 UTC
Permalink
On 05 June 2015 10:30, Edward Diener wrote:
> On 6/5/2015 3:41 AM, John Maddock wrote:
> > There is a pull-request for Config to provide support for switching
>> between boost:: and std:: library equivalents:
>> https://github.com/boostorg/config/pull/63
>>
>> My questions are:
>>
>> * Is this the right approach? And,
>> * Is Boost.Config the right place for it?
>>
>> Thanks for your comments, John.
>
> That is my pull request so I will comment now that you have so graciously provided a forum for my idea.
>
> I don't know what "the right approach" would be but this is one approach that does work easily, following the documentation I have written about it and added to the Boost.config documentation.

[snip good detection/reporting macros stuff]

> 3) In code for that library's functionality use the namespace macro provided for accessing the library's functionality:
>
> BOOST_CPP_XXX_NS::some_functionality etc.

It would be useful to compare the BOOST_CPP_XXX_NS macro approach to providing a namespace with using declarations. I use 'bst'.

One advantage is flexibility to adapt the mapping where necessary, e.g. while Boost placeholders were in boost, but std::placeholders.


Best regards,
Gareth




************************************************************************ The information contained in this message or any of its attachments may be confidential and is intended for the exclusive use of the addressee(s). Any disclosure, reproduction, distribution or other dissemination or use of this communication is strictly prohibited without the express permission of the sender. The views expressed in this email are those of the individual and not necessarily those of Sony or Sony affiliated companies. Sony email is for business use only. This email and any response may be monitored by Sony to be in compliance with Sony's global policies and standards

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-05 14:32:44 UTC
Permalink
On 6/5/2015 6:15 AM, Sylvester-Bradley, Gareth wrote:
> On 05 June 2015 10:30, Edward Diener wrote:
>> On 6/5/2015 3:41 AM, John Maddock wrote:
>>> There is a pull-request for Config to provide support for switching
>>> between boost:: and std:: library equivalents:
>>> https://github.com/boostorg/config/pull/63
>>>
>>> My questions are:
>>>
>>> * Is this the right approach? And,
>>> * Is Boost.Config the right place for it?
>>>
>>> Thanks for your comments, John.
>>
>> That is my pull request so I will comment now that you have so graciously provided a forum for my idea.
>>
>> I don't know what "the right approach" would be but this is one approach that does work easily, following the documentation I have written about it and added to the Boost.config documentation.
>
> [snip good detection/reporting macros stuff]
>
>> 3) In code for that library's functionality use the namespace macro provided for accessing the library's functionality:
>>
>> BOOST_CPP_XXX_NS::some_functionality etc.
>
> It would be useful to compare the BOOST_CPP_XXX_NS macro approach to providing a namespace with using declarations. I use 'bst'.

You could just as easily write:

using namespace BOOST_CPP_XXX_NS;

>
> One advantage is flexibility to adapt the mapping where necessary, e.g. while Boost placeholders were in boost, but std::placeholders.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Rob Stewart
2015-06-05 14:00:42 UTC
Permalink
On June 5, 2015 5:30:03 AM EDT, Edward Diener <***@tropicsoft.com> wrote:
> On 6/5/2015 3:41 AM, John Maddock wrote:
> > There is a pull-request for Config to provide support for switching
> > between boost:: and std:: library equivalents:
> > https://github.com/boostorg/config/pull/63
> >
> > My questions are:
> >
> > * Is this the right approach? And,
> > * Is Boost.Config the right place for it?
>
> I don't know what "the right approach" would be but this is one
> approach that does work easily.

It does seem like a reasonable approach overall. It's relatively simple and doesn't try to hide much.

I can't think of a better place for this than Config.

> It is very easy to use. For library 'XXX':
>
> 1) Just include the particular Boost.config header provided for a
> particular interoperable library XXX:
>
> #include <boost/config/cpp/XXX.hpp>

I noticed in your PR that you also provide a header to get all such headers at once. I wonder whether the individual headers are really that useful. You could keep the implementation you have, but just document the one header.

> 2) Include that library's main header file using the macro provided
> for that library:
>
> #include BOOST_CPP_XXX_HDR

Why do you have "CPP" in that name? BOOST_XXX_HDR would seem sufficient. I also would suggest using HEADER rather than HDR.

> 3) In code for that library's functionality use the namespace macro
> provided for accessing the library's functionality:
> BOOST_CPP_XXX_NS::some_functionality etc.

Why do you have "CPP" in that name? BOOST_XXX_NS would seem sufficient.

> If you need to do anything different depending on whether you are
> using
> the C++ standard version of the library or the Boost version of the
> library you can test the BOOST_CPP_HAS_XXX macro, which is 1 for the
> C++
> standard version existing in the compiler implementation and is 0 for
> only the Boost version existing in the compiler implementation.

That macro would seem better named, BOOST_HAS_STD_XXX our BOOST_XXX_IS_STD. (The latter is more consistent with my earlier suggestions.)

___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-05 14:42:50 UTC
Permalink
On 6/5/2015 10:00 AM, Rob Stewart wrote:
> On June 5, 2015 5:30:03 AM EDT, Edward Diener <***@tropicsoft.com> wrote:
>> On 6/5/2015 3:41 AM, John Maddock wrote:
>>> There is a pull-request for Config to provide support for switching
>>> between boost:: and std:: library equivalents:
>>> https://github.com/boostorg/config/pull/63
>>>
>>> My questions are:
>>>
>>> * Is this the right approach? And,
>>> * Is Boost.Config the right place for it?
>>
>> I don't know what "the right approach" would be but this is one
>> approach that does work easily.
>
> It does seem like a reasonable approach overall. It's relatively simple and doesn't try to hide much.
>
> I can't think of a better place for this than Config.
>
>> It is very easy to use. For library 'XXX':
>>
>> 1) Just include the particular Boost.config header provided for a
>> particular interoperable library XXX:
>>
>> #include <boost/config/cpp/XXX.hpp>
>
> I noticed in your PR that you also provide a header to get all such headers at once. I wonder whether the individual headers are really that useful. You could keep the implementation you have, but just document the one header.

The one header is documented. I have the individual headers to avoid
flooding the macro namespaces with lots of macros you are not going to use.

>
>> 2) Include that library's main header file using the macro provided
>> for that library:
>>
>> #include BOOST_CPP_XXX_HDR
>
> Why do you have "CPP" in that name? BOOST_XXX_HDR would seem sufficient. I also would suggest using HEADER rather than HDR.

I like to avoid macro name clashes, Having a common prefix, such as CPP,
tends to do that.

As far as the more verbose HEADER instead of the shorter HDR that's fine
with me if others like that instead. I could even change
BOOST_CPP_XXX_NS to BOOST_CPP_XXX_NAMESPACE and have everybody type out
the fully explicit names.

>
>> 3) In code for that library's functionality use the namespace macro
>> provided for accessing the library's functionality:
>> BOOST_CPP_XXX_NS::some_functionality etc.
>
> Why do you have "CPP" in that name? BOOST_XXX_NS would seem sufficient.
>
>> If you need to do anything different depending on whether you are
>> using
>> the C++ standard version of the library or the Boost version of the
>> library you can test the BOOST_CPP_HAS_XXX macro, which is 1 for the
>> C++
>> standard version existing in the compiler implementation and is 0 for
>> only the Boost version existing in the compiler implementation.
>
> That macro would seem better named, BOOST_HAS_STD_XXX our BOOST_XXX_IS_STD. (The latter is more consistent with my earlier suggestions.)

Again I like distinct macro names so BOOST_CPP_something seems right,
but your other suggestions, as BOOST_CPP_HAS_STD_XXX or
BOOST_CPP_XXX_IS_STD, are fine. Please realize that all macros are in a
global namespace with everything and avoiding macro name clashes in any
TU is of paramount importance.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Rob Stewart
2015-06-06 00:14:08 UTC
Permalink
On June 5, 2015 10:42:50 AM EDT, Edward Diener <***@tropicsoft.com> wrote:
> On 6/5/2015 10:00 AM, Rob Stewart wrote:
> > On June 5, 2015 5:30:03 AM EDT, Edward Diener
> <***@tropicsoft.com> wrote:
> >
> >> It is very easy to use. For library 'XXX':
> >>
> >> 1) Just include the particular Boost.config header provided for a
> >> particular interoperable library XXX:
> >>
> >> #include <boost/config/cpp/XXX.hpp>
> >
> > I noticed in your PR that you also provide a header to get all such
> headers at once. I wonder whether the individual headers are really
> that useful. You could keep the implementation you have, but just
> document the one header.
>
> The one header is documented. I have the individual headers to avoid
> flooding the macro namespaces with lots of macros you are not going to
> use.

I know you documented the everything header. I was suggesting that you not document or mention the others.

I don't think the flooding issue you mention is significant. The macro names are reasonably unique and I don't think there are so many that you need worry about defining them all.

> >> 2) Include that library's main header file using the macro provided
> >> for that library:
> >>
> >> #include BOOST_CPP_XXX_HDR
> >
> > Why do you have "CPP" in that name? BOOST_XXX_HDR would seem
> sufficient. I also would suggest using HEADER rather than HDR.
>
> I like to avoid macro name clashes, Having a common prefix, such as
> CPP, tends to do that.

I understand the concern, but I don't think BOOST_ATOMIC_HEADER, BOOST_ATOMIC_NAMESPACE, BOOST_ATOMIC_IS_STD, etc. would be likely to clash.

> I could even change BOOST_CPP_XXX_NS to BOOST_CPP_XXX_NAMESPACE and have everybody type
> out the fully explicit names.

HEADER won't appear very often, so I thought spelling it out would be fine. The namespace macro might be used more often, so I didn't suggest expanding it. OTOH, the longer name can be mitigated by a namespace alias.

___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-06 01:18:46 UTC
Permalink
On 6/5/2015 8:14 PM, Rob Stewart wrote:
> On June 5, 2015 10:42:50 AM EDT, Edward Diener <***@tropicsoft.com> wrote:
>> On 6/5/2015 10:00 AM, Rob Stewart wrote:
>>> On June 5, 2015 5:30:03 AM EDT, Edward Diener
>> <***@tropicsoft.com> wrote:
>>>
>>>> It is very easy to use. For library 'XXX':
>>>>
>>>> 1) Just include the particular Boost.config header provided for a
>>>> particular interoperable library XXX:
>>>>
>>>> #include <boost/config/cpp/XXX.hpp>
>>>
>>> I noticed in your PR that you also provide a header to get all such
>> headers at once. I wonder whether the individual headers are really
>> that useful. You could keep the implementation you have, but just
>> document the one header.
>>
>> The one header is documented. I have the individual headers to avoid
>> flooding the macro namespaces with lots of macros you are not going to
>> use.
>
> I know you documented the everything header. I was suggesting that you not document or mention the others.
>
> I don't think the flooding issue you mention is significant. The macro names are reasonably unique and I don't think there are so many that you need worry about defining them all.

I think giving people choices is better than not doing so. Why bring in
what isn't needed for any give TU ?

>
>>>> 2) Include that library's main header file using the macro provided
>>>> for that library:
>>>>
>>>> #include BOOST_CPP_XXX_HDR
>>>
>>> Why do you have "CPP" in that name? BOOST_XXX_HDR would seem
>> sufficient. I also would suggest using HEADER rather than HDR.
>>
>> I like to avoid macro name clashes, Having a common prefix, such as
>> CPP, tends to do that.
>
> I understand the concern, but I don't think BOOST_ATOMIC_HEADER, BOOST_ATOMIC_NAMESPACE, BOOST_ATOMIC_IS_STD, etc. would be likely to clash.

Actually I do, and I think you are wrong. It is customary for Boost
libraries which have macros to name them starting with BOOST_XXX_ where
XXX is the library name. Why should I worry about potential clashes by
following the exacts same convention for my macros.

OTOH I do like your suggestion about changing the name of the
BOOST_CPP_HAS_XXX macros to something like BOOST_CPP_XXX_IS_STD, or
better yet BOOST_CPP_XXX_USES_STD_LIB, as being much more descriptive
even if less terse.

>
>> I could even change BOOST_CPP_XXX_NS to BOOST_CPP_XXX_NAMESPACE and have everybody type
>> out the fully explicit names.
>
> HEADER won't appear very often, so I thought spelling it out would be fine. The namespace macro might be used more often, so I didn't suggest expanding it. OTOH, the longer name can be mitigated by a namespace alias.

OK, that seems reasonable. the BOOST_CPP_XXX_HEADER would only be used
once each TU so I agree with you on that. No need for the HDR abbreviation.

I want to wait until all discussion of the macros are complete before I
implement macro naming changes, but I do appreciate your suggestions.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-06 09:07:40 UTC
Permalink
On Friday 05 June 2015 20:14:08 Rob Stewart wrote:
> On June 5, 2015 10:42:50 AM EDT, Edward Diener <***@tropicsoft.com>
wrote:
> >
> > The one header is documented. I have the individual headers to avoid
> > flooding the macro namespaces with lots of macros you are not going to
> > use.
>
> I know you documented the everything header. I was suggesting that you not
> document or mention the others.

If those headers are public, they have to be documented. FWIW, I'm more
interested in the individual headers and not the include-all one.

> > I like to avoid macro name clashes, Having a common prefix, such as
> > CPP, tends to do that.
>
> I understand the concern, but I don't think BOOST_ATOMIC_HEADER,
> BOOST_ATOMIC_NAMESPACE, BOOST_ATOMIC_IS_STD, etc. would be likely to clash.

Those names are in the namespace of Boost.Atomic by the current conventions.
They may not be used now, but can be used later. Please, don't do it.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Rob Stewart
2015-06-06 10:12:21 UTC
Permalink
On June 6, 2015 5:07:40 AM EDT, Andrey Semashev <***@gmail.com> wrote:
> On Friday 05 June 2015 20:14:08 Rob Stewart wrote:
> >
> > I don't think BOOST_ATOMIC_HEADER,
> > BOOST_ATOMIC_NAMESPACE, BOOST_ATOMIC_IS_STD, etc. would be likely to
> clash.
>
> Those names are in the namespace of Boost.Atomic by the current
> conventions.
> They may not be used now, but can be used later. Please, don't do it.

Each of the affected libraries can consider this set of names as belonging to the library despite being defined by Config. They also don't seem likely, though I haven't checked, to be used currently. For those reasons I don't see the problem.

The proposed unique tag, CPP, is meaningless. It may create a namespace not already used, but it also doesn't relate to the function of the macros. Since Boost.Config doesn't have its own tag, it seemed reasonable that these not have a tag, which makes them extensions of the affected libraries' macros.

Whether there is a tag, or even if the tag is CPP, the macros appear useful.

___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-06 10:52:52 UTC
Permalink
On Saturday 06 June 2015 06:12:21 Rob Stewart wrote:
> On June 6, 2015 5:07:40 AM EDT, Andrey Semashev <***@gmail.com>
wrote:
> > On Friday 05 June 2015 20:14:08 Rob Stewart wrote:
> > > I don't think BOOST_ATOMIC_HEADER,
> > > BOOST_ATOMIC_NAMESPACE, BOOST_ATOMIC_IS_STD, etc. would be likely to
> >
> > clash.
> >
> > Those names are in the namespace of Boost.Atomic by the current
> > conventions.
> > They may not be used now, but can be used later. Please, don't do it.
>
> Each of the affected libraries can consider this set of names as belonging
> to the library despite being defined by Config. They also don't seem
> likely, though I haven't checked, to be used currently. For those reasons I
> don't see the problem.

I disagree. The macros, as they are currently proposed, are part of
Boost.Config. Otherwise they should be proposed to each library separately and
then, yes, they would have names according to each library's namespace.

Whether the libraries are used or not is irrelevant, the namespaces are still
reserved.

> The proposed unique tag, CPP, is meaningless. It may create a namespace not
> already used, but it also doesn't relate to the function of the macros.
> Since Boost.Config doesn't have its own tag, it seemed reasonable that
> these not have a tag, which makes them extensions of the affected
> libraries' macros.

I suggested to change the tag to CXX in the pull request, to follow the
current practice in Boost.Config. It seems a reasonable tag to me as these
macros deal with C++ implementation capabilities (or rather STL capabilities -
which could be used as an alternative tag).

I don't mind if a different tag is chosen. I would just like the names to be
still organized and not clash with other libraries namespaces.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-06 19:35:29 UTC
Permalink
On 6/6/2015 5:07 AM, Andrey Semashev wrote:
> On Friday 05 June 2015 20:14:08 Rob Stewart wrote:
>> On June 5, 2015 10:42:50 AM EDT, Edward Diener <***@tropicsoft.com>
> wrote:
>>>
>>> The one header is documented. I have the individual headers to avoid
>>> flooding the macro namespaces with lots of macros you are not going to
>>> use.
>>
>> I know you documented the everything header. I was suggesting that you not
>> document or mention the others.
>
> If those headers are public, they have to be documented. FWIW, I'm more
> interested in the individual headers and not the include-all one.

They are "public" and they are documented. The general header is for
convenience and to give uses of the macro system a choice.

>
>>> I like to avoid macro name clashes, Having a common prefix, such as
>>> CPP, tends to do that.
>>
>> I understand the concern, but I don't think BOOST_ATOMIC_HEADER,
>> BOOST_ATOMIC_NAMESPACE, BOOST_ATOMIC_IS_STD, etc. would be likely to clash.
>
> Those names are in the namespace of Boost.Atomic by the current conventions.
> They may not be used now, but can be used later. Please, don't do it.

I agree with you and that is the reason for using a mnemonic for each
macro. I am not against changing from BOOST_CPP_ to BOOST_CXX_. I just
want to make sure before I do that no other Boost library or set of
macros is using BOOST_CXX_.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Robert Ramey
2015-06-05 14:11:46 UTC
Permalink
On 6/5/15 2:30 AM, Edward Diener wrote:

>
> Questions, concerns etc are welcome.

Is there an easy way to see the html verions of this?

Robert Ramey



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-05 15:54:46 UTC
Permalink
On 6/5/2015 10:11 AM, Robert Ramey wrote:
> On 6/5/15 2:30 AM, Edward Diener wrote:
>
>>
>> Questions, concerns etc are welcome.
>
> Is there an easy way to see the html verions of this?

https://htmlpreview.github.io/?https://github.com/eldiener/config/blob/develop/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_choose_standard_or_boost_libraries



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-05 19:37:52 UTC
Permalink
On Friday 05 June 2015 05:30:03 Edward Diener wrote:
> On 6/5/2015 3:41 AM, John Maddock wrote:
> > There is a pull-request for Config to provide support for switching
> > between boost:: and std:: library equivalents:
> > https://github.com/boostorg/config/pull/63
> >
> > My questions are:
> >
> > * Is this the right approach? And,
> > * Is Boost.Config the right place for it?
> >
> > Thanks for your comments, John.
>
> That is my pull request so I will comment now that you have so
> graciously provided a forum for my idea.
>
> I don't know what "the right approach" would be but this is one approach
> that does work easily, following the documentation I have written about
> it and added to the Boost.config documentation.
>
> I have written and added tests for all the Boost libraries involved
> which have a C++ standard version which may be interoperably used
> instead of the Boost version in code. These tests I would add as PRs to
> the particular libraries once this config PR is pushed to 'develop'. The
> tests are largely proof of concept tests that show that code does work.
> The tests are not meant to be extensive tests for each library's
> functionality.
>
> I have also used the code successfully in this PR for a library I am
> developing.
>
> It is very easy to use. For library 'XXX':
>
> 1) Just include the particular Boost.config header provided for a
> particular interoperable library XXX:
>
> #include <boost/config/cpp/XXX.hpp>
>
> 2) Include that library's main header file using the macro provided for
> that library:
>
> #include BOOST_CPP_XXX_HDR
>
> 3) In code for that library's functionality use the namespace macro
> provided for accessing the library's functionality:
>
> BOOST_CPP_XXX_NS::some_functionality etc.

In general, this might be useful in some constrained contexts, but I have a
few concerns:

1. What if the Boost version requires linking with a built library? These
headers won't be able to hide that.

2. I'm worried if these tools will be used in Boost libraries in a way that
affects library API/ABI. What if one library uses these tools and the other
doesn't - will these libraries be able to interoperate? Or is it a user's
problem? There is also the possibility that Boost is built in C++03 mode and
the user builds his code in C++11. I think this will be most apparent with
utilities like shared_ptr and function, which are often present in the
interfaces.

> If you need to do anything different depending on whether you are using
> the C++ standard version of the library or the Boost version of the
> library you can test the BOOST_CPP_HAS_XXX macro, which is 1 for the C++
> standard version existing in the compiler implementation and is 0 for
> only the Boost version existing in the compiler implementation.
>
> That's it for any given library supported. You are using the C++
> standard version of the library if it exists in the compiler
> implementation or the Boost version of the library if it does not exists
> in the compiler implementation.
>
> The Boost implementations supported are:
>
> array
> atomic
> bind
> chrono
> function
> hash
> mem_fn
> random
> ratio
> reg/creg
> regex
> shared_ptr
> thread
> tuple
> type_index
> type_traits
> unordered_map
> unordered_multimap
> unordered_set
> unordered_multiset
>
> If I have missed any Boost libraries which have a close C++ standard
> equivalent just tell me and I will add it with some added tests for that
> particular library.

If you have thread you could also add mutex, condition_variable and locks.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-05 21:05:08 UTC
Permalink
On 6/5/2015 3:37 PM, Andrey Semashev wrote:
> On Friday 05 June 2015 05:30:03 Edward Diener wrote:
>> On 6/5/2015 3:41 AM, John Maddock wrote:
>>> There is a pull-request for Config to provide support for switching
>>> between boost:: and std:: library equivalents:
>>> https://github.com/boostorg/config/pull/63
>>>
>>> My questions are:
>>>
>>> * Is this the right approach? And,
>>> * Is Boost.Config the right place for it?
>>>
>>> Thanks for your comments, John.
>>
>> That is my pull request so I will comment now that you have so
>> graciously provided a forum for my idea.
>>
>> I don't know what "the right approach" would be but this is one approach
>> that does work easily, following the documentation I have written about
>> it and added to the Boost.config documentation.
>>
>> I have written and added tests for all the Boost libraries involved
>> which have a C++ standard version which may be interoperably used
>> instead of the Boost version in code. These tests I would add as PRs to
>> the particular libraries once this config PR is pushed to 'develop'. The
>> tests are largely proof of concept tests that show that code does work.
>> The tests are not meant to be extensive tests for each library's
>> functionality.
>>
>> I have also used the code successfully in this PR for a library I am
>> developing.
>>
>> It is very easy to use. For library 'XXX':
>>
>> 1) Just include the particular Boost.config header provided for a
>> particular interoperable library XXX:
>>
>> #include <boost/config/cpp/XXX.hpp>
>>
>> 2) Include that library's main header file using the macro provided for
>> that library:
>>
>> #include BOOST_CPP_XXX_HDR
>>
>> 3) In code for that library's functionality use the namespace macro
>> provided for accessing the library's functionality:
>>
>> BOOST_CPP_XXX_NS::some_functionality etc.
>
> In general, this might be useful in some constrained contexts, but I have a
> few concerns:
>
> 1. What if the Boost version requires linking with a built library? These
> headers won't be able to hide that.

You are correct. But what are the issues about linking to a Boost
library which needs to be addressed as you see it ?

Notice that anything necessary to linking to a Boost library can be
figured out macro-wise for a given library by first currently testing
BOOST_CPP_HAS_XXX for 0 to determine that it is the Boost library which
will be used. Of course some other BOOST_CPP_XXX macro would need to be
added to specify whether the Boost library needs to be linked or not. So
if there is anything which could be automated as part of the source code
to automate linking I should be able to automatically configure it
using macros also. As an expansion of the basic set of macros which are
offered for each library, if the solution to linking is a generic
solution I do not mind adding it in. But let's first identify the
problem before we can identify any possible generic solution.

>
> 2. I'm worried if these tools will be used in Boost libraries in a way that
> affects library API/ABI. What if one library uses these tools and the other
> doesn't - will these libraries be able to interoperate? Or is it a user's
> problem? There is also the possibility that Boost is built in C++03 mode and
> the user builds his code in C++11. I think this will be most apparent with
> utilities like shared_ptr and function, which are often present in the
> interfaces.

Its no different from some Boost library using the C++ standard version
of, let's say, std::function because it is available and another library
using boost::function. Is API/ABI compatibility affected ? If so that
has to be taken into account if you use those libraries internally.
Suppose library X is compiled using C++11 mode and your own library Y,
which uses library X as a dependency, is compiled without C++11 mode.
Again those factors of interoperability between the libraries must be
taken into account. Using my macros is not going to change any of that,
and my macro system cannot solve that problem, or make it more or less
than if the macro system I propose were not used at all.

So while I understand your worries I think it is a general one as more
Boost libraries use C++ standard equivalents of Boost libraries as
dependencies while other current Boost libraries stay with their Boost
library equivalents as dependencies. My macro system, while making it
easier to generically use one or the other, just brings out a problem
that would have happened anyway. The only way to stop this problem is to
establish rigid rules of what each Boost library must use, and we can't
of course do that.

>
>> If you need to do anything different depending on whether you are using
>> the C++ standard version of the library or the Boost version of the
>> library you can test the BOOST_CPP_HAS_XXX macro, which is 1 for the C++
>> standard version existing in the compiler implementation and is 0 for
>> only the Boost version existing in the compiler implementation.
>>
>> That's it for any given library supported. You are using the C++
>> standard version of the library if it exists in the compiler
>> implementation or the Boost version of the library if it does not exists
>> in the compiler implementation.
>>
>> The Boost implementations supported are:
>>
>> array
>> atomic
>> bind
>> chrono
>> function
>> hash
>> mem_fn
>> random
>> ratio
>> reg/creg
>> regex
>> shared_ptr
>> thread
>> tuple
>> type_index
>> type_traits
>> unordered_map
>> unordered_multimap
>> unordered_set
>> unordered_multiset
>>
>> If I have missed any Boost libraries which have a close C++ standard
>> equivalent just tell me and I will add it with some added tests for that
>> particular library.
>
> If you have thread you could also add mutex, condition_variable and locks.

OK, I will look into this. If any of them are in different headers
and/or namespaces than 'thread' they will need there own set of HDR, NS,
and HAS macros and initial boost/config/cpp/xxx.hpp header file to be
included. Thanks for pointing these other implementations out ! I
expected I might have missed a few.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Peter Dimov
2015-06-05 21:20:28 UTC
Permalink
Edward Diener wrote:

> Suppose library X is compiled using C++11 mode and your own library Y,
> which uses library X as a dependency, is compiled without C++11 mode.
> Again those factors of interoperability between the libraries must be
> taken into account. Using my macros is not going to change any of that,
> ...

No, but one could argue that the existence of your macros in Boost.Config is
going to encourage people to use them and hence make this situation more
likely.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-05 23:44:03 UTC
Permalink
On 6/5/2015 5:20 PM, Peter Dimov wrote:
> Edward Diener wrote:
>
>> Suppose library X is compiled using C++11 mode and your own library Y,
>> which uses library X as a dependency, is compiled without C++11 mode.
>> Again those factors of interoperability between the libraries must be
>> taken into account. Using my macros is not going to change any of
>> that, ...
>
> No, but one could argue that the existence of your macros in
> Boost.Config is going to encourage people to use them and hence make
> this situation more likely.

I agree but incorporating C++11 libraries or using C++11 language
features in code is inevitable anyway. If my macros make it easier to do
the former I view that as a success. I certainly feel that making easier
to move forward toward C++11/C++14/C++17 should be one of the goals of
Boost, rather than holding people back from doing so. I know that in a
library on which I am working if the corresponding C++ standard
equivalent libraries to certain Boost libraries are available I want to
use them.

There are situations where you might want to stick to the Boost version
of a library when a C++ standard equivalent is available, but that's
easy to do by just ignoring my macro system. Similarly you can use my
macro system so that if you only want to use the C++ standard equivalent
version of a Boost library you can easily create a preprocessor #error
if it is not available.




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-05 22:35:01 UTC
Permalink
On Friday 05 June 2015 17:05:08 Edward Diener wrote:
> On 6/5/2015 3:37 PM, Andrey Semashev wrote:
> >
> > 1. What if the Boost version requires linking with a built library? These
> > headers won't be able to hide that.
>
> You are correct. But what are the issues about linking to a Boost
> library which needs to be addressed as you see it ?
>
> Notice that anything necessary to linking to a Boost library can be
> figured out macro-wise for a given library by first currently testing
> BOOST_CPP_HAS_XXX for 0 to determine that it is the Boost library which
> will be used. Of course some other BOOST_CPP_XXX macro would need to be
> added to specify whether the Boost library needs to be linked or not. So
> if there is anything which could be automated as part of the source code
> to automate linking I should be able to automatically configure it
> using macros also. As an expansion of the basic set of macros which are
> offered for each library, if the solution to linking is a generic
> solution I do not mind adding it in. But let's first identify the
> problem before we can identify any possible generic solution.

In general, you won't get away with just macros, as autolinking is only
present in MSVC & friends. This would also affect build system scripts.

Suppose I'm a (Boost) library writer; the library has a compiled part and I'm
writing a Makefile/Jamfile. If I'm using these macros, I still have to know
when to link and when not to link with Boost libs. This can be rather tricky
as not only compiler versions should be checked but also their options; and it
also needs to be in sync with Boost.Config. The same happens when I'm a user
of a (Boost) library that uses these macros, only it becomes more difficult to
be in sync with Boost.Config. My point is that since these macros don't
actually abstract me away from the configuration, why would I use them?

Arguably, this problem goes away if the macros only handle components which
are header-only in Boost.

> > 2. I'm worried if these tools will be used in Boost libraries in a way
> > that
> > affects library API/ABI. What if one library uses these tools and the
> > other
> > doesn't - will these libraries be able to interoperate? Or is it a user's
> > problem? There is also the possibility that Boost is built in C++03 mode
> > and the user builds his code in C++11. I think this will be most apparent
> > with utilities like shared_ptr and function, which are often present in
> > the interfaces.
>
> Its no different from some Boost library using the C++ standard version
> of, let's say, std::function because it is available and another library
> using boost::function. Is API/ABI compatibility affected ? If so that
> has to be taken into account if you use those libraries internally.
> Suppose library X is compiled using C++11 mode and your own library Y,
> which uses library X as a dependency, is compiled without C++11 mode.

It's more likely that Boost is compiled in one mode and distributed in a
standard package (say, with a Linux distro) and I'm building my app locally
with that Boost. Most Linux distros build Boost with default compiler options
which means C++03. If these macros affect Boost libraries ABI I will no longer
be able to build my app in C++11 mode.

> Again those factors of interoperability between the libraries must be
> taken into account. Using my macros is not going to change any of that,
> and my macro system cannot solve that problem, or make it more or less
> than if the macro system I propose were not used at all.

As Peter noted, having these macros in Boost.Config can be seen as
encouragement to use. And when used improperly they can cause real problems.

So far I'm seeing these macros only applicable under the following conditions:

a) the macros can be used in header-only libraries or concealed in the
compiled part of the library without exposing it to API/ABI, and

b) only when these macros allow to switch between STL and header-only Boost
alternatives (not compiled ones).

I'm not sure how to enforce these restrictions and I'm not sure adding them
without doing something about their dangerous use is a good idea. Sorry if I'm
not being helpful here.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-06 01:07:20 UTC
Permalink
On 6/5/2015 6:35 PM, Andrey Semashev wrote:
> On Friday 05 June 2015 17:05:08 Edward Diener wrote:
>> On 6/5/2015 3:37 PM, Andrey Semashev wrote:
>>>
>>> 1. What if the Boost version requires linking with a built library? These
>>> headers won't be able to hide that.
>>
>> You are correct. But what are the issues about linking to a Boost
>> library which needs to be addressed as you see it ?
>>
>> Notice that anything necessary to linking to a Boost library can be
>> figured out macro-wise for a given library by first currently testing
>> BOOST_CPP_HAS_XXX for 0 to determine that it is the Boost library which
>> will be used. Of course some other BOOST_CPP_XXX macro would need to be
>> added to specify whether the Boost library needs to be linked or not. So
>> if there is anything which could be automated as part of the source code
>> to automate linking I should be able to automatically configure it
>> using macros also. As an expansion of the basic set of macros which are
>> offered for each library, if the solution to linking is a generic
>> solution I do not mind adding it in. But let's first identify the
>> problem before we can identify any possible generic solution.
>
> In general, you won't get away with just macros, as autolinking is only
> present in MSVC & friends. This would also affect build system scripts.
>
> Suppose I'm a (Boost) library writer; the library has a compiled part and I'm
> writing a Makefile/Jamfile. If I'm using these macros, I still have to know
> when to link and when not to link with Boost libs. This can be rather tricky
> as not only compiler versions should be checked but also their options; and it
> also needs to be in sync with Boost.Config. The same happens when I'm a user
> of a (Boost) library that uses these macros, only it becomes more difficult to
> be in sync with Boost.Config. My point is that since these macros don't
> actually abstract me away from the configuration, why would I use them?

They abstract you away from having to write complicated code which
caters to whether or not a C++ standard library equivalent to a Boost
library is available or not. They don't relieve the responsibility of a
built library from naming itself in such a way that those linking with
the library can do so successfully if auto-linking is not available.

>
> Arguably, this problem goes away if the macros only handle components which
> are header-only in Boost.
>
>>> 2. I'm worried if these tools will be used in Boost libraries in a way
>>> that
>>> affects library API/ABI. What if one library uses these tools and the
>>> other
>>> doesn't - will these libraries be able to interoperate? Or is it a user's
>>> problem? There is also the possibility that Boost is built in C++03 mode
>>> and the user builds his code in C++11. I think this will be most apparent
>>> with utilities like shared_ptr and function, which are often present in
>>> the interfaces.

The problem goes beyond the use of my macro system. Are we going to give
library developers the choice of whether they can use the C++ standard
library equivalent to a Boost library or not ? Please see my answer to
this at the emnd of my response.

>>
>> Its no different from some Boost library using the C++ standard version
>> of, let's say, std::function because it is available and another library
>> using boost::function. Is API/ABI compatibility affected ? If so that
>> has to be taken into account if you use those libraries internally.
>> Suppose library X is compiled using C++11 mode and your own library Y,
>> which uses library X as a dependency, is compiled without C++11 mode.
>
> It's more likely that Boost is compiled in one mode and distributed in a
> standard package (say, with a Linux distro) and I'm building my app locally
> with that Boost. Most Linux distros build Boost with default compiler options
> which means C++03. If these macros affect Boost libraries ABI I will no longer
> be able to build my app in C++11 mode.

The macros don't determine the mode; compiler options do that. I believe
Boost is going to have to work out anyway, if it has not already done
so, a difference in final naming between a library built with or without
C++11/C++14/C++17 support if that library supports building in more than
one C++ mode.

>
>> Again those factors of interoperability between the libraries must be
>> taken into account. Using my macros is not going to change any of that,
>> and my macro system cannot solve that problem, or make it more or less
>> than if the macro system I propose were not used at all.
>
> As Peter noted, having these macros in Boost.Config can be seen as
> encouragement to use. And when used improperly they can cause real problems.
>
> So far I'm seeing these macros only applicable under the following conditions:
>
> a) the macros can be used in header-only libraries or concealed in the
> compiled part of the library without exposing it to API/ABI, and
>
> b) only when these macros allow to switch between STL and header-only Boost
> alternatives (not compiled ones).
>
> I'm not sure how to enforce these restrictions and I'm not sure adding them
> without doing something about their dangerous use is a good idea. Sorry if I'm
> not being helpful here.

Arguing that a facility is bad because it makes it easier to use either
a C++ standard library equivalent to a Boost library or the Boost
library itself, as you and Peter have done, is counterproductive IMO.
The same problems would exist as soon as anyone decides to use one or
the other in their code even without my macros. I can't view it as being
better to only use Boost libraries in Boost library code simply because
it creates a single variant of a library. Eventually people will become
tired of not having the ability to use C++ standard library equivalents
in Boost code, and this will become more so if Boost moves to a more
modular distribution system. What will you tell people ? That they must
hard-code whether to use a Boost library or a C++ standard equivalent
library in their code ? And if the C++ standard library equivalent is
not available their library must be unusable in that environment ? I
don't think Boost is going to get very far in that direction.

I acknowledge the concerns which you have with a built library which can
be compiled in different C++ modes. My point of view is different in
that Boost has to face the fact that for any given library XXX it may
want to use a Boost library in one C++ mode, presumably C++03, and the
C++ standard equivalent of that Boost library in another C++ mode,
presumably C++11 or above. For this different naming conventions for
such a dual mode ( or more ) built library has to be created to
accomodate the situation. Either that or the library itself must be
treated under a different name for each mode in which it can be built,
but that's not a problem which my macro system itself can solve.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-06 12:26:50 UTC
Permalink
On Friday 05 June 2015 21:07:20 Edward Diener wrote:
> On 6/5/2015 6:35 PM, Andrey Semashev wrote:
> >
> > In general, you won't get away with just macros, as autolinking is only
> > present in MSVC & friends. This would also affect build system scripts.
> >
> > Suppose I'm a (Boost) library writer; the library has a compiled part and
> > I'm writing a Makefile/Jamfile. If I'm using these macros, I still have
> > to know when to link and when not to link with Boost libs. This can be
> > rather tricky as not only compiler versions should be checked but also
> > their options; and it also needs to be in sync with Boost.Config. The
> > same happens when I'm a user of a (Boost) library that uses these macros,
> > only it becomes more difficult to be in sync with Boost.Config. My point
> > is that since these macros don't actually abstract me away from the
> > configuration, why would I use them?
>
> They abstract you away from having to write complicated code which
> caters to whether or not a C++ standard library equivalent to a Boost
> library is available or not. They don't relieve the responsibility of a
> built library from naming itself in such a way that those linking with
> the library can do so successfully if auto-linking is not available.

I think you missed my point above. It's not about naming the library, its
about the solution being incomplete to the point when you are not saved much
by using these macros.

I've looked at the headers, and a similar code in a few Boost libraries that
does the same - there's nothing complicated there. I believe that implementing
a similar logic in a Jamfile to link with Boost libraries only when needed
would be much more difficult and error prone.

> The problem goes beyond the use of my macro system. Are we going to give
> library developers the choice of whether they can use the C++ standard
> library equivalent to a Boost library or not ?

My current view on this is if you're writing a C++11 library it's fairly
logical for you to use STL11. No macros are needed for that. If you aim for
C++03 compatibility, you should use STL03 and Boost where STL lacks something.
Admittedly, this approach still has the library interoperability problem but
at least your API and ABI are stable and do not depend on compiler options.

I realize that someone might want to switch to C++11 components when
available, for example, to reduce dependencies on other Boost libraries. But I
believe this should only be done in a way that does not affect API and ABI of
the library.

> > It's more likely that Boost is compiled in one mode and distributed in a
> > standard package (say, with a Linux distro) and I'm building my app
> > locally
> > with that Boost. Most Linux distros build Boost with default compiler
> > options which means C++03. If these macros affect Boost libraries ABI I
> > will no longer be able to build my app in C++11 mode.
>
> The macros don't determine the mode; compiler options do that. I believe
> Boost is going to have to work out anyway, if it has not already done
> so, a difference in final naming between a library built with or without
> C++11/C++14/C++17 support if that library supports building in more than
> one C++ mode.

I think the current solution is to provide ABI that does not depend on C++
mode. This is what I'm doing in Boost.Log, and AFAIR there was a bugfix in
Boost.Filesystem that also followed this direction. I can also remember a fix
in Boost.Range that removed the difference in binary layout of iterator_range
between release and debug builds - not a C++ mode issue, but similar enough.
One may argue that this approach is limiting, and I would agree, but this has
worked best for the downstream so far.

> Arguing that a facility is bad because it makes it easier to use either
> a C++ standard library equivalent to a Boost library or the Boost
> library itself, as you and Peter have done, is counterproductive IMO.

Maybe. That's why I apologized for not being helpful.

I understand your argument - after all C++ allows you to shoot yourself in the
foot, so do your macros. But unlike C++ they don't make it really difficult.
Maybe we just need a documented policy of use of these macros so that they
don't get misused. Maybe we need testing, when the library and tests are
compiled in different C++ modes. I don't know.

> The same problems would exist as soon as anyone decides to use one or
> the other in their code even without my macros. I can't view it as being
> better to only use Boost libraries in Boost library code simply because
> it creates a single variant of a library. Eventually people will become
> tired of not having the ability to use C++ standard library equivalents
> in Boost code, and this will become more so if Boost moves to a more
> modular distribution system. What will you tell people ? That they must
> hard-code whether to use a Boost library or a C++ standard equivalent
> library in their code ? And if the C++ standard library equivalent is
> not available their library must be unusable in that environment ? I
> don't think Boost is going to get very far in that direction.

Some of these questions I've answered above. I'll just add that developers
have always had to find balance between maintainability and usability and I
don't think it'll change any time soon. Personally, for my projects I have
decided that trying to use STL11 opportunistically doesn't worth the hassle.
Even for C++11 projects I still prefer Boost to STL in some cases. But your
mileage may wary, of course.

> I acknowledge the concerns which you have with a built library which can
> be compiled in different C++ modes. My point of view is different in
> that Boost has to face the fact that for any given library XXX it may
> want to use a Boost library in one C++ mode, presumably C++03, and the
> C++ standard equivalent of that Boost library in another C++ mode,
> presumably C++11 or above. For this different naming conventions for
> such a dual mode ( or more ) built library has to be created to
> accomodate the situation. Either that or the library itself must be
> treated under a different name for each mode in which it can be built,
> but that's not a problem which my macro system itself can solve.

Producing different library names for different C++ modes has been discussed
before but I don't quite remember the outcome of that discussion. Clearly, it
has not been implemented.

By the way, Boost is not the only project that attempts to maintain stable ABI
regardless of the C++ mode. libstdc++ is also doing that, for example.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-06 20:54:22 UTC
Permalink
On 6/6/2015 8:26 AM, Andrey Semashev wrote:
> On Friday 05 June 2015 21:07:20 Edward Diener wrote:
>> On 6/5/2015 6:35 PM, Andrey Semashev wrote:
>>>
>>> In general, you won't get away with just macros, as autolinking is only
>>> present in MSVC & friends. This would also affect build system scripts.
>>>
>>> Suppose I'm a (Boost) library writer; the library has a compiled part and
>>> I'm writing a Makefile/Jamfile. If I'm using these macros, I still have
>>> to know when to link and when not to link with Boost libs. This can be
>>> rather tricky as not only compiler versions should be checked but also
>>> their options; and it also needs to be in sync with Boost.Config. The
>>> same happens when I'm a user of a (Boost) library that uses these macros,
>>> only it becomes more difficult to be in sync with Boost.Config. My point
>>> is that since these macros don't actually abstract me away from the
>>> configuration, why would I use them?
>>
>> They abstract you away from having to write complicated code which
>> caters to whether or not a C++ standard library equivalent to a Boost
>> library is available or not. They don't relieve the responsibility of a
>> built library from naming itself in such a way that those linking with
>> the library can do so successfully if auto-linking is not available.
>
> I think you missed my point above. It's not about naming the library, its
> about the solution being incomplete to the point when you are not saved much
> by using these macros.

I do not understand what sort of completeness you desire.

>
> I've looked at the headers, and a similar code in a few Boost libraries that
> does the same - there's nothing complicated there.

Absolutely. I invented a general solution so that each Boost library
doesn't have to re-invent it. It's meant to be simple.

> I believe that implementing
> a similar logic in a Jamfile to link with Boost libraries only when needed
> would be much more difficult and error prone.
>
>> The problem goes beyond the use of my macro system. Are we going to give
>> library developers the choice of whether they can use the C++ standard
>> library equivalent to a Boost library or not ?
>
> My current view on this is if you're writing a C++11 library it's fairly
> logical for you to use STL11. No macros are needed for that. If you aim for
> C++03 compatibility, you should use STL03 and Boost where STL lacks something.
> Admittedly, this approach still has the library interoperability problem but
> at least your API and ABI are stable and do not depend on compiler options.

And suppose you want your library to work with either STL11 or STL03 ?
Do you just decide that it is not possible so you have to choose one or
the other ? That after all is what you are essentially saying a Boost
library must do, is it not ?

I find that irritating, not because I think the Boost libraries are any
worse than their C++ equivalents, but because I see no reason why I
should either have dependencies on other Boost libraries when I don't
need to or that I have to cut off all end-users of my library compiler
implementations if I choose just C++11 mode and STL11.

>
> I realize that someone might want to switch to C++11 components when
> available, for example, to reduce dependencies on other Boost libraries. But I
> believe this should only be done in a way that does not affect API and ABI of
> the library.
>
>>> It's more likely that Boost is compiled in one mode and distributed in a
>>> standard package (say, with a Linux distro) and I'm building my app
>>> locally
>>> with that Boost. Most Linux distros build Boost with default compiler
>>> options which means C++03. If these macros affect Boost libraries ABI I
>>> will no longer be able to build my app in C++11 mode.
>>
>> The macros don't determine the mode; compiler options do that. I believe
>> Boost is going to have to work out anyway, if it has not already done
>> so, a difference in final naming between a library built with or without
>> C++11/C++14/C++17 support if that library supports building in more than
>> one C++ mode.
>
> I think the current solution is to provide ABI that does not depend on C++
> mode. This is what I'm doing in Boost.Log, and AFAIR there was a bugfix in
> Boost.Filesystem that also followed this direction. I can also remember a fix
> in Boost.Range that removed the difference in binary layout of iterator_range
> between release and debug builds - not a C++ mode issue, but similar enough.
> One may argue that this approach is limiting, and I would agree, but this has
> worked best for the downstream so far.
>
>> Arguing that a facility is bad because it makes it easier to use either
>> a C++ standard library equivalent to a Boost library or the Boost
>> library itself, as you and Peter have done, is counterproductive IMO.
>
> Maybe. That's why I apologized for not being helpful.
>
> I understand your argument - after all C++ allows you to shoot yourself in the
> foot, so do your macros. But unlike C++ they don't make it really difficult.
> Maybe we just need a documented policy of use of these macros so that they
> don't get misused. Maybe we need testing, when the library and tests are
> compiled in different C++ modes. I don't know.

I have developed a series of proof of concept tests for each of the
libraries the macro system supports in either C++03 or C++11 mode. I
have not tried to add PRs for those tests for each Boost library yet
because my macro system is not in Boost.config 'develop' yet, and I
don't want failings test for no reason.

>
>> The same problems would exist as soon as anyone decides to use one or
>> the other in their code even without my macros. I can't view it as being
>> better to only use Boost libraries in Boost library code simply because
>> it creates a single variant of a library. Eventually people will become
>> tired of not having the ability to use C++ standard library equivalents
>> in Boost code, and this will become more so if Boost moves to a more
>> modular distribution system. What will you tell people ? That they must
>> hard-code whether to use a Boost library or a C++ standard equivalent
>> library in their code ? And if the C++ standard library equivalent is
>> not available their library must be unusable in that environment ? I
>> don't think Boost is going to get very far in that direction.
>
> Some of these questions I've answered above. I'll just add that developers
> have always had to find balance between maintainability and usability and I
> don't think it'll change any time soon. Personally, for my projects I have
> decided that trying to use STL11 opportunistically doesn't worth the hassle.
> Even for C++11 projects I still prefer Boost to STL in some cases. But your
> mileage may wary, of course.
>
>> I acknowledge the concerns which you have with a built library which can
>> be compiled in different C++ modes. My point of view is different in
>> that Boost has to face the fact that for any given library XXX it may
>> want to use a Boost library in one C++ mode, presumably C++03, and the
>> C++ standard equivalent of that Boost library in another C++ mode,
>> presumably C++11 or above. For this different naming conventions for
>> such a dual mode ( or more ) built library has to be created to
>> accomodate the situation. Either that or the library itself must be
>> treated under a different name for each mode in which it can be built,
>> but that's not a problem which my macro system itself can solve.
>
> Producing different library names for different C++ modes has been discussed
> before but I don't quite remember the outcome of that discussion. Clearly, it
> has not been implemented.

Boost has implemented the notion that for libraries being built that the
library name changes depending on whether or not the dynamic RTL or
static RTL of the compiler implementation is being used. Also the
library name changes depending on whether the library itself being built
is a static or shared library. And there are a few more of these name
manipulations which Boost enforces. I am simply arguing that we can come
up with a means for doing the same on demand for C++ modes, not that we
must do the same thing for C++ modes at all times.

Let me give a very simple practical use case and this will illustrate
what I am trying to discuss.

I develop library EDS_LIB and it is a Boost library which must be built
as a library and is not header-only, and my library uses regex in some
interface it exports.

I have a decision to make: do I use Boost.regex and therefore work in
any C++ mode or do I use std::regex and therefore works only in C++11
mode ( which I will assume supports the std::regex library ). Most
people will say to use Boost.regex and be able to support any mode. Fair
enough, but now EDS_LIB depends on Boost regex. If Boost ever goes to a
more modular distribution all distribution of EDS_LIB must also include
Boost regex.

OTOH if I choose C++11 mode the dependency on Boost.regex goes away, but
now you need to compile whatever uses EDS_LIB in C++11 mode else my
library is useless to you.

Now let's suppose, using my macro system, I can distribute my library as
EDS_LIB in C++03 mode or EDS_LIB_C11 in C++11 mode. My exported
interface using regex is:

#include <boost/config/cpp/regex.hpp>
#include BOOST_CPP_REGEX_HDR
void EdsFunction(BOOST_CPP_REGEX_NS::regex & rx);

Now if you compile your library or application in C++03 mode you link
with EDS_LIB and you get its dependency on Boost.regex. If you compile
your library or application in C++11 mode you link with EDS_LIB_C11 and
you no longer have its dependency on Boost.regex. In your application or
library you use my macro system in order to pass the correct regex in
either case without worrying about which it is:

#include <boost/config/cpp/regex.hpp>
#include BOOST_CPP_REGEX_HDR

BOOST_CPP_REGEX_NS::regex myregex("Some regular expression");
EdsFunction(myregex);

Where is the ABI problem in this case ? ( rhetorical question )

Multiply the dependency beyond just regex to a few other Boost libraries
which have C++11 standard library equivalents and you can see how the
problem of choosing builds up. Either you are going to have a number of
dependencies on other Boost libraries in C++03 mode or you are again
going to be unusable in C++11 mode to other modules not using C++11.

You are saying: choose, either your library may have a number of
dependencies when building it in C++03 mode, or your library will not
have those dependencies but will be usable only in C++11 mode.

I am saying: having to choose is not acceptable in Boost as more
compilers support C++11, but some either do not support C++11 or are not
usable by end-users in C++11 mode.

>
> By the way, Boost is not the only project that attempts to maintain stable ABI
> regardless of the C++ mode. libstdc++ is also doing that, for example.

How many other library dependencies does libstdc++ have ? Then ask
yourself how many other library dependencies does any given Boost
library have ? Have I made my point ?


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Peter Dimov
2015-06-06 21:05:46 UTC
Permalink
Edward Diener wrote:
> Let me give a very simple practical use case and this will illustrate what
> I am trying to discuss.
>
> I develop library EDS_LIB and it is a Boost library which must be built as
> a library and is not header-only, and my library uses regex in some
> interface it exports.
>
> I have a decision to make: do I use Boost.regex and therefore work in any
> C++ mode or do I use std::regex and therefore works only in C++11 mode (
> which I will assume supports the std::regex library ). Most people will
> say to use Boost.regex and be able to support any mode. Fair enough, but
> now EDS_LIB depends on Boost regex.

And what is the use case in which you don't have Boost.Regex but do have
Boost.Config so that you can use your proposed mechanism?

If your library is not part of the Boost distribution, it might make sense
for your library to support building without Boost, in which case one would
expect your library to not need Boost.Config, wouldn't one?

And if your library is part of the Boost distribution, one would expect
Boost.Regex to also be present, wouldn't one?

> If Boost ever goes to a more modular distribution all distribution of
> EDS_LIB must also include Boost regex.

Right. But this isn't the case now.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-06 22:46:40 UTC
Permalink
On 6/6/2015 5:05 PM, Peter Dimov wrote:
> Edward Diener wrote:
>> Let me give a very simple practical use case and this will illustrate
>> what I am trying to discuss.
>>
>> I develop library EDS_LIB and it is a Boost library which must be
>> built as a library and is not header-only, and my library uses regex
>> in some interface it exports.
>>
>> I have a decision to make: do I use Boost.regex and therefore work in
>> any C++ mode or do I use std::regex and therefore works only in C++11
>> mode ( which I will assume supports the std::regex library ). Most
>> people will say to use Boost.regex and be able to support any mode.
>> Fair enough, but now EDS_LIB depends on Boost regex.
>
> And what is the use case in which you don't have Boost.Regex but do have
> Boost.Config so that you can use your proposed mechanism?

That use case does not currently exist. But I am missing your point.

The mechanism says that if std::regex exists, use it instead of
boost::regex. If std::regex does not exist use boost::regex instead. If
I don't have a dependency on boost::regex and std::regex supplies all my
module's needs is it not better to use std::regex, so that in a future
modular Boost distribution based system I will not have to distribute
boost::regex with my library ?

>
> If your library is not part of the Boost distribution, it might make
> sense for your library to support building without Boost, in which case
> one would expect your library to not need Boost.Config, wouldn't one?

I can have my macros not be part of Boost.Config but why would I do that
? The macros work to choose either a Boost library or its C++ standard
equivalent at compile time. The macros also use what is in Boost.config
to make that choice. If the macros are dependent on Boost.Config why
should they not be a part of Boost.config ?

>
> And if your library is part of the Boost distribution, one would expect
> Boost.Regex to also be present, wouldn't one?

Of course.

There is some sort of disconnect here, because I can't make out what you
are getting at.

>
>> If Boost ever goes to a more modular distribution all distribution of
>> EDS_LIB must also include Boost regex.
>
> Right. But this isn't the case now.

Correct. You can say that now my macros don't buy you anything and the
right choice is to always use Boost libraries instead of their C++11
standard library equivalents. But of course if you are one of those
people who see unneeded dependencies on other Boost libraries as a
negative thing, you could argue that cutting down on those dependencies,
by using their C++11 standard equivalents when compiling in C++11 mode,
is a positive thing.

My argument is that if Boost ever goes to a modular Boost distribution
system, where a single library, whether built ot header-only, is
distributed with its dependencies, you could use my macro system so that
you can distribute the library without having to distribute, as in the
example, boost::regex with it when the library is going to be used in
C++11 mode. And you do that without having to change your code in any way.

I can fully understand the viewpoint which says that in our current
Boost distribution it does not mean anything to reduce a dependency on
Boost libraries when compiled in C++11 mode, since the library is
already there in the distribution. For those people, who are probably
the vast majority, you simple decide to use the Boost library, even in
C++11 mode, and you are done with it, and my macro system is a waste of
time and an added complication. My solution is for the future, if and
when we distribute Boost libraries independently. Somebody, I forget
who, wrote a Boost tool for extracting a library and its dependencies
into a sort of mini-distribution. So somebody else is thinking somewhat
along the lines I was thinking when I came up with my macro solution,
that allowing a single library to be used with its dependencies might be
a good thing, and therefore reducing its dependencies without
impairing/changing its functionality helps that situation.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Peter Dimov
2015-06-06 23:21:45 UTC
Permalink
Edward Diener wrote:

> That use case does not currently exist. But I am missing your point.

That was my point. The use case doesn't exist yet.

You were obviously motivated by something to propose the macros, and I was
wondering what that something was. Did you actually have a use case, or was
that in anticipation of what the future will bring.

It appears that it's the latter, in which case, I'm still interested in your
anticipated future use case.

> The mechanism says that if std::regex exists, use it instead of
> boost::regex. If std::regex does not exist use boost::regex instead. If I
> don't have a dependency on boost::regex and std::regex supplies all my
> module's needs is it not better to use std::regex, so that in a future
> modular Boost distribution based system I will not have to distribute
> boost::regex with my library ?

So your anticipated future use case is that you want to create a
distribution for your library that contains Boost.Config but does not
contain Boost.Regex?

> There is some sort of disconnect here, because I can't make out what you
> are getting at.

You're putting the cart before the horse (Cartesius ante equum, as they
say). The modular future hasn't arrived yet and we have no idea what it will
be.

> Somebody, I forget who, wrote a Boost tool for extracting a library and
> its dependencies into a sort of mini-distribution.

John Maddock, the tool is called bcp.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 03:17:04 UTC
Permalink
On 6/6/2015 7:21 PM, Peter Dimov wrote:
> Edward Diener wrote:
>
>> That use case does not currently exist. But I am missing your point.
>
> That was my point. The use case doesn't exist yet.
>
> You were obviously motivated by something to propose the macros, and I
> was wondering what that something was. Did you actually have a use case,
> or was that in anticipation of what the future will bring.
>
> It appears that it's the latter, in which case, I'm still interested in
> your anticipated future use case.

The use case is that I support/use the C++ standard library equivalents
to Boost libraries in C++11 mode and I support/use the Boost libraries
in C++03 mode. That should make it easier for my library's code to work
with what the user of my library will most likely use in his own code.

I design a library which, let's say, takes a regex object as parameter
to some exported function. If the end-user of my library is compiling in
C++11 mode is it more likely that his use of regex will be std::regex or
boost::regex ? IMO it is the former. Conversely if the end-user of my
library is compiling in C++03 mode is it more likely that his use of
regex will be std::regex or boost::regex ? That's a loaded question of
course because std::regex won't be available to him if he compiles in
C++03 mode. So my preferred usage of regex in my library, all else being
equal, is to use boost::regex in C++03 mode and std::regex in C++11 mode.

Even if Boost is a single distribution as it is now, so that
boost::regex is always available for my Boost library I think it is
advantageous to use the scheme just described.

>
>> The mechanism says that if std::regex exists, use it instead of
>> boost::regex. If std::regex does not exist use boost::regex instead.
>> If I don't have a dependency on boost::regex and std::regex supplies
>> all my module's needs is it not better to use std::regex, so that in a
>> future modular Boost distribution based system I will not have to
>> distribute boost::regex with my library ?
>
> So your anticipated future use case is that you want to create a
> distribution for your library that contains Boost.Config but does not
> contain Boost.Regex?

Yes, for C++11 mode.

>
>> There is some sort of disconnect here, because I can't make out what
>> you are getting at.
>
> You're putting the cart before the horse (Cartesius ante equum, as they
> say). The modular future hasn't arrived yet and we have no idea what it
> will be.

You are right. But I don't think it is unreasonable to consider that if
it does arrive so that individual Boost libraries with their
dependencies are distributed separately from the complete Boost tree as
we do now, the elimination of dependencies for a particular distribution
of a library is a good thing as long as it does not compromise the
quality of the code.

>
>> Somebody, I forget who, wrote a Boost tool for extracting a library
>> and its dependencies into a sort of mini-distribution.
>
> John Maddock, the tool is called bcp.

I was kidding and referring to your bpm tool.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Peter Dimov
2015-06-07 10:41:32 UTC
Permalink
Edward Diener wrote:
> I design a library which, let's say, takes a regex object as parameter to
> some exported function. If the end-user of my library is compiling in
> C++11 mode is it more likely that his use of regex will be std::regex or
> boost::regex ? IMO it is the former. Conversely if the end-user of my
> library is compiling in C++03 mode is it more likely that his use of regex
> will be std::regex or boost::regex ? That's a loaded question of course
> because std::regex won't be available to him if he compiles in C++03 mode.
> So my preferred usage of regex in my library, all else being equal, is to
> use boost::regex in C++03 mode and std::regex in C++11 mode.

This makes sense, and the question of dependencies and modular distributions
is actually a side show.

But you do realize that you'll be breaking your customer's C++03 (presumably
tried and tested) code the moment he adds -std=c++11 in order to use a
for(:) loop, right?


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 15:53:35 UTC
Permalink
On 6/7/2015 6:41 AM, Peter Dimov wrote:
> Edward Diener wrote:
>> I design a library which, let's say, takes a regex object as parameter
>> to some exported function. If the end-user of my library is compiling
>> in C++11 mode is it more likely that his use of regex will be
>> std::regex or boost::regex ? IMO it is the former. Conversely if the
>> end-user of my library is compiling in C++03 mode is it more likely
>> that his use of regex will be std::regex or boost::regex ? That's a
>> loaded question of course because std::regex won't be available to him
>> if he compiles in C++03 mode. So my preferred usage of regex in my
>> library, all else being equal, is to use boost::regex in C++03 mode
>> and std::regex in C++11 mode.
>
> This makes sense, and the question of dependencies and modular
> distributions is actually a side show.
>
> But you do realize that you'll be breaking your customer's C++03
> (presumably tried and tested) code the moment he adds -std=c++11 in
> order to use a for(:) loop, right?

Not if they use the macro system I propose in their own code to choose
between Boost or C++ standard library equivalents. Or at least use the
macro system I propose when interfacing with my library. Although for
consistency's sake it would be easier to use the macro system in all
places in their module, if they choose to not use it when not
interfacing with my library that is their business.

Breaking code when switching between C++03 mode and C++11 mode can occur
outside the macro system I propose easily enough. Someone writes their
code to use std::regex and compile in C++11 mode. They then switch to
C++03 mode. Is std::regex still available in C++03 mode ? If it is not
they have broken their code. It's not as if switching compile modes is
as easy people suggest. A number of considerations have to be taken into
account.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Bjorn Reese
2015-06-07 11:05:29 UTC
Permalink
On 06/07/2015 05:17 AM, Edward Diener wrote:

> I design a library which, let's say, takes a regex object as parameter
> to some exported function. If the end-user of my library is compiling in
> C++11 mode is it more likely that his use of regex will be std::regex or
> boost::regex ? IMO it is the former. Conversely if the end-user of my

What if your library uses extension in boost::regex that are not present
in std::regex?


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 16:28:53 UTC
Permalink
On 6/7/2015 7:05 AM, Bjorn Reese wrote:
> On 06/07/2015 05:17 AM, Edward Diener wrote:
>
>> I design a library which, let's say, takes a regex object as parameter
>> to some exported function. If the end-user of my library is compiling in
>> C++11 mode is it more likely that his use of regex will be std::regex or
>> boost::regex ? IMO it is the former. Conversely if the end-user of my
>
> What if your library uses extension in boost::regex that are not present
> in std::regex?

In that case I don't use the macros for choosing between boost::regex
and std::regex, but just decide to always use boost::regex in my interface.

Using the macros are optional. Even bringing in the macros are optional,
as including boost.config.hpp does not automatically include any of the
macro header files.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-06 23:23:14 UTC
Permalink
On Sat, Jun 6, 2015 at 11:54 PM, Edward Diener <***@tropicsoft.com> wrote:
> On 6/6/2015 8:26 AM, Andrey Semashev wrote:
>>
>> On Friday 05 June 2015 21:07:20 Edward Diener wrote:
>>>
>>> On 6/5/2015 6:35 PM, Andrey Semashev wrote:
>>>>
>>>> In general, you won't get away with just macros, as autolinking is only
>>>> present in MSVC & friends. This would also affect build system scripts.
>>>>
>>>> Suppose I'm a (Boost) library writer; the library has a compiled part
>>>> and
>>>> I'm writing a Makefile/Jamfile. If I'm using these macros, I still have
>>>> to know when to link and when not to link with Boost libs. This can be
>>>> rather tricky as not only compiler versions should be checked but also
>>>> their options; and it also needs to be in sync with Boost.Config. The
>>>> same happens when I'm a user of a (Boost) library that uses these
>>>> macros,
>>>> only it becomes more difficult to be in sync with Boost.Config. My point
>>>> is that since these macros don't actually abstract me away from the
>>>> configuration, why would I use them?
>>>
>>> They abstract you away from having to write complicated code which
>>> caters to whether or not a C++ standard library equivalent to a Boost
>>> library is available or not. They don't relieve the responsibility of a
>>> built library from naming itself in such a way that those linking with
>>> the library can do so successfully if auto-linking is not available.
>>
>> I think you missed my point above. It's not about naming the library, its
>> about the solution being incomplete to the point when you are not saved
>> much
>> by using these macros.
>
> I do not understand what sort of completeness you desire.

I think I explained it multiple times now. The macros don't abstract
away what implementation is being used - STL or Boost - because I have
to deal with linking anyway. That's why the solution is incomplete.

>> My current view on this is if you're writing a C++11 library it's fairly
>> logical for you to use STL11. No macros are needed for that. If you aim
>> for
>> C++03 compatibility, you should use STL03 and Boost where STL lacks
>> something.
>> Admittedly, this approach still has the library interoperability problem
>> but
>> at least your API and ABI are stable and do not depend on compiler
>> options.
>
> And suppose you want your library to work with either STL11 or STL03 ? Do
> you just decide that it is not possible so you have to choose one or the
> other ?

First, as I said, I don't see much point in this exercise. Second, if
this affects API/ABI then this severely harms my library usability, so
I definitely wouldn't do that. So yes, I decide which C++ level I will
target and write the code accordingly.

> That after all is what you are essentially saying a Boost library
> must do, is it not ?

I'm sorry, I didn't understand this question. I expressed my view on
the matter, based on my experience. It's not an official Boost policy,
if that's what you're asking.

> I find that irritating, not because I think the Boost libraries are any
> worse than their C++ equivalents, but because I see no reason why I should
> either have dependencies on other Boost libraries when I don't need to or
> that I have to cut off all end-users of my library compiler implementations
> if I choose just C++11 mode and STL11.

I explained why. You are free to ignore my reasoning, of course, but I
doubt your users will be happy in this case.

>> I understand your argument - after all C++ allows you to shoot yourself in
>> the
>> foot, so do your macros. But unlike C++ they don't make it really
>> difficult.
>> Maybe we just need a documented policy of use of these macros so that they
>> don't get misused. Maybe we need testing, when the library and tests are
>> compiled in different C++ modes. I don't know.
>
> I have developed a series of proof of concept tests for each of the
> libraries the macro system supports in either C++03 or C++11 mode. I have
> not tried to add PRs for those tests for each Boost library yet because my
> macro system is not in Boost.config 'develop' yet, and I don't want failings
> test for no reason.

If I understood you correctly, that's not the kind of tests I was talking about.

> Boost has implemented the notion that for libraries being built that the
> library name changes depending on whether or not the dynamic RTL or static
> RTL of the compiler implementation is being used. Also the library name
> changes depending on whether the library itself being built is a static or
> shared library. And there are a few more of these name manipulations which
> Boost enforces. I am simply arguing that we can come up with a means for
> doing the same on demand for C++ modes, not that we must do the same thing
> for C++ modes at all times.
>
> Let me give a very simple practical use case and this will illustrate what I
> am trying to discuss.
>
> I develop library EDS_LIB and it is a Boost library which must be built as a
> library and is not header-only, and my library uses regex in some interface
> it exports.
>
> I have a decision to make: do I use Boost.regex and therefore work in any
> C++ mode or do I use std::regex and therefore works only in C++11 mode (
> which I will assume supports the std::regex library ). Most people will say
> to use Boost.regex and be able to support any mode. Fair enough, but now
> EDS_LIB depends on Boost regex. If Boost ever goes to a more modular
> distribution all distribution of EDS_LIB must also include Boost regex.

Why? EDS_LIB would depend on Boost.Regex but not include it.

> OTOH if I choose C++11 mode the dependency on Boost.regex goes away, but now
> you need to compile whatever uses EDS_LIB in C++11 mode else my library is
> useless to you.

Correct.

> Now let's suppose, using my macro system, I can distribute my library as
> EDS_LIB in C++03 mode or EDS_LIB_C11 in C++11 mode. My exported interface
> using regex is:
>
> #include <boost/config/cpp/regex.hpp>
> #include BOOST_CPP_REGEX_HDR
> void EdsFunction(BOOST_CPP_REGEX_NS::regex & rx);
>
> Now if you compile your library or application in C++03 mode you link with
> EDS_LIB and you get its dependency on Boost.regex. If you compile your
> library or application in C++11 mode you link with EDS_LIB_C11 and you no
> longer have its dependency on Boost.regex. In your application or library
> you use my macro system in order to pass the correct regex in either case
> without worrying about which it is:
>
> #include <boost/config/cpp/regex.hpp>
> #include BOOST_CPP_REGEX_HDR
>
> BOOST_CPP_REGEX_NS::regex myregex("Some regular expression");
> EdsFunction(myregex);
>
> Where is the ABI problem in this case ? ( rhetorical question )

The ABI problem is right here. EDS_LIB, as it is distributed in a
Linux distro, is built in C++03, and it is incompatible with user's
code that is built in C++11. At least not in the way you describe.

My suggested approach would be to avoid both Boost.Regex and
std::regex in the binary interface - for example by passing strings in
the ABI. You can still use whatever regex you like in the API, or even
better - use concepts to accept any regex-like type, be that
std::regex, boost::regex or boost::xpressive::regex - whatever the
user happens to be using in his code.

> Multiply the dependency beyond just regex to a few other Boost libraries
> which have C++11 standard library equivalents and you can see how the
> problem of choosing builds up. Either you are going to have a number of
> dependencies on other Boost libraries in C++03 mode or you are again going
> to be unusable in C++11 mode to other modules not using C++11.

I'm sorry, I don't see what the number of dependencies have to do with
ABI stability.

> You are saying: choose, either your library may have a number of
> dependencies when building it in C++03 mode, or your library will not have
> those dependencies but will be usable only in C++11 mode.
>
> I am saying: having to choose is not acceptable in Boost as more compilers
> support C++11, but some either do not support C++11 or are not usable by
> end-users in C++11 mode.

It worked for me so far, I don't see the problem.

>> By the way, Boost is not the only project that attempts to maintain stable
>> ABI
>> regardless of the C++ mode. libstdc++ is also doing that, for example.
>
> How many other library dependencies does libstdc++ have ? Then ask yourself
> how many other library dependencies does any given Boost library have ? Have
> I made my point ?

No, I don't think you did. How the number of dependencies have any
relevance to API/ABI stability?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 03:39:57 UTC
Permalink
On 6/6/2015 7:23 PM, Andrey Semashev wrote:
> On Sat, Jun 6, 2015 at 11:54 PM, Edward Diener <***@tropicsoft.com> wrote:
>> On 6/6/2015 8:26 AM, Andrey Semashev wrote:
>>>
>>> On Friday 05 June 2015 21:07:20 Edward Diener wrote:
>>>>
>>>> On 6/5/2015 6:35 PM, Andrey Semashev wrote:
>>>>>
>>>>> In general, you won't get away with just macros, as autolinking is only
>>>>> present in MSVC & friends. This would also affect build system scripts.
>>>>>
>>>>> Suppose I'm a (Boost) library writer; the library has a compiled part
>>>>> and
>>>>> I'm writing a Makefile/Jamfile. If I'm using these macros, I still have
>>>>> to know when to link and when not to link with Boost libs. This can be
>>>>> rather tricky as not only compiler versions should be checked but also
>>>>> their options; and it also needs to be in sync with Boost.Config. The
>>>>> same happens when I'm a user of a (Boost) library that uses these
>>>>> macros,
>>>>> only it becomes more difficult to be in sync with Boost.Config. My point
>>>>> is that since these macros don't actually abstract me away from the
>>>>> configuration, why would I use them?
>>>>
>>>> They abstract you away from having to write complicated code which
>>>> caters to whether or not a C++ standard library equivalent to a Boost
>>>> library is available or not. They don't relieve the responsibility of a
>>>> built library from naming itself in such a way that those linking with
>>>> the library can do so successfully if auto-linking is not available.
>>>
>>> I think you missed my point above. It's not about naming the library, its
>>> about the solution being incomplete to the point when you are not saved
>>> much
>>> by using these macros.
>>
>> I do not understand what sort of completeness you desire.
>
> I think I explained it multiple times now. The macros don't abstract
> away what implementation is being used - STL or Boost - because I have
> to deal with linking anyway. That's why the solution is incomplete.
>

I have repeated again and again that for built libraries, as opposed to
header-only libraries, a system of distinct names for the same library
depending on whether the library is compiled in C++03 mode or C++11 mode
can solve this problem.

I know that you think that solving this problem is the responsibility of
my macro solution, and therefore the macros are not worthwhile using
unless I solve it in my implementation. That's your right and I am not
going to bother to argue with it. I think we are just at a point of
basic disagreement on this issue.

>>> My current view on this is if you're writing a C++11 library it's fairly
>>> logical for you to use STL11. No macros are needed for that. If you aim
>>> for
>>> C++03 compatibility, you should use STL03 and Boost where STL lacks
>>> something.
>>> Admittedly, this approach still has the library interoperability problem
>>> but
>>> at least your API and ABI are stable and do not depend on compiler
>>> options.
>>
>> And suppose you want your library to work with either STL11 or STL03 ? Do
>> you just decide that it is not possible so you have to choose one or the
>> other ?
>
> First, as I said, I don't see much point in this exercise. Second, if
> this affects API/ABI then this severely harms my library usability, so
> I definitely wouldn't do that. So yes, I decide which C++ level I will
> target and write the code accordingly.
>
>> That after all is what you are essentially saying a Boost library
>> must do, is it not ?
>
> I'm sorry, I didn't understand this question. I expressed my view on
> the matter, based on my experience. It's not an official Boost policy,
> if that's what you're asking.
>
>> I find that irritating, not because I think the Boost libraries are any
>> worse than their C++ equivalents, but because I see no reason why I should
>> either have dependencies on other Boost libraries when I don't need to or
>> that I have to cut off all end-users of my library compiler implementations
>> if I choose just C++11 mode and STL11.
>
> I explained why. You are free to ignore my reasoning, of course, but I
> doubt your users will be happy in this case.
>
>>> I understand your argument - after all C++ allows you to shoot yourself in
>>> the
>>> foot, so do your macros. But unlike C++ they don't make it really
>>> difficult.
>>> Maybe we just need a documented policy of use of these macros so that they
>>> don't get misused. Maybe we need testing, when the library and tests are
>>> compiled in different C++ modes. I don't know.
>>
>> I have developed a series of proof of concept tests for each of the
>> libraries the macro system supports in either C++03 or C++11 mode. I have
>> not tried to add PRs for those tests for each Boost library yet because my
>> macro system is not in Boost.config 'develop' yet, and I don't want failings
>> test for no reason.
>
> If I understood you correctly, that's not the kind of tests I was talking about.
>
>> Boost has implemented the notion that for libraries being built that the
>> library name changes depending on whether or not the dynamic RTL or static
>> RTL of the compiler implementation is being used. Also the library name
>> changes depending on whether the library itself being built is a static or
>> shared library. And there are a few more of these name manipulations which
>> Boost enforces. I am simply arguing that we can come up with a means for
>> doing the same on demand for C++ modes, not that we must do the same thing
>> for C++ modes at all times.
>>
>> Let me give a very simple practical use case and this will illustrate what I
>> am trying to discuss.
>>
>> I develop library EDS_LIB and it is a Boost library which must be built as a
>> library and is not header-only, and my library uses regex in some interface
>> it exports.
>>
>> I have a decision to make: do I use Boost.regex and therefore work in any
>> C++ mode or do I use std::regex and therefore works only in C++11 mode (
>> which I will assume supports the std::regex library ). Most people will say
>> to use Boost.regex and be able to support any mode. Fair enough, but now
>> EDS_LIB depends on Boost regex. If Boost ever goes to a more modular
>> distribution all distribution of EDS_LIB must also include Boost regex.
>
> Why? EDS_LIB would depend on Boost.Regex but not include it.

How in the world would EDS_LIB depend on Boost.Regex but not have it
part of the distribution of EDS_LIB if we go with a modular Boost
distribution where EDS_LIB could be distributed by itself with its
dependencies ?

>
>> OTOH if I choose C++11 mode the dependency on Boost.regex goes away, but now
>> you need to compile whatever uses EDS_LIB in C++11 mode else my library is
>> useless to you.
>
> Correct.
>
>> Now let's suppose, using my macro system, I can distribute my library as
>> EDS_LIB in C++03 mode or EDS_LIB_C11 in C++11 mode. My exported interface
>> using regex is:
>>
>> #include <boost/config/cpp/regex.hpp>
>> #include BOOST_CPP_REGEX_HDR
>> void EdsFunction(BOOST_CPP_REGEX_NS::regex & rx);
>>
>> Now if you compile your library or application in C++03 mode you link with
>> EDS_LIB and you get its dependency on Boost.regex. If you compile your
>> library or application in C++11 mode you link with EDS_LIB_C11 and you no
>> longer have its dependency on Boost.regex. In your application or library
>> you use my macro system in order to pass the correct regex in either case
>> without worrying about which it is:
>>
>> #include <boost/config/cpp/regex.hpp>
>> #include BOOST_CPP_REGEX_HDR
>>
>> BOOST_CPP_REGEX_NS::regex myregex("Some regular expression");
>> EdsFunction(myregex);
>>
>> Where is the ABI problem in this case ? ( rhetorical question )
>
> The ABI problem is right here. EDS_LIB, as it is distributed in a
> Linux distro, is built in C++03, and it is incompatible with user's
> code that is built in C++11. At least not in the way you describe.

EDS_LIB distribution is not distributed for C++11 use. For that my
previously mentioned EDS_LIB_C11 is distributed with its dependencies
for C++11 use.

>
> My suggested approach would be to avoid both Boost.Regex and
> std::regex in the binary interface - for example by passing strings in
> the ABI. You can still use whatever regex you like in the API, or even
> better - use concepts to accept any regex-like type, be that
> std::regex, boost::regex or boost::xpressive::regex - whatever the
> user happens to be using in his code.
>

I know you are not kidding but I consider your solution "not optimal".
Your solution is that two perfectly usable versions of regex exist but I
need to manufacture another. Needless to say that is not my idea of
programming in this situation.

>> Multiply the dependency beyond just regex to a few other Boost libraries
>> which have C++11 standard library equivalents and you can see how the
>> problem of choosing builds up. Either you are going to have a number of
>> dependencies on other Boost libraries in C++03 mode or you are again going
>> to be unusable in C++11 mode to other modules not using C++11.
>
> I'm sorry, I don't see what the number of dependencies have to do with
> ABI stability.
>
>> You are saying: choose, either your library may have a number of
>> dependencies when building it in C++03 mode, or your library will not have
>> those dependencies but will be usable only in C++11 mode.
>>
>> I am saying: having to choose is not acceptable in Boost as more compilers
>> support C++11, but some either do not support C++11 or are not usable by
>> end-users in C++11 mode.
>
> It worked for me so far, I don't see the problem.
>
>>> By the way, Boost is not the only project that attempts to maintain stable
>>> ABI
>>> regardless of the C++ mode. libstdc++ is also doing that, for example.
>>
>> How many other library dependencies does libstdc++ have ? Then ask yourself
>> how many other library dependencies does any given Boost library have ? Have
>> I made my point ?
>
> No, I don't think you did. How the number of dependencies have any
> relevance to API/ABI stability?

What does API/ABI stability mean in this context to you ? We are
probably discussing this at cross-purposes because my interpretation of
what it means is not what you mean.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-07 10:22:26 UTC
Permalink
On 07.06.2015 06:39, Edward Diener wrote:
> On 6/6/2015 7:23 PM, Andrey Semashev wrote:
>>
>> The macros don't abstract
>> away what implementation is being used - STL or Boost - because I have
>> to deal with linking anyway. That's why the solution is incomplete.
>
> I have repeated again and again that for built libraries, as opposed to
> header-only libraries, a system of distinct names for the same library
> depending on whether the library is compiled in C++03 mode or C++11 mode
> can solve this problem.

I don't see how.

>>> I have a decision to make: do I use Boost.regex and therefore work in
>>> any
>>> C++ mode or do I use std::regex and therefore works only in C++11 mode (
>>> which I will assume supports the std::regex library ). Most people
>>> will say
>>> to use Boost.regex and be able to support any mode. Fair enough, but now
>>> EDS_LIB depends on Boost regex. If Boost ever goes to a more modular
>>> distribution all distribution of EDS_LIB must also include Boost regex.
>>
>> Why? EDS_LIB would depend on Boost.Regex but not include it.
>
> How in the world would EDS_LIB depend on Boost.Regex but not have it
> part of the distribution of EDS_LIB if we go with a modular Boost
> distribution where EDS_LIB could be distributed by itself with its
> dependencies ?

Huh? I didn't know we were going for that kind of modularity. My
understanding was that modular Boost would consist of multiple
independent libraries (which distribute only their own code) and a tool
that is able to download a library and its dependencies.

If we're going to bundle a library and all its dependencies together
then that's not the modular Boost I want to use or develop.

>>> Now let's suppose, using my macro system, I can distribute my library as
>>> EDS_LIB in C++03 mode or EDS_LIB_C11 in C++11 mode. My exported
>>> interface
>>> using regex is:
>>>
>>> #include <boost/config/cpp/regex.hpp>
>>> #include BOOST_CPP_REGEX_HDR
>>> void EdsFunction(BOOST_CPP_REGEX_NS::regex & rx);
>>>
>>> Now if you compile your library or application in C++03 mode you link
>>> with
>>> EDS_LIB and you get its dependency on Boost.regex. If you compile your
>>> library or application in C++11 mode you link with EDS_LIB_C11 and
>>> you no
>>> longer have its dependency on Boost.regex. In your application or
>>> library
>>> you use my macro system in order to pass the correct regex in either
>>> case
>>> without worrying about which it is:
>>>
>>> #include <boost/config/cpp/regex.hpp>
>>> #include BOOST_CPP_REGEX_HDR
>>>
>>> BOOST_CPP_REGEX_NS::regex myregex("Some regular expression");
>>> EdsFunction(myregex);
>>>
>>> Where is the ABI problem in this case ? ( rhetorical question )
>>
>> The ABI problem is right here. EDS_LIB, as it is distributed in a
>> Linux distro, is built in C++03, and it is incompatible with user's
>> code that is built in C++11. At least not in the way you describe.
>
> EDS_LIB distribution is not distributed for C++11 use. For that my
> previously mentioned EDS_LIB_C11 is distributed with its dependencies
> for C++11 use.

What exactly do you mean by "distribution"? Does it include library
headers? Are these headers different in EDS_LIB and EDS_LIB_C11? If both
are yes, do they not conflict?

>> My suggested approach would be to avoid both Boost.Regex and
>> std::regex in the binary interface - for example by passing strings in
>> the ABI. You can still use whatever regex you like in the API, or even
>> better - use concepts to accept any regex-like type, be that
>> std::regex, boost::regex or boost::xpressive::regex - whatever the
>> user happens to be using in his code.
>
> I know you are not kidding but I consider your solution "not optimal".
> Your solution is that two perfectly usable versions of regex exist but I
> need to manufacture another. Needless to say that is not my idea of
> programming in this situation.

Why would you have to manufacture one?

>>> How many other library dependencies does libstdc++ have ? Then ask
>>> yourself
>>> how many other library dependencies does any given Boost library have
>>> ? Have
>>> I made my point ?
>>
>> No, I don't think you did. How the number of dependencies have any
>> relevance to API/ABI stability?
>
> What does API/ABI stability mean in this context to you ?

For the course of this discussion it means that API/ABI do not depend on
compiler options, including C++ mode.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Niall Douglas
2015-06-06 16:14:31 UTC
Permalink
On 5 Jun 2015 at 5:30, Edward Diener wrote:

> I don't know what "the right approach" would be but this is one approach
> that does work easily, following the documentation I have written about
> it and added to the Boost.config documentation.

Firstly, this is a long overdue patch and I find it a hugely welcome
development. Thank you Edward for taking the time to implement it.

> If I have missed any Boost libraries which have a close C++ standard
> equivalent just tell me and I will add it with some added tests for that
> particular library.

I didn't see system_error?

> 5) I wanted to push it to 'develop' and let others use it and add the
> per library PR's to test it. If it was found to be flawed or could be
> better in any way I could then change it on 'develop', and if people
> were satisfied with it as a workable solution it could eventually be
> merged to 'master'. If not it could be easily removed if necessary since
> it exists in its own header files apart from the rest of Boost.config.
> Even its documentation is a separate Boost.config .qbk file.

Here's a crazy idea: If Boost.Build is in >= C++ 11 build mode, turn
all these macros on by default. That should ease testing enormously.

Build needs to gain an official C++ 11 build mode first though.
Something where libraries in their Jamfile can say "I can only
compile with C++11 or better, so if not >= C++ 11 then ignore this
library during build".

> If there are better interoperable systems I would love to hear about
> them. But for me personally any system where I have to jump through
> hoops simply to be able to write code which works whether I am using a
> Boost library or its C++ standard library equivalent, will not be worth it.

I think this support is a great first step to making Boost less
obsolete in a C++ 11 world. It doesn't solve all the other problems
Boost has, but it's still a huge improvement.

> Questions, concerns etc are welcome.

My only real worry is the ABI problems. You need to permute the
symbols being linked to avoid config mismatches colliding in an
unhelpful way.

Perhaps for each config macro have during build the library output an
extern dll visible empty function with a mangled name representing
the config. On use, import and use that function. This should
generate link errors if one is trying to use a config against a
binary not built the same way.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/
http://ie.linkedin.com/in/nialldouglas/
Edward Diener
2015-06-06 19:30:54 UTC
Permalink
On 6/6/2015 12:14 PM, Niall Douglas wrote:
> On 5 Jun 2015 at 5:30, Edward Diener wrote:
>
>> I don't know what "the right approach" would be but this is one approach
>> that does work easily, following the documentation I have written about
>> it and added to the Boost.config documentation.
>
> Firstly, this is a long overdue patch and I find it a hugely welcome
> development. Thank you Edward for taking the time to implement it.
>
>> If I have missed any Boost libraries which have a close C++ standard
>> equivalent just tell me and I will add it with some added tests for that
>> particular library.
>
> I didn't see system_error?+

I will look into it. Thanks !

>
>> 5) I wanted to push it to 'develop' and let others use it and add the
>> per library PR's to test it. If it was found to be flawed or could be
>> better in any way I could then change it on 'develop', and if people
>> were satisfied with it as a workable solution it could eventually be
>> merged to 'master'. If not it could be easily removed if necessary since
>> it exists in its own header files apart from the rest of Boost.config.
>> Even its documentation is a separate Boost.config .qbk file.
>
> Here's a crazy idea: If Boost.Build is in >= C++ 11 build mode, turn
> all these macros on by default. That should ease testing enormously.

I am not sure what you mean by "turn all these macros on by default."

If Boost Build is in C++11 mode then the underlying Boost.config macros,
upon which each XXX library macro is based, will no doubt show that the
C++11 library is available for use. This in turn means that if a
particular boost/config/cpp/XXX.hpp header is included by the end-user
the corresponding BOOST_CPP_HAS_XXX macro will be 1 and not 0. Of course
it is barely possible that c++11 mode for a particular compiler/version
implementation does not support a mandated C++11 library, but that is
not anything Boost or my XXX library macro can do anything about. But at
least that fact will be totally consistent for all modules built with
that particcular compiler/version implementation.

So in effect in C++11 mode for a compiler/version implementation all of
the corresponding BOOST_CPP_HAS_XXX macros for each XXX library should
automatically be 1.

>
> Build needs to gain an official C++ 11 build mode first though.
> Something where libraries in their Jamfile can say "I can only
> compile with C++11 or better, so if not >= C++ 11 then ignore this
> library during build".

You can do that with my macros, for any one of the libraries supported,
by simply issuing a preprocessor #error. I show this in the
documentation. Essentially if a library needs C++11 mode to be built
because it requires a particular C++11 library equivalent to be used
instead of the Boost library it can create code for the equivalent
library XXX of:

#include <boost/config/cpp/XXX.hpp>
#if !BOOST_CPP_HAS_XXX
#error Standard Library XXX is needed to use this library.
#endif

But my macros do not have, nor are they intended to have, the general
ability to just say that if C++11 mode is not being used it should be an
error.

The macros are generally intended to be used by a library or code which
wants to work in a dual mode, both pre-C++11 and C++11 on up. This is
very different from your perspective that a libraries should be built
that will work only for C++11. I am not in disagreement with your point
of view if that is what a library needs to implement its functionality.
But I believe that there are still many programmers who will design
their library to work with either C++03 and C++11 and the macros Im have
created offer a way of doing that when using other Boost libraries or
their equivalent in C++11.

>
>> If there are better interoperable systems I would love to hear about
>> them. But for me personally any system where I have to jump through
>> hoops simply to be able to write code which works whether I am using a
>> Boost library or its C++ standard library equivalent, will not be worth it.
>
> I think this support is a great first step to making Boost less
> obsolete in a C++ 11 world. It doesn't solve all the other problems
> Boost has, but it's still a huge improvement.

Thanks ! It has very practical use for me in a library on which I am
working, which will be a header-only template library.

>
>> Questions, concerns etc are welcome.
>
> My only real worry is the ABI problems. You need to permute the
> symbols being linked to avoid config mismatches colliding in an
> unhelpful way.

The issue as far as ABI comes down to the ability of using such a
dual-mode library that is a built library and is not a header only library.

My point of view is that Boost needs to establish a way so that a
library built in C++03 mode could be named slightly differently from the
same library built in C++11 mode. We already have a system in place
which can name a library differently depending on whether it uses the
dynamic or static RTL of its implementation, or whether the library
itself is a static lib or a shared lib, among other naming conventions.
What I am positing for a built library is that the developer of that
library should have the ability to specify that his library have a
different name depending on whether it is C++03 or C++11 mode, and that
this choice should work so that the correct name is used during both a
link of the library and when that library is being used by another library.

Boost.config already has a system of auto-linking which must be
coordinated with Boost Build to use the correct library name, so adding
the compile-time ability to change the name slightly between a C++03
mode build and a C++11 mode build must also I believe be co-ordinated
with Boost Build.

>
> Perhaps for each config macro have during build the library output an
> extern dll visible empty function with a mangled name representing
> the config. On use, import and use that function. This should
> generate link errors if one is trying to use a config against a
> binary not built the same way.

This elaboration does not seem necessary to me, but I don't really
understand its reason.

I believe the problem can be solved by a library naming convention that
can give a C++03 library a slightly different name than a C++11 library,
but only if the library developer needs to do this.

The use case I see for this need can be illustrated in this way. One
creates a built dual-mode library using my macros, and the interface to
my library specifies that, let's say, in C++03 mode you pass a
boost::ratio object to some exported function while in C++11 mode you
pass its C++ standard equivalent std::ratio object to some function. A
user of my library compiling in C++03 mode will link to the version name
of my library built in C++03 mode, and using my macros will
automatically be passing the correct ratio object to my library's
functionality. Likewise a user of my library compiling in C++11 mode
will link to my library built in C++11 mode, and once again using my
macros will automatically be passing the correct ratio object to my
library's functionality. As long as the correct name of my library is
being linked the ABI problem of using the correct library is solved. So
the only ABI problem I see here is establishing a convention and a
system in Boost by which a dual-mode library using one or more of my set
of XXX macros might want to be built using slightly different names for
C++03 and C++11 mode.

You may know of ABI problems between a library built for C++03 or C++11
which are outside the problem I have tried to solve with my macro
system. But my macros themselves are only meant to solve a particular
problem and not the perhaps larger one of ABI compatibility between a
library built in one C++ mode or another or possibly both.

It is important that Boost not consign its libraries to support only one
particular subset of Boost libraries and/or C++11 equivalent libraries.
This will prevent Boost library development from moving into the C+11
world of programming when the idioms and libraries of C++11 prove highly
useful to C++ library design and development. My macro system is an
effort to support both C++ modes with the least amount of syntactical
problems. I have no doubt as more and more compilers support C++11 more
thoroughly that new Boost libraries will use C++11 features to enhance
their ability. But the reality is currently such that until a full
transition is made by all major compilers to support C++11, C++14, and
beyond ( C++17 ? ) library developers may still target new libraries to
accomodate the C++03 standard as the lowest common denominator, so to
speak, of C++ compatibility.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Niall Douglas
2015-06-07 09:39:52 UTC
Permalink
On 6 Jun 2015 at 15:30, Edward Diener wrote:

> > Here's a crazy idea: If Boost.Build is in >= C++ 11 build mode, turn
> > all these macros on by default. That should ease testing enormously.
>
> I am not sure what you mean by "turn all these macros on by default."
>
> If Boost Build is in C++11 mode then the underlying Boost.config macros,
> upon which each XXX library macro is based, will no doubt show that the
> C++11 library is available for use. This in turn means that if a
> particular boost/config/cpp/XXX.hpp header is included by the end-user
> the corresponding BOOST_CPP_HAS_XXX macro will be 1 and not 0. Of course
> it is barely possible that c++11 mode for a particular compiler/version
> implementation does not support a mandated C++11 library, but that is
> not anything Boost or my XXX library macro can do anything about. But at
> least that fact will be totally consistent for all modules built with
> that particcular compiler/version implementation.
>
> So in effect in C++11 mode for a compiler/version implementation all of
> the corresponding BOOST_CPP_HAS_XXX macros for each XXX library should
> automatically be 1.

Sorry. I missed that you need to explicitly opt into the switching
functionality by using a macro which expands into the true underlying
implementation. I thought you wouldn't need to prefix every single
use with a macro.

APIBind does the same thing as you've done using aliasing and is
therefore macro-free. Sadly aliasing is C++ 11 only. One could
emulate it using shims, but they participate in overload resolution
:(

If a library has its own namespace though (most of the newer ones
do), a simple namespace alias can save a lot of ugly macros. You
might add that to your docs.

> But my macros do not have, nor are they intended to have, the general
> ability to just say that if C++11 mode is not being used it should be an
> error.

It's more the case that right now each C++ 11 mandatory library
simply forces on -std=c++11 in their Jamfile. That seems silly to me,
and guaranteed to cause problems once the first C++ 11 mandatory
library enters Boost.

What we need is something like <requirements><c++standard>2014. Or
similar.

I agree this is a totally separate issue to your patch.

> > I think this support is a great first step to making Boost less
> > obsolete in a C++ 11 world. It doesn't solve all the other problems
> > Boost has, but it's still a huge improvement.
>
> Thanks ! It has very practical use for me in a library on which I am
> working, which will be a header-only template library.

Did I see that you've patched all the other Boost libraries such that
any Boost library which uses regex can be switched into std::regex?

If so, cool. But ABI worrying. If not, then it might explain me
getting confused below (if so disregard what I say below).

> >> Questions, concerns etc are welcome.
> >
> > My only real worry is the ABI problems. You need to permute the
> > symbols being linked to avoid config mismatches colliding in an
> > unhelpful way.
>
> The issue as far as ABI comes down to the ability of using such a
> dual-mode library that is a built library and is not a header only library.

Not entirely. What if I build my DLL A which configures Boost header
only libraries with std and someone else builds DLL B which
configures Boost header only libraries with boost and then a third
party tries loading both DLLs into the same process?

On Windows it would probably somewhat work, but god help you if you
try passing object instances from one DLL to the other.

> My point of view is that Boost needs to establish a way so that a
> library built in C++03 mode could be named slightly differently from the
> same library built in C++11 mode. We already have a system in place
> which can name a library differently depending on whether it uses the
> dynamic or static RTL of its implementation, or whether the library
> itself is a static lib or a shared lib, among other naming conventions.
> What I am positing for a built library is that the developer of that
> library should have the ability to specify that his library have a
> different name depending on whether it is C++03 or C++11 mode, and that
> this choice should work so that the correct name is used during both a
> link of the library and when that library is being used by another library.

Similar to APIBind's use of an ABI mangled inline namespace.

> Boost.config already has a system of auto-linking which must be
> coordinated with Boost Build to use the correct library name, so adding
> the compile-time ability to change the name slightly between a C++03
> mode build and a C++11 mode build must also I believe be co-ordinated
> with Boost Build.

Apart from GCC not supporting auto-linking, great.

I really wish GCC did support auto-linking. It's a trivial feature
add, the only hard part is getting it past the gatekeepers for the
GCC tooling.

> It is important that Boost not consign its libraries to support only one
> particular subset of Boost libraries and/or C++11 equivalent libraries.
> This will prevent Boost library development from moving into the C+11
> world of programming when the idioms and libraries of C++11 prove highly
> useful to C++ library design and development. My macro system is an
> effort to support both C++ modes with the least amount of syntactical
> problems. I have no doubt as more and more compilers support C++11 more
> thoroughly that new Boost libraries will use C++11 features to enhance
> their ability. But the reality is currently such that until a full
> transition is made by all major compilers to support C++11, C++14, and
> beyond ( C++17 ? ) library developers may still target new libraries to
> accomodate the C++03 standard as the lowest common denominator, so to
> speak, of C++ compatibility.

As everyone knows, my personal position on that is that we are long
overdue a C++ 11 only separate Boost distro.

Additional distros consisting of just the well maintained libraries
would be even better. That would reduce Boost to eighty or ninety
libraries, and help users not constantly waste time using Boost
libraries riddled with bugs that will never be fixed. It is deeply
unfair that we do that to users. Undermaintained libraries should, as
a minimum, have a big flashing warning next to their name with a
suggestion that if you would like to take over maintaining that
library we can do you a deal (as per the new policy agreed at C++
Now).

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/
http://ie.linkedin.com/in/nialldouglas/
Edward Diener
2015-06-07 13:57:44 UTC
Permalink
On 6/7/2015 5:39 AM, Niall Douglas wrote:
> On 6 Jun 2015 at 15:30, Edward Diener wrote:
>
>>> Here's a crazy idea: If Boost.Build is in >= C++ 11 build mode, turn
>>> all these macros on by default. That should ease testing enormously.
>>
>> I am not sure what you mean by "turn all these macros on by default."
>>
>> If Boost Build is in C++11 mode then the underlying Boost.config macros,
>> upon which each XXX library macro is based, will no doubt show that the
>> C++11 library is available for use. This in turn means that if a
>> particular boost/config/cpp/XXX.hpp header is included by the end-user
>> the corresponding BOOST_CPP_HAS_XXX macro will be 1 and not 0. Of course
>> it is barely possible that c++11 mode for a particular compiler/version
>> implementation does not support a mandated C++11 library, but that is
>> not anything Boost or my XXX library macro can do anything about. But at
>> least that fact will be totally consistent for all modules built with
>> that particcular compiler/version implementation.
>>
>> So in effect in C++11 mode for a compiler/version implementation all of
>> the corresponding BOOST_CPP_HAS_XXX macros for each XXX library should
>> automatically be 1.
>
> Sorry. I missed that you need to explicitly opt into the switching
> functionality by using a macro which expands into the true underlying
> implementation. I thought you wouldn't need to prefix every single
> use with a macro.
>
> APIBind does the same thing as you've done using aliasing and is
> therefore macro-free. Sadly aliasing is C++ 11 only. One could
> emulate it using shims, but they participate in overload resolution
> :(
>
> If a library has its own namespace though (most of the newer ones
> do), a simple namespace alias can save a lot of ugly macros. You
> might add that to your docs.

Good idea !

You could also use a using directive, with its usual pitfalls, easily
enough:

#include <boost/cpp/XXX.hpp>
#include BOOST_CPP_XXX_HDR
using namespace BOOST_CPP_XXX_NS;

etc.

>
>> But my macros do not have, nor are they intended to have, the general
>> ability to just say that if C++11 mode is not being used it should be an
>> error.
>
> It's more the case that right now each C++ 11 mandatory library
> simply forces on -std=c++11 in their Jamfile. That seems silly to me,
> and guaranteed to cause problems once the first C++ 11 mandatory
> library enters Boost.
>
> What we need is something like <requirements><c++standard>2014. Or
> similar.
>
> I agree this is a totally separate issue to your patch.
>
>>> I think this support is a great first step to making Boost less
>>> obsolete in a C++ 11 world. It doesn't solve all the other problems
>>> Boost has, but it's still a huge improvement.
>>
>> Thanks ! It has very practical use for me in a library on which I am
>> working, which will be a header-only template library.
>
> Did I see that you've patched all the other Boost libraries such that
> any Boost library which uses regex can be switched into std::regex?

No, I did not do that.

What I have done locally, but not yet created forks and PRs, is to add
simple tests to each Boost library that show that the technique of using
my macros will work whether one compiles in C++11 mode or not.

>
> If so, cool. But ABI worrying. If not, then it might explain me
> getting confused below (if so disregard what I say below).
>
>>>> Questions, concerns etc are welcome.
>>>
>>> My only real worry is the ABI problems. You need to permute the
>>> symbols being linked to avoid config mismatches colliding in an
>>> unhelpful way.
>>
>> The issue as far as ABI comes down to the ability of using such a
>> dual-mode library that is a built library and is not a header only library.
>
> Not entirely. What if I build my DLL A which configures Boost header
> only libraries with std and someone else builds DLL B which
> configures Boost header only libraries with boost and then a third
> party tries loading both DLLs into the same process?
>
> On Windows it would probably somewhat work, but god help you if you
> try passing object instances from one DLL to the other.
>

This is no different from anyone doing this manually without the use of
my macros. Any DLL can pick which libraries it wants to use, whether a
Boost library or a C++ standard library equivalent. If I create DLL A
which uses Boost regex in its interface and DLL B which uses the C++11
std::regex in its interface, naturally I can't mix them in the sense of
trying to pass a Boost regex object to a library that expects a
std::regex object or vice versa. As far as actually loading both
libraries that in itself should cause no problems AFAICS.

>> My point of view is that Boost needs to establish a way so that a
>> library built in C++03 mode could be named slightly differently from the
>> same library built in C++11 mode. We already have a system in place
>> which can name a library differently depending on whether it uses the
>> dynamic or static RTL of its implementation, or whether the library
>> itself is a static lib or a shared lib, among other naming conventions.
>> What I am positing for a built library is that the developer of that
>> library should have the ability to specify that his library have a
>> different name depending on whether it is C++03 or C++11 mode, and that
>> this choice should work so that the correct name is used during both a
>> link of the library and when that library is being used by another library.
>
> Similar to APIBind's use of an ABI mangled inline namespace.
>
>> Boost.config already has a system of auto-linking which must be
>> coordinated with Boost Build to use the correct library name, so adding
>> the compile-time ability to change the name slightly between a C++03
>> mode build and a C++11 mode build must also I believe be co-ordinated
>> with Boost Build.
>
> Apart from GCC not supporting auto-linking, great.
>
> I really wish GCC did support auto-linking. It's a trivial feature
> add, the only hard part is getting it past the gatekeepers for the
> GCC tooling.

I agree that GCC providing auto-linking would be good. But even without
auto-linking I think that Boost Build already might have some way to
"name" a library based on its compile time parameters.

>
>> It is important that Boost not consign its libraries to support only one
>> particular subset of Boost libraries and/or C++11 equivalent libraries.
>> This will prevent Boost library development from moving into the C+11
>> world of programming when the idioms and libraries of C++11 prove highly
>> useful to C++ library design and development. My macro system is an
>> effort to support both C++ modes with the least amount of syntactical
>> problems. I have no doubt as more and more compilers support C++11 more
>> thoroughly that new Boost libraries will use C++11 features to enhance
>> their ability. But the reality is currently such that until a full
>> transition is made by all major compilers to support C++11, C++14, and
>> beyond ( C++17 ? ) library developers may still target new libraries to
>> accomodate the C++03 standard as the lowest common denominator, so to
>> speak, of C++ compatibility.
>
> As everyone knows, my personal position on that is that we are long
> overdue a C++ 11 only separate Boost distro.
>
> Additional distros consisting of just the well maintained libraries
> would be even better. That would reduce Boost to eighty or ninety
> libraries, and help users not constantly waste time using Boost
> libraries riddled with bugs that will never be fixed. It is deeply
> unfair that we do that to users. Undermaintained libraries should, as
> a minimum, have a big flashing warning next to their name with a
> suggestion that if you would like to take over maintaining that
> library we can do you a deal (as per the new policy agreed at C++
> Now).

I know your opinion about a separate Boost for C++11 libraries. My
solution is different. I think libraries for C++11 can coexist in Boost
with libraries supporting C++03.

I see nothing wrong with the ability of header-only libraries being used
in dual mode with my macros. As far as built libraries if Boost could
come up with a naming solution so that the C++11 version of a library
has a slightly different name than its C++03 counterpart I think that
will work fine.

Most of the talk about the problems of my macro system presupposes that
programmers using Boost will mistakenly try to use a C++11 version of a
library during a C++03 mode build and vice versa, and therefore the
system must be flawed. Naturally I don't agree but I do understand the
reticence of others to accept a dual mode system such as I am proposing.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Peter Dimov
2015-06-07 14:36:51 UTC
Permalink
Edward Diener wrote:
> Most of the talk about the problems of my macro system presupposes that
> programmers using Boost will mistakenly try to use a C++11 version of a
> library during a C++03 mode build and vice versa, and therefore the system
> must be flawed.

This was some of the talk but I'm not sure about "most". A substantial part
of the talk was about programmers wanting to use boost::regex even when the
compiler happens to be in C++11 mode. In other words, talk that challenges
your assumption that

> If the end-user of my library is compiling in C++11 mode is it more likely
> that his use of regex will be std::regex or boost::regex ? IMO it is the
> former.

There are several good reasons to prefer boost::regex. First, the one I
pointed out, you want to maintain a single code base that compiles under
C++03 and C++11. Second, you want to use boost::regex's extensions that
std::regex doesn't have. Third, you want predictable performance that is
independent of the standard library in use.

On the other side of the coin, we have the desire to avoid use of Boost when
use of standard facilities would suffice, which is real and legitimate.
However, in my experience at least, this desire is only strong when you can
avoid use of Boost _altogether_, which is not the case under discussion.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 16:22:49 UTC
Permalink
On 6/7/2015 10:36 AM, Peter Dimov wrote:
> Edward Diener wrote:
>> Most of the talk about the problems of my macro system presupposes
>> that programmers using Boost will mistakenly try to use a C++11
>> version of a library during a C++03 mode build and vice versa, and
>> therefore the system must be flawed.
>
> This was some of the talk but I'm not sure about "most". A substantial
> part of the talk was about programmers wanting to use boost::regex even
> when the compiler happens to be in C++11 mode. In other words, talk that
> challenges your assumption that
>
>> If the end-user of my library is compiling in C++11 mode is it more
>> likely that his use of regex will be std::regex or boost::regex ? IMO
>> it is the former.
>
> There are several good reasons to prefer boost::regex. First, the one I
> pointed out, you want to maintain a single code base that compiles under
> C++03 and C++11. Second, you want to use boost::regex's extensions that
> std::regex doesn't have. Third, you want predictable performance that is
> independent of the standard library in use.

If you use my macro system you can continue to maintain a single code
base under C++03 and C++11.

Sometimes it is the other way around and a C++ standard library
equivalent has functionality which its corresponding Boost library does
not have.

>
> On the other side of the coin, we have the desire to avoid use of Boost
> when use of standard facilities would suffice, which is real and
> legitimate. However, in my experience at least, this desire is only
> strong when you can avoid use of Boost _altogether_, which is not the
> case under discussion.

It is the case under discussion if there is no other use of Boost
libraries outside of the ones which have their equivalent in the C++
standard library for a given module.

If the above is not the case I don't think that the desire to avoid
using Boost altogether is realistic either. Boost has approximately 100
or so libraries which are not "duplicated" by C++ standard library
equivalents. Why would anyone refuse to use any of those 100 or so
libraries on principle if the use of a Boost library made their
programming easier ?

I understand that in the present incarnation of Boost as a single
distribution that the attempt to use C++ standard library equivalents to
Boost libraries when compiling in C++11 mode does not offer much of an
advantage. But if and when in a future incarnation of Boost an
individual Boost library, whether header-only or not, along with its
dependencies can be distributed and used outside the currently
monolithic Boost distribution it will be an advantage to be able to use
C++ standard library equivalents to Boost libraries.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
John Maddock
2015-06-07 17:04:14 UTC
Permalink
On 07/06/2015 15:36, Peter Dimov wrote:
> Edward Diener wrote:
>> Most of the talk about the problems of my macro system presupposes
>> that programmers using Boost will mistakenly try to use a C++11
>> version of a library during a C++03 mode build and vice versa, and
>> therefore the system must be flawed.
>
> This was some of the talk but I'm not sure about "most". A substantial
> part of the talk was about programmers wanting to use boost::regex
> even when the compiler happens to be in C++11 mode. In other words,
> talk that challenges your assumption that
>
>> If the end-user of my library is compiling in C++11 mode is it more
>> likely that his use of regex will be std::regex or boost::regex ? IMO
>> it is the former.
>
> There are several good reasons to prefer boost::regex. First, the one
> I pointed out, you want to maintain a single code base that compiles
> under C++03 and C++11. Second, you want to use boost::regex's
> extensions that std::regex doesn't have. Third, you want predictable
> performance that is independent of the standard library in use.
>
Right. But if lib X prefers/needs to use the Boost version always, they
don't have to use this mechanism.
> On the other side of the coin, we have the desire to avoid use of
> Boost when use of standard facilities would suffice, which is real and
> legitimate. However, in my experience at least, this desire is only
> strong when you can avoid use of Boost _altogether_, which is not the
> case under discussion.
Right, we're nowhere near having a package manager that's smart enough
to avoid dependence on boost::whatever if the user tells it they have a
C++11 compiler.

I guess my concerns are somewhat different from those already expressed:

* I'm not sure that this adds much over the existing macros
BOOST_NO_CXX11_HDR_REGEX etc.
* If this evolved into a more "complete" solution, then (a) It doesn't
belong in Config (too many dependencies), and (b) I would worry that we
repeat the mistake of Boost.TR1 - which is to say creating that
particular unmaintainable monster it in the first place -just ask the
author ;)
* Folks are correct to be concerned about ABI issues: we not that long
ago changed 'nix installs to install "one true binary" for each library
as there was *very* strong user preference for that. Splitting into '03
and '11 binaries is IMO a significant retrograde step. If you do that
expect endless newbie support requests wondering why things don't work.

On the other hand:

* I can see a legitimate use for this as a library internal (rather like
what Math does with std::tuple and boost::tuple).
* The need to have different linking requirements in Boost.Build is a
solved issue - just use check_target_builds to set the dependency.

So... I guess what I would like to see expressed, is what are the
concrete use cases for this? What do *you* want to use it for?

And finally, you are aware that there are 3 tuples available? boost::,
fusion:: and std::, and they they all are slightly different? Oh and
std::tr1::tuple too ;)

What I suspect we will see more of, is libraries becoming implementation
agnostic - "give me something that looks like a
tuple/thread/future/function and I'll go off and do the right thing".
The latest Math code does that with tuple types, and it was a pain in
the neck to get working (or possibly I was just being dense at the
time), certainly the hoops you have to jump through to support that go
way beyond the scope of this addition.

Regards, John.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Peter Dimov
2015-06-07 17:29:32 UTC
Permalink
John Maddock wrote:

> Right. But if lib X prefers/needs to use the Boost version always, they
> don't have to use this mechanism.

What I'm saying is more like lib X has a dual interface, but _the user_ of
lib X wants to use the boost:: version, whereas lib X detects C++11 and
provides the std:: version.

Lib X is

#if CXX11

void libx_f( std::regex const & rx );

#else

void libx_f( boost::regex const & rx );

#endif

but the user wants to continue using boost::regex under C++11.

This could in principle be addressed in some way by giving the user the
option to override libX's decision to go with std::regex.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
John Maddock
2015-06-07 17:43:12 UTC
Permalink
>> Right. But if lib X prefers/needs to use the Boost version always,
>> they don't have to use this mechanism.
>
> What I'm saying is more like lib X has a dual interface, but _the
> user_ of lib X wants to use the boost:: version, whereas lib X detects
> C++11 and provides the std:: version.
>

Got you. Yes that's an issue, and probably the only solution is for
each library to have a macro that signals which to use :(

John.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 18:50:51 UTC
Permalink
On 6/7/2015 1:29 PM, Peter Dimov wrote:
> John Maddock wrote:
>
>> Right. But if lib X prefers/needs to use the Boost version always,
>> they don't have to use this mechanism.
>
> What I'm saying is more like lib X has a dual interface, but _the user_
> of lib X wants to use the boost:: version, whereas lib X detects C++11
> and provides the std:: version.
>
> Lib X is
>
> #if CXX11
>
> void libx_f( std::regex const & rx );
>
> #else
>
> void libx_f( boost::regex const & rx );
>
> #endif
>
> but the user wants to continue using boost::regex under C++11.
>
> This could in principle be addressed in some way by giving the user the
> option to override libX's decision to go with std::regex.

I have thought of letting the end-user override libX's decision. For a
currently supported XXX library in my macro system I could allow a
BOOST_CPP_XXX_USE_BOOST be defined by the user which would force the use
of the Boost library even in C++11 mode. I have also contemplated a
convenient BOOST_CPP_USE_BOOST macro being defined by the end-user which
would force the use of a Boost library for any XXX library in C++11
mode. Programming this idea into my macro system is trivial.

But suppose compiling in C++11 mode one TU has BOOST_CPP_XXX_USE_BOOST
defined and another TU does not and both include some interface affected
by this decision.

I think in this case KISS is better than the kiss of death <g>.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 18:16:03 UTC
Permalink
On 6/7/2015 1:04 PM, John Maddock wrote:
>
>
> On 07/06/2015 15:36, Peter Dimov wrote:
>> Edward Diener wrote:
>>> Most of the talk about the problems of my macro system presupposes
>>> that programmers using Boost will mistakenly try to use a C++11
>>> version of a library during a C++03 mode build and vice versa, and
>>> therefore the system must be flawed.
>>
>> This was some of the talk but I'm not sure about "most". A substantial
>> part of the talk was about programmers wanting to use boost::regex
>> even when the compiler happens to be in C++11 mode. In other words,
>> talk that challenges your assumption that
>>
>>> If the end-user of my library is compiling in C++11 mode is it more
>>> likely that his use of regex will be std::regex or boost::regex ? IMO
>>> it is the former.
>>
>> There are several good reasons to prefer boost::regex. First, the one
>> I pointed out, you want to maintain a single code base that compiles
>> under C++03 and C++11. Second, you want to use boost::regex's
>> extensions that std::regex doesn't have. Third, you want predictable
>> performance that is independent of the standard library in use.
>>
> Right. But if lib X prefers/needs to use the Boost version always, they
> don't have to use this mechanism.

Of course. The mechanism is completely optional.

>> On the other side of the coin, we have the desire to avoid use of
>> Boost when use of standard facilities would suffice, which is real and
>> legitimate. However, in my experience at least, this desire is only
>> strong when you can avoid use of Boost _altogether_, which is not the
>> case under discussion.
> Right, we're nowhere near having a package manager that's smart enough
> to avoid dependence on boost::whatever if the user tells it they have a
> C++11 compiler.

Boost doesn't have a package manager to begin with so I am not sure what
the above means.

>
> I guess my concerns are somewhat different from those already expressed:
>
> * I'm not sure that this adds much over the existing macros
> BOOST_NO_CXX11_HDR_REGEX etc.

I am obviously using BOOST_NO_CXX11_HDR_REGEX for regex. I don't make
any attempt to hide this. The current BOOST_CPP_HAS_REGEX is, I believe,
a friendlier name of finding out if the C++ standard library regex is
available than BOOST_NO_CXX11_HDR_REGEX but that is not the issue. On
top of BOOST_NO_CXX11_HDR_REGEX I have built the simple
BOOST_CPP_REGEX_HDR and BOOST_CPP_REGEX_NS macros and I seek to
regularize this sort of naming for each library. It's not rocket science
but I think it has value rather than everybody inventing this as a
one-off situation for their own use. But of course that's my point of
view as the inventor and I am biased.

> * If this evolved into a more "complete" solution, then (a) It doesn't
> belong in Config (too many dependencies), and (b) I would worry that we
> repeat the mistake of Boost.TR1 - which is to say creating that
> particular unmaintainable monster it in the first place -just ask the
> author ;)

I don't think a more complete solution at the level I have specified is
needed. if any further solution is needed it would be the ability, on
demand, to name a non-header only library slightly differently whether
or not that library is built in C++11 mode or not, and to link to the
correct library name depending on C++11 mode. It seems the auto-link
code in config could accomodate that for compilers that support
auto-linking, but wouldn't any change have to be synced to changes in
Boost Build ? For non-autolink compilers how is the library name
generated ? Is it done in Boost Build or is it wholly decided by the
programmer in a jam script ? I really don't know all these things but I
suspect that you do and/or the Boost Build experts do.

> * Folks are correct to be concerned about ABI issues: we not that long
> ago changed 'nix installs to install "one true binary" for each library
> as there was *very* strong user preference for that. Splitting into '03
> and '11 binaries is IMO a significant retrograde step. If you do that
> expect endless newbie support requests wondering why things don't work.

First splitting binaries into C++03 and C++11 libs should only be done
on demand for non-header only libraries that want to use my macro
system. Secondly if the names are different the documentation explains
what each variation is and it is up to the end-user to understand and
use appropriately. If Boost Build automatically links the correct
binary, as I believe it now does for our current naming scheme where we
have different names for different variations of the same library, then
the end-user should not have any problems.

For any library program-wise I think it is fairly simple and I should
have documented this better. If my own Boost library, called it EDS_LIB,
uses my macro system for, let's say, regex, in one of its public
interfaces, then any other module interfaces with EDS_LIB by hardcoding
neither boost::regex or std::regex but BOOST_CPP_REGEX_NS::regex instead
whenever it has to interact with my interface. Whatever compiler mode
they are using, whether C++03 or C++11, it just works. Of course if they
are using boost::regex everywhere else and they are forced by my macro
system to use BOOST_CPP_REGEX_NS::regex and in C++11 mode that means
std::regex, it's a real PITA. But that is no different than someone
designing a library for C++11 use, using std::regex in a public
interface, only to find out that another module compiling in C++11 mode
is happily using boost::regex everywhere else but wants to use that library.

>
> On the other hand:
>
> * I can see a legitimate use for this as a library internal (rather like
> what Math does with std::tuple and boost::tuple).
> * The need to have different linking requirements in Boost.Build is a
> solved issue - just use check_target_builds to set the dependency.
>
> So... I guess what I would like to see expressed, is what are the
> concrete use cases for this? What do *you* want to use it for?

I see these options realistically for Boost library developers:

1) We can continue to use public interfaces in our libraries that use
other Boost libraries as the LCD, even if the C++ standard has a pretty
close equivalent. Programmers compiling in C++11 mode, and inevitably
there will be more as time goes on, who use the C++ standard library
equivalents of Boost libraries, and inevitably there will be more using
these equivalents as time goes on, may well be irritated about this
situation. But if we view that as their problem and not ours, this is
the obvious option.

2) We can design totally separate implementations of the same library,
one to be used for C++11 and using C++ standard library equivalents in
public interfaces, the other to be used for C++03 and using the
equivalent Boost libraries in their public interfaces.

3) We can support our public interfaces with both the C++ standard
library equivalent ( in C++11 mode ) and the Boost library equivalent,
so as to accomodate end-users.

4) We can use the macro system I have created.

Realistically 2) or 3) is an awful amount of work, which I as a
developer would not want to do.

>
> And finally, you are aware that there are 3 tuples available? boost::,
> fusion:: and std::, and they they all are slightly different? Oh and
> std::tr1::tuple too ;)
>

Yes I am aware. It is certainly permissible to say: this is my interface
and if you want to use my library this is what you will use. We all do
that as programmers. I just thought we could be a little more user
friendly as C++11 becomes more of the norm for C++ programmers ( he
ducks <g> ).

> What I suspect we will see more of, is libraries becoming implementation
> agnostic - "give me something that looks like a
> tuple/thread/future/function and I'll go off and do the right thing".
> The latest Math code does that with tuple types, and it was a pain in
> the neck to get working (or possibly I was just being dense at the
> time), certainly the hoops you have to jump through to support that go
> way beyond the scope of this addition.

I hate to re-invent the wheel.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Niall Douglas
2015-06-07 23:17:16 UTC
Permalink
On 7 Jun 2015 at 14:16, Edward Diener wrote:

> I see these options realistically for Boost library developers:
>
> 1) We can continue to use public interfaces in our libraries that use
> other Boost libraries as the LCD, even if the C++ standard has a pretty
> close equivalent. Programmers compiling in C++11 mode, and inevitably
> there will be more as time goes on, who use the C++ standard library
> equivalents of Boost libraries, and inevitably there will be more using
> these equivalents as time goes on, may well be irritated about this
> situation. But if we view that as their problem and not ours, this is
> the obvious option.
>
> 2) We can design totally separate implementations of the same library,
> one to be used for C++11 and using C++ standard library equivalents in
> public interfaces, the other to be used for C++03 and using the
> equivalent Boost libraries in their public interfaces.
>
> 3) We can support our public interfaces with both the C++ standard
> library equivalent ( in C++11 mode ) and the Boost library equivalent,
> so as to accomodate end-users.
>
> 4) We can use the macro system I have created.
>
> Realistically 2) or 3) is an awful amount of work, which I as a
> developer would not want to do.

5) We can use APIBind to enable Boost library users to easily inject
which dependencies a library uses from the outside, where each
possible configuration of that library gets its own ABI thus ensuring
that impossible or dangerous combinations fail to link and the
compiler will refuse to pass ABI incompatible implementations into
one another.

6) We can use APIBind to enable a Boost library to be C++ 98
compatible as part of Boost or be C++ 11 mandatory and no longer
require any Boost, with an identical source code base for both config
options. Also with ABI safety.

> [snip]
> I hate to re-invent the wheel.

APIBind comes at the C++ 11 problem from the outside coming in. Yours
comes from inside Boost going out. Like your solution, APIBind is
proven working solution which should be better understood by the
community soon at the end of July during the AFIO review, and there
is a C++ Now presentation with 90 minutes on just APIBind, with
plenty of valuable audience commentary by WG21 members and long time
Boost community members.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/
http://ie.linkedin.com/in/nialldouglas/
Edward Diener
2015-06-08 02:07:00 UTC
Permalink
On 6/7/2015 7:17 PM, Niall Douglas wrote:
> On 7 Jun 2015 at 14:16, Edward Diener wrote:
>
>> I see these options realistically for Boost library developers:
>>
>> 1) We can continue to use public interfaces in our libraries that use
>> other Boost libraries as the LCD, even if the C++ standard has a pretty
>> close equivalent. Programmers compiling in C++11 mode, and inevitably
>> there will be more as time goes on, who use the C++ standard library
>> equivalents of Boost libraries, and inevitably there will be more using
>> these equivalents as time goes on, may well be irritated about this
>> situation. But if we view that as their problem and not ours, this is
>> the obvious option.
>>
>> 2) We can design totally separate implementations of the same library,
>> one to be used for C++11 and using C++ standard library equivalents in
>> public interfaces, the other to be used for C++03 and using the
>> equivalent Boost libraries in their public interfaces.
>>
>> 3) We can support our public interfaces with both the C++ standard
>> library equivalent ( in C++11 mode ) and the Boost library equivalent,
>> so as to accomodate end-users.
>>
>> 4) We can use the macro system I have created.
>>
>> Realistically 2) or 3) is an awful amount of work, which I as a
>> developer would not want to do.
>
> 5) We can use APIBind to enable Boost library users to easily inject
> which dependencies a library uses from the outside, where each
> possible configuration of that library gets its own ABI thus ensuring
> that impossible or dangerous combinations fail to link and the
> compiler will refuse to pass ABI incompatible implementations into
> one another.
>
> 6) We can use APIBind to enable a Boost library to be C++ 98
> compatible as part of Boost or be C++ 11 mandatory and no longer
> require any Boost, with an identical source code base for both config
> options. Also with ABI safety.
>
>> [snip]
>> I hate to re-invent the wheel.
>
> APIBind comes at the C++ 11 problem from the outside coming in. Yours
> comes from inside Boost going out. Like your solution, APIBind is
> proven working solution which should be better understood by the
> community soon at the end of July during the AFIO review, and there
> is a C++ Now presentation with 90 minutes on just APIBind, with
> plenty of valuable audience commentary by WG21 members and long time
> Boost community members.

APIBind is not finished AFAICS and I do not even remotely understand the
documentation you currently have for it. If others find it usable to
solve this problem that is fine by me.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Niall Douglas
2015-06-08 22:44:47 UTC
Permalink
On 7 Jun 2015 at 22:07, Edward Diener wrote:

> >> I hate to re-invent the wheel.
> >
> > APIBind comes at the C++ 11 problem from the outside coming in. Yours
> > comes from inside Boost going out. Like your solution, APIBind is
> > proven working solution which should be better understood by the
> > community soon at the end of July during the AFIO review, and there
> > is a C++ Now presentation with 90 minutes on just APIBind, with
> > plenty of valuable audience commentary by WG21 members and long time
> > Boost community members.
>
> APIBind is not finished AFAICS and I do not even remotely understand the
> documentation you currently have for it. If others find it usable to
> solve this problem that is fine by me.

A step by step explanation of how it works and feature organisation
is in the slides at
https://github.com/boostcon/cppnow_presentations_2015/raw/master/files
/A-review-of-Cxx-11-14-only-Boost-libraries-Fiber-AFIO-DI-and-APIBind.
pdf

Rationale is at
https://svn.boost.org/trac/boost/wiki/BestPracticeHandbook#a16.COUPLIN
G:Considerallowingyourlibraryuserstodependencyinjectyourdependencieson
otherlibraries

What remains lacking is a step by step tutorial, but it's hardly
difficult. I noticed at C++ Now I didn't find anyone didn't fully
understand what was going on and how it worked, indeed Beman
mentioned the same technique had been in use in C++ 11 standard
library implementations for many years now.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/
http://ie.linkedin.com/in/nialldouglas/
Edward Diener
2015-06-09 00:16:46 UTC
Permalink
On 6/8/2015 6:44 PM, Niall Douglas wrote:
> On 7 Jun 2015 at 22:07, Edward Diener wrote:
>
>>>> I hate to re-invent the wheel.
>>>
>>> APIBind comes at the C++ 11 problem from the outside coming in. Yours
>>> comes from inside Boost going out. Like your solution, APIBind is
>>> proven working solution which should be better understood by the
>>> community soon at the end of July during the AFIO review, and there
>>> is a C++ Now presentation with 90 minutes on just APIBind, with
>>> plenty of valuable audience commentary by WG21 members and long time
>>> Boost community members.
>>
>> APIBind is not finished AFAICS and I do not even remotely understand the
>> documentation you currently have for it. If others find it usable to
>> solve this problem that is fine by me.
>
> A step by step explanation of how it works and feature organisation
> is in the slides at
> https://github.com/boostcon/cppnow_presentations_2015/raw/master/files
> /A-review-of-Cxx-11-14-only-Boost-libraries-Fiber-AFIO-DI-and-APIBind.
> pdf
>
> Rationale is at
> https://svn.boost.org/trac/boost/wiki/BestPracticeHandbook#a16.COUPLIN
> G:Considerallowingyourlibraryuserstodependencyinjectyourdependencieson
> otherlibraries
>
> What remains lacking is a step by step tutorial, but it's hardly
> difficult. I noticed at C++ Now I didn't find anyone didn't fully
> understand what was going on and how it worked, indeed Beman
> mentioned the same technique had been in use in C++ 11 standard
> library implementations for many years now.

Thanks for the links. I admit I get frustrated when documentation starts
off explaining to me how to use XXX without telling me what XXX is about
first.

If the only thing lacking is a step by step tutorial wouldn't it be
better to remove the "What state is this tool in ?" in your readme.md
which implies that what you are doing is not close to being finished ?


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Niall Douglas
2015-06-10 10:47:32 UTC
Permalink
On 8 Jun 2015 at 20:16, Edward Diener wrote:

> > What remains lacking is a step by step tutorial, but it's hardly
> > difficult. I noticed at C++ Now I didn't find anyone didn't fully
> > understand what was going on and how it worked, indeed Beman
> > mentioned the same technique had been in use in C++ 11 standard
> > library implementations for many years now.
>
> Thanks for the links. I admit I get frustrated when documentation starts
> off explaining to me how to use XXX without telling me what XXX is about
> first.
>
> If the only thing lacking is a step by step tutorial wouldn't it be
> better to remove the "What state is this tool in ?" in your readme.md
> which implies that what you are doing is not close to being finished ?

I didn't want to overpromise what is there and what it can do.

There is also the question of buy in. If the community buys into
APIBind, then it's worth finishing it to Boost quality standards. If
there isn't the interest, then it can remain as a personal private
library standalone modularity toolkit only I use.

tl;dr; If other people start using APIBind then I'll see plenty of
reason to finish it. Otherwise I don't know if I'm solving a problem
anyone else has.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/
http://ie.linkedin.com/in/nialldouglas/
Rob Stewart
2015-06-07 11:31:04 UTC
Permalink
On June 6, 2015 3:30:54 PM EDT, Edward Diener <***@tropicsoft.com> wrote:
> On 6/6/2015 12:14 PM, Niall Douglas wrote:
> > On 5 Jun 2015 at 5:30, Edward Diener wrote:
> >
> > My only real worry is the ABI problems. You need to permute the
> > symbols being linked to avoid config mismatches colliding in an
> > unhelpful way.
>
> The issue as far as ABI comes down to the ability of using such a
> dual-mode library that is a built library and is not a header only
> library.
>
> My point of view is that Boost needs to establish a way so that a
> library built in C++03 mode could be named slightly differently from
> the
> same library built in C++11 mode. We already have a system in place
> which can name a library differently depending on whether it uses the
> dynamic or static RTL of its implementation, or whether the library
> itself is a static lib or a shared lib, among other naming
> conventions.
> What I am positing for a built library is that the developer of that
> library should have the ability to specify that his library have a
> different name depending on whether it is C++03 or C++11 mode, and
> that
> this choice should work so that the correct name is used during both a
>
> link of the library and when that library is being used by another
> library.

I see a problem of combinations here. If a given library depends upon several different boost/std namespace components, it will probably switch among them consistently (all Boost or all Standard Library). But if that library always chooses to use a Boost library to get some extension it provides, and that library switches things incompatibly with the first library (or doesn't switch at all), problems will ensue.

These problems might be checked at runtime via version tests. The symbol check Niall mentions below is similar. At any rate, a library naming convention won't solve the problem unless there's a way to poison combining them in the wrong way.

> > Perhaps for each config macro have during build the library output
> an
> > extern dll visible empty function with a mangled name representing
> > the config. On use, import and use that function. This should
> > generate link errors if one is trying to use a config against a
> > binary not built the same way.

___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Edward Diener
2015-06-07 16:43:53 UTC
Permalink
On 6/7/2015 7:31 AM, Rob Stewart wrote:
> On June 6, 2015 3:30:54 PM EDT, Edward Diener <***@tropicsoft.com> wrote:
>> On 6/6/2015 12:14 PM, Niall Douglas wrote:
>>> On 5 Jun 2015 at 5:30, Edward Diener wrote:
>>>
>>> My only real worry is the ABI problems. You need to permute the
>>> symbols being linked to avoid config mismatches colliding in an
>>> unhelpful way.
>>
>> The issue as far as ABI comes down to the ability of using such a
>> dual-mode library that is a built library and is not a header only
>> library.
>>
>> My point of view is that Boost needs to establish a way so that a
>> library built in C++03 mode could be named slightly differently from
>> the
>> same library built in C++11 mode. We already have a system in place
>> which can name a library differently depending on whether it uses the
>> dynamic or static RTL of its implementation, or whether the library
>> itself is a static lib or a shared lib, among other naming
>> conventions.
>> What I am positing for a built library is that the developer of that
>> library should have the ability to specify that his library have a
>> different name depending on whether it is C++03 or C++11 mode, and
>> that
>> this choice should work so that the correct name is used during both a
>>
>> link of the library and when that library is being used by another
>> library.
>
> I see a problem of combinations here. If a given library depends upon several different boost/std namespace components, it will probably switch among them consistently (all Boost or all Standard Library). But if that library always chooses to use a Boost library to get some extension it provides, and that library switches things incompatibly with the first library (or doesn't switch at all), problems will ensue.

If my interface to my library uses my macro system for a particular
Boost library, and you interface to my library then you should use the
same macro system for that interface. But outside that interface you can
use what you want.

This is absolutely no different from this situation: you are compiling
in C++11 mode and using std::xxx and some Boost library uses boost::xxx
instead in its interface. What do you do ?

I honestly don't mind and do understand the opinion that a Boost library
should always use another Boost library rather than its C++ standard
library equivalent in its public interfaces as the LCD that will work
with C++03 and C++11. I just don't think this scales well as more C++
programmers use C++11 and find themselves using the C++ standard
libraries in their code. My macro system is an attempt to accomodate
that situation in C++'s future, which I view as inevitable.

>
> These problems might be checked at runtime via version tests. The symbol check Niall mentions below is similar. At any rate, a library naming convention won't solve the problem unless there's a way to poison combining them in the wrong way.
>
>>> Perhaps for each config macro have during build the library output
>> an
>>> extern dll visible empty function with a mangled name representing
>>> the config. On use, import and use that function. This should
>>> generate link errors if one is trying to use a config against a
>>> binary not built the same way.



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Vicente J. Botet Escriba
2015-06-07 08:39:06 UTC
Permalink
Le 05/06/15 09:41, John Maddock a écrit :
> There is a pull-request for Config to provide support for switching
> between boost:: and std:: library equivalents:
> https://github.com/boostorg/config/pull/63
>
> My questions are:
>
> * Is this the right approach? And,
> * Is Boost.Config the right place for it?
>
This PR makes Boost.Config depend on all the related Boost libraries
creating a whole cycle and modularity will be broken.

It would suggest to have some kind of Boost.Std library with different
versions c++11/c++14 and why not TSs.

However the concerned libraries couldn't use this library without adding
cycles :(

Having a sub-library for each file Boost.Std/Regex would make it
possible for a Boost library to use these sub-libraries without adding
cycles.

An alternative is to add these files in the concerned libraries, e.g.
boost/regex/std/regex.hpp

Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Andrey Semashev
2015-06-07 10:25:22 UTC
Permalink
On 07.06.2015 11:39, Vicente J. Botet Escriba wrote:
> Le 05/06/15 09:41, John Maddock a écrit :
>> There is a pull-request for Config to provide support for switching
>> between boost:: and std:: library equivalents:
>> https://github.com/boostorg/config/pull/63
>>
>> My questions are:
>>
>> * Is this the right approach? And,
>> * Is Boost.Config the right place for it?
>>
> This PR makes Boost.Config depend on all the related Boost libraries
> creating a whole cycle and modularity will be broken.

These headers don't add a dependency since they don't include headers of
the related libraries. They only define macros.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/li
Edward Diener
2015-06-07 13:14:51 UTC
Permalink
On 6/7/2015 4:39 AM, Vicente J. Botet Escriba wrote:
> Le 05/06/15 09:41, John Maddock a écrit :
>> There is a pull-request for Config to provide support for switching
>> between boost:: and std:: library equivalents:
>> https://github.com/boostorg/config/pull/63
>>
>> My questions are:
>>
>> * Is this the right approach? And,
>> * Is Boost.Config the right place for it?
>>
> This PR makes Boost.Config depend on all the related Boost libraries
> creating a whole cycle and modularity will be broken.

The PR just adds macros. It does not add dependencies to Boost.config.

>
> It would suggest to have some kind of Boost.Std library with different
> versions c++11/c++14 and why not TSs.
>
> However the concerned libraries couldn't use this library without adding
> cycles :(
>
> Having a sub-library for each file Boost.Std/Regex would make it
> possible for a Boost library to use these sub-libraries without adding
> cycles.
>
> An alternative is to add these files in the concerned libraries, e.g.
> boost/regex/std/regex.hpp




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Loading...