/* functions using pointers to functions */

#include <cstdlib>
#include <cstdio>

typedef int (*functionType)(int);

/* functions that do stuff */
int funcA 
( 
  int input 
)
{
  printf ( "funcA: %d\n", input );
  return (1);
}

int funcB ( int input )
{
  printf ( "funcB: %d\n", input );
  return (1);
}

int funcC ( int input )
{
  printf ( "funcC: %d\n", input );
  return (1);
}

/* functions receiving pts to functions */
int
func_pass_func1 ( functionType F, int input )
{
  /* call the pass function */
  return F(input);
}

int 
func_pass_func2 (  int(*F)(int), int input )
{
  /* call the pass function */
  return F(input);
}


/* functions returning funtions */
/* method 1 */
functionType
which_func1 ( char input )
{
  switch ( input )
  {
    case 'A':
    case 'a':
    {
      return ( funcA );
    }
    break;     
    case 'B':
    case 'b':
    {
      return ( funcB );
    }
    break;     
    case 'C':
    case 'c':
    {
      return ( funcC );
    }
    break;

    default:
    {
      printf ( "Unsupported func%c\n"
               "Executing funcA\n", input );
    }
    break;
  }
  return ( funcA );
}               

/* method 2 */
int 
(*which_func2( char input ))(int)
{
  switch ( input )
  {
    case 'A':
    case 'a':
    {
      return ( funcA );
    }
    break;     
    case 'B':
    case 'b':
    {
      return ( funcB );
    }
    break;     
    case 'C':
    case 'c':
    {
      return ( funcC );
    }
    break;

    default:
    {
      printf ( "Unsupported func%c\n"
               "Executing funcB\n", input );
    }
    break;
  }
  return ( funcB );
}                 

int
main ( void )
{

  func_pass_func1 ( funcA, 99 );

  func_pass_func2 ( funcB, 11 );

  (which_func1('B'))( 44 );
 
  (which_func2('C'))( 133 );
 
  (which_func1('F'))( -1 );

  return (1);
}

/* example output

funcA: 99
funcB: 11
funcB: 44
funcC: 133
Unsupported funcF
Executing funcA
funcA: -1

*/
