Boost logo

Boost :

Subject: [boost] [pimpl] Preliminary Review
From: Gregory Crosswhite (gcross_at_[hidden])
Date: 2011-05-26 22:07:30


Hey everyone,

Here are my preliminary thoughts regarding the pimpl library.

First, I like the idea of having it or something similar to it be part
of Boost because the functionality seems like it would be useful in a
lot of cases. One of the strengths of including such a library in boost
in my opinion is that it will appear in the "Libraries" list, which
means that more people will be exposed to the idiom and will think of it
as a possible option than they would otherwise. Put another way, Boost
is both a collection of libraries and of best practices, so a good pimpl
implementation belongs in boost even if it is a relatively small one.

Now the question is whether this particular implementation itself is
good enough. Honestly, I have trouble figuring out exactly what it does
except by reading through the code since the documentation itself
doesn't say what it does behind the scenes except to say vaguely that it
implements "pointer semantics" or "value semantics". So one thing that
the documentation really needs (among the many others that have been
mentioned) is a section that clearly lists the features that it offers.

One objection that Artyom reasonably raised is that this implementation
may try to do too much, and doesn't offer much in the way of
customization. However, people like Artyom are most likely going to be
rolling their own implementation of the pimpl idiom anyway. I think
that it is sufficient that a implementation be "good enough" for an
ordinary user's needs that they won't have to think about any of the
ugly details since it does all of that work for them, and to the extent
that this is true of the current implementation

Now for my thoughts on the code itself. Two of the classes in the
implementation should probably be reviewed separately and put in
different Boost libraries rather than the Pimpl library, namely safebool
and value_semantics_ptr.

safebool is an interesting solution to the problem that implicit
conversions to the "bool" type implies implicit conversions to hosts of
other types such as integers which can result in all sorts of
unexpected behaviors that will bite you when you least expect it.
safebool solves this problem by providing a convenient way for you to
implement an effective "bool()" by instead implementing an operator that
returns a special function-pointer that is specialized to your class and
thus is equal neither in type nor value to a safebool for any other
class; a minor cost that is presumably incurred by this is that a small
amount of code will be added to the binary for this special no-op
function, since I don't see how this can be optimized away. The
implementation looks straightforward and the comments contain good
documentation explaining both the usage and the rationale. I would
recommend that safebool be accepted into boost and added to the
utilities library on its own merits.

value_semantics_ptr is a class that contains a pointer to data (or
possibly a null pointer) and has the semantics that upon assignment it
copies the data from another pointer, allocating (or freeing) its
internal pointer if necessary. I think that this is a good idea and
that something like this belongs in boost, but I suggest that the
current implementation should be changed at least as follows before
being accepted:

First, it should be taken out of the pimpl<> class and made independent.

Second, the traits struct member should be changed from a derived class
to a second parameter in the list of template arguments to the
value_semantics_ptr type, with the deep_copy member being pulled outside
and being made the default value of the new second template argument.
Alternatively, a type function --- e.g., copy_traits<T> --- could be
used instead.

Third, if Boost::Move is going to be ready soon it would be ideal if
this class could be modified to support it in order to potentially save
some extraneous copies.

Fourth, one of the methods confuses me and apparently also the author:

     bool operator<(value_semantics_ptr const& that) const
     {
         return this->impl_ < that.impl_;
         // Should it be "*this->impl_ < *that.impl_" instead?
     }

so this should be finalized.

Fifth, the implementation will need to be fleshed out. operators such
as * (dereference) and -> will need to be added, as well as some
additional typedefs such as value, pointer, reference, etc. Operator
safebool() will also need to be added.

In conclusion, if pimpl is accepted I think it would be better for there
to be a polished value_semantics_ptr that we feel comfortable having be
directly tested and exposed to users be the back-end of this class than
something hidden away, so when value_semantics_ptr is ready I think that
it should ultimately be accepted to the Smart Ptr library.

So much for safebool and value_semantics_ptr, now on to pimpl itself.

The code looks straightforward and the comments document it reasonably
well --- in fact, the ratio of comments to code in the main pimpl class
is roughly 2:1, and in that count I was lazily including whitespace and
single { and } lines as code lines, so that gives you a sense of how
heavily it is commented. I have only taken a quick glance through it
since this is a pre-review, but it all looks simple and straightforward
to me, and it does a good job of generating tedious boilerplate so the
user doesn't have to, exactly as it claims. On a side note, one
additional set of semantics that I would recommend adding is move
semantics, which could be implemented using the Boost::Move library.

In conclusion, I think that this library should be broken into parts
with safebool being put in utilities, value_semantics_ptr (and we can
bikeshed over the name here of course :-) ) being put in smart ptr, and
pimpl being put in a separate library. After this is done pimpl will be
quite small, but I think that it pulls enough weight that it is
nonetheless useful. To repeat what I said earlier, boost is not just a
repository of libraries but of C++ best practices, so even if pimpl is
small if it does a good job of capturing the pimpl idiom I still think
that it should be accepted into Boost.

Cheers,
Greg


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk