Skip to content

Commit bd2aafa

Browse files
committed
Add extended methods and documentation
1 parent a7cfccc commit bd2aafa

File tree

6 files changed

+320
-52
lines changed

6 files changed

+320
-52
lines changed

doc/modules/set.rst

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,87 @@
22
.. File : doc/modules/set.rst
33
.. ############################################################################
44
5-
.. _modules_set:
5+
.. _modules_Set:
66

77
***
88
Set
99
***
1010

11-
Sorted sets with unions, intersections, etc., are not yet implemented as
12-
objects. However, the :ref:`modules_algorithm_set_operations` for arrays can
13-
replicate some basic Set-like functionality.
11+
Sets are sorted containers of unique elements. The ``flc_set`` module
12+
defines sets of ``integer`` and of ``type(String)``.
13+
14+
Common functionality
15+
====================
16+
17+
All set types support the following basic operations.
18+
19+
Construction and destruction
20+
----------------------------
21+
22+
Like other wrapped C++ classes in Flibcpp, sets are
23+
constructed using an interface function. The default constructor is an empty
24+
set. Sets are destroyed using the ``release`` type-bound subroutine.
25+
26+
Modification
27+
------------
28+
29+
The two primary operations on a set are ``insert`` and ``erase`` for adding
30+
an element to and removing an element from the set. A ``clear`` subroutine
31+
removes all elements from the set.
32+
33+
The ``size`` method returns the number of elements, and ``count`` will return
34+
the number of elements of a given value
35+
36+
Here's an example of creating, modifying, and destroying a set::
37+
38+
use flc_set, only : Set => SetInt4
39+
type(Set) :: s
40+
s = Set()
41+
call s%insert(2)
42+
call s%insert(3) ! Set has 2 elements
43+
call s%insert(3) ! Duplicate element, ignored
44+
call s%erase(2) ! Remove 2 from the set
45+
call s%erase(1) ! Nonexistent set element, ignored
46+
write(0,*) "Number of 3s in the set:" s%count(3)
47+
call s%clear() ! Remove all elements, size is now zero
48+
call s%insert(1)
49+
call s%release() ! Free memory
50+
51+
Set operations
52+
--------------
53+
54+
Union, intersection, etc. are not yet implemented.
55+
56+
Numeric sets
57+
===============
58+
59+
Unlike :ref:`vectors<modules_Vector>`, the ``flc_set`` module includes
60+
a single "native integer" numeric instantiations. The value type is
61+
``integer(C_INT)`` and is 64 bits on most modern systems.
62+
63+
Construct from an array
64+
-----------------------
65+
66+
Numeric sets can be created very efficiently from Fortran data by accepting
67+
an array argument::
68+
69+
use flc_set, only : Set => SetInt
70+
type(Set) :: s
71+
72+
s = Set([1, 1, 2, 10])
73+
write(0,*) "Size should be 3:", s%size()
74+
75+
The ``assign`` bound method acts like a constructor but for an existing set.
76+
77+
String sets
78+
==============
79+
80+
The native "element" type of ``SetString`` is a ``character(len=:)``. Set
81+
operations that accept an input will take any native character string; and
82+
returned values will be allocatable character arrays.
83+
84+
An additional ``insert_ref`` function allows assignment of
85+
:ref:`String types <modules_string_type>`
1486

1587
.. ############################################################################
1688
.. end of doc/modules/set.rst

doc/modules/vector.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@ All vector types support the following basic operations.
2020
Construction and destruction
2121
----------------------------
2222

23-
Vectors are constructed using three interface functions:
23+
Vectors are constructed using four interface functions:
2424

2525
- The function without arguments creates an empty vector;
2626
- A single integer argument assigns that many elements with default values;
2727
and
2828
- An integer argument followed by an element with the vector's element type
2929
will copy that value to all elements of the vector.
30-
31-
(To do: copy construction)
30+
- A vector object will create a copy of that vector.
3231

3332
Here are three examples of initialization::
3433

@@ -153,7 +152,7 @@ However, as with native pointers described above, these references are
153152
``%release()`` bound method.
154153

155154
An additional ``set_ref`` function allows vector elements to be assigned from
156-
vector classes.
155+
``String`` types.
157156

158157
.. ############################################################################
159158
.. end of doc/modules/vector.rst

include/flc_set.i

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,76 @@
1111

1212
%include <std_set.i>
1313

14+
/* -------------------------------------------------------------------------
15+
* Macro definitions
16+
* ------------------------------------------------------------------------- */
17+
18+
%define %flc_extend_set_pod(CTYPE)
19+
%apply (const SWIGTYPE *DATA, ::size_t SIZE)
20+
{ (const CTYPE* DATA, size_type SIZE) };
21+
22+
// Construct from an array of data
23+
set(const CTYPE* DATA, size_type SIZE) {
24+
return new std::set<CTYPE>(DATA, DATA + SIZE);
25+
}
26+
27+
// Insert an array of data
28+
void insert(const CTYPE* DATA, size_type SIZE) {
29+
$self->insert(DATA, DATA + SIZE);
30+
}
31+
32+
%enddef
33+
34+
/* ------------------------------------------------------------------------- */
35+
/*! \def %specialize_std_set_pod
36+
*
37+
* Inject member functions and typemaps for POD classes.
38+
*
39+
* These provide an efficient constructor from a Fortan array view. It also
40+
* offers a "view" functionality for getting an array pointer to the
41+
* set-owned data.
42+
*
43+
* This definition is considered part of the \em public API so that downstream
44+
* apps that generate FLC-based bindings can instantiate their own POD sets.
45+
*/
46+
%define %specialize_std_set_pod(T)
47+
48+
// Automatically free temporary sets as appropriate
49+
%fortran_autofree_rvalue(std::set<T>);
50+
51+
namespace std {
52+
template<> class set<T> {
53+
54+
SWIG_STD_SET_COMMON(set, T, std::less<T>, std::allocator<T>)
55+
%extend {
56+
%flc_extend_set_pod(T)
57+
}
58+
};
59+
}
60+
%enddef
61+
1462
/* -------------------------------------------------------------------------
1563
* Numeric sets
1664
* ------------------------------------------------------------------------- */
1765

18-
%template(SetInt) std::set<int>;
66+
%specialize_std_set_pod(int)
1967

20-
%include <std_string.i>
21-
%import "flc_string.i"
68+
%template(SetInt) std::set<int>;
2269

2370
/* -------------------------------------------------------------------------
2471
* String sets
2572
* ------------------------------------------------------------------------- */
2673

74+
%fortran_autofree_rvalue(std::set<std::string>);
75+
76+
// Allow direct insertion of a wrapped std::string
77+
%extend std::set<std::string> {
78+
void insert_ref(std::string& str) {
79+
$self->insert(str);
80+
}
81+
}
82+
83+
%include <std_string.i>
84+
%import "flc_string.i"
2785
%template(SetString) std::set<std::string>;
86+

src/flc_set.f90

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ module flc_set
2323
type(C_PTR), public :: cptr = C_NULL_PTR
2424
integer(C_INT), public :: cmemflags = 0
2525
end type
26+
type, bind(C) :: SwigArrayWrapper
27+
type(C_PTR), public :: data = C_NULL_PTR
28+
integer(C_SIZE_T), public :: size = 0
29+
end type
2630
! class std::set< int >
2731
type, public :: SetInt
2832
type(SwigClassWrapper), public :: swigdata
@@ -32,18 +36,17 @@ module flc_set
3236
procedure :: clear => swigf_SetInt_clear
3337
procedure :: erase => swigf_SetInt_erase
3438
procedure :: count => swigf_SetInt_count
35-
procedure :: insert => swigf_SetInt_insert
39+
procedure, private :: swigf_SetInt_insert__SWIG_0
40+
procedure, private :: swigf_SetInt_insert__SWIG_1
3641
procedure :: release => swigf_release_SetInt
3742
procedure, private :: swigf_SetInt_op_assign__
3843
generic :: assignment(=) => swigf_SetInt_op_assign__
44+
generic :: insert => swigf_SetInt_insert__SWIG_0, swigf_SetInt_insert__SWIG_1
3945
end type SetInt
4046
interface SetInt
41-
module procedure swigf_create_SetInt
47+
module procedure swigf_new_SetInt__SWIG_0
48+
module procedure swigf_new_SetInt__SWIG_1
4249
end interface
43-
type, bind(C) :: SwigArrayWrapper
44-
type(C_PTR), public :: data = C_NULL_PTR
45-
integer(C_SIZE_T), public :: size = 0
46-
end type
4750
! class std::set< std::string >
4851
type, public :: SetString
4952
type(SwigClassWrapper), public :: swigdata
@@ -54,6 +57,7 @@ module flc_set
5457
procedure :: erase => swigf_SetString_erase
5558
procedure :: count => swigf_SetString_count
5659
procedure :: insert => swigf_SetString_insert
60+
procedure :: insert_ref => swigf_SetString_insert_ref
5761
procedure :: release => swigf_release_SetString
5862
procedure, private :: swigf_SetString_op_assign__
5963
generic :: assignment(=) => swigf_SetString_op_assign__
@@ -64,8 +68,8 @@ module flc_set
6468

6569
! WRAPPER DECLARATIONS
6670
interface
67-
function swigc_new_SetInt() &
68-
bind(C, name="_wrap_new_SetInt") &
71+
function swigc_new_SetInt__SWIG_0() &
72+
bind(C, name="_wrap_new_SetInt__SWIG_0") &
6973
result(fresult)
7074
use, intrinsic :: ISO_C_BINDING
7175
import :: swigclasswrapper
@@ -117,14 +121,33 @@ function swigc_SetInt_count(farg1, farg2) &
117121
integer(C_LONG) :: fresult
118122
end function
119123

120-
subroutine swigc_SetInt_insert(farg1, farg2) &
121-
bind(C, name="_wrap_SetInt_insert")
124+
subroutine swigc_SetInt_insert__SWIG_0(farg1, farg2) &
125+
bind(C, name="_wrap_SetInt_insert__SWIG_0")
122126
use, intrinsic :: ISO_C_BINDING
123127
import :: swigclasswrapper
124128
type(SwigClassWrapper) :: farg1
125129
integer(C_INT), intent(in) :: farg2
126130
end subroutine
127131

132+
function swigc_new_SetInt__SWIG_1(farg1) &
133+
bind(C, name="_wrap_new_SetInt__SWIG_1") &
134+
result(fresult)
135+
use, intrinsic :: ISO_C_BINDING
136+
import :: swigclasswrapper
137+
import :: swigarraywrapper
138+
type(SwigArrayWrapper) :: farg1
139+
type(SwigClassWrapper) :: fresult
140+
end function
141+
142+
subroutine swigc_SetInt_insert__SWIG_1(farg1, farg2) &
143+
bind(C, name="_wrap_SetInt_insert__SWIG_1")
144+
use, intrinsic :: ISO_C_BINDING
145+
import :: swigclasswrapper
146+
import :: swigarraywrapper
147+
type(SwigClassWrapper) :: farg1
148+
type(SwigArrayWrapper) :: farg2
149+
end subroutine
150+
128151
subroutine swigc_delete_SetInt(farg1) &
129152
bind(C, name="_wrap_delete_SetInt")
130153
use, intrinsic :: ISO_C_BINDING
@@ -204,6 +227,14 @@ subroutine swigc_SetString_insert(farg1, farg2) &
204227
type(SwigArrayWrapper) :: farg2
205228
end subroutine
206229

230+
subroutine swigc_SetString_insert_ref(farg1, farg2) &
231+
bind(C, name="_wrap_SetString_insert_ref")
232+
use, intrinsic :: ISO_C_BINDING
233+
import :: swigclasswrapper
234+
type(SwigClassWrapper) :: farg1
235+
type(SwigClassWrapper) :: farg2
236+
end subroutine
237+
207238
subroutine swigc_delete_SetString(farg1) &
208239
bind(C, name="_wrap_delete_SetString")
209240
use, intrinsic :: ISO_C_BINDING
@@ -224,13 +255,13 @@ subroutine swigc_SetString_op_assign__(farg1, farg2) &
224255

225256
contains
226257
! MODULE SUBPROGRAMS
227-
function swigf_create_SetInt() &
258+
function swigf_new_SetInt__SWIG_0() &
228259
result(self)
229260
use, intrinsic :: ISO_C_BINDING
230261
type(SetInt) :: self
231262
type(SwigClassWrapper) :: fresult
232263

233-
fresult = swigc_new_SetInt()
264+
fresult = swigc_new_SetInt__SWIG_0()
234265
self%swigdata = fresult
235266
end function
236267

@@ -316,7 +347,7 @@ function swigf_SetInt_count(self, x) &
316347
swig_result = int(fresult)
317348
end function
318349

319-
subroutine swigf_SetInt_insert(self, x)
350+
subroutine swigf_SetInt_insert__SWIG_0(self, x)
320351
use, intrinsic :: ISO_C_BINDING
321352
class(SetInt), intent(in) :: self
322353
integer(C_INT), intent(in) :: x
@@ -325,7 +356,48 @@ subroutine swigf_SetInt_insert(self, x)
325356

326357
farg1 = self%swigdata
327358
farg2 = x
328-
call swigc_SetInt_insert(farg1, farg2)
359+
call swigc_SetInt_insert__SWIG_0(farg1, farg2)
360+
end subroutine
361+
362+
subroutine SWIGTM_fin_int_Sb__SB_(finp, iminp)
363+
use, intrinsic :: ISO_C_BINDING
364+
integer(C_INT), dimension(:), intent(in), target :: finp
365+
type(SwigArrayWrapper), intent(out) :: iminp
366+
integer(C_SIZE_T) :: sz
367+
integer(C_INT), pointer :: imtemp
368+
369+
sz = size(finp, kind=C_SIZE_T)
370+
if (sz > 0_c_size_t) then
371+
imtemp => finp(1)
372+
iminp%data = c_loc(imtemp)
373+
else
374+
iminp%data = c_null_ptr
375+
end if
376+
iminp%size = sz
377+
end subroutine
378+
function swigf_new_SetInt__SWIG_1(data) &
379+
result(self)
380+
use, intrinsic :: ISO_C_BINDING
381+
type(SetInt) :: self
382+
integer(C_INT), dimension(:), intent(in), target :: data
383+
type(SwigClassWrapper) :: fresult
384+
type(SwigArrayWrapper) :: farg1
385+
386+
call SWIGTM_fin_int_Sb__SB_(data, farg1)
387+
fresult = swigc_new_SetInt__SWIG_1(farg1)
388+
self%swigdata = fresult
389+
end function
390+
391+
subroutine swigf_SetInt_insert__SWIG_1(self, data)
392+
use, intrinsic :: ISO_C_BINDING
393+
class(SetInt), intent(in) :: self
394+
integer(C_INT), dimension(:), intent(in), target :: data
395+
type(SwigClassWrapper) :: farg1
396+
type(SwigArrayWrapper) :: farg2
397+
398+
farg1 = self%swigdata
399+
call SWIGTM_fin_int_Sb__SB_(data, farg2)
400+
call swigc_SetInt_insert__SWIG_1(farg1, farg2)
329401
end subroutine
330402

331403
subroutine swigf_release_SetInt(self)
@@ -467,6 +539,18 @@ subroutine swigf_SetString_insert(self, x)
467539
call swigc_SetString_insert(farg1, farg2)
468540
end subroutine
469541

542+
subroutine swigf_SetString_insert_ref(self, str)
543+
use, intrinsic :: ISO_C_BINDING
544+
class(SetString), intent(in) :: self
545+
class(string), intent(in) :: str
546+
type(SwigClassWrapper) :: farg1
547+
type(SwigClassWrapper) :: farg2
548+
549+
farg1 = self%swigdata
550+
farg2 = str%swigdata
551+
call swigc_SetString_insert_ref(farg1, farg2)
552+
end subroutine
553+
470554
subroutine swigf_release_SetString(self)
471555
use, intrinsic :: ISO_C_BINDING
472556
class(SetString), intent(inout) :: self

0 commit comments

Comments
 (0)