Skip to content

Commit 9015cff

Browse files
committed
Add equal_range
1 parent 560327f commit 9015cff

File tree

5 files changed

+439
-10
lines changed

5 files changed

+439
-10
lines changed

doc/modules/algorithm.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,31 @@ Example::
9898
idx = binary_search(iarr, 9) ! returns 6
9999
idx = binary_search(iarr, 10) ! returns 0
100100

101+
equal_range
102+
-----------
103+
104+
Finds the range of elements in a sorted array equivalent to the given value. If
105+
the exact value isn't present, the first index will point
106+
to the index at which the value could be inserted to maintain a sorted array.
107+
If searching for a value that's in the sorted array more than once, the
108+
expression ``arr(first_idx:last_idx)`` will return the equal values. If the
109+
value isn't present, ``arr(first_idx:last_idx)`` will be an empty array, and
110+
the first index will be the point at which the element would be located if it
111+
were present.
112+
113+
Example::
114+
use flc_algorithm, only : equal_range, INDEX_INT
115+
implicit none
116+
integer(INDEX_INT) :: first, last
117+
integer, dimension(6) :: iarr = [ -5, 1, 1, 2, 4, 9]
118+
119+
call equal_range(iarr, -6, first, last) ! (first,last) are (1,0)
120+
call equal_range(iarr, -5, first, last) ! (first,last) are (1,1)
121+
call equal_range(iarr, 1, first, last) ! (first,last) are (2,3)
122+
call equal_range(iarr, 3, first, last) ! (first,last) are (5,4)
123+
call equal_range(iarr, 9, first, last) ! (first,last) are (6,6)
124+
125+
101126
minmax_element
102127
--------------
103128

src/flc_algorithm.i

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,17 @@ static index_int binary_search_impl(const T *data, size_t size, T value, Compare
109109
return (iter - data) + 1;
110110
}
111111

112+
template<class T, class Compare>
113+
static void equal_range_impl(const T *data, size_t size, T value, index_int *first_index, index_int *last_index, Compare cmp) {
114+
const T *end = data + size;
115+
auto range_pair = std::equal_range(data, end, value, cmp);
116+
// Index of the min/max items *IN FORTAN INDEXING*
117+
*first_index = range_pair.first - data + 1;
118+
*last_index = range_pair.second - data;
119+
}
120+
112121
template<class T, class Compare>
113122
static void minmax_element_impl(const T *data, size_t size, index_int *min_index, index_int *max_index, Compare cmp) {
114-
if (size == 0) {
115-
*min_index = 0;
116-
*max_index = 0;
117-
return;
118-
}
119123
const T *end = data + size;
120124
auto mm_pair = std::minmax_element(data, end, cmp);
121125
// Index of the min/max items *IN FORTAN INDEXING*
@@ -128,6 +132,11 @@ static void minmax_element_impl(const T *data, size_t size, index_int *min_index
128132
T value),
129133
%arg(DATA, DATASIZE, value))
130134

135+
%flc_cmp_algorithm(void, equal_range, %arg(const T *DATA, size_t DATASIZE,
136+
T value,
137+
index_int *first_index, index_int *last_index),
138+
%arg(DATA, DATASIZE, value, first_index, last_index))
139+
131140
%flc_cmp_algorithm(void, minmax_element, %arg(const T *DATA, size_t DATASIZE,
132141
index_int *min_index, index_int *max_index),
133142
%arg(DATA, DATASIZE, min_index, max_index))

src/generated/flc_algorithm.f90

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ module flc_algorithm
4949
swigf_is_sorted__SWIG_5, swigf_is_sorted__SWIG_6
5050
end interface
5151
public :: is_sorted
52+
interface equal_range
53+
module procedure swigf_equal_range__SWIG_1, swigf_equal_range__SWIG_2, swigf_equal_range__SWIG_3, swigf_equal_range__SWIG_4, &
54+
swigf_equal_range__SWIG_5, swigf_equal_range__SWIG_6
55+
end interface
56+
public :: equal_range
5257
interface sort
5358
module procedure swigf_sort__SWIG_1, swigf_sort__SWIG_2, swigf_sort__SWIG_3, swigf_sort__SWIG_4, swigf_sort__SWIG_5, &
5459
swigf_sort__SWIG_6
@@ -278,6 +283,69 @@ function swigc_binary_search__SWIG_6(farg1, farg3, farg4) &
278283
integer(C_INT) :: fresult
279284
end function
280285

286+
subroutine swigc_equal_range__SWIG_1(farg1, farg3, farg4, farg5) &
287+
bind(C, name="_wrap_equal_range__SWIG_1")
288+
use, intrinsic :: ISO_C_BINDING
289+
import :: swigarraywrapper
290+
type(SwigArrayWrapper) :: farg1
291+
integer(C_INT32_T), intent(in) :: farg3
292+
type(C_PTR), value :: farg4
293+
type(C_PTR), value :: farg5
294+
end subroutine
295+
296+
subroutine swigc_equal_range__SWIG_2(farg1, farg3, farg4, farg5) &
297+
bind(C, name="_wrap_equal_range__SWIG_2")
298+
use, intrinsic :: ISO_C_BINDING
299+
import :: swigarraywrapper
300+
type(SwigArrayWrapper) :: farg1
301+
integer(C_INT64_T), intent(in) :: farg3
302+
type(C_PTR), value :: farg4
303+
type(C_PTR), value :: farg5
304+
end subroutine
305+
306+
subroutine swigc_equal_range__SWIG_3(farg1, farg3, farg4, farg5) &
307+
bind(C, name="_wrap_equal_range__SWIG_3")
308+
use, intrinsic :: ISO_C_BINDING
309+
import :: swigarraywrapper
310+
type(SwigArrayWrapper) :: farg1
311+
real(C_DOUBLE), intent(in) :: farg3
312+
type(C_PTR), value :: farg4
313+
type(C_PTR), value :: farg5
314+
end subroutine
315+
316+
subroutine swigc_equal_range__SWIG_4(farg1, farg3, farg4, farg5, farg6) &
317+
bind(C, name="_wrap_equal_range__SWIG_4")
318+
use, intrinsic :: ISO_C_BINDING
319+
import :: swigarraywrapper
320+
type(SwigArrayWrapper) :: farg1
321+
integer(C_INT32_T), intent(in) :: farg3
322+
type(C_PTR), value :: farg4
323+
type(C_PTR), value :: farg5
324+
type(C_FUNPTR), value :: farg6
325+
end subroutine
326+
327+
subroutine swigc_equal_range__SWIG_5(farg1, farg3, farg4, farg5, farg6) &
328+
bind(C, name="_wrap_equal_range__SWIG_5")
329+
use, intrinsic :: ISO_C_BINDING
330+
import :: swigarraywrapper
331+
type(SwigArrayWrapper) :: farg1
332+
integer(C_INT64_T), intent(in) :: farg3
333+
type(C_PTR), value :: farg4
334+
type(C_PTR), value :: farg5
335+
type(C_FUNPTR), value :: farg6
336+
end subroutine
337+
338+
subroutine swigc_equal_range__SWIG_6(farg1, farg3, farg4, farg5, farg6) &
339+
bind(C, name="_wrap_equal_range__SWIG_6")
340+
use, intrinsic :: ISO_C_BINDING
341+
import :: swigarraywrapper
342+
type(SwigArrayWrapper) :: farg1
343+
real(C_DOUBLE), intent(in) :: farg3
344+
type(C_PTR), value :: farg4
345+
type(C_PTR), value :: farg5
346+
type(C_FUNPTR), value :: farg6
347+
end subroutine
348+
281349
subroutine swigc_minmax_element__SWIG_1(farg1, farg3, farg4) &
282350
bind(C, name="_wrap_minmax_element__SWIG_1")
283351
use, intrinsic :: ISO_C_BINDING
@@ -956,6 +1024,171 @@ function swigf_binary_search__SWIG_6(data, value, cmp) &
9561024
swig_result = fresult
9571025
end function
9581026

1027+
subroutine swigf_equal_range__SWIG_1(data, value, first_index, last_index)
1028+
use, intrinsic :: ISO_C_BINDING
1029+
integer(C_INT32_T), dimension(:), intent(in), target :: data
1030+
integer(C_INT32_T), pointer :: farg1_view
1031+
integer(C_INT32_T), intent(in) :: value
1032+
integer(INDEX_INT), target, intent(inout) :: first_index
1033+
integer(INDEX_INT), target, intent(inout) :: last_index
1034+
type(SwigArrayWrapper) :: farg1
1035+
integer(C_INT32_T) :: farg3
1036+
type(C_PTR) :: farg4
1037+
type(C_PTR) :: farg5
1038+
1039+
if (size(data) > 0) then
1040+
farg1_view => data(1)
1041+
farg1%data = c_loc(farg1_view)
1042+
farg1%size = size(data)
1043+
else
1044+
farg1%data = c_null_ptr
1045+
farg1%size = 0
1046+
end if
1047+
farg3 = value
1048+
farg4 = c_loc(first_index)
1049+
farg5 = c_loc(last_index)
1050+
call swigc_equal_range__SWIG_1(farg1, farg3, farg4, farg5)
1051+
end subroutine
1052+
1053+
subroutine swigf_equal_range__SWIG_2(data, value, first_index, last_index)
1054+
use, intrinsic :: ISO_C_BINDING
1055+
integer(C_INT64_T), dimension(:), intent(in), target :: data
1056+
integer(C_INT64_T), pointer :: farg1_view
1057+
integer(C_INT64_T), intent(in) :: value
1058+
integer(INDEX_INT), target, intent(inout) :: first_index
1059+
integer(INDEX_INT), target, intent(inout) :: last_index
1060+
type(SwigArrayWrapper) :: farg1
1061+
integer(C_INT64_T) :: farg3
1062+
type(C_PTR) :: farg4
1063+
type(C_PTR) :: farg5
1064+
1065+
if (size(data) > 0) then
1066+
farg1_view => data(1)
1067+
farg1%data = c_loc(farg1_view)
1068+
farg1%size = size(data)
1069+
else
1070+
farg1%data = c_null_ptr
1071+
farg1%size = 0
1072+
end if
1073+
farg3 = value
1074+
farg4 = c_loc(first_index)
1075+
farg5 = c_loc(last_index)
1076+
call swigc_equal_range__SWIG_2(farg1, farg3, farg4, farg5)
1077+
end subroutine
1078+
1079+
subroutine swigf_equal_range__SWIG_3(data, value, first_index, last_index)
1080+
use, intrinsic :: ISO_C_BINDING
1081+
real(C_DOUBLE), dimension(:), intent(in), target :: data
1082+
real(C_DOUBLE), pointer :: farg1_view
1083+
real(C_DOUBLE), intent(in) :: value
1084+
integer(INDEX_INT), target, intent(inout) :: first_index
1085+
integer(INDEX_INT), target, intent(inout) :: last_index
1086+
type(SwigArrayWrapper) :: farg1
1087+
real(C_DOUBLE) :: farg3
1088+
type(C_PTR) :: farg4
1089+
type(C_PTR) :: farg5
1090+
1091+
if (size(data) > 0) then
1092+
farg1_view => data(1)
1093+
farg1%data = c_loc(farg1_view)
1094+
farg1%size = size(data)
1095+
else
1096+
farg1%data = c_null_ptr
1097+
farg1%size = 0
1098+
end if
1099+
farg3 = value
1100+
farg4 = c_loc(first_index)
1101+
farg5 = c_loc(last_index)
1102+
call swigc_equal_range__SWIG_3(farg1, farg3, farg4, farg5)
1103+
end subroutine
1104+
1105+
subroutine swigf_equal_range__SWIG_4(data, value, first_index, last_index, cmp)
1106+
use, intrinsic :: ISO_C_BINDING
1107+
integer(C_INT32_T), dimension(:), intent(in), target :: data
1108+
integer(C_INT32_T), pointer :: farg1_view
1109+
integer(C_INT32_T), intent(in) :: value
1110+
integer(INDEX_INT), target, intent(inout) :: first_index
1111+
integer(INDEX_INT), target, intent(inout) :: last_index
1112+
type(C_FUNPTR), intent(in), value :: cmp
1113+
type(SwigArrayWrapper) :: farg1
1114+
integer(C_INT32_T) :: farg3
1115+
type(C_PTR) :: farg4
1116+
type(C_PTR) :: farg5
1117+
type(C_FUNPTR) :: farg6
1118+
1119+
if (size(data) > 0) then
1120+
farg1_view => data(1)
1121+
farg1%data = c_loc(farg1_view)
1122+
farg1%size = size(data)
1123+
else
1124+
farg1%data = c_null_ptr
1125+
farg1%size = 0
1126+
end if
1127+
farg3 = value
1128+
farg4 = c_loc(first_index)
1129+
farg5 = c_loc(last_index)
1130+
farg6 = cmp
1131+
call swigc_equal_range__SWIG_4(farg1, farg3, farg4, farg5, farg6)
1132+
end subroutine
1133+
1134+
subroutine swigf_equal_range__SWIG_5(data, value, first_index, last_index, cmp)
1135+
use, intrinsic :: ISO_C_BINDING
1136+
integer(C_INT64_T), dimension(:), intent(in), target :: data
1137+
integer(C_INT64_T), pointer :: farg1_view
1138+
integer(C_INT64_T), intent(in) :: value
1139+
integer(INDEX_INT), target, intent(inout) :: first_index
1140+
integer(INDEX_INT), target, intent(inout) :: last_index
1141+
type(C_FUNPTR), intent(in), value :: cmp
1142+
type(SwigArrayWrapper) :: farg1
1143+
integer(C_INT64_T) :: farg3
1144+
type(C_PTR) :: farg4
1145+
type(C_PTR) :: farg5
1146+
type(C_FUNPTR) :: farg6
1147+
1148+
if (size(data) > 0) then
1149+
farg1_view => data(1)
1150+
farg1%data = c_loc(farg1_view)
1151+
farg1%size = size(data)
1152+
else
1153+
farg1%data = c_null_ptr
1154+
farg1%size = 0
1155+
end if
1156+
farg3 = value
1157+
farg4 = c_loc(first_index)
1158+
farg5 = c_loc(last_index)
1159+
farg6 = cmp
1160+
call swigc_equal_range__SWIG_5(farg1, farg3, farg4, farg5, farg6)
1161+
end subroutine
1162+
1163+
subroutine swigf_equal_range__SWIG_6(data, value, first_index, last_index, cmp)
1164+
use, intrinsic :: ISO_C_BINDING
1165+
real(C_DOUBLE), dimension(:), intent(in), target :: data
1166+
real(C_DOUBLE), pointer :: farg1_view
1167+
real(C_DOUBLE), intent(in) :: value
1168+
integer(INDEX_INT), target, intent(inout) :: first_index
1169+
integer(INDEX_INT), target, intent(inout) :: last_index
1170+
type(C_FUNPTR), intent(in), value :: cmp
1171+
type(SwigArrayWrapper) :: farg1
1172+
real(C_DOUBLE) :: farg3
1173+
type(C_PTR) :: farg4
1174+
type(C_PTR) :: farg5
1175+
type(C_FUNPTR) :: farg6
1176+
1177+
if (size(data) > 0) then
1178+
farg1_view => data(1)
1179+
farg1%data = c_loc(farg1_view)
1180+
farg1%size = size(data)
1181+
else
1182+
farg1%data = c_null_ptr
1183+
farg1%size = 0
1184+
end if
1185+
farg3 = value
1186+
farg4 = c_loc(first_index)
1187+
farg5 = c_loc(last_index)
1188+
farg6 = cmp
1189+
call swigc_equal_range__SWIG_6(farg1, farg3, farg4, farg5, farg6)
1190+
end subroutine
1191+
9591192
subroutine swigf_minmax_element__SWIG_1(data, min_index, max_index)
9601193
use, intrinsic :: ISO_C_BINDING
9611194
integer(C_INT32_T), dimension(:), intent(in), target :: data

0 commit comments

Comments
 (0)