📄 interface.hpp
字号:
// (C) Copyright Tobias Schwinger//// Use modification and distribution are subject to the boost Software License,// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).//------------------------------------------------------------------------------//// This example implements interfaces. // // Detailed description// ====================//// An interface is a collection of member function prototypes that may be// implemented by classes. Objects of classes that implement the interface can // then be assigned to an interface variable through which the interface's // functions can be called.//// Interfaces are a feature of the Java programming language [Gosling] and the// most obvious way to model interfaces in C++ is (multiple) inheritance.// Using inheritance for this purpose, however, is neither the most efficient // nor the most flexible solution, because://// - all functions must be virtual,//// => a function that calls another function of the interface must do so// via virtual dispatch (as opposed to inlining)// => a class can not implement an interface's (overloaded) function via// a function template//// - inhertitance is intrusive//// => object size increases // => client's are always polymorphic// => dependencies cause tighter coupling//// Fortunately it is possible to eliminate all the drawbacks mentioned above// based on an alternative implementation proposed by David Abrahams. // We'll add some detail to the original scheme (see [Abrahams]) such as // support for overloaded and const qualified functions.// The implementation in this example uses Boost.FunctionTypes to shift // metaprogramming code from the preprocessor into templates, to reduce // preprocessing time and increase maintainability.//// // Limitations// ===========//// There is no lifetime management as implemented by the Boost candidate// Interfaces library (see [Turkanis]).//// This example does not compile with Visual C++. Template argument deduction// from the result of the address-of operator does not work properly with this// compiler. It is possible to partially work around the problem, but it isn't// done here for the sake of readability.////// Bibliography// ============//// [Gosling] Gosling, J., Joy, B., Steele, G. The Java Language Specification// http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html//// [Abrahams] Abrahams, D. Proposal: interfaces, Post to newsgroup comp.std.c++// http://groups.google.com/group/comp.std.c++/msg/85af30a61bf677e4//// [Turkanis] Turkanis, J., Diggins, C. Boost candidate Interfaces library// http://www.kangaroologic.com/interfaces/libs/interfaces/doc/index.html#include <cstddef>#include <boost/function_types/function_pointer.hpp>#include <boost/function_types/member_function_pointer.hpp>#include <boost/config.hpp>#include <boost/detail/workaround.hpp>#include <boost/utility/addressof.hpp>#include <boost/mpl/at.hpp>#include <boost/mpl/vector.hpp>#include <boost/mpl/joint_view.hpp>#include <boost/mpl/single_view.hpp>#include <boost/mpl/transform_view.hpp>#include <boost/preprocessor/seq/seq.hpp>#include <boost/preprocessor/seq/enum.hpp>#include <boost/preprocessor/seq/elem.hpp>#include <boost/preprocessor/seq/size.hpp>#include <boost/preprocessor/tuple/elem.hpp>#include <boost/preprocessor/arithmetic/dec.hpp>#include <boost/preprocessor/arithmetic/inc.hpp>#include <boost/preprocessor/facilities/empty.hpp>#include <boost/preprocessor/facilities/identity.hpp>#include <boost/preprocessor/punctuation/comma_if.hpp>#include <boost/preprocessor/iteration/local.hpp>#include <boost/preprocessor/repetition/enum.hpp>#include <boost/preprocessor/repetition/enum_params.hpp>#include <boost/preprocessor/repetition/enum_binary_params.hpp>#include <boost/preprocessor/repetition/enum_trailing_params.hpp>#include "detail/param_type.hpp"namespace example { namespace ft = boost::function_types; namespace mpl = boost::mpl; using namespace mpl::placeholders; // join a single type and an MPL-sequence // in some ways similar to mpl::push_front (but mpl::push_front requires // an MPL Extensible Sequence and this template does not) template<typename T, typename Seq> struct concat_view : mpl::joint_view<mpl::single_view<T>, Seq> { }; // metafunction returning a function pointer type for a vtable entry template<typename Inf> struct vtable_entry : ft::function_pointer < concat_view< typename Inf::result, mpl::transform_view< typename Inf::params, param_type<_> > > > { }; // the expression '& member<MetaInfo,Tag>::wrap<& Class::Function> ' in an // assignment context binds the member function Function of Class with the // properties described by MetaInfo and Tag to the corresponding vtable // entry template<typename Inf, typename Tag> struct member { typedef typename ft::member_function_pointer < concat_view<typename Inf::result,typename Inf::params>,Tag >::type mem_func_ptr; typedef typename mpl::at_c<typename Inf::params,0>::type context; template<mem_func_ptr MemFuncPtr> static typename Inf::result wrap(void* c) { return (reinterpret_cast<context*>(c)->*MemFuncPtr)(); } template<mem_func_ptr MemFuncPtr, typename T0> static typename Inf::result wrap(void* c, T0 a0) { return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0); } template<mem_func_ptr MemFuncPtr, typename T0, typename T1> static typename Inf::result wrap(void* c, T0 a0, T1 a1) { return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0,a1); } // continue with the preprocessor (the scheme should be clear, by now) #define BOOST_PP_LOCAL_MACRO(n) \ template<mem_func_ptr MemFuncPtr, BOOST_PP_ENUM_PARAMS(n,typename T)> \ static typename Inf::result wrap(void* c, \ BOOST_PP_ENUM_BINARY_PARAMS(n,T,a)) \ { \ return (reinterpret_cast<context*>(c)->*MemFuncPtr)( \ BOOST_PP_ENUM_PARAMS(n,a) ); \ } #define BOOST_PP_LOCAL_LIMITS (3,BOOST_FT_MAX_ARITY-1) #include BOOST_PP_LOCAL_ITERATE() }; // extract a parameter by index template<typename Inf, std::size_t Index> struct param : param_type< typename mpl::at_c< typename Inf::params,Index>::type > { };}// the interface definition on the client's side#define BOOST_EXAMPLE_INTERFACE(name,def) \ class name \ { \ struct vtable \ { \ BOOST_EXAMPLE_INTERFACE__MEMBERS(def,VTABLE) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -