Skip to content

Commit afae511

Browse files
committed
Change set algorithms to be member functions
1 parent 6758e11 commit afae511

File tree

4 files changed

+488
-462
lines changed

4 files changed

+488
-462
lines changed

doc/modules/set.rst

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Set
1111
Sets are sorted containers of unique elements. The ``flc_set`` module
1212
defines sets of ``integer`` and of ``type(String)``.
1313

14-
Common functionality
14+
Basic functionality
1515
===================
1616

1717
All set types support the following basic operations.
@@ -49,17 +49,42 @@ Here's an example of creating, modifying, and destroying a set::
4949
call s%release() ! Free memory
5050

5151
Set operations
52-
==============
52+
--------------
53+
54+
The Fortran ``Set`` classes have been extended to include several useful set
55+
algorithms. (In C++, these are implemented using the ``<algorithm>`` header and
56+
therefore should resemble the functions in
57+
:ref:`the flc_algorithm module <modules_algorithm_set_operations>`.
58+
59+
All set operations take a single argument, another ``Set`` object, and do not
60+
modify either the original or the argument. All but the ``includes`` return
61+
newly allocated ``Set`` instances and do not modify the original sets.
62+
63+
``difference``: :math:`A \setminus B`
64+
Returns a new set with all elements from the original that are *not* present
65+
in the other set.
66+
67+
``intersection``: :math:`A \cap B`
68+
Return all elements that are in both sets.
69+
70+
``symmetric_difference``: :math:`(A \setminus B) \cup (B \setminus A)`
71+
Return all elements that are in one set or the other but not both.
5372

54-
Operations that take two sets are implemented as free functions.
73+
``union``: :math:`A \cup B`
74+
Return all elements that are in either set.
5575

76+
``includes``: :math:`A \supseteq B`
77+
Return whether all elements of the other set are in the original set.
5678

5779
Numeric sets
5880
===============
5981

6082
Unlike :ref:`vectors<modules_Vector>`, the ``flc_set`` module includes
6183
a single "native integer" numeric instantiations. The value type is
62-
``integer(C_INT)`` and is 64 bits on most modern systems.
84+
``integer(C_INT)`` and is 64 bits on most modern systems. Since the C++
85+
implementation of numerical sets is not very efficient, the assumption is that
86+
the ``set`` will be used in a non-numerically-intensive capacity where the
87+
default integer is the most appropriate option.
6388

6489
Construct from an array
6590
-----------------------

include/flc_set.i

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,28 @@
2121
* Macro definitions
2222
* ------------------------------------------------------------------------- */
2323

24-
%define %flc_set_algorithm(FUNCNAME)
25-
%inline {
26-
template<class Set_t>
27-
static Set_t FUNCNAME(const Set_t& left, const Set_t& right)
28-
{
29-
Set_t result;
30-
std::FUNCNAME(left.begin(), left.end(),
31-
right.begin(), right.end(),
32-
std::inserter(result, result.end()));
33-
return result;
34-
}
35-
}
36-
37-
%template(FUNCNAME) FUNCNAME<std::set<int> >;
38-
%template(FUNCNAME) FUNCNAME<std::set<std::string> >;
24+
%define %flc_define_set_algorithm(FUNCNAME)
25+
%insert("header") {
26+
template<class Set_t>
27+
static Set_t flc_##FUNCNAME(const Set_t& left, const Set_t& right)
28+
{
29+
Set_t result;
30+
std::FUNCNAME(left.begin(), left.end(),
31+
right.begin(), right.end(),
32+
std::inserter(result, result.end()));
33+
return result;
34+
}
35+
} // end %insert
36+
%enddef
3937

38+
%define %flc_extend_set_algorithm(FUNCNAME, RETVAL, TYPE)
39+
// The rename with the stringifying macro is necessary because 'union' is a
40+
// keyword.
41+
%rename(#FUNCNAME) std::set<TYPE>::set_##FUNCNAME;
42+
%extend std::set<TYPE> {
43+
RETVAL set_##FUNCNAME(const std::set<TYPE>& other)
44+
{ return flc_set_##FUNCNAME(*$self, other); }
45+
} // end %extend
4046
%enddef
4147

4248
%define %flc_extend_set_pod(CTYPE)
@@ -52,7 +58,6 @@ static Set_t FUNCNAME(const Set_t& left, const Set_t& right)
5258
void insert(const CTYPE* DATA, size_type SIZE) {
5359
$self->insert(DATA, DATA + SIZE);
5460
}
55-
5661
%enddef
5762

5863
/* ------------------------------------------------------------------------- */
@@ -83,10 +88,37 @@ namespace std {
8388
}
8489
%enddef
8590

91+
/* -------------------------------------------------------------------------
92+
* Algorithms
93+
* ------------------------------------------------------------------------- */
94+
95+
%flc_define_set_algorithm(set_difference)
96+
%flc_define_set_algorithm(set_intersection)
97+
%flc_define_set_algorithm(set_symmetric_difference)
98+
%flc_define_set_algorithm(set_union)
99+
100+
%insert("header") %{
101+
template<class Set_t>
102+
static bool flc_set_includes(const Set_t& left, const Set_t& right)
103+
{
104+
return std::includes(left.begin(), left.end(),
105+
right.begin(), right.end());
106+
}
107+
%}
108+
109+
%define %flc_extend_algorithms(TYPE)
110+
%flc_extend_set_algorithm(difference, std::set<TYPE >, TYPE)
111+
%flc_extend_set_algorithm(intersection, std::set<TYPE >, TYPE)
112+
%flc_extend_set_algorithm(symmetric_difference, std::set<TYPE >, TYPE)
113+
%flc_extend_set_algorithm(union, std::set<TYPE >, TYPE)
114+
%flc_extend_set_algorithm(includes, bool, TYPE)
115+
%enddef
116+
86117
/* -------------------------------------------------------------------------
87118
* Numeric sets
88119
* ------------------------------------------------------------------------- */
89120

121+
%flc_extend_algorithms(int)
90122
%specialize_std_set_pod(int)
91123

92124
%template(SetInt) std::set<int>;
@@ -106,26 +138,5 @@ namespace std {
106138

107139
%include <std_string.i>
108140
%import "flc_string.i"
141+
%flc_extend_algorithms(std::string)
109142
%template(SetString) std::set<std::string>;
110-
111-
/* -------------------------------------------------------------------------
112-
* Algorithms
113-
* ------------------------------------------------------------------------- */
114-
115-
%flc_set_algorithm(set_difference)
116-
%flc_set_algorithm(set_intersection)
117-
%flc_set_algorithm(set_symmetric_difference)
118-
%flc_set_algorithm(set_union)
119-
120-
%inline %{
121-
template<class Set_t>
122-
static bool includes(const Set_t& left, const Set_t& right)
123-
{
124-
return std::includes(left.begin(), left.end(),
125-
right.begin(), right.end());
126-
}
127-
%}
128-
129-
%template(includes) includes<std::set<int> >;
130-
%template(includes) includes<std::set<std::string> >;
131-

0 commit comments

Comments
 (0)