// 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 # include // // 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 m_impl; \ }; #endif // PIMPL_DWA200381_HPP