Skip to content

Commit 4b47d30

Browse files
authored
Merge pull request #144 from swig-fortran/std-set
Add `set`, `multiset`, and test
2 parents cdfe886 + 6189e5f commit 4b47d30

File tree

6 files changed

+140
-11
lines changed

6 files changed

+140
-11
lines changed

Doc/Manual/src/Fortran.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,10 +850,14 @@ subroutine mysub(x, y, swig_result)
850850
integer(C_INT), intent(out), optional :: swig_result
851851
end subroutine
852852
```
853-
854853
The resulting subroutine can be overloaded with other C++ void-returning
855854
functions.
856855

856+
A common use case of `%fortransubroutine` is for C functions that return error
857+
codes or other noncritical information such as the number of items deleted. C++
858+
users should know that a `function` in Fortran is a stronger version of a
859+
`[[nodiscard]]`-marked function (since C++17): ignoring the return value is an
860+
error.
857861

858862
## Global variables
859863

Examples/test-suite/fortran/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ CPP_TEST_CASES = \
2828
fortran_openacc \
2929
fortran_overloads \
3030
fortran_subroutine \
31+
li_std_set \
3132

3233
C_TEST_CASES = \
3334
fortran_array_typemap \
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
! File : li_std_set_runme.f90
2+
3+
#include "fassert.h"
4+
5+
program li_std_set_runme
6+
use ISO_C_BINDING
7+
implicit none
8+
9+
call test_set_string
10+
call test_multiset_int
11+
contains
12+
13+
subroutine test_multiset_int
14+
use ISO_C_BINDING
15+
! Note that the test instantiates *multiset* as a set_int
16+
use li_std_set, only : multiset_int => set_int
17+
implicit none
18+
type(multiset_int) :: s
19+
integer(c_size_t) :: num_erased
20+
21+
s = multiset_int()
22+
ASSERT(s%empty())
23+
24+
call s%insert(10)
25+
call s%insert(3)
26+
ASSERT(s%size() == 2)
27+
ASSERT(s%count(3) == 1)
28+
ASSERT(s%count(5) == 0)
29+
30+
! Duplicate elements allowed in multiset
31+
call s%insert(3)
32+
ASSERT(s%count(3) == 2)
33+
ASSERT(s%size() == 3)
34+
35+
call s%erase(10)
36+
ASSERT(s%size() == 2)
37+
ASSERT(s%count(10) == 0)
38+
39+
call s%erase(3, num_erased)
40+
ASSERT(num_erased == 2)
41+
ASSERT(s%count(3) == 0)
42+
43+
call s%insert(1)
44+
call s%clear()
45+
ASSERT(s%empty())
46+
47+
call s%release()
48+
end subroutine
49+
50+
subroutine test_set_string
51+
use ISO_C_BINDING
52+
use li_std_set, only : set_string
53+
implicit none
54+
type(set_string) :: s
55+
56+
s = set_string()
57+
ASSERT(s%empty())
58+
59+
call s%insert("yoohoo")
60+
call s%insert("howdy")
61+
ASSERT(s%size() == 2)
62+
ASSERT(s%count("yoohoo") == 1)
63+
ASSERT(s%count("hiya") == 0)
64+
65+
call s%insert("howdy")
66+
ASSERT(s%count("howdy") == 1)
67+
ASSERT(s%size() == 2)
68+
69+
call s%erase("yoohoo")
70+
ASSERT(s%size() == 1)
71+
ASSERT(s%count("yoohoo") == 0)
72+
73+
call s%clear()
74+
ASSERT(s%empty())
75+
76+
call s%release()
77+
end subroutine
78+
79+
end program
80+

Examples/test-suite/li_std_set.i

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* a test of set containers.
2+
* a test of set containers.
33
* Languages should define swig::LANGUAGE_OBJ to be
44
* an entity of their native pointer type which can be
55
* included in a STL container.
@@ -26,9 +26,9 @@
2626

2727

2828
#if defined(SWIGRUBY)
29-
%template(LanguageSet) std::set<swig::LANGUAGE_OBJ>;
29+
%template(LanguageSet) std::set<swig::LANGUAGE_OBJ>;
3030
#endif
3131

3232
#if defined(SWIGPYTHON)
33-
%template(pyset) std::set<swig::SwigPtr_PyObject>;
33+
%template(pyset) std::set<swig::SwigPtr_PyObject>;
3434
#endif

Lib/fortran/std_multiset.i

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* -------------------------------------------------------------------------
2+
* std_multiset.i
3+
*
4+
* Note: multiset interface is identical to std::set. It simply allows multiple
5+
* keys.
6+
* ------------------------------------------------------------------------- */
7+
8+
%{
9+
#include <set>
10+
%}
11+
12+
%fortransubroutine std::multiset::erase;
13+
14+
namespace std {
15+
16+
template<class _Key, class _Compare = std::less<_Key>, class _Alloc = std::allocator<_Key> >
17+
class multiset {
18+
public:
19+
typedef _Key value_type;
20+
typedef _Key key_type;
21+
typedef std::size_t size_type;
22+
typedef ptrdiff_t difference_type;
23+
typedef value_type *pointer;
24+
typedef const value_type *const_pointer;
25+
typedef value_type &reference;
26+
typedef const value_type &const_reference;
27+
typedef _Alloc allocator_type;
28+
29+
public:
30+
set();
31+
32+
bool empty() const;
33+
size_type size() const;
34+
void clear();
35+
size_type erase(const key_type& x);
36+
size_type count(const key_type& x) const;
37+
void insert(const_reference x);
38+
};
39+
} // namespace std
40+

Lib/fortran/std_set.i

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@
66
#include <set>
77
%}
88

9-
template<class _Key, class _Compare = std::less<_Key>, class _Alloc = allocator<_Key> >
9+
%fortransubroutine std::set::erase;
10+
11+
namespace std {
12+
13+
template<class _Key, class _Compare = std::less<_Key>, class _Alloc = std::allocator<_Key> >
1014
class set {
1115
public:
12-
typedef std::size_t size_type;
13-
typedef ptrdiff_t difference_type;
1416
typedef _Key value_type;
1517
typedef _Key key_type;
18+
typedef std::size_t size_type;
19+
typedef ptrdiff_t difference_type;
1620
typedef value_type *pointer;
1721
typedef const value_type *const_pointer;
1822
typedef value_type &reference;
@@ -25,9 +29,9 @@ public:
2529
bool empty() const;
2630
size_type size() const;
2731
void clear();
28-
size_type erase(const key_type &x);
29-
size_type count(const key_type &x) const;
32+
size_type erase(const key_type& x);
33+
size_type count(const key_type& x) const;
34+
void insert(const_reference x);
3035
};
3136

32-
33-
37+
} // namespace std

0 commit comments

Comments
 (0)