Vector¶
Vectors are resizeable arrays of elements. The flc_vector
module
instantiates vectors of integer(4)
, integer(8)
, real(8)
,
complex(8)
, and type(String)
.
Common functionality¶
All vector types support the following basic operations.
Construction and destruction¶
Vectors are constructed using four interface functions:
- The function without arguments creates an empty vector;
- A single integer argument assigns that many elements with default values; and
- An integer argument followed by an element with the vector’s element type will copy that value to all elements of the vector.
- A vector object will create a copy of that vector.
Here are three examples of initialization:
use flc_vector, only : Vector => VectorInt4
type(Vector) :: v
v = Vector()
! v%size() == 0
v = Vector(10)
! v%size() == 10
! v%get(i) == 0
v = Vector(10, 123)
! v%size() == 10
! v%get(i) == 123
Vectors are destroyed using the release
type-bound subroutine:
call v%release()
Modification¶
Vectors can be resized dynamically using resize
, which acts like the
constructors described above. An element can be added to
the end of the vector (increasing the size by one) with push_back
. The
insert
method can insert an element at a specific index, and erase
removes a specific vector index or range of indices. clear
removes
all elements. Finally, set
sets the value of an element at a given index.
Important
Unlike the C++ version of this class, all vectors in Flibcpp
use 1-offset indexing. This means that v%get(1)
is the same as the C++
v[0]
: it returns the first element (i.e. the element with an offset of
zero).
Here’s an example of modifying a vector:
use flc_vector, only : Vector => VectorInt4
type(Vector) :: v
v = Vector()
call v%resize(4, 123) ! give each element the value 123
call v%push_back(-1) ! size increased by 1, last element has value -1
call v%insert(2, -2) ! First 3 elements are [123, 123, -2]
call v%erase(1, 3) ! Remove the first two elements
call v%erase(2) ! Remove the second element
call v%set(1, -123) ! Change the value of the first element
call v%clear() ! Remove all elements, size is now zero
Access¶
The size of a vector is returned by the bound function size
; get
returns the value at an index; and front
and back
are aliases for
get(1)
and get(v%size())
, respectively.
Additionally, front_ref
, back_ref
, and get_ref
return Fortran
pointers to the elements of the array.
Warning
Array element pointers are valid only as long as the vector’s
size is not changed. Calling erase
, push_back
, and so forth will
invalidate the pointer; accessing it at that point results in undefined
behavior.
Numeric vectors¶
As with the algorithms and other methods, the flc_vector
module includes
three scalar numeric instantiations, but it also includes an instantiation for
complex numbers. Each instantiation has a distinct derived type:
VectorInt4
: each element isinteger(4)
VectorInt8
: each element isinteger(8)
VectorReal8
: each element isreal(8)
VectorComplex8
: each element iscomplex(8)
Construct from an array¶
Numeric vectors can be created very efficiently from Fortran data by accepting an array pointer:
use flc_vector, only : Vector => VectorInt4
integer(4), dimension(4), parameter :: iarr = [ 1, -2, 4, -8 ]
type(Vector) :: v
v = Vector(iarr)
write(0,*) "Size should be 4:", v%size()
The assign
bound method acts like a constructor but for an existing vector.
View as an array pointer¶
Numeric vectors can also return an array pointer to the vector’s contents. These views support native Fortran array operations and access the same underlying memory as the C++ object:
use flc_vector, only : Vector => VectorInt4
integer(4), dimension(:), pointer :: vptr
type(Vector) :: v
! <snip>
vptr => v%view()
if (size(vptr) > 2) then
vptr(2) = 4
end if
Warning
A vector’s view is valid only as long as the vector’s size is
not changed. Calling erase
, push_back
, and so forth will invalidate
the view; accessing it at that point results in undefined behavior.
String vectors¶
The native “element” type of VectorString
is a character(len=:)
. Vector
operations that accept an input will take any native character string; and
returned values will be allocatable character arrays.
The front_ref
, back_ref
, and get_ref
functions allow the underlying
std::string
class to be accessed with the String
Fortran derived type
wrapper. Note that unlike for intrinsic types, where these functions return a
integer, pointer
, the vector of strings returns just type(String)
.
However, as with native pointers described above, these references are
invalid once the string changes size. They should be cleared with the
%release()
bound method.
An additional set_ref
function allows vector elements to be assigned from
String
types.