Here's an example I just cooked up of using the PP lib to solve a
classic C++ OO problem: repeated boilerplate in the definition of
Pimpl classes. Paul, if you want to put it (or something like it) in
the PP lib docs, you're welcome to.
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef PIMPL_DWA200381_HPP
# define PIMPL_DWA200381_HPP
# include <boost/preprocessor/seq/for_each.hpp>
# include <boost/shared_ptr.hpp>
//
// implementation details
//
# define PIMPL_PURE_VIRTUAL(r, _, func) \
virtual func = 0;
# define PIMPL_DISPATCH(r, _, func) \
func;
# define PIMPL_CONSTRUCTOR(r, name, args) \
name args ;
//
// Given a Boost.Preprocessor "Sequence" of function signatures,
// generates the signatures followed by semicolons. This is useful
// for generating declarations of concrete implementations of the
// abstract handle##_impl class (see PIMPL_IMPL_DECL, below). For
// example:
//
// PIMPL_IMPL_DECL(
// (int f() const)
// (void g(double*))
// )
//
// yields:
//
// int f() const;
// void g(double*);
//
// This is unexciting unless you've #defined a macro which contains
// the signatures that you can pass to PIMPL_IMPL_DECL
# define PIMPL_IMPL_DECL(interface) \
BOOST_PP_SEQ_FOR_EACH_R(1, PIMPL_DISPATCH, _, interface)
//
// Given a handle class name, an interface, and a list of constructor
// signatures for the handle, declares a pimpl implementation class
// handle##_impl and the handle class itself. For example:
//
// #define FOO_INTERFACE \
// (int f() const) \
// (void g(double*))
//
// PIMPL_DECL( Foo, FOO_INTERFACE, (()) ((int)) )
//
// yields:
//
// class Foo_impl
// {
// public:
// virtual ~Foo_impl();
// virtual int f() const = 0;
// virtual void g(double*) = 0;
// };
//
// class Foo
// {
// public:
// Foo();
// Foo(int);
//
// int f() const;
// void g(double*);
// };
//
// In an implementation file,
//
// class MyFoo
// {
// PIMPL_IMPL_DECL(FOO_INTERFACE);
// ...
// };
//
// Could be used to declare a concrete implementation.
//
# define PIMPL_DECL(handle, interface, constructors) \
class handle##_##impl \
{ \
public: \
virtual ~name##_##impl(); \
BOOST_PP_SEQ_FOR_EACH_R(1, PIMPL_PURE_VIRTUAL, _, interface) \
}; \
\
class handle \
{ \
public: \
BOOST_PP_SEQ_FOR_EACH_R(1, PIMPL_CONSTRUCTOR, name, constructors) \
PIMPL_IMPL_DECL(interface) \
private: \
boost::shared_ptr<name##_##impl> m_impl; \
};
#endif // PIMPL_DWA200381_HPP
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost