Task: Optional parameters


C++: #include <vector>
#include <algorithm>
#include <string>


template <class T>
struct sort_table_functor {
  typedef bool (*CompFun)(const T &, const T &);
  const CompFun ordering;
  const int column;
  const bool reverse;
  sort_table_functor(CompFun o, int c, bool r) :
    ordering(o), column(c), reverse(r) { }
  bool operator()(const std::vector<T> &x, const std::vector<T> &y) const {
    const T &a = x[column],
            &b = y[column];
    return reverse ? ordering(b, a)
                   : ordering(a, b);
  }
};


template <class T>
bool myLess(const T &x, const T &y) { return x < y; }


template <class T>
void sort_table(std::vector<std::vector<T> > &table,
                int column = 0, bool reverse = false,
                bool (*ordering)(const T &, const T &) = myLess) {
  std::sort(table.begin(), table.end(),
            sort_table_functor<T>(ordering, column, reverse));
}

#include <iostream>


template <class T>
void print_matrix(std::vector<std::vector<T> > &data) {
  for () {
    for (int j = 0; j < 3; j++)
      std::cout << data[i][j] << "\t";
    std::cout << std::endl;
  }
}


bool desc_len_comparator(const std::string &x, const std::string &y) {
  return x.length() > y.length();
}

int main() {

  std::string data_array[3][3] =
    {
      {"a", "b", "c"},
      {"", "q", "z"},
      {"zap", "zip", "Zot"}
    };

  std::vector<std::vector<std::string> > data_orig;
  for (int i = 0; i < 3; i++) {
    std::vector<std::string> row;
    for (int j = 0; j < 3; j++)
      row.push_back(data_array[i][j]);
    data_orig.push_back(row);
  }
  print_matrix(data_orig);

  std::vector<std::vector<std::string> > data = data_orig;
  sort_table(data);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 2);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 1);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 1, true);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 0, false, desc_len_comparator);
  print_matrix(data);

  return 0;
}









Fortran: module ExampleOptionalParameter
  
  
  implicit none
contains

  subroutine sort_table(table, ordering, column, reverse)
    type(table_type), intent(inout) :: table
    integer, optional :: column
    logical, optional :: reverse
    optional :: ordering
    interface
       integer function ordering(a, b)
         type(table_element), intent(in) :: a, b
       end function ordering
    end interface

    integer :: the_column, i
    logical :: reversing
    type(table_row) :: rowA, rowB

    if ( present(column) ) then
       if ( column > get_num_of_columns(table) ) then
          
       else
          the_column = column
       end if
    else
       the_column = 1   
    end if

    reversing = .false.  
    if ( present(reverse) ) reversing = reverse

    do
       
       
       
       
       ea = get_element(rowA, the_column)
       eb = get_element(rowB, the_column)
       if ( present(ordering) ) then
          if ( .not. reversing ) then
             if ( ordering(ea, eb) > 0 ) then
                
             end if
          else   
             if ( ordering(ea, eb) < 0 ) then
                
             end if
          end if
       else
          if ( .not. reversing ) then
             if ( lexinternal(ea, eb) > 0 ) then
                
             end if
          else   
             if ( lexinternal(ea, eb) < 0 ) then
                
             end if
          end if
       end if
       
       
    end do

  end subroutine sort_table

end module ExampleOptionalParameter