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.