@@ -22,49 +22,44 @@ contains
2222 ${t1}$, intent(in) :: array(:)
2323 logical(lk), intent(in), optional :: sorted
2424 ${t2}$, allocatable :: unique_values(:)
25-
25+
2626 ${t2}$ :: temp_array(size(array))
2727 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+
3331 n = size(array)
32+
33+ ! Handle edge cases first
3434 if (n == 0) then
35+ ! Return empty array for empty input
3536 allocate(unique_values(0))
3637 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
3743 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+
4752 ! Find unique elements using a mask
4853 ! Start with first element always marked as unique
4954 mask(1) = .true.
50-
55+
5156 ! Compare each element with previous to mark duplicates
52- do i = 2, n
57+ do concurrent (i=2:n)
5358 mask(i) = temp_array(i) /= temp_array(i-1)
5459 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)
6863 end function ${name1}$_unique
6964
7065#:endfor
0 commit comments