#!/usr/bin/env perl
#
#  apply to $BOOST/boost/lambda/detail/function_adaptors.hpp
#

local $/;

sub templ_args { ($a)=@_; return if $a !~ m/\(A/; $a =~ s/.*\((A.*)\).*/, $1/; $a =~ s/Arg([0-9]*)/class A$1/g; $a }
sub ref_params { ($a)=@_; return if $a !~ m/\(A/; $a =~ s/.*\((A.*)\).*/, $1/; $a =~ s/Arg([0-9]*)/A$1& a$1/g; $a }
sub call_args  { ($a)=@_; return if $a !~ m/\(A/; $a =~ s/.*\((A.*)\).*/$1/; $a =~ s/Arg([0-9]*)/a$1/g; $a }

while (<>)
{
      s~\G(.*)(\n\nnamespace boost {)~$1\n#include <boost\/get_pointer.hpp>$2~sgc;

      if (m/\G(.*?\n\Qstruct function_adaptor<\E)(\QResult (Object::*)\E([^>]*))(\>.*?)(\n};)/sgc)
      {
         print "$1$2$4\n";
         $templ_args = templ_args($2);
         $ref_params = ref_params($2);
         $call_args  = call_args($2);
         print <<ENDCXX;
  template <class RET, class ObjectPtr$templ_args>
  static Result apply( Result (Object::*func)$3, const ObjectPtr& o$ref_params, typename disable_if<is_convertible<const ObjectPtr&, const Object&> >::type* = 0) {
    return (get_pointer(o)->*func)($call_args);
ENDCXX
         print "  }$5";
         redo;
      }
      elsif (m/\G.*/sgc)
      {
         print $&;
      }
}

