@@ -22,49 +22,44 @@ contains
22
22
${t1}$, intent(in) :: array(:)
23
23
logical(lk), intent(in), optional :: sorted
24
24
${t2}$, allocatable :: unique_values(:)
25
-
25
+
26
26
${t2}$ :: temp_array(size(array))
27
27
logical :: mask(size(array))
28
- integer :: i, j, n, unique_count
29
- logical :: want_sorted
30
-
31
- want_sorted = optval(sorted, .false.)
32
-
28
+ integer :: i, n
29
+ logical :: is_input_sorted
30
+
33
31
n = size(array)
32
+
33
+ ! Handle edge cases first
34
34
if (n == 0) then
35
+ ! Return empty array for empty input
35
36
allocate(unique_values(0))
36
37
return
38
+ else if (n == 1) then
39
+ ! For single-element arrays, return that element directly
40
+ allocate(unique_values(1))
41
+ unique_values(1) = array(1)
42
+ return
37
43
endif
38
-
39
- ! Create a temporary copy that may be sorted
40
- if (want_sorted) then
41
- temp_array = array
42
- call sort(temp_array)
43
- else
44
- temp_array = array
45
- endif
46
-
44
+
45
+ ! Determine if the input is already sorted
46
+ is_input_sorted = optval(sorted, .false.)
47
+
48
+ ! Create a temporary copy and sort it if needed
49
+ temp_array = array
50
+ if (.not. is_input_sorted) call sort(temp_array)
51
+
47
52
! Find unique elements using a mask
48
53
! Start with first element always marked as unique
49
54
mask(1) = .true.
50
-
55
+
51
56
! Compare each element with previous to mark duplicates
52
- do i = 2, n
57
+ do concurrent (i=2:n)
53
58
mask(i) = temp_array(i) /= temp_array(i-1)
54
59
end do
55
-
56
- ! Count unique elements and allocate result array
57
- unique_count = count(mask)
58
- allocate(unique_values(unique_count))
59
-
60
- ! Extract unique elements to result array
61
- j = 0
62
- do i = 1, n
63
- if (mask(i)) then
64
- j = j + 1
65
- unique_values(j) = temp_array(i)
66
- endif
67
- end do
60
+
61
+ ! Extract unique elements to result array using pack
62
+ unique_values = pack(temp_array, mask)
68
63
end function ${name1}$_unique
69
64
70
65
#:endfor
0 commit comments