Skip to content

Commit 8a0af91

Browse files
committed
Add and document numeric vectors
1 parent 3e2ff73 commit 8a0af91

File tree

9 files changed

+3578
-5
lines changed

9 files changed

+3578
-5
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ swig_fortran_add_module(flc_random)
169169
target_link_libraries(flc_random flc)
170170
swig_fortran_add_module(flc_algorithm)
171171
target_link_libraries(flc_algorithm flc_random flc)
172+
swig_fortran_add_module(flc_vector)
173+
target_link_libraries(flc_vector flc)
172174

173175
#---------------------------------------------------------------------------#
174176
# INSTALLATION

doc/interface.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,24 @@ flc_algorithm
2424
.. literalinclude:: ../src/flc_algorithm.i
2525
:linenos:
2626

27+
flc_chrono
28+
=============
29+
30+
.. literalinclude:: ../src/flc_chrono.i
31+
:linenos:
32+
2733
flc_random
2834
=============
2935

3036
.. literalinclude:: ../src/flc_random.i
3137
:linenos:
3238

39+
flc_vector
40+
=============
41+
42+
.. literalinclude:: ../src/flc_vector.i
43+
:linenos:
44+
3345
.. ############################################################################
3446
.. end of doc/interface.rst
3547
.. ############################################################################

doc/modules.rst

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,24 @@ The modules themselves are namespaced with a ``flc_`` prefix, so
1313
for example the ``std::sort`` algorithm, available in the ``<algorithm>``
1414
header, can be obtained via::
1515

16-
use :: flc_algorithm, only : sort
16+
use flc_algorithm, only : sort
1717

18-
All templated routines are instantiated with 32- and 64-bit signed integers,
19-
and double-precision floats.
18+
All templated routines are instantiated with 32- and 64-bit signed integers
19+
(``integer(4)`` and ``integer(8)``), and double-precision floats (``real(8)``).
20+
21+
Some modules support error handling for checking input values. In all cases,
22+
the error status and a message can be accessed and cleared through the main
23+
``flc`` module::
24+
25+
use flc, only : ierr, get_serr
26+
27+
! <snip>
28+
if (ierr /= 0) then
29+
write(1,*) "Error", ierr, ":", get_serr()
30+
! Reset the error flag to indicate that the error has been successfully
31+
! handled.
32+
ierr = 0
33+
fi
2034

2135
.. toctree::
2236
modules/algorithm.rst
@@ -25,6 +39,7 @@ and double-precision floats.
2539
modules/random.rst
2640
modules/set.rst
2741
modules/string.rst
42+
modules/vector.rst
2843

2944

3045
.. ############################################################################

doc/modules/vector.rst

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
.. ############################################################################
2+
.. File : doc/modules/vector.rst
3+
.. ############################################################################
4+
5+
.. _modules_Vector:
6+
7+
******
8+
Vector
9+
******
10+
11+
Vectors are resizeable arrays of elements. All vectors support the following
12+
basic operations.
13+
14+
Construction and destruction
15+
----------------------------
16+
17+
Vectors are constructed using three interface functions:
18+
19+
- The function without arguments creates an empty vector;
20+
- A single integer argument assigns that many elements with default values;
21+
and
22+
- An integer argument followed by an element with the vector's element type
23+
will copy that value to all elements of the vector.
24+
25+
(To do: copy construction)
26+
27+
Here are three examples of initialization::
28+
29+
use flc_vector, only : Vector => VectorInt4
30+
type(Vector) :: v
31+
32+
v = Vector()
33+
! v%size() == 0
34+
v = Vector(10)
35+
! v%size() == 10
36+
! v%get(i) == 0
37+
v = Vector(10, 123)
38+
! v%size() == 10
39+
! v%get(i) == 123
40+
41+
Vectors are destroyed using the ``release`` type-bound subroutine::
42+
43+
call v%release()
44+
45+
Modification
46+
------------
47+
48+
Vectors can be resized dynamically using ``resize``, which acts like the
49+
constructors described above. An element can be added to
50+
the end of the vector (increasing the size by one) with ``push_back``. The
51+
``insert`` method can insert an element at a specific index, and ``erase``
52+
removes a specific vector index or range of indices. ``clear`` removes
53+
all elements. Finally, ``set`` sets the value of an element at a given index.
54+
55+
.. important:: Unlike the C++ version of this class, **all vectors in flibcpp
56+
use 1-offset indexing**. This means that ``v%get(1)`` is the same as the C++
57+
``v[0]``: it returns the first element (i.e. the element with an offset of
58+
zero).
59+
60+
Here's an example of modifying a vector::
61+
62+
use flc_vector, only : Vector => VectorInt4
63+
type(Vector) :: v
64+
v = Vector()
65+
call v%resize(4, 123) ! give each element the value 123
66+
call v%push_back(-1) ! size increased by 1, last element has value -1
67+
call v%insert(2, -2) ! First 3 elements are [123, 123, -2]
68+
call v%erase(1, 3) ! Remove the first two elements
69+
call v%erase(2) ! Remove the second element
70+
call v%set(1, -123) ! Change the value of the first element
71+
call v%clear() ! Remove all elements, size is now zero
72+
73+
Access
74+
------
75+
76+
The size of a vector is returned by the bound function ``size``; ``get``
77+
returns the value at an index; and ``front`` and ``back`` are aliases for
78+
``get(1)`` and ``get(v%size())``, respectively.
79+
80+
Numeric vectors
81+
===============
82+
83+
As with the algorithms and other methods, the ``flc_vector`` module includes
84+
three numeric instantiations. They each have distinct derived types:
85+
86+
- ``VectorInt4``: each element is ``integer(4)``
87+
- ``VectorInt8``: each element is ``integer(8)``
88+
- ``VectorReal8``: each element is ``real(8)``
89+
90+
Construct from an array
91+
-----------------------
92+
93+
Numeric vectors can be created very efficiently from Fortran data by accepting
94+
an array pointer::
95+
96+
use flc_vector, only : Vector => VectorInt4
97+
integer(4), dimension(4), parameter :: iarr = [ 1, -2, 4, -8 ]
98+
type(Vector) :: v
99+
100+
v = Vector(iarr)
101+
write(0,*) "Size should be 4:", v%size()
102+
103+
View as an array pointer
104+
------------------------
105+
106+
Numeric vectors can also return an array pointer to the vector's contents.
107+
These views support native Fortran array operations and access the same
108+
underlying memory as the C++ object::
109+
110+
use flc_vector, only : Vector => VectorInt4
111+
integer(4), dimension(:), pointer :: vptr
112+
type(Vector) :: v
113+
114+
! <snip>
115+
vptr => v%view()
116+
if (size(vptr) > 2) then
117+
vptr(2) = 4
118+
end if
119+
120+
.. warning:: A vector's view is valid **only** as long as the vector's size is
121+
not changed. Calling ``erase``, ``push_back``, and so forth will invalidate
122+
the view; accessing it at that point results in undefined behavior.
123+
124+
String vectors
125+
==============
126+
127+
String vectors are not yet implemented.
128+
129+
.. ############################################################################
130+
.. end of doc/modules/vector.rst
131+
.. ############################################################################

src/flc_vector.i

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*!
2+
* \file flc_vector.i
3+
*
4+
* Copyright (c) 2019 Oak Ridge National Laboratory, UT-Battelle, LLC.
5+
* Distributed under an MIT open source license: see LICENSE for details.
6+
*/
7+
8+
%module "flc_vector"
9+
%include "import_flc.i"
10+
11+
%include <std_vector.i>
12+
13+
/* ------------------------------------------------------------------------- */
14+
%define EXTEND_STD_VECTOR_POD_INTERNAL(CTYPE)
15+
%apply (const SWIGTYPE *DATA, ::size_t SIZE)
16+
{ (const CTYPE* DATA, size_type SIZE) };
17+
18+
// Construct from an array of data
19+
vector(const CTYPE* DATA, size_type SIZE) {
20+
return new std::vector<CTYPE>(DATA, DATA + SIZE);
21+
}
22+
23+
// Assign from another vector
24+
void assign(const CTYPE* DATA, size_type SIZE) {
25+
$self->assign(DATA, DATA + SIZE);
26+
}
27+
28+
// Get a mutable view to ourself
29+
%fortran_array_pointer(CTYPE, vector<CTYPE>& view);
30+
31+
%typemap(out, noblock=1) vector<CTYPE>& view {
32+
$result.data = ($1->empty() ? NULL : &(*$1->begin()));
33+
$result.size = $1->size();
34+
}
35+
36+
vector<CTYPE>& view() {
37+
return *$self;
38+
}
39+
%enddef
40+
41+
/* ------------------------------------------------------------------------- */
42+
/*! \def EXTEND_STD_VECTOR_POD_INTERNAL
43+
*
44+
* Inject member functions and typemaps for POD classes.
45+
*
46+
* These provide an efficient constructor from a Fortan array view. It also
47+
* offers a "view" functionality for getting an array pointer to the
48+
* vector-owned data.
49+
*/
50+
%define %specialize_std_vector_pod(T)
51+
namespace std {
52+
template<> class vector<T> {
53+
SWIG_STD_VECTOR_MINIMUM_INTERNAL(T, const T&)
54+
%extend {
55+
EXTEND_STD_VECTOR_POD_INTERNAL(T)
56+
}
57+
};
58+
}
59+
%enddef
60+
61+
/* ------------------------------------------------------------------------- */
62+
63+
%specialize_std_vector_pod(int32_t)
64+
%specialize_std_vector_pod(int64_t)
65+
%specialize_std_vector_pod(double)
66+
67+
%template(VectorInt4) std::vector<int32_t>;
68+
%template(VectorInt8) std::vector<int64_t>;
69+
%template(VectorReal8) std::vector<double>;

0 commit comments

Comments
 (0)