Boost logo

Boost Users :

Subject: Re: [Boost-users] Avoiding reinventing the wheel for a public api with binary compatibility in mind
From: Nigel Rantor (wiggly_at_[hidden])
Date: 2009-11-04 20:52:59


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.

   n


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