|
Boost Users : |
Subject: Re: [Boost-users] Avoiding reinventing the wheel for a public api with binary compatibility in mind
From: Geoff Hilton (geoff.hilton_at_[hidden])
Date: 2009-11-05 11:59:21
OvermindDL1 wrote:
> On Wed, Nov 4, 2009 at 6:52 PM, Nigel Rantor <wiggly_at_[hidden]> wrote:
>> Geoff Hilton wrote:
>>> I'm writing a public api for a product which will be bundled as a
>>> precompiled dll or binary and one of my goals is binary compatibility (if
>>> not across major versions, at least across minor). I'd like to implement the
>>> pimpl idiom and reference counting for the handle classes as appropriate,
>>> but I'm worried about all the typical stuff (exception safety, memory leaks,
>>> etc) and I'd rather not reinvent the wheel.
>>>
>>> eg.
>>> template<typename T>
>>> class MyClass {
>>> public:
>>> T foo();
>>> private:
>>> boost::shared_ptr<MyClassImpl<T> > impl;
>>> };
>>>
>>> Using boost::shared_ptr would be great, but this means clients of my code
>>> would have to have the same version of boost installed that we use, and I
>>> imagine this could cause conflicts in the event that they happen to use
>>> boost (and a different version of it). I'd rather not include more code
>>> dependencies than I absolutely have to, especially if they may prove
>>> problematic in the future. What do I do? I know I'm not the first in this
>>> situation. How often have others opted for this dependency as opposed to
>>> furnishing their own alternative that would avoid additional dependencies
>>> (at the expense of the benefit of time-tested code)?
>> One way around this is to include the boost libraries you require in your
>> own distribution with the top-level namespace appropriately renamed. Yes,
>> this is ugly, it means distributing the code and modifying it so that all
>> the namespaces are different.
>>
>> e.g. boost::shared_ptr -> boost_1_38::shared_ptr
>>
>> Within your own code you can use a namespace alias to make it easier to move
>> to new versions of boost as and when required.
>>
>> e.g. namespace geoff_boost = boost_1_38;
>>
>> Then use geoff_boost::* within your own code. You can then move your own
>> code to new versions of boost by changing that single alias.
>>
>> Externally you can provide typedefs to smart_ptr classes.
>>
>> e.g.
>> namespace package
>> {
>> class foo;
>> typedef geoff_boost::smart_ptr<foo> foo_ptr
>> }
>>
>> So clients of the library deal with names like package::foo_ptr and have no
>> idea that behind the scenes you're using a specific version of boost hidden
>> behind a couple of namepsaces...
>>
>> It's a trade-off - you have to do something nasty, but the client gets to
>> see nice names, you get to re-use solid code but you'll have to live with
>> the dirty feeling of modifying the boost headers (a perl script or two, so
>> you can do it automatically for a new version) and re-distributing them.
>
> The tool "bcp" that comes with boost can take out parts of Boost that
> you want to include in your projects, and as I recall it can also
> rename namespaces automatically (either that or it is a feature being
> worked on).
bcp sounds interesting but according to
http://www.boost.org/doc/libs/1_40_0/tools/bcp/bcp.html (which happens
to use boost::shared_ptr as an example), using it would pull in 274
header dependencies.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net