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

Reply via email to