Feedback for generics prototype

In a previous thread @Arjen posted an algorithm to reverse an array.

I have now written this algorithm with the new generics:

module reverse_module
  
    implicit none
    private
    public :: reverse_tmpl, test_reverse
  
    requirement default_behavior(T)
      type :: T; end type
    end requirement
  
    template reverse_tmpl(T)
      requires default_behavior(T)
      private
      public :: reverse
    contains
        subroutine reverse(array)
            type(T), intent(inout) :: array(:)
            type(T) :: tmp
            integer :: i, j
        
            do i = 1,size(array)/2
                j        = size(array) + 1 - i
                tmp = array(i)
                array(i) = array(j)
                array(j) = tmp
            end do
        end subroutine reverse
    end template
    
contains

  subroutine test_reverse()
      instantiate reverse_tmpl(integer), only: irev => reverse
      integer :: a(5)
      a = [1,2,3,4,5]
      call irev(a)
      print *, a
  end subroutine
  
end module

  program main
  use reverse_module
  call test_reverse()
  end program

Unfortunately I hit a code generation error.

Edit: for comparison here is the way you’d do it in C++:

#include <array>
#include <iostream>
#include <algorithm> // reverse
 
template<class C>
void myreverse(C &array)
{
    using T = C::value_type;
    using I = C::size_type;
    
    T tmp; I i, j;
    for (i = 0; i < array.size()/2; i++) {
        j = array.size() - i - 1;
        tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
}

template<class C>
void print(const C &array)
{
    for (auto i: array)
        std::cout << i << ' ';
    std::cout << '\n';    
}

int main(int argc, char const *argv[])
{
    std::array<int,5> a{1,2,3,4,5};

    // reverse
    myreverse(a);
    print(a);

    // built-in reverse
    std::ranges::reverse(a);
    print(a);

    return 0;
}

I haven’t used C++20 concepts here, so the requirements on the class are implicit.

2 Likes