Squashed 'third_party/boostorg/function_types/' content from commit ae4fde2

Change-Id: I946aaade9862a3a50fdce89fbc618c914b0edae6
git-subtree-dir: third_party/boostorg/function_types
git-subtree-split: ae4fde2e2ae88291d6d656137169ff4003d184a1
diff --git a/example/Jamfile b/example/Jamfile
new file mode 100644
index 0000000..08ab43d
--- /dev/null
+++ b/example/Jamfile
@@ -0,0 +1,20 @@
+
+# (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).
+
+#-------------------------------------------------------------------------------
+
+exe  interpreter_example     : interpreter_example.cpp ;
+
+exe  result_of_example       : result_of_example.cpp   ;
+
+exe  interface_example       : interface_example.cpp   ;
+
+exe  fast_mem_fn_example     : fast_mem_fn_example.cpp 
+    : <include>. ; # needed for Boost.PP file iteration with some compilers
+
+exe  macro_type_args_example : macro_type_args_example.cpp ;
+
+
diff --git a/example/detail/param_type.hpp b/example/detail/param_type.hpp
new file mode 100644
index 0000000..7c0fd5f
--- /dev/null
+++ b/example/detail/param_type.hpp
@@ -0,0 +1,71 @@
+
+// (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).
+
+//------------------------------------------------------------------------------
+
+// Metafunction to compute optimal parameter type for argument forwarding. 
+
+// This header is not an FT example in itself -- it's used by some of them to 
+// optimize argument forwarding. 
+//
+// For more details see 'fast_mem_fn.hpp' in this directory or the documentation
+// of the CallTraits utility [1].
+//
+//
+// References
+// ==========
+//
+// [1] http://www.boost.org/libs/utility/call_traits.htm
+
+#ifndef BOOST_UTILITY_PARAM_TYPE_HPP_INCLUDED
+#define BOOST_UTILITY_PARAM_TYPE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+
+#include <boost/mpl/aux_/lambda_support.hpp>
+// #include <boost/type_traits/detail/template_arity_spec.hpp>
+
+// namespace boost
+namespace example
+{
+  namespace mpl = boost::mpl;
+
+  // namespace utility
+  // {
+    namespace param_type_detail
+    {
+      template<typename T>
+      struct by_ref_cond
+      {
+        typedef by_ref_cond type;
+        BOOST_STATIC_CONSTANT(bool,value = sizeof(void*) < sizeof(T));
+      };
+
+      template<typename T>
+      struct add_ref_to_const
+        : boost::add_reference< typename boost::add_const<T>::type >
+      { };
+    }
+
+    template<typename T>
+    struct param_type
+      : mpl::eval_if< param_type_detail::by_ref_cond<T> 
+                    , param_type_detail::add_ref_to_const<T>, mpl::identity<T> >
+    { 
+      BOOST_MPL_AUX_LAMBDA_SUPPORT(1,param_type,(T))
+    };
+  // }
+  // BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,utility::param_type)
+}
+
+#endif
+
diff --git a/example/fast_mem_fn.hpp b/example/fast_mem_fn.hpp
new file mode 100644
index 0000000..2587c18
--- /dev/null
+++ b/example/fast_mem_fn.hpp
@@ -0,0 +1,248 @@
+
+// (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 a very efficient, generic member function wrapper.
+//
+//
+// Detailed description
+// ====================
+//
+// For most platforms C++ runs on (maybe all hardware platforms, as opposed to
+// virtual machines) there are indirect calls that take more time to execute 
+// than direct ones. Further calling a function usually takes more time than 
+// inlining it at the call site.
+//
+// A direct call is a machine instruction that calls a subroutine at a known
+// address encoded in the instruction itself. C++ compilers usually emit one of
+// these instructions for each function call to a nonvirtual function (a call to
+// a virtual function requires either two direct calls or one indirect call).
+// An indirect call is a machine instruction that calls a subroutine at an 
+// address known at runtime. C++ compilers usually emit at least one of these 
+// instructions for a call through a callable builtin variable.
+//
+// It is possible to use callable scalars as non-type template arguments. This
+// way the compiler knows which function we want to call when generating the
+// code for the call site, so it may inline (if it decides to do so) or use a 
+// direct call instead of being forced to use a slow, indirect call.
+//
+// We define a functor class template that encodes the function to call in its
+// type via a non-type template argument. Its (inline declared) overloaded 
+// function call operator calls the function through that non-type template 
+// argument. In the best case we end up inlining the callee directly at the
+// point of the call.
+//
+// Decomposition of the wrapped member function's type is needed in order to 
+// implement argument forwarding (just using a templated call operator we would 
+// encounter what is known as "the forwarding problem" [Dimov1]). Further we
+// can eliminate unecessary copies for each by-value parameter by using a 
+// reference to its const qualified type for the corresponding parameter of the
+// wrapper's function call operator.
+//
+// Finally we provide a macro that does have similar semantics to the function 
+// template mem_fn of the Bind [2] library.
+// We can't use a function template and use a macro instead, because we use a
+// member function pointer that is a compile time constant. So we first have to
+// deduce the type and create a template that accepts this type as a non-type 
+// template argument, which is passed in in a second step. The macro hides this
+// lengthy expression from the user.
+//
+//
+// Limitations
+// ===========
+//
+// The "this-argument" must be specified as a reference.
+//
+//
+// Bibliography
+// ============
+//
+// [Dimov1] Dimov, P., Hinnant H., Abrahams, D. The Forwarding Problem
+//          http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
+//
+// [Dimov2] Dimov, P. Documentation of boost::mem_fn
+//          http://www.boost.org/libs/bind/mem_fn.html
+
+#ifndef BOOST_EXAMPLE_FAST_MEM_FN_HPP_INCLUDED
+#ifndef BOOST_PP_IS_ITERATING
+
+
+#include <boost/function_types/result_type.hpp>
+#include <boost/function_types/function_arity.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/is_member_function_pointer.hpp>
+
+#include <boost/mpl/transform_view.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/deref.hpp>
+
+#include <boost/utility/enable_if.hpp>
+
+#include "detail/param_type.hpp"
+
+namespace example
+{
+
+  namespace ft = boost::function_types;
+  namespace mpl = boost::mpl;
+  using namespace mpl::placeholders;
+
+  // the functor class template
+  template< typename MFPT, MFPT MemberFunction
+    , size_t Arity = ::example::ft::function_arity<MFPT>::value
+  >
+  struct fast_mem_fn;
+
+  // ------- ---- --- -- - - - -
+
+  // deduce type and capture compile time value 
+  #define BOOST_EXAMPLE_FAST_MEM_FN(mfp) \
+      ::example::make_fast_mem_fn(mfp).make_fast_mem_fn<mfp>()
+
+  template<typename MFPT>
+  struct fast_mem_fn_maker
+  {
+    template<MFPT Callee>
+    fast_mem_fn<MFPT,Callee> make_fast_mem_fn()
+    {
+      return fast_mem_fn<MFPT,Callee>();
+    } 
+  };
+
+  template<typename MFPT>
+      typename boost::enable_if<boost::is_member_function_pointer<MFPT>, 
+  fast_mem_fn_maker<MFPT>                                                >::type
+  make_fast_mem_fn(MFPT)
+  {
+    return fast_mem_fn_maker<MFPT>();
+  }
+
+
+  // ------- ---- --- -- - - - -
+
+  namespace detail
+  {
+    // by-value forwarding optimization
+    template<typename T>
+    struct parameter_types
+      : mpl::transform_view<ft::parameter_types<T>,param_type<_> >
+    { }; 
+  }
+
+  // ------- ---- --- -- - - - -
+
+  template< typename MFPT, MFPT MemberFunction >
+  struct fast_mem_fn<MFPT, MemberFunction, 1>
+  {
+    // decompose the result and the parameter types (public for introspection)
+    typedef typename ft::result_type<MFPT>::type result_type;
+    typedef detail::parameter_types<MFPT> parameter_types;
+  private:
+    // iterate the parameter types 
+    typedef typename mpl::begin<parameter_types>::type i0;
+  public: 
+    // forwarding function call operator
+    result_type operator()( typename mpl::deref<i0>::type a0) const
+    {
+      return (a0.*MemberFunction)();
+    };
+  };
+
+  template< typename MFPT, MFPT MemberFunction >
+  struct fast_mem_fn<MFPT, MemberFunction, 2>
+  {
+    // decompose the result and the parameter types (public for introspection)
+    typedef typename ft::result_type<MFPT>::type result_type;
+    typedef detail::parameter_types<MFPT> parameter_types;
+  private:
+    // iterate the parameter types 
+    typedef typename mpl::begin<parameter_types>::type i0;
+    typedef typename mpl::next<i0>::type i1;
+  public: 
+    // forwarding function call operator
+    result_type operator()( typename mpl::deref<i0>::type a0
+                          , typename mpl::deref<i1>::type a1) const
+    {
+      return (a0.*MemberFunction)(a1);
+    };
+  };
+
+  template< typename MFPT, MFPT MemberFunction >
+  struct fast_mem_fn<MFPT, MemberFunction, 3>
+  {
+    // decompose the result and the parameter types (public for introspection)
+    typedef typename ft::result_type<MFPT>::type result_type;
+    typedef detail::parameter_types<MFPT> parameter_types;
+  private:
+    // iterate the parameter types 
+    typedef typename mpl::begin<parameter_types>::type i0;
+    typedef typename mpl::next<i0>::type i1;
+    typedef typename mpl::next<i1>::type i2;
+  public: 
+    // forwarding function call operator
+    result_type operator()( typename mpl::deref<i0>::type a0
+                          , typename mpl::deref<i1>::type a1
+                          , typename mpl::deref<i2>::type a2) const
+    {
+      return (a0.*MemberFunction)(a1,a2);
+    };
+  };
+
+  // ...
+}
+
+// ------- ---- --- -- - - - -
+
+// preprocessor-based code generator to continue the repetitive part, above
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+namespace example
+{
+  #if BOOST_FT_MAX_ARITY >= 4
+  #   define  BOOST_PP_FILENAME_1 "fast_mem_fn.hpp"
+  #   define  BOOST_PP_ITERATION_LIMITS (4,BOOST_FT_MAX_ARITY)
+  #   include BOOST_PP_ITERATE()
+  #endif
+}
+
+#define BOOST_EXAMPLE_FAST_MEM_FN_HPP_INCLUDED
+#else
+
+  #define N BOOST_PP_FRAME_ITERATION(1)
+  template< typename MFPT, MFPT MemberFunction >
+  struct fast_mem_fn<MFPT, MemberFunction, N >
+  {
+    // decompose the result and the parameter types (public for introspection)
+    typedef typename ft::result_type<MFPT>::type result_type;
+    typedef detail::parameter_types<MFPT> parameter_types;
+  private:
+    // iterate the parameter types 
+    typedef typename mpl::begin<parameter_types>::type i0;
+    #define  BOOST_PP_LOCAL_LIMITS (0,N-2)
+    #define  BOOST_PP_LOCAL_MACRO(j) \
+    typedef typename mpl::next< i ## j >::type BOOST_PP_CAT(i,BOOST_PP_INC(j)) ;
+    #include BOOST_PP_LOCAL_ITERATE()
+  public: 
+    // forwarding function call operator
+    result_type operator()( 
+        BOOST_PP_ENUM_BINARY_PARAMS(N, typename mpl::deref<i,>::type a) )  const
+    {
+      return (a0.*MemberFunction)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,a));
+    };
+  };
+  #undef N
+
+#endif
+#endif
+
diff --git a/example/fast_mem_fn_example.cpp b/example/fast_mem_fn_example.cpp
new file mode 100644
index 0000000..381ee14
--- /dev/null
+++ b/example/fast_mem_fn_example.cpp
@@ -0,0 +1,122 @@
+
+// (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).
+
+//------------------------------------------------------------------------------
+// See fast_mem_fn.hpp in this directory for details.
+
+#include <vector>
+#include <cassert>
+#include <iostream>
+#include <algorithm>
+#include <functional>
+
+#include <boost/timer.hpp>
+#include <boost/mem_fn.hpp>
+
+#include "fast_mem_fn.hpp"
+
+// test class that holds a single integer with getter function
+class test
+{
+  int val_id;
+public:
+
+  explicit test(int id)
+    : val_id(id)
+  { }
+
+  int id() const
+  { return val_id; }
+
+};
+
+// STL style comparator that applies the CriterionExtractor function to both 
+// operands and compares the results with Comparator
+template<typename CriterionExtractor, typename Comparator>
+class test_compare
+{
+  CriterionExtractor fnc_criterion;
+  Comparator         fnc_compare;
+public:
+
+  explicit test_compare(CriterionExtractor criterion, Comparator compare)
+    : fnc_criterion(criterion)
+    , fnc_compare(compare)
+  { }
+
+  template<typename T>
+  inline bool operator()(T const & lhs, T const & rhs) const
+  {
+    return fnc_compare(fnc_criterion(lhs),fnc_criterion(rhs));
+  }
+};
+
+// helper function to construct an instance of the test_compare comparator.
+template<typename CriterionExtractor, typename Comparator>
+test_compare<CriterionExtractor,Comparator> 
+make_test_compare(CriterionExtractor criterion, Comparator compare)
+{
+  return test_compare<CriterionExtractor,Comparator>(criterion,compare);
+}
+
+// the test case: sort N test objects by id
+//
+// the objects are in ascending order before the test run and in descending
+// order after it
+
+static const unsigned N = 2000000;
+
+typedef std::vector<test> test_vector;
+
+
+void setup_test(test_vector & v)
+{
+  v.clear();
+  v.reserve(N);
+  for (unsigned i = 0; i < N; ++i)
+    v.push_back(test(i));
+}
+
+template<typename F> void do_test(test_vector & v, F criterion)
+{
+  std::sort(v.begin(),v.end(),make_test_compare(criterion,std::greater<int>()));
+  assert(v.begin()->id() == N-1);
+}
+
+
+// compare performance with boost::mem_fn
+int main()
+{
+  test_vector v;
+  boost::timer t;
+  double time1, time2;
+
+  std::cout << 
+      "Test case: sorting " << N << " objects.\n\n"
+      "Criterion accessor called with | elasped seconds\n"
+      "-------------------------------|----------------" << std::endl;
+
+  setup_test(v);
+  t.restart();
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1400)
+  do_test(v, BOOST_EXAMPLE_FAST_MEM_FN(& test::id));
+#else // MSVC<8 does not like the implementation of the deduction macro:
+  do_test(v, ::example::fast_mem_fn< int (test::*)() const, & test::id >());
+#endif
+  time1 = t.elapsed();
+  std::cout << "fast_mem_fn                    | " << time1 << std::endl;
+
+  setup_test(v);
+  t.restart();
+  do_test(v, boost::mem_fn(& test::id));
+  time2 = t.elapsed();
+  std::cout << "mem_fn                         | " << time2 << std::endl;
+
+  std::cout << '\n' << (time2/time1-1)*100 << "% speedup" << std::endl;
+
+  return 0;
+}
+
diff --git a/example/interface.hpp b/example/interface.hpp
new file mode 100644
index 0000000..cadf740
--- /dev/null
+++ b/example/interface.hpp
@@ -0,0 +1,361 @@
+
+// (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)                           \
+      };                                                                       \
+                                                                               \
+      vtable const * ptr_vtable;                                               \
+      void * ptr_that;                                                         \
+                                                                               \
+      template<class T> struct vtable_holder                                   \
+      {                                                                        \
+        static vtable const val_vtable;                                        \
+      };                                                                       \
+                                                                               \
+    public:                                                                    \
+                                                                               \
+      template<class T>                                                        \
+      inline name (T & that)                                                   \
+        : ptr_vtable(& vtable_holder<T>::val_vtable)                           \
+        , ptr_that(boost::addressof(that))                                     \
+      { }                                                                      \
+                                                                               \
+      BOOST_EXAMPLE_INTERFACE__MEMBERS(def,FUNCTION)                           \
+    };                                                                         \
+                                                                               \
+    template<typename T>                                                       \
+    name ::vtable const name ::vtable_holder<T>::val_vtable                    \
+        = { BOOST_EXAMPLE_INTERFACE__MEMBERS(def,INIT_VTABLE) }
+
+
+#ifdef BOOST_PP_NIL // never defined -- a comment with syntax highlighting
+
+BOOST_EXAMPLE_INTERFACE( interface_x,
+  (( a_func, (void)(int), const_qualified ))
+  (( another_func, (int), non_const   )) 
+);
+
+// expands to:
+class interface_x 
+{ 
+  struct vtable 
+  {
+    // meta information for first function 
+    template<typename T = void*> struct inf0 
+    {
+      typedef void result; 
+      typedef ::boost::mpl::vector< T, int > params; 
+    };
+    // function pointer with void* context pointer and parameters optimized
+    // for forwarding 
+    ::example::vtable_entry<inf0<> >::type func0; 
+
+    // second function
+    template<typename T = void*> struct inf1 
+    {
+      typedef int result; 
+      typedef ::boost::mpl::vector< T > params; 
+    }; 
+    ::example::vtable_entry<inf1<> >::type func1; 
+  }; 
+
+  // data members
+  vtable const * ptr_vtable; 
+  void * ptr_that; 
+
+  // this template is instantiated for every class T this interface is created
+  // from, causing the compiler to emit an initialized vtable for this type 
+  // (see aggregate assignment, below)
+  template<class T> struct vtable_holder 
+  {
+    static vtable const val_vtable; 
+  }; 
+
+public: 
+
+  // converting ctor, creates an interface from an arbitrary class
+  template<class T> 
+  inline interface_x (T & that) 
+    : ptr_vtable(& vtable_holder<T>::val_vtable)
+    , ptr_that(boost::addressof(that)) 
+  { } 
+
+  // the member functions from the interface definition, parameters are 
+  // optimized for forwarding
+
+  inline vtable::inf0<> ::result a_func (
+      ::example::param<vtable::inf0<>,1>::type p0) const 
+  { 
+    return ptr_vtable-> func0(ptr_that , p0); 
+  } 
+
+  inline vtable::inf1<> ::result another_func () 
+  {
+    return ptr_vtable-> func1(ptr_that ); 
+  } 
+}; 
+
+template<typename T> 
+interface_x ::vtable const interface_x ::vtable_holder<T>::val_vtable = 
+{
+  // instantiate function templates that wrap member function pointers (which
+  // are known at compile time) by taking their addresses in assignment to
+  // function pointer context
+  & ::example::member< vtable::inf0<T>, ::example::ft:: const_qualified >
+        ::template wrap < &T:: a_func > 
+, & ::example::member< vtable::inf1<T>, ::example::ft:: non_const >
+        ::template wrap < &T:: another_func > 
+};
+#endif
+
+// preprocessing code details
+
+// iterate all of the interface's members and invoke a macro (prefixed with
+// BOOST_EXAMPLE_INTERFACE_)
+#define BOOST_EXAMPLE_INTERFACE__MEMBERS(seq,macro)                            \
+    BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq),                                    \
+        BOOST_EXAMPLE_INTERFACE__ ## macro,seq)
+
+// extract signature sequence from entry 
+#define BOOST_EXAMPLE_INTERFACE__VTABLE(z,i,seq)                               \
+    BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i,                                     \
+        BOOST_PP_TUPLE_ELEM(3,1,BOOST_PP_SEQ_ELEM(i,seq)))
+
+// split the signature sequence result/params and insert T at the beginning of
+// the params part
+#define BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i,seq)                             \
+    BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i,                                    \
+        BOOST_PP_SEQ_HEAD(seq),(T)BOOST_PP_SEQ_TAIL(seq))
+
+// emit the meta information structure and function pointer declaration
+#define BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i,result_type,param_types)        \
+    template<typename T = void*>                                               \
+    struct BOOST_PP_CAT(inf,i)                                                 \
+    {                                                                          \
+      typedef result_type result;                                              \
+      typedef ::boost::mpl::vector< BOOST_PP_SEQ_ENUM(param_types) > params;   \
+    };                                                                         \
+    ::example::vtable_entry<BOOST_PP_CAT(inf,i)<> >::type BOOST_PP_CAT(func,i);
+
+// extract tuple entry from sequence and precalculate the name of the function
+// pointer variable
+#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE(z,i,seq)                          \
+    BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,BOOST_PP_CAT(func,i),         \
+        BOOST_PP_SEQ_ELEM(i,seq))
+
+// emit a function pointer expression that encapsulates the corresponding
+// member function of T
+#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,func,desc)                \
+    BOOST_PP_COMMA_IF(i) & ::example::member< BOOST_PP_CAT(vtable::inf,i)<T>,  \
+        ::example::ft:: BOOST_PP_TUPLE_ELEM(3,2,desc) >::template wrap         \
+                                          < &T:: BOOST_PP_TUPLE_ELEM(3,0,desc) >
+        
+// extract tuple entry from sequence
+#define BOOST_EXAMPLE_INTERFACE__FUNCTION(z,i,seq)                             \
+    BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,BOOST_PP_SEQ_ELEM(i,seq))
+
+// precalculate function name, arity, name of meta info structure and cv-
+// qualifiers
+#define BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,desc)                          \
+    BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i,                                  \
+        BOOST_PP_TUPLE_ELEM(3,0,desc),                                         \
+        BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(3,1,desc))),        \
+        BOOST_PP_CAT(vtable::inf,i)<>,                                         \
+        BOOST_PP_CAT(BOOST_EXAMPLE_INTERFACE___,BOOST_PP_TUPLE_ELEM(3,2,desc)) \
+    )
+
+// emit the definition for a member function of the interface
+#define BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i,name,arity,types,cv)          \
+    inline types ::result name                                                 \
+      (BOOST_PP_ENUM_ ## z (arity,BOOST_EXAMPLE_INTERFACE__PARAM,types)) cv()  \
+    {                                                                          \
+      return ptr_vtable-> BOOST_PP_CAT(func,i)(ptr_that                        \
+          BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,arity,p));                         \
+    }
+
+// emit a parameter of the function definition
+#define BOOST_EXAMPLE_INTERFACE__PARAM(z,j,types)                              \
+    ::example::param<types,BOOST_PP_INC(j)>::type BOOST_PP_CAT(p,j)
+
+// helper macros to map 'const_qualified' to 'const' an 'non_const' to ''
+#define BOOST_EXAMPLE_INTERFACE___const_qualified BOOST_PP_IDENTITY(const)
+#define BOOST_EXAMPLE_INTERFACE___non_const BOOST_PP_EMPTY
+
+
diff --git a/example/interface_example.cpp b/example/interface_example.cpp
new file mode 100644
index 0000000..6b7f8d9
--- /dev/null
+++ b/example/interface_example.cpp
@@ -0,0 +1,80 @@
+
+// (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).
+
+//------------------------------------------------------------------------------
+// See interface.hpp in this directory for details.
+
+#include <iostream>
+#include <typeinfo>
+
+#include "interface.hpp"
+
+
+BOOST_EXAMPLE_INTERFACE( interface_x,
+  (( a_func, (void)(int) , const_qualified ))
+  (( a_func, (void)(long), const_qualified ))
+  (( another_func, (int) , non_const   )) 
+);
+
+
+// two classes that implement interface_x
+
+struct a_class
+{
+  void a_func(int v) const
+  {
+    std::cout << "a_class::void a_func(int v = " << v << ")" << std::endl;
+  }
+
+  void a_func(long v) const
+  {
+    std::cout << "a_class::void a_func(long v = " << v << ")" << std::endl;
+  }
+
+  int another_func()
+  {
+    std::cout << "a_class::another_func() = 3" << std::endl;
+    return 3;
+  } 
+};
+
+struct another_class
+{
+  // note: overloaded a_func implemented as a function template
+  template<typename T>
+  void a_func(T v) const
+  {
+    std::cout << 
+      "another_class::void a_func(T v = " << v << ")" 
+      "  [ T = " << typeid(T).name() << " ]" << std::endl;
+  }
+
+  int another_func()
+  {
+    std::cout << "another_class::another_func() = 5" << std::endl;
+    return 5;
+  } 
+};
+
+
+// both classes above can be assigned to the interface variable and their
+// member functions can be called through it
+int main()
+{
+  a_class x;
+  another_class y;
+
+  interface_x i(x);
+  i.a_func(12);
+  i.a_func(77L);
+  i.another_func();
+
+  i = y;
+  i.a_func(13);
+  i.a_func(21L);
+  i.another_func();
+}
+
diff --git a/example/interpreter.hpp b/example/interpreter.hpp
new file mode 100644
index 0000000..72cd78b
--- /dev/null
+++ b/example/interpreter.hpp
@@ -0,0 +1,189 @@
+
+// (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 a simple batch-style interpreter that is capable of
+// calling functions previously registered with it. The parameter types of the
+// functions are used to control the parsing of the input.
+//
+// Implementation description
+// ==========================
+//
+// When a function is registered, an 'invoker' template is instantiated with
+// the function's type. The 'invoker' fetches a value from the 'token_parser'
+// for each parameter of the function into a tuple and finally invokes the the
+// function with these values as arguments. The invoker's entrypoint, which
+// is a function of the callable builtin that describes the function to call and
+// a reference to the 'token_parser', is partially bound to the registered
+// function and put into a map so it can be found by name during parsing.
+
+#include <map>
+#include <string>
+#include <stdexcept>
+
+#include <boost/token_iterator.hpp>
+#include <boost/token_functions.hpp>
+
+#include <boost/lexical_cast.hpp>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/fusion/include/push_back.hpp>
+#include <boost/fusion/include/cons.hpp>
+#include <boost/fusion/include/invoke.hpp>
+
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/deref.hpp>
+
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/function_types/is_nonmember_callable_builtin.hpp>
+#include <boost/function_types/parameter_types.hpp>
+
+namespace example
+{
+  namespace fusion = boost::fusion;
+  namespace ft = boost::function_types;
+  namespace mpl = boost::mpl;
+
+  class interpreter
+  {
+    class token_parser;
+    typedef boost::function<void(token_parser &)> invoker_function;
+    typedef std::map<std::string, invoker_function> dictionary;
+
+    dictionary map_invokers;
+  public:
+    // Registers a function with the interpreter.
+    template<typename Function>
+    typename boost::enable_if< ft::is_nonmember_callable_builtin<Function>
+    >::type register_function(std::string const & name, Function f);
+
+    // Parse input for functions to call.
+    void parse_input(std::string const & text) const;
+
+  private:
+    template< typename Function
+    , class From = typename mpl::begin< ft::parameter_types<Function> >::type
+    , class To   = typename mpl::end< ft::parameter_types<Function> >::type
+    >
+    struct invoker;
+  };
+
+  class interpreter::token_parser
+  {
+    typedef boost::token_iterator_generator<
+        boost::char_separator<char> >::type token_iterator;
+
+    token_iterator itr_at, itr_to;
+  public:
+
+    token_parser(token_iterator from, token_iterator to)
+      : itr_at(from), itr_to(to)
+    { }
+
+  private:
+    template<typename T>
+    struct remove_cv_ref
+      : boost::remove_cv< typename boost::remove_reference<T>::type >
+    { };
+  public:
+    // Returns a token of given type.
+    // We just apply boost::lexical_cast to whitespace separated string tokens
+    // for simplicity.
+    template<typename RequestedType>
+    typename remove_cv_ref<RequestedType>::type get()
+    {
+      if (! this->has_more_tokens())
+        throw std::runtime_error("unexpected end of input");
+
+      try
+      {
+        typedef typename remove_cv_ref<RequestedType>::type result_type;
+        result_type result = boost::lexical_cast
+            <typename remove_cv_ref<result_type>::type>(*this->itr_at);
+        ++this->itr_at;
+        return result;
+      }
+
+      catch (boost::bad_lexical_cast &)
+      { throw std::runtime_error("invalid argument: " + *this->itr_at); }
+    }
+
+    // Any more tokens?
+    bool has_more_tokens() const { return this->itr_at != this->itr_to; }
+  };
+
+  template<typename Function, class From, class To>
+  struct interpreter::invoker
+  {
+    // add an argument to a Fusion cons-list for each parameter type
+    template<typename Args>
+    static inline
+    void apply(Function func, token_parser & parser, Args const & args)
+    {
+      typedef typename mpl::deref<From>::type arg_type;
+      typedef typename mpl::next<From>::type next_iter_type;
+
+      interpreter::invoker<Function, next_iter_type, To>::apply
+          ( func, parser, fusion::push_back(args, parser.get<arg_type>()) );
+    }
+  };
+
+  template<typename Function, class To>
+  struct interpreter::invoker<Function,To,To>
+  {
+    // the argument list is complete, now call the function
+    template<typename Args>
+    static inline
+    void apply(Function func, token_parser &, Args const & args)
+    {
+      fusion::invoke(func,args);
+    }
+  };
+
+  template<typename Function>
+  typename boost::enable_if< ft::is_nonmember_callable_builtin<Function> >::type
+  interpreter::register_function(std::string const & name, Function f)
+  {
+    // instantiate and store the invoker by name
+    this->map_invokers[name] = boost::bind(
+        & invoker<Function>::template apply<fusion::nil>, f,_1,fusion::nil() );
+  }
+
+
+  void interpreter::parse_input(std::string const & text) const
+  {
+    boost::char_separator<char> s(" \t\n\r");
+
+    token_parser parser
+      ( boost::make_token_iterator<std::string>(text.begin(), text.end(), s)
+      , boost::make_token_iterator<std::string>(text.end()  , text.end(), s) );
+
+    while (parser.has_more_tokens())
+    {
+      // read function name
+      std::string func_name = parser.get<std::string>();
+
+      // look up function
+      dictionary::const_iterator entry = map_invokers.find( func_name );
+      if (entry == map_invokers.end())
+        throw std::runtime_error("unknown function: " + func_name);
+
+      // call the invoker which controls argument parsing
+      entry->second(parser);
+    }
+  }
+
+}
+
diff --git a/example/interpreter_example.cpp b/example/interpreter_example.cpp
new file mode 100644
index 0000000..9e6118b
--- /dev/null
+++ b/example/interpreter_example.cpp
@@ -0,0 +1,56 @@
+
+// (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).
+
+//------------------------------------------------------------------------------
+
+#include <string>
+#include <iostream>
+#include <stdexcept>
+
+#include "interpreter.hpp"
+
+void echo(std::string const & s)
+{
+  std::cout << s << std::endl;
+}
+
+void add(int a, int b)
+{
+  std::cout << a + b << std::endl;
+}
+
+void repeat(std::string const & s, int n)
+{
+  while (--n >= 0) std::cout << s;
+  std::cout << std::endl; 
+}
+
+int main()
+{
+  example::interpreter interpreter;
+
+  interpreter.register_function("echo", & echo);
+  interpreter.register_function("add", & add);
+  interpreter.register_function("repeat", & repeat);
+
+  std::string line = "nonempty";
+  while (! line.empty())
+  {
+    std::cout << std::endl << "] ", std::getline(std::cin,line);
+
+    try                          
+    {
+      interpreter.parse_input(line);
+    }
+    catch (std::runtime_error &error) 
+    { 
+      std::cerr << error.what() << std::endl; 
+    }
+  }
+
+  return 0;
+}
+
diff --git a/example/macro_type_args.hpp b/example/macro_type_args.hpp
new file mode 100644
index 0000000..3500524
--- /dev/null
+++ b/example/macro_type_args.hpp
@@ -0,0 +1,73 @@
+
+// (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 a utility to accept a type expression, that may
+// contain commas to a macro.
+//
+// 
+// Detailed description
+// ====================
+//
+// Accepting a type as macro argument can cause problems if the type expression
+// contains commas:
+//
+//    #define MY_MACRO(a_type)
+//    ...
+//    MY_MACRO(std::map<int,int>)  // ERROR (wrong number of macro arguments)
+//
+// This problem can be solved by pasing using a parenthesized type
+//
+//    MY_MACRO((std::map<int,int>) // OK
+//
+// but then there is no way to remove the parentheses in the macro argument
+// with the preprocessor.
+// We can, however, form a pointer to a function with a single argument (the
+// parentheses become part of the type) and extract the argument with template
+// metaprogramming:
+//
+//   // Inside the macro definition
+//
+//   typename mpl::front< parameter_types<void(*)a_type> >::type 
+//
+// This code snippet does not read too expressive so we use another macro
+// to encapsulate the solution:
+//
+//   // Inside the macro definition
+//
+//   BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(a_type)
+// 
+// As a generalization of this technique we can accept a comma-separated list of
+// types. Omitting the mpl::front invocation gives us an MPL-sequence.
+//
+// 
+// Limitations
+// ===========
+//
+// - only works for types that are valid function arguments
+//
+// Acknowledgments
+// ===============
+//
+// Thanks go to Dave Abrahams for letting me know this technique.
+
+#ifndef BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
+#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
+
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/mpl/front.hpp>
+
+#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type)                  \
+    boost::mpl::front<                                                         \
+        BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_type) >::type
+
+#define BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types)            \
+  ::boost::function_types::parameter_types< void(*) parenthesized_types >
+
+
+#endif
+
diff --git a/example/macro_type_args_example.cpp b/example/macro_type_args_example.cpp
new file mode 100644
index 0000000..9f83883
--- /dev/null
+++ b/example/macro_type_args_example.cpp
@@ -0,0 +1,71 @@
+
+// (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).
+
+//------------------------------------------------------------------------------
+// See macro_type_arugment.hpp in this directory for details.
+
+#include <string>
+#include <typeinfo>
+#include <iostream>
+
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/deref.hpp>
+
+#include "macro_type_args.hpp"
+
+
+#define TYPE_NAME(parenthesized_type) \
+    typeid(BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type)).name()
+
+namespace example
+{
+  namespace mpl = boost::mpl;
+
+  template<class Curr, class End>
+  struct mpl_seq_to_string_impl
+  {
+    static std::string get(std::string const & prev)
+    {
+      typedef typename mpl::next<Curr>::type next_pos;
+      typedef typename mpl::deref<Curr>::type type;
+
+      return mpl_seq_to_string_impl<next_pos,End>::get(
+          prev + (prev.empty()? '\0' : ',') + typeid(type).name() );
+    }
+  };
+  template<class End>
+  struct mpl_seq_to_string_impl<End, End>
+  {
+    static std::string get(std::string const & prev)
+    {
+      return prev;
+    }
+  };
+
+  template<class Seq>
+  std::string mpl_seq_to_string()
+  {
+    typedef typename mpl::begin<Seq>::type begin;
+    typedef typename mpl::end<Seq>::type end;
+
+    return mpl_seq_to_string_impl<begin, end>::get("");
+  }
+
+}
+
+#define TYPE_NAMES(parenthesized_types) \
+    ::example::mpl_seq_to_string< \
+        BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types) >()
+
+int main()
+{
+  std::cout << TYPE_NAME((int)) << std::endl;
+
+  std::cout << TYPE_NAMES((int,char)) << std::endl;
+  std::cout << TYPE_NAMES((int,char,long)) << std::endl;
+
+}
+
diff --git a/example/result_of.hpp b/example/result_of.hpp
new file mode 100644
index 0000000..7c3341a
--- /dev/null
+++ b/example/result_of.hpp
@@ -0,0 +1,86 @@
+
+// (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).
+
+//------------------------------------------------------------------------------
+//
+// Reimplementation of the Boost result_of utility (see [Gregor01] and 
+// [Gregor02]).
+//
+//
+// Detailed description
+// ====================
+//
+// This example implements the functionality of the Boost result_of utility.
+// Because of FunctionTypes we get away without repetitive code and the Boost
+// Preprocessor library.
+//
+//
+// Bibliography
+// ============
+//
+// [Gregor01] Gregor, D. The Boost result_of utility
+//            http://www.boost.org/libs/utility
+//
+// [Gregor02] Gregor, D. A uniform method for computing function object return
+//            types (revision 1)
+//            http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html
+
+#include <boost/function_types/result_type.hpp>
+#include <boost/function_types/is_callable_builtin.hpp>
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/has_xxx.hpp>
+
+namespace example
+{
+  namespace ft = boost::function_types;
+  namespace mpl = boost::mpl;
+
+  template<typename F> struct result_of;
+
+  namespace detail
+  {
+    BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
+
+    template<typename F>
+    struct result_type_member
+    {
+      typedef typename F::result_type type;
+    };
+
+    template<typename F, typename Desc>
+    struct result_member_template
+    {
+      typedef typename F::template result<Desc>::type type;
+    };
+
+#if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564))
+    template<typename F> 
+    struct result_member_template< F, F(void) > 
+    { 
+      typedef void type; 
+    };
+#endif
+
+    template<typename F, typename Desc>
+    struct result_of_impl
+      : mpl::eval_if
+        < ft::is_callable_builtin<F>
+        , ft::result_type<F>
+        , mpl::eval_if
+          < has_result_type<F> 
+          , result_type_member<F>
+          , result_member_template<F,Desc>
+        > > 
+    { };
+  }
+
+  template<typename Desc>
+  struct result_of
+    : detail::result_of_impl< typename ft::result_type<Desc>::type, Desc >
+  { };
+}
+
diff --git a/example/result_of_example.cpp b/example/result_of_example.cpp
new file mode 100644
index 0000000..a8fe2d2
--- /dev/null
+++ b/example/result_of_example.cpp
@@ -0,0 +1,59 @@
+
+// (C) Copyright Douglas Gregor 2003-2004.
+// (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 file is a modified copy of the original Boost.ResultOf test-suite.
+// See result_of.hpp in this directory for details.
+
+
+#include "result_of.hpp"
+
+#include <utility>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+struct int_result_type { typedef int result_type; };
+
+struct int_result_of
+{
+  template<typename F> struct result { typedef int type; };
+};
+
+struct int_result_type_and_float_result_of
+{
+  typedef int result_type;
+  template<typename F> struct result { typedef float type; };
+};
+
+struct X {};
+
+int main()
+{
+  using namespace boost;
+  namespace e = example;
+
+  typedef int (*func_ptr)(float, double);
+  typedef int (&func_ref)(float, double);
+  typedef int (X::*mem_func_ptr)(float);
+  typedef int (X::*mem_func_ptr_c)(float) const;
+  typedef int (X::*mem_func_ptr_v)(float) volatile;
+  typedef int (X::*mem_func_ptr_cv)(float) const volatile;
+
+  BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_type(float)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_of(double)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_of(void)>::type, void>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<const int_result_of(double)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<volatile int_result_of(void)>::type, void>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_type_and_float_result_of(char)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<func_ptr(char, float)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<func_ref(char, float)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr(X,char)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_c(X,char)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_v(X,char)>::type, int>::value));
+  BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
+  return 0;
+}