STD Algorithm Library in C++

 
L
a
b
 
8
 
STD algorithm library,  STD filesystem,
measuring time with std::chrono
 
 
 
 
 
23
. 10. 2023
O
u
t
l
i
n
e
 
2023/2024
 
Programming in C++ (labs)
 
2
 
1.
STD algorithms
2.
STD filesystem library
3.
Measuring time with std::chrono
4.
Task 08 - recursive file searcher
 
1
)
 
S
T
D
 
a
l
g
o
r
i
t
h
m
s
M
o
t
i
v
a
t
i
o
n
 
2023/2024
 
Programming in C++ (labs)
 
4
 
It makes code more expressive
Less readable code, more useful work
Avoid common mistakes
Like off-by-one problems
Battle-tested and reasonably performant
Readibility
same interface across all C++ users
https://www.youtube.com/watch?v=2olsGf6JIkU
F
u
r
t
h
e
r
 
r
e
a
d
i
n
g
The part about
algorithms is well
presented in the
cppcon talk here
O
v
e
r
v
i
e
w
 
o
f
 
<
a
l
g
o
r
i
t
h
m
>
 
2023/2024
 
Programming in C++ (labs)
 
5
 
Permutations
Playing with the order of elements inside some range
Queries
Do not mutate the source ranges
Just retrieve/compute/aggregate some information about the range
Set algorithms
on any sorted range
Element movers
copy, move
Value modifiers
Modify the values in ranges
Structure changers
Remove certain elements from the range
std::transform and std::for_each
 
 
 
 
 
r
a
n
g
e
 
~
 
a
n
y
t
h
i
n
g
 
y
o
u
 
c
a
n
 
i
t
e
r
a
t
e
 
o
v
e
r
(e.g. a container, range, initializer_list)
#include <algorithm>
https://en.cppreference.com/w/cpp/algorithm
https://en.cppreference.com/w/cpp/algorithm/ranges
F
u
r
t
h
e
r
 
r
e
a
d
i
n
g
C++20 brings even
more power and
flexibility to STD
algorithms
There is no longer need to
provide iterator pairs all the time.
std::vector is implicitly convertible
to a range
B
e
 
a
w
a
r
e
 
t
h
a
t
 
f
u
n
c
t
i
o
n
s
 
t
a
k
i
n
g
 
i
t
e
r
a
t
o
r
s
 
c
a
n
n
o
t
 
c
h
a
n
g
e
 
t
h
e
 
a
c
t
u
a
l
 
c
o
n
t
a
i
n
e
r
 
s
i
z
e
 
2023/2024
 
Programming in C++ (labs)
 
6
 
F
u
n
c
t
i
o
n
s
 
i
n
 
t
h
e
 
a
l
g
o
r
i
t
h
m
 
l
i
b
r
a
r
y
 
c
a
n
n
o
t
 
c
h
a
n
g
e
 
t
h
e
 
s
i
z
e
 
o
f
 
t
h
e
 
a
c
t
u
a
l
 
u
n
d
e
r
l
y
i
n
g
 
s
t
r
u
c
t
u
r
e
They can only work on the range provided
Move things around
Change values
Read values and compute things from it
 
E.g. function `std::pop_heap(it_begin, it_end);` cannot change the size of the underlying
structure
It will leave the "popped" value at the end
You will need to call vec.pop_back() separately
P
e
r
m
u
t
a
t
i
o
n
s
:
 
h
e
a
p
s
 
2023/2024
 
Programming in C++ (labs)
 
7
 
For contiguous memory ranges
 
std::make_heap
Creates the heap structure in-place in the vector
 
std::push_heap
Takes the last element and inserts it into the heap
 
 
std::pop_heap
Moves the first element to the back, and creates
heap on the range without the last element
P
e
r
m
u
t
a
t
i
o
n
s
:
 
h
e
a
p
s
 
2023/2024
 
Programming in C++ (labs)
 
8
std
::
vector
<
int
> 
xs1
({
3
, 
2
, 
4
, 
1
, 
5
, 
9
});
// initially: 3 2 4 1 5 9
// Making the heap from range
std
::
make_heap
(
xs1
.
begin
(), 
xs1
.
end
());
// after make_heap: 9 5 4 1 2 3
// Pushing new element into the heap
xs1
.
push_back
(
10
);
// after push_back: 9 5 4 1 2 3 10
std
::
ranges
::
push_heap
(xs1);
 //< Using ranges!
// after push_heap: 10 5 9 1 2 3 4
// Poping the heap element
std
::
pop_heap
(
xs1
.
begin
(), 
xs1
.
end
());
// after pop_heap : 9 5 4 1 2 3 10
xs1
.
pop_back
();
// after pop_back: 9 5 4 1 2 3
P
e
r
m
u
t
a
t
i
o
n
s
:
 
s
o
r
t
i
n
g
 
2023/2024
 
Programming in C++ (labs)
 
9
 
std::sort
Sorts the provided range
std::partial_sort
Sorts the 
first `(
middle
 
-
 
begin
)`
 elements  from the
whole range and leaves them in the beginning
 
 
 
 
 
std::nth_element
Puts the element to the provided middle iterator what
would be there if the range was sorted
the rest is in unspecified order
P
e
r
m
u
t
a
t
i
o
n
s
:
 
s
o
r
t
i
n
g
 
2023/2024
 
Programming in C++ (labs)
 
10
std
::
vector
<
int
> 
xs1
({ 
4
, 
9
, 
5
, 
1
, 
2
, 
3
 });
std
::vector
<
int
>
 xs2, xs3, xs4, xs5;
xs2 
=
 xs3 
=
 xs4 
=
 xs5 
=
 xs1;
// initially: 3 2 4 1 5 9
std
::
stable_sort
(
xs1
.
begin
(), 
xs1
.
end
());
// after sort : 1 2 3 4 5 9
std
::
ranges
::
sort
(xs2);
// after ranges sort : 1 2 3 4 5 9
std
::
ranges
::
sort
(
std
::
ranges
::
reverse_view
(xs3));
// after reverse ranges sort : 9 5 4 3 2 1
std
::
partial_sort
(
xs4
.
begin
(), 
xs4
.
begin
() 
+
 
3
, 
xs4
.
end
());
// after partial_sort with mid 3: 1 2 3 9 5 4
std
::
nth_element
(
xs5
.
begin
(), 
xs5
.
begin
() 
+
 
3
, 
xs5
.
end
());
// after nth_element with mid 3: 3 2 1 4 9 5
P
e
r
m
u
t
a
t
i
o
n
s
:
 
p
a
r
t
i
t
i
o
n
i
n
g
 
2023/2024
 
Programming in C++ (labs)
 
11
 
Separates the range into those returning true from predicate
These are at the beginning
P
e
r
m
u
t
a
t
i
o
n
s
:
 
p
a
r
t
i
t
i
o
n
i
n
g
 
2023/2024
 
Programming in C++ (labs)
 
12
std
::forward_list
<
int
>
 xs1 {
0
, 
1
, 
2
, 
3
, 
4
, 
5
, 
6
, 
7
, 
8
, 
9
};
std
::forward_list
<
int
>
 xs2, xs3, xs4, xs5;
xs2 
=
 xs3 
=
 xs4 
=
 xs5 
=
 xs1;
// Returns partition point
auto
 par_point1 
=
 
std
::
partition
(
xs1
.
begin
(), 
xs1
.
end
(), [](
int
 
i
) {
return
 i 
%
 
2
 
==
 
0
; });
// par_point1: 5
// after partition : 0 2 4 6 8 5 3 7 1 9
// Returns subrange to the second group
auto
 subrange 
=
 
std
::
ranges
::
partition
(xs2, [](
int
 
i
) {
return
 i 
%
 
2
 
==
 
0
; });
// subrange: 5 3 7 1 9
// after partition : 0 2 4 6 8 5 3 7 1 9
P
e
r
m
u
t
a
t
i
o
n
s
:
 
r
o
t
a
t
e
 
a
n
d
 
s
h
u
f
f
l
e
 
2023/2024
 
Programming in C++ (labs)
 
13
 
std::rotate
Takes element from the back and puts it into the front
 
std::shuffle
 
 
 
 
 
std::next_permutation/prev_permutation
Useful if you want to iterate over all possible permutations
 
std::reverse
in-place reverse of the range
 
 
P
e
r
m
u
t
a
t
i
o
n
s
:
 
r
o
t
a
t
e
 
a
n
d
 
s
h
u
f
f
l
e
 
2023/2024
 
Programming in C++ (labs)
 
14
 
std
::
deque
<
int
> 
xs1
({
1
, 
2
, 
3
, 
4
, 
5
 });
std
::
deque
<
int
>
 xs2, xs3, xs4, xs5, xs6;
xs2 
=
 xs3 
=
 xs4 
=
 xs5 
=
 xs6 
=
 xs1;
// initially: 1 2 3 4 5
// simple rotation to the left
std
::
rotate
(
xs1
.
begin
(), 
xs1
.
begin
() 
+
 
2
, 
xs1
.
end
());
// rotate left by 2: 3 4 5 1 2
// simple rotation to the right
std
::
rotate
(
xs2
.
rbegin
(), 
xs2
.
rbegin
() 
+
 
2
, 
xs2
.
rend
());
// rotate right by 2: 4 5 1 2 3
// Shuffle randomly
std
::
random_device 
rd;
std
::
mt19937
 
g
(
rd
());
std
::
shuffle
(
xs3
.
begin
(), 
xs3
.
end
(), g);
// shuffle: 3 1 2 5 4
std
::
ranges
::
shuffle
(xs4, g);
// range shuffle: 1 4 2 5 3
// Next permutation
std
::
next_permutation
(
xs5
.
begin
(), 
xs5
.
end
());
// next permutation: 1 2 3 5 4
// Prev permutation
std
::
ranges
::
prev_permutation
(xs6);
// prev permutation: 5 4 3 2 1
Q
u
e
r
i
e
s
 
2023/2024
 
Programming in C++ (labs)
 
15
 
count
reduce
inclusive_scan
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
#include <
numeric
>
Q
u
e
r
i
e
s
 
2023/2024
 
Programming in C++ (labs)
 
16
std
::
vector
<
int
> 
xs1
({ 
1
, 
2
, 
3
, 
4
, 
5
 });
// Use count
auto
 cnt1 
=
 
std
::
count
(
xs1
.
begin
(), 
xs1
.
end
(), 
4
);
// # elems == 4: 1
// Use count_if
auto
 cnt2 
=
 
std
::
count_if
(
xs1
.
begin
(), 
xs1
.
end
(),
    [](
int
 
x
) -> 
bool
 { 
return
 x 
>=
 
4
; });
// # elems >= 4: 2
// Using reduce to sum
int
 sum 
=
 
std
::
reduce
(
xs1
.
begin
(), 
xs1
.
end
());
// total sum: 15
// Inclusive sum
std
::
vector
<
int
> 
incl_sum
(
xs1
.
size
());
std
::
inclusive_scan
(
xs1
.
begin
(), 
xs1
.
end
(), 
incl_sum
.
begin
());
// cumulative sum: 1 3 6 10 15
M
o
r
e
 
q
u
e
r
i
e
s
 
2023/2024
 
Programming in C++ (labs)
 
17
 
inner_product -> dot product
adjacent_difference
sample
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
M
o
r
e
 
q
u
e
r
i
e
s
 
2023/2024
 
Programming in C++ (labs)
 
18
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
// Example 1: Use std::inner_product to calculate the dot product of two vectors
std
::vector
<
int
>
 
x
s1 
=
 { 
1, 
2
, 
3
, 
4
, 
5
 };
std
::vector
<
int
>
 ys1 
=
 { 
2
, 
4
, 
6
, 
8
, 
10
 };
int
 dot_product 
=
 
std
::
inner_product
(
xs1
.
begin
(), 
xs1
.
end
(), 
ys1
.
begin
(), 
0
);
// Dot product of xs1 and ys1: 110
// Example 2: Use std::adjacent_difference to calculate the differences between adjacent elements
std
::
vector
<
int
> 
differences
(
xs1
.
size
());
std
::
adjacent_difference
(
xs1
.
begin
(), 
xs1
.
end
(), 
differences
.
begin
());
// 
The first element is untouched
// Adjacent differences: 1 1 1 1 1
// Example 3: Use std::sample to randomly sample elements from xs1
std
::vector
<
int
>
 sampled;
std
::
mt19937
 
generator
(
std
::
random_device
{}());
std
::
sample
(
xs1
.
begin
(), 
xs1
.
end
(), 
std
::
back_inserter
(sampled), 
2
, generator);
// Randomly sampled elements: 4 5
Q
u
e
r
i
e
s
:
 
l
o
g
i
c
a
l
 
q
u
a
n
t
i
f
i
e
r
s
 
2023/2024
 
Programming in C++ (labs)
 
19
 
all_of
any_of
none_of
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
Q
u
e
r
i
e
s
:
 
l
o
g
i
c
a
l
 
q
u
a
n
t
i
f
i
e
r
s
 
2023/2024
 
Programming in C++ (labs)
 
20
std
::
vector
<
int
> 
xs1
({ 
2
, 
4
, 
6
 });
std
::cout 
<<
 
std
::
all_of
(
    
xs1
.
cbegin
(), 
xs1
.
cend
(), [](
int
 
i
) { 
return
 i 
%
 
2
 
==
 
0
; })
<<
 
std
::endl;
// 1
std
::cout 
<<
 
std
::
none_of
(
    
xs1
.
cbegin
(), 
xs1
.
cend
(), [](
int
 
i
) { 
return
 i 
%
 
2
 
!=
 
0
; })
<<
 
std
::endl;
// 1
std
::cout 
<<
 
std
::
any_of
(
    
xs1
.
cbegin
(), 
xs1
.
cend
(), [](
int
 
i
) { 
return
 i 
%
 
2
 
!=
 
0
; })
<<
 
std
::endl;
// 0
Q
u
e
r
i
e
s
:
 
c
o
m
p
a
r
i
n
g
 
r
a
n
g
e
s
 
2023/2024
 
Programming in C++ (labs)
 
21
 
equal
lexicographical_compare
mismatch
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
Q
u
e
r
i
e
s
:
 
c
o
m
p
a
r
i
n
g
 
r
a
n
g
e
s
 
2023/2024
 
Programming in C++ (labs)
 
22
std
::
deque
<
int
> 
xs1
({ 
1
, 
2
, 
3
, 
4
, 
5
 });
std
::
deque
<
int
> 
xs2
({ 
1
, 
2
, 
3
, 
4
, 
4
 });
// Example 1: Use std::equal to check if two ranges are equal
bool
 are_equal 
=
 
std
::
equal
(
xs1
.
begin
(), 
xs1
.
end
(), 
xs2
.
begin
());
std
::cout 
<<
 
std
::boolalpha 
<<
 are_equal 
<<
 
std
::endl;
// false
// Example 2: Use std::lexicographical_compare to check the lexicographical order of two ranges
bool
 is_less 
=
 
std
::
lexicographical_compare
(
xs2
.
begin
(), 
xs2
.
end
(), 
xs1
.
begin
(), 
xs1
.
end
());
std
::cout 
<<
 
std
::boolalpha 
<<
 is_less 
<<
 
std
::endl;
// true
// Example 3: Use std::mismatch to find the first position where two ranges differ
auto
 [fst_it, snd_it] 
=
 
std
::
mismatch
(
xs1
.
begin
(), 
xs1
.
end
(), 
xs2
.
begin
());
// *fst_it: 5, *snd_it: 4
Q
u
e
r
i
e
s
:
 
s
e
a
r
c
h
i
n
g
 
f
o
r
 
v
a
l
u
e
s
 
2023/2024
 
Programming in C++ (labs)
 
23
 
find
adjacent_find
 
lower_bound
upper_bound
binary_search
r
e
t
u
r
n
s
 
b
o
o
l
,
 
n
o
t
 
i
t
e
r
a
t
o
r
!
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
Q
u
e
r
i
e
s
:
 
s
e
a
r
c
h
i
n
g
 
f
o
r
 
r
a
n
g
e
 
o
f
 
v
a
l
u
e
s
 
2023/2024
 
Programming in C++ (labs)
 
24
 
Search for the sequence of elements
search
find_end
Search for one of the sequence elements
find_first_of
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
Q
u
e
r
i
e
s
:
 
s
e
a
r
c
h
i
n
g
 
f
o
r
 
r
e
l
a
t
i
v
e
 
v
a
l
u
e
s
 
2023/2024
 
Programming in C++ (labs)
 
25
 
max_element
min_element
minmax_element
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
A
l
g
o
r
i
t
h
m
s
 
o
n
 
s
e
t
s
 
/
 
s
o
r
t
e
d
 
r
a
n
g
e
s
 
2023/2024
 
Programming in C++ (labs)
 
26
 
F
r
o
m
 
t
h
e
 
P
O
V
 
o
f
 
t
h
e
 
a
l
g
o
r
i
t
h
m
 
l
i
b
r
a
r
y
,
 
a
s
e
t
 
i
s
 
a
n
y
 
s
o
r
t
e
d
 
c
o
n
t
a
i
n
e
r
 
(
a
l
s
o
 
s
o
r
t
e
d
s
t
d
:
:
v
e
c
t
o
r
)
i.e. iterators must iterate in a specific order
T
h
e
y
 
a
r
e
 
i
n
 
O
(
n
)
 
t
i
m
e
 
s
i
n
c
e
t
h
e
y
 
r
e
l
y
 
o
n
 
t
h
e
 
f
a
c
t
 
t
h
e
 
i
n
p
u
t
s
a
r
e
 
s
o
r
t
e
d
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
E
l
e
m
e
n
t
 
m
o
v
e
r
s
:
 
b
a
c
k
w
a
r
d
s
_
c
o
p
y
/
m
o
v
e
 
2023/2024
 
Programming in C++ (labs)
 
27
 
copy_backwards
move_backwards
 
How to transform this, into the bottom one?
we need to copy from the back to not rewrite the
values that we will need
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
2023/2024
Programming in C++ (labs)
28
fill
generate
function callable without any parameters
iota
fills with incremented values
replace
replaces the given values with the provided
new value
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
V
a
l
u
e
 
m
o
d
i
f
i
e
r
s
2023/2024
Programming in C++ (labs)
29
remove
Does not change the size of the underlying container
Iterators cannot do that, they cannot change the size
pre-C++20 -> erase-remove idiom 
https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
C++20, free functions
std::erase
does the erase-remove idiom for you
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
S
t
r
u
c
t
u
r
e
 
c
h
a
n
g
e
r
s
2023/2024
Programming in C++ (labs)
30
S
t
r
u
c
t
u
r
e
 
c
h
a
n
g
e
r
s
std
::vector
<
int
>
 xs1 
=
 { 
1
, 
2
, 
3
, 
4
, 
2
, 
5
, 
2
, 
6
 };
// Example 1: Use std::remove with the remove-erase idiom to remove specific elements
int
 to_remove 
=
 
2
;
auto
 it_to_erase 
=
 
std
::
remove
(
xs1
.
begin
(), 
xs1
.
end
(), to_remove);
print
(
"After removing "
 
+
 
std
::
to_string
(to_remove), xs1);
// After removing 2: 1 3 4 5 6
 2 2 2
// 
The 2s are left at the end, returned iterator to the first 2
xs1
.
erase
(it_to_erase, 
xs1
.
end
());
print
(
"After erasing "
 
+
 
std
::
to_string
(to_remove), xs1);
// After erasing 2: 1 3 4 5 6
// Example 2: Use std::erase to remove specific elements (C++20 and later)
std
::
erase
(xs1, 
4
);
print
(
"After removing 4 using std::erase"
, xs1);
// After erasing 4 using std::erase: 1 3 5 6
*
_
c
o
p
y
 
m
o
d
i
f
i
e
r
 
2023/2024
 
Programming in C++ (labs)
 
31
 
Algorithms that work in-place will
produce the output to some other range
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
*
_
i
f
 
m
o
d
i
f
i
e
r
 
2023/2024
 
Programming in C++ (labs)
 
32
 
Will do the operation on the element only if provided
predicate holds (returns true)
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
*
_
n
 
m
o
d
i
f
i
e
r
 
2023/2024
 
Programming in C++ (labs)
 
33
 
Changes the interface
From [begin, end) to [begin, begin + N)
 
 
 
 
 
 
 
This inserts 5 elements of value 42 to the collection:
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
s
t
d
:
:
t
r
a
n
s
f
o
r
m
 
2023/2024
 
Programming in C++ (labs)
 
34
 
Applies a function to a range
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
s
t
d
:
:
f
o
r
_
e
a
c
h
 
2023/2024
 
Programming in C++ (labs)
 
35
 
The function can return void
It is made for function f that does side effects
 
https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/
s
t
d
:
:
t
r
a
n
s
f
o
r
m
 
&
 
s
t
d
:
:
f
o
r
_
e
a
c
h
 
2023/2024
 
Programming in C++ (labs)
 
36
 
std
::vector
<
int
>
 numbers 
=
 { 
1
, 
2
, 
3
, 
4
, 
5
 };
// Lambda to print each element in the vector
auto
 print_element 
=
 [](
auto&&
 
x
) { 
std
::cout 
<<
 x 
<<
 
" "
; };
// Lambda to square each element in the vector (used with std::transform)
auto
 square 
=
 [](
auto&&
 
x
) -> 
int
 { 
return
 x 
*
 x; };
// Example 1: Use std::for_each to print each element (side effect)
std
::
for_each
(
numbers
.
begin
(), 
numbers
.
end
(), print_element);
// 1 2 3 4 5
// Example 2: Use std::transform to square each element in the vector
std
::
vector
<
int
> 
squared_numbers
(
numbers
.
size
());
std
::
transform
(
numbers
.
begin
(), 
numbers
.
end
(), 
squared_numbers
.
begin
(), square);
// Print the squared numbers
std
::
for_each
(
squared_numbers
.
begin
(), 
squared_numbers
.
end
(), print_element);
// 1 4 9 16 25
 
2
)
 
S
T
D
 
f
i
l
e
s
y
s
t
e
m
O
v
e
r
v
i
e
w
 
o
f
 
<
f
i
l
e
s
y
s
t
e
m
>
 
2023/2024
 
Programming in C++ (labs)
 
38
 
Library for manipulating the filesystem
Most operations throw, so handle that
 
Create/delete files/directories/hard links/symlinks
Copy/move directories/files
Iterating over directory entries
Even recursively
Option to follow symlinks
Reading file metadata
size, permissions, …
https://en.cppreference.com/w/cpp/filesystem
F
u
r
t
h
e
r
 
r
e
a
d
i
n
g
#include <
filesystem
>
C
r
e
a
t
e
,
 
d
e
l
e
t
e
 
 
&
 
c
o
p
y
,
 
m
o
v
e
 
2023/2024
 
Programming in C++ (labs)
 
39
 
namespace
 
fs
 
=
 
std
::
filesystem
;
fs
::
create_directory
(
"example_directory"
);
fs
::
create_directories
(
"example/dir"
);
// Place your file creation or manipulation code here
fs
::
remove_all
(
"example_directory"
);
  // Deletes the directory and its contents
fs
::
remove
(
"somefile.txt"
);
fs
::
copy
(
"source_directory"
, 
"destination_directory"
);
  // Copy
 
fs
::
rename
(
"source_directory"
, 
"new_directory_name"
);
  // Move/Rename
I
t
e
r
a
t
i
n
g
 
o
v
e
r
 
d
i
r
e
c
t
o
r
y
 
e
n
t
r
i
e
s
 
2023/2024
 
Programming in C++ (labs)
 
40
// Recursive iterator that DOES NOT follow symlinks
for
 (
const
 
auto
&
 entry : 
fs
::
recursive_directory_iterator
(
"./some_dir/"
)) {
    
std
::cout 
<<
 
entry
.
path
() 
<<
 
std
::endl;
}
// Recursive iterator that follows symlinks
for
 (
const
 
auto
&
 entry : 
fs
::
recursive_directory_iterator
(
    
"./some_dir/"
, 
fs
::
directory_options
::follow_directory_symlink)) {
    
std
::cout 
<<
 
entry
.
path
() 
<<
 
std
::endl;
}
R
e
a
d
i
n
g
 
m
e
t
a
d
a
t
a
 
2023/2024
 
Programming in C++ (labs)
 
41
 
// Prints the permissions like `ls -l`
void
 
print_perms
(
std
::
filesystem
::
perms
 
p
)
{
    
using
 
std
::
filesystem
::perms;
    
auto
 show 
=
 [
=
](
char
 
op
, 
perms
 
perm
)
    {
        
std
::cout 
<<
 (
perms
::none 
==
 (perm 
&
 p) 
?
 
'-'
 
:
 op);
    };
    
show
(
'r'
, 
perms
::owner_read);
    
show
(
'w'
, 
perms
::owner_write);
    
show
(
'x'
, 
perms
::owner_exec);
    
show
(
'r'
, 
perms
::group_read);
    
show
(
'w'
, 
perms
::group_write);
    
show
(
'x'
, 
perms
::group_exec);
    
show
(
'r'
, 
perms
::others_read);
    
show
(
'w'
, 
perms
::others_write);
    
show
(
'x'
, 
perms
::others_exec);
    
std
::cout 
<<
 
std
::endl;
}
for
 (
const
 
auto
&
 entry : 
fs
::
directory_iterator
(
"file_directory"
)) {
    
std
::cout 
<<
 
"File: "
 
<<
 
entry
.
path
() 
<<
 
std
::endl;
    
std
::cout 
<<
 
"Size: "
 
<<
 
fs
::
file_size
(entry) 
<<
 
" bytes"
 
<<
 
std
::endl;
    
print_perms
(
fs
::
status
(entry).
permissions
());
}
 
3
)
 
M
e
a
s
u
r
i
n
g
 
t
i
m
e
 
w
i
t
h
 
C
+
+
(
s
t
d
:
:
c
h
r
o
n
o
)
O
v
e
r
v
i
e
w
 
o
f
 
<
c
h
r
o
n
o
>
 
2023/2024
 
Programming in C++ (labs)
 
43
 
Library for measuring time
 The wall clock is the normal time we are used to
A
 
s
t
e
a
d
y
 
c
l
o
c
k
 
c
a
n
 
b
e
 
u
s
e
d
 
o
n
l
y
 
t
o
 
m
e
a
s
u
r
e
 
r
e
l
a
t
i
v
e
 
t
i
m
e
s
Also for calendar functionality
 
https://en.cppreference.com/w/cpp/chrono
F
u
r
t
h
e
r
 
r
e
a
d
i
n
g
#include <
chrono
>
H
o
w
 
y
o
u
 
c
a
n
 
m
e
a
s
u
r
e
 
t
i
m
e
 
i
n
 
C
+
+
2023/2024
Programming in C++ (labs)
44
Via <ctime>
Nah, it's too C
std::chrono
The syntax is quite long!
void
 
long_function
() {
    // Place your function code here
    
for
 (
int
 i 
=
 
0
; i 
<
 
1000000
; 
++
i) {
        // Some computation
    }
}
int
 
main
() {
    
auto
 start_time 
=
 
std
::
chrono
::
high_resolution_clock
::
now
();
    // Call the function whose runtime you want to measure
    
long_function
();
    
auto
 end_time 
=
 
std
::
chrono
::
high_resolution_clock
::
now
();
    
auto
 duration 
=
 
std
::
chrono
::
duration_cast
<
std
::
chrono
::
microseconds
>(end_time 
-
 start_time);
    
std
::cout 
<<
 
"Runtime: "
 
<<
 
duration
.
count
() 
<<
 
" microseconds"
 
<<
 
std
::endl;
}
 
T
a
s
k
 
8
R
e
c
u
r
s
i
v
e
 
f
i
l
e
 
s
e
a
r
c
h
e
r
 
(
l
i
k
e
 
g
r
e
p
)
 
2023/2024
 
Programming in C++ (labs)
 
46
 
Start from:
https://gitlab.mff.cuni.cz/teaching/nprg041/mejzlik/labs-cpp-pub/-/blob/master/lab_08/lab_08.cpp
Write a program that will recursively search the provided directory for per-line
occurrences in those files
Will work only with directories, not single files
It will print the results in the given format (if `world` was the query):
[/abs/path/to/file.txt] Hello world!
On the last line, there will be a number of milliseconds (as integer, no floating point) it took to
run the search
We will call it like this
lab_08
 world ./dir/
W
ill traverse all files in the
 
./dir/ as well as all the subsequent directories
D
o not follow symlinks
E
x
a
m
p
l
e
 
i
n
p
u
t
s
 
2023/2024
 
Programming in C++ (labs)
 
47
 
For `tests/test1/` in the public repo:
https://gitlab.mff.cuni.cz/teaching/nprg041/mejzlik/labs-cpp-pub/-/tree/master/lab_08/tests/test1
input: 
lab_08 brambory ./tests/test1/
 
 
On my computer, I'd get this:
You should get different absolute paths to the files
[C:\Users\frank\source\repos\cpp-labs\cpp-labs\lab_08\tests\test1\a.txt]  Ahoj brambory!
[C:\Users\frank\source\repos\cpp-labs\cpp-labs\lab_08\tests\test1\dir2\b.txt]  Ahoj brambory!
[C:\Users\frank\source\repos\cpp-labs\cpp-labs\lab_08\tests\test1\dir2\c.txt]  Ahoj brambory!
2
 
W
r
a
p
p
i
n
g
 
i
t
 
u
p
L
a
b
 
8
 
w
r
a
p
 
u
p
 
2023/2024
 
Programming in C++ (labs)
 
49
 
You should know
N
e
x
t
 
l
a
b
:
Lambdas, functors
Operator overloading
Random numbers
Y
o
u
r
 
t
a
s
k
s
 
u
n
t
i
l
 
t
h
e
 
n
e
x
t
 
l
a
b
:
Task 
8
 (24h before, so I can give feedback).
Just a directory lab_0
5
 with one CPP file will do
R
e
C
o
d
e
x
 
a
s
s
i
g
n
m
e
n
t
 
3
 
2023/2024
 
Programming in C++ (labs)
 
50
 
T
h
i
s
 
o
n
e
 
w
i
l
l
 
b
e
 
u
s
e
d
 
a
s
 
a
 
b
a
s
i
s
 
f
o
r
 
t
h
e
 
e
x
t
e
n
s
i
o
n
 
f
o
r
 
t
h
e
 
m
o
c
k
 
t
e
r
m
 
e
x
a
m
 
(
1
8
.
1
2
.
 
2
0
2
3
)
!
The better you code the assignment, the easier will be for you to extend it!
You will get an email when the assignment is ready in ReCodex.
It is a new assignment created by me, so there may be some technical issues
Feel free to contact me if you encounter some!
Slide Note
Embed
Share

Explore the STD algorithm library in C++ for efficient programming tasks such as handling file systems, measuring time using std

  • chrono
  • implementing recursive file search algorithms
  • and more. Learn about the importance of using algorithms to make your code more expressive
  • readable
  • and performant. Discover the power and flexibility that C++20 brings to STD algorithms. Dive into concepts like permutations
  • queries
  • element movers
  • and structure changers while understanding the limitations of functions in the algorithm library.

Uploaded on Sep 10, 2024 | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

E N D

Presentation Transcript


  1. Lab 8 STD algorithm library, STD filesystem, measuring time with std::chrono 23. 10. 2023

  2. Outline 1. STD algorithms 2. STD filesystem library 3. Measuring time with std::chrono 4. Task 08 - recursive file searcher 2023/2024 2 Programming in C++ (labs)

  3. 1) STD algorithms

  4. Motivation It makes code more expressive Less readable code, more useful work Avoid common mistakes Like off-by-one problems Battle-tested and reasonably performant Readibility same interface across all C++ users The part about algorithms is well presented in the cppcon talk here Further reading https://www.youtube.com/watch?v=2olsGf6JIkU 2023/2024 4 Programming in C++ (labs)

  5. Overview of <algorithm> #include <algorithm> Permutations Playing with the order of elements inside some range Queries Do not mutate the source ranges Just retrieve/compute/aggregate some information about the range Set algorithms on any sorted range Element movers copy, move Value modifiers Modify the values in ranges Structure changers Remove certain elements from the range std::transform and std::for_each range ~ anything you can iterate over (e.g. a container, range, initializer_list) C++20 brings even more power and flexibility to STD algorithms There is no longer need to provide iterator pairs all the time. std::vector is implicitly convertible to a range Further reading https://en.cppreference.com/w/cpp/algorithm https://en.cppreference.com/w/cpp/algorithm/ranges 2023/2024 5 Programming in C++ (labs)

  6. Be aware that functions taking iterators cannot change the actual container size Functions in the algorithm library cannot change the size of the actual underlying structure They can only work on the range provided Move things around Change values Read values and compute things from it E.g. function `std::pop_heap(it_begin, it_end);` cannot change the size of the underlying structure It will leave the "popped" value at the end You will need to call vec.pop_back() separately 2023/2024 6 Programming in C++ (labs)

  7. Permutations: heaps For contiguous memory ranges std::make_heap Creates the heap structure in-place in the vector std::push_heap Takes the last element and inserts it into the heap std::pop_heap Moves the first element to the back, and creates heap on the range without the last element 2023/2024 7 Programming in C++ (labs)

  8. Permutations: heaps std::vector<int> xs1({3, 2, 4, 1, 5, 9}); // initially: 3 2 4 1 5 9 // Making the heap from range std::make_heap(xs1.begin(), xs1.end()); // after make_heap: 9 5 4 1 2 3 // Pushing new element into the heap xs1.push_back(10); // after push_back: 9 5 4 1 2 3 10 std::ranges::push_heap(xs1); //< Using ranges! // after push_heap: 10 5 9 1 2 3 4 // Poping the heap element std::pop_heap(xs1.begin(), xs1.end()); // after pop_heap : 9 5 4 1 2 3 10 xs1.pop_back(); // after pop_back: 9 5 4 1 2 3 2023/2024 8 Programming in C++ (labs)

  9. Permutations: sorting std::sort std::partial_sort Sorts the first `(middle - begin)` elements from the whole range and leaves them in the beginning Sorts the provided range std::nth_element Puts the element to the provided middle iterator what would be there if the range was sorted the rest is in unspecified order 2023/2024 9 Programming in C++ (labs)

  10. Permutations: sorting std::vector<int> xs1({ 4, 9, 5, 1, 2, 3 }); std::vector<int> xs2, xs3, xs4, xs5; xs2 = xs3 = xs4 = xs5 = xs1; // initially: 3 2 4 1 5 9 std::stable_sort(xs1.begin(), xs1.end()); // after sort : 1 2 3 4 5 9 std::ranges::sort(xs2); // after ranges sort : 1 2 3 4 5 9 std::ranges::sort(std::ranges::reverse_view(xs3)); // after reverse ranges sort : 9 5 4 3 2 1 std::partial_sort(xs4.begin(), xs4.begin() + 3, xs4.end()); // after partial_sort with mid 3: 1 2 3 9 5 4 std::nth_element(xs5.begin(), xs5.begin() + 3, xs5.end()); // after nth_element with mid 3: 3 2 1 4 9 5 2023/2024 10 Programming in C++ (labs)

  11. Permutations: partitioning Separates the range into those returning true from predicate These are at the beginning 2023/2024 11 Programming in C++ (labs)

  12. Permutations: partitioning std::forward_list<int> xs1 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; std::forward_list<int> xs2, xs3, xs4, xs5; xs2 = xs3 = xs4 = xs5 = xs1; // Returns partition point auto par_point1 = std::partition(xs1.begin(), xs1.end(), [](int i) {return i % 2 == 0; }); // par_point1: 5 // after partition : 0 2 4 6 8 5 3 7 1 9 // Returns subrange to the second group auto subrange = std::ranges::partition(xs2, [](int i) {return i % 2 == 0; }); // subrange: 5 3 7 1 9 // after partition : 0 2 4 6 8 5 3 7 1 9 2023/2024 12 Programming in C++ (labs)

  13. Permutations: rotate and shuffle std::rotate Takes element from the back and puts it into the front std::shuffle std::next_permutation/prev_permutation Useful if you want to iterate over all possible permutations std::reverse in-place reverse of the range 2023/2024 13 Programming in C++ (labs)

  14. Permutations: rotate and shuffle std::deque<int> xs1({1, 2, 3, 4, 5 }); std::deque<int> xs2, xs3, xs4, xs5, xs6; xs2 = xs3 = xs4 = xs5 = xs6 = xs1; // initially: 1 2 3 4 5 // simple rotation to the left std::rotate(xs1.begin(), xs1.begin() + 2, xs1.end()); // rotate left by 2: 3 4 5 1 2 // simple rotation to the right std::rotate(xs2.rbegin(), xs2.rbegin() + 2, xs2.rend()); // rotate right by 2: 4 5 1 2 3 // Shuffle randomly std::random_device rd; std::mt19937 g(rd()); std::shuffle(xs3.begin(), xs3.end(), g); // shuffle: 3 1 2 5 4 std::ranges::shuffle(xs4, g); // range shuffle: 1 4 2 5 3 // Next permutation std::next_permutation(xs5.begin(), xs5.end()); // next permutation: 1 2 3 5 4 // Prev permutation std::ranges::prev_permutation(xs6); // prev permutation: 5 4 3 2 1 2023/2024 14 Programming in C++ (labs)

  15. Queries #include <numeric> count reduce inclusive_scan https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 15 Programming in C++ (labs)

  16. Queries std::vector<int> xs1({ 1, 2, 3, 4, 5 }); // Use count auto cnt1 = std::count(xs1.begin(), xs1.end(), 4); // # elems == 4: 1 // Use count_if auto cnt2 = std::count_if(xs1.begin(), xs1.end(), [](int x) -> bool { return x >= 4; }); // # elems >= 4: 2 // Using reduce to sum int sum = std::reduce(xs1.begin(), xs1.end()); // total sum: 15 // Inclusive sum std::vector<int> incl_sum(xs1.size()); std::inclusive_scan(xs1.begin(), xs1.end(), incl_sum.begin()); // cumulative sum: 1 3 6 10 15 2023/2024 16 Programming in C++ (labs)

  17. More queries inner_product -> dot product adjacent_difference sample https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 17 Programming in C++ (labs)

  18. More queries // Example 1: Use std::inner_product to calculate the dot product of two vectors std::vector<int> xs1 = { 1, 2, 3, 4, 5 }; std::vector<int> ys1 = { 2, 4, 6, 8, 10 }; int dot_product = std::inner_product(xs1.begin(), xs1.end(), ys1.begin(), 0); // Dot product of xs1 and ys1: 110 // Example 2: Use std::adjacent_difference to calculate the differences between adjacent elements std::vector<int> differences(xs1.size()); std::adjacent_difference(xs1.begin(), xs1.end(), differences.begin()); // The first element is untouched // Adjacent differences: 1 1 1 1 1 // Example 3: Use std::sample to randomly sample elements from xs1 std::vector<int> sampled; std::mt19937 generator(std::random_device{}()); std::sample(xs1.begin(), xs1.end(), std::back_inserter(sampled), 2, generator); // Randomly sampled elements: 4 5 https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 18 Programming in C++ (labs)

  19. Queries: logical quantifiers all_of any_of none_of https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 19 Programming in C++ (labs)

  20. Queries: logical quantifiers std::vector<int> xs1({ 2, 4, 6 }); std::cout << std::all_of( xs1.cbegin(), xs1.cend(), [](int i) { return i % 2 == 0; }) << std::endl; // 1 std::cout << std::none_of( xs1.cbegin(), xs1.cend(), [](int i) { return i % 2 != 0; }) << std::endl; // 1 std::cout << std::any_of( xs1.cbegin(), xs1.cend(), [](int i) { return i % 2 != 0; }) << std::endl; // 0 2023/2024 20 Programming in C++ (labs)

  21. Queries: comparing ranges equal lexicographical_compare mismatch https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 21 Programming in C++ (labs)

  22. Queries: comparing ranges std::deque<int> xs1({ 1, 2, 3, 4, 5 }); std::deque<int> xs2({ 1, 2, 3, 4, 4 }); // Example 1: Use std::equal to check if two ranges are equal bool are_equal = std::equal(xs1.begin(), xs1.end(), xs2.begin()); std::cout << std::boolalpha << are_equal << std::endl; // false // Example 2: Use std::lexicographical_compare to check the lexicographical order of two ranges bool is_less = std::lexicographical_compare(xs2.begin(), xs2.end(), xs1.begin(), xs1.end()); std::cout << std::boolalpha << is_less << std::endl; // true // Example 3: Use std::mismatch to find the first position where two ranges differ auto [fst_it, snd_it] = std::mismatch(xs1.begin(), xs1.end(), xs2.begin()); // *fst_it: 5, *snd_it: 4 2023/2024 22 Programming in C++ (labs)

  23. Queries: searching for values find adjacent_find lower_bound upper_bound binary_search returns bool, not iterator! https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 23 Programming in C++ (labs)

  24. Queries: searching for range of values Search for the sequence of elements search find_end Search for one of the sequence elements find_first_of https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 24 Programming in C++ (labs)

  25. Queries: searching for relative values max_element min_element minmax_element https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 25 Programming in C++ (labs)

  26. Algorithms on sets / sorted ranges From the POV of the algorithm library, a set is any sorted container (also sorted std::vector) i.e. iterators must iterate in a specific order They are in O(n) time since they rely on the fact the inputs are sorted https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 26 Programming in C++ (labs)

  27. Element movers: backwards_copy/move copy_backwards move_backwards How to transform this, into the bottom one? we need to copy from the back to not rewrite the values that we will need https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 27 Programming in C++ (labs)

  28. Value modifiers fill generate function callable without any parameters iota fills with incremented values replace replaces the given values with the provided new value https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 28 Programming in C++ (labs)

  29. Structure changers remove Does not change the size of the underlying container Iterators cannot do that, they cannot change the size pre-C++20 -> erase-remove idiom https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom C++20, free functions std::erase does the erase-remove idiom for you https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 29 Programming in C++ (labs)

  30. Structure changers std::vector<int> xs1 = { 1, 2, 3, 4, 2, 5, 2, 6 }; // Example 1: Use std::remove with the remove-erase idiom to remove specific elements int to_remove = 2; auto it_to_erase = std::remove(xs1.begin(), xs1.end(), to_remove); print("After removing " + std::to_string(to_remove), xs1); // After removing 2: 1 3 4 5 6 2 2 2 // The 2s are left at the end, returned iterator to the first 2 xs1.erase(it_to_erase, xs1.end()); print("After erasing " + std::to_string(to_remove), xs1); // After erasing 2: 1 3 4 5 6 // Example 2: Use std::erase to remove specific elements (C++20 and later) std::erase(xs1, 4); print("After removing 4 using std::erase", xs1); // After erasing 4 using std::erase: 1 3 5 6 2023/2024 30 Programming in C++ (labs)

  31. *_copy modifier Algorithms that work in-place will produce the output to some other range https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 31 Programming in C++ (labs)

  32. *_if modifier Will do the operation on the element only if provided predicate holds (returns true) https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 32 Programming in C++ (labs)

  33. *_n modifier Changes the interface From [begin, end) to [begin, begin + N) This inserts 5 elements of value 42 to the collection: https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 33 Programming in C++ (labs)

  34. std::transform Applies a function to a range https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 34 Programming in C++ (labs)

  35. std::for_each The function can return void It is made for function f that does side effects https://www.fluentcpp.com/2018/07/10/105-stl-algorithms-in-less-than-an-hour/ 2023/2024 35 Programming in C++ (labs)

  36. std::transform & std::for_each std::vector<int> numbers = { 1, 2, 3, 4, 5 }; // Lambda to print each element in the vector auto print_element = [](auto&& x) { std::cout << x << " "; }; // Lambda to square each element in the vector (used with std::transform) auto square = [](auto&& x) -> int { return x * x; }; // Example 1: Use std::for_each to print each element (side effect) std::for_each(numbers.begin(), numbers.end(), print_element); // 1 2 3 4 5 // Example 2: Use std::transform to square each element in the vector std::vector<int> squared_numbers(numbers.size()); std::transform(numbers.begin(), numbers.end(), squared_numbers.begin(), square); // Print the squared numbers std::for_each(squared_numbers.begin(), squared_numbers.end(), print_element); // 1 4 9 16 25 2023/2024 36 Programming in C++ (labs)

  37. 2) STD filesystem

  38. Overview of <filesystem> #include <filesystem> Library for manipulating the filesystem Most operations throw, so handle that Create/delete files/directories/hard links/symlinks Copy/move directories/files Iterating over directory entries Even recursively Option to follow symlinks Reading file metadata size, permissions, Further reading https://en.cppreference.com/w/cpp/filesystem 2023/2024 38 Programming in C++ (labs)

  39. Create, delete & copy, move namespace fs = std::filesystem; fs::create_directory("example_directory"); fs::create_directories("example/dir"); // Place your file creation or manipulation code here fs::remove_all("example_directory"); // Deletes the directory and its contents fs::remove("somefile.txt"); fs::copy("source_directory", "destination_directory"); // Copy fs::rename("source_directory", "new_directory_name"); // Move/Rename 2023/2024 39 Programming in C++ (labs)

  40. Iterating over directory entries // Recursive iterator that DOES NOT follow symlinks for (const auto& entry : fs::recursive_directory_iterator("./some_dir/")) { std::cout << entry.path() << std::endl; } // Recursive iterator that follows symlinks for (const auto& entry : fs::recursive_directory_iterator( "./some_dir/", fs::directory_options::follow_directory_symlink)) { std::cout << entry.path() << std::endl; } 2023/2024 40 Programming in C++ (labs)

  41. Reading metadata // Prints the permissions like `ls -l` void print_perms(std::filesystem::perms p) { using std::filesystem::perms; auto show = [=](char op, perms perm) { std::cout << (perms::none == (perm & p) ? '-' : op); }; show('r', perms::owner_read); show('w', perms::owner_write); show('x', perms::owner_exec); show('r', perms::group_read); show('w', perms::group_write); show('x', perms::group_exec); show('r', perms::others_read); show('w', perms::others_write); show('x', perms::others_exec); std::cout << std::endl; } for (const auto& entry : fs::directory_iterator("file_directory")) { std::cout << "File: " << entry.path() << std::endl; std::cout << "Size: " << fs::file_size(entry) << " bytes" << std::endl; print_perms(fs::status(entry).permissions()); } 2023/2024 41 Programming in C++ (labs)

  42. 3) Measuring time with C++ (std::chrono)

  43. Overview of <chrono> #include <chrono> Library for measuring time The wall clock is the normal time we are used to A steady clock can be used only to measure relative times Also for calendar functionality Further reading https://en.cppreference.com/w/cpp/chrono 2023/2024 43 Programming in C++ (labs)

  44. How you can measure time in C++ Via <ctime> Nah, it's too C std::chrono The syntax is quite long! void long_function() { // Place your function code here for (int i = 0; i < 1000000; ++i) { // Some computation } } int main() { auto start_time = std::chrono::high_resolution_clock::now(); // Call the function whose runtime you want to measure long_function(); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time); std::cout << "Runtime: " << duration.count() << " microseconds" << std::endl; } 2023/2024 44 Programming in C++ (labs)

  45. Task 8

  46. Recursive file searcher (like grep) Start from: https://gitlab.mff.cuni.cz/teaching/nprg041/mejzlik/labs-cpp-pub/-/blob/master/lab_08/lab_08.cpp Write a program that will recursively search the provided directory for per-line occurrences in those files Will work only with directories, not single files It will print the results in the given format (if `world` was the query): [/abs/path/to/file.txt] Hello world! On the last line, there will be a number of milliseconds (as integer, no floating point) it took to run the search We will call it like this lab_08 world ./dir/ Will traverse all files in the ./dir/ as well as all the subsequent directories Do not follow symlinks 2023/2024 46 Programming in C++ (labs)

  47. Example inputs For `tests/test1/` in the public repo: https://gitlab.mff.cuni.cz/teaching/nprg041/mejzlik/labs-cpp-pub/-/tree/master/lab_08/tests/test1 input: lab_08 brambory ./tests/test1/ On my computer, I'd get this: You should get different absolute paths to the files [C:\Users\frank\source\repos\cpp-labs\cpp-labs\lab_08\tests\test1\a.txt] Ahoj brambory! [C:\Users\frank\source\repos\cpp-labs\cpp-labs\lab_08\tests\test1\dir2\b.txt] Ahoj brambory! [C:\Users\frank\source\repos\cpp-labs\cpp-labs\lab_08\tests\test1\dir2\c.txt] Ahoj brambory! 2 2023/2024 47 Programming in C++ (labs)

  48. Wrapping it up

  49. Lab 8 wrap up You should know Next lab: Lambdas, functors Operator overloading Random numbers Your tasks until the next lab: Task 8 (24h before, so I can give feedback). Just a directory lab_05 with one CPP file will do 2023/2024 49 Programming in C++ (labs)

  50. ReCodex assignment 3 This one will be used as a basis for the extension for the mock term exam (18. 12. 2023)! The better you code the assignment, the easier will be for you to extend it! You will get an email when the assignment is ready in ReCodex. It is a new assignment created by me, so there may be some technical issues Feel free to contact me if you encounter some! 2023/2024 50 Programming in C++ (labs)

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#