stlab
2.4.0
Modern, modular C++ algorithms, data structures, and concurrency primitives
Toggle main menu visibility
Loading...
Searching...
No Matches
model.hpp
Go to the documentation of this file.
1
/*
2
Copyright 2015 Adobe
3
Distributed under the Boost Software License, Version 1.0.
4
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
*/
6
7
/**************************************************************************************************/
8
9
#ifndef STLAB_MODEL_HPP
10
#define STLAB_MODEL_HPP
11
19
20
/**************************************************************************************************/
21
22
#include <stlab/config.hpp>
23
24
#include <atomic>
25
#include <condition_variable>
26
#include <iostream>
27
#include <mutex>
28
29
#include <
stlab/concurrency/await.hpp
>
30
31
/**************************************************************************************************/
32
33
namespace
stlab
{
34
STLAB_VERSION_NAMESPACE_BEGIN()
35
36
41
42
/**************************************************************************************************/
43
44
45
struct
annotate_counters
{
46
std::atomic_size_t _dtor{0};
47
std::atomic_size_t _copy_ctor{0};
48
std::atomic_size_t _move_ctor{0};
49
std::atomic_size_t _copy_assign_lhs{0};
50
std::atomic_size_t _copy_assign_rhs{0};
51
std::atomic_size_t _move_assign_lhs{0};
52
std::atomic_size_t _move_assign_rhs{0};
53
std::atomic_size_t _swap{0};
54
std::atomic_size_t _equality{0};
55
std::mutex _mutex;
56
std::condition_variable _condition;
57
58
auto
remaining()
const
-> std::size_t {
return
_copy_ctor + _move_ctor - _dtor + 1; }
59
60
void
wait(std::size_t count) {
61
stlab::invoke_waiting
([&] {
62
std::unique_lock<std::mutex> lock(_mutex);
63
_condition.wait(lock, [&] {
return
count == remaining(); });
64
});
65
}
66
67
friend
inline
auto
operator<<(std::ostream& out,
const
annotate_counters
& x) -> std::ostream& {
68
out <<
" dtor: "
<< x._dtor <<
"\n"
;
69
out <<
" copy_ctor: "
<< x._copy_ctor <<
"\n"
;
70
out <<
" move_ctor: "
<< x._move_ctor <<
"\n"
;
71
out <<
"copy_assign_lhs: "
<< x._copy_assign_lhs <<
"\n"
;
72
out <<
"copy_assign_rhs: "
<< x._copy_assign_rhs <<
"\n"
;
73
out <<
"move_assign_lhs: "
<< x._move_assign_lhs <<
"\n"
;
74
out <<
"move_assign_rhs: "
<< x._move_assign_rhs <<
"\n"
;
75
out <<
" swap: "
<< x._swap <<
"\n"
;
76
out <<
" equality: "
<< x._equality <<
"\n"
;
77
78
return
out;
79
}
80
};
81
87
struct
annotate {
88
annotate_counters
* _counters;
89
explicit
annotate(
annotate_counters
& counters) : _counters(&counters) {}
90
91
~annotate() {
92
{
93
++_counters->_dtor;
94
_counters->_condition.notify_one();
95
}
96
}
97
98
annotate(
const
annotate& x) : _counters(x._counters) { ++_counters->_copy_ctor; }
99
annotate(annotate&& x) noexcept : _counters(x._counters) { ++_counters->_move_ctor; }
100
101
auto
operator=(
const
annotate& x) -> annotate& {
102
if
(
this
== &x)
return
*
this
;
103
++x._counters->_copy_assign_rhs;
104
++_counters->_copy_assign_lhs;
105
return
*
this
;
106
}
107
auto
operator=(annotate&& x)
noexcept
-> annotate& {
108
++x._counters->_move_assign_rhs;
109
++_counters->_move_assign_lhs;
110
return
*
this
;
111
}
112
113
friend
inline
void
swap(annotate& x, annotate& y)
noexcept
{
114
++x._counters->_swap;
115
++y._counters->_swap;
116
}
117
118
friend
inline
auto
operator==(
const
annotate& x,
const
annotate& y) ->
bool
{
119
++x._counters->_equality;
120
++y._counters->_equality;
121
return
true
;
122
}
123
friend
inline
auto
operator!=(
const
annotate& x,
const
annotate& y) ->
bool
{
124
return
!(x == y);
125
}
126
};
127
128
/**************************************************************************************************/
129
134
struct
regular {
135
int
_x;
136
137
explicit
regular(
int
x) : _x(x) { std::cout << _x <<
" ctor"
<<
'\n'
; }
138
~regular() { std::cout << _x <<
" dtor"
<<
'\n'
; }
139
140
regular(
const
regular& rhs) : _x(rhs._x) { std::cout << _x <<
" copy-ctor"
<<
'\n'
; }
141
regular(regular&& rhs) noexcept : _x(rhs._x) {
142
std::cout << _x <<
" move-ctor"
<<
'\n'
;
143
rhs._x = 0;
144
}
145
146
auto
operator=(
const
regular& rhs) -> regular& {
147
std::cout << _x <<
" assign"
<<
'\n'
;
148
if
(&rhs ==
this
)
return
*
this
;
149
_x = rhs._x;
150
return
*
this
;
151
}
152
auto
operator=(regular&& rhs)
noexcept
-> regular& {
153
std::cout << _x <<
" move-assign"
<<
'\n'
;
154
_x = rhs._x;
155
rhs._x = 0;
156
return
*
this
;
157
}
158
159
friend
inline
void
swap(regular& lhs, regular& rhs)
noexcept
{
160
std::cout << lhs._x <<
"/"
<< rhs._x <<
" swap "
<<
'\n'
;
161
std::swap(lhs._x, rhs._x);
162
}
163
164
friend
inline
auto
operator==(
const
regular& lhs,
const
regular& rhs) ->
bool
{
165
return
lhs._x == rhs._x;
166
}
167
friend
inline
auto
operator!=(
const
regular& lhs,
const
regular& rhs) ->
bool
{
168
return
!(lhs == rhs);
169
}
170
171
friend
inline
auto
operator<(
const
regular& lhs,
const
regular& rhs) ->
bool
{
172
bool
result(lhs._x < rhs._x);
173
std::cout << lhs._x <<
" < "
<< rhs._x <<
": "
<< std::boolalpha << result <<
'\n'
;
174
return
result;
175
}
176
};
177
178
/**************************************************************************************************/
179
185
class
move_only {
186
private
:
187
int
_member{0};
188
189
public
:
190
move_only() =
default
;
191
move_only(
int
member) : _member(member) {}
192
move_only(
const
move_only&) =
delete
;
193
auto
operator=(
const
move_only&) -> move_only& =
delete
;
194
move_only(move_only&&) =
default
;
195
auto
operator=(move_only&&) -> move_only& =
default
;
196
virtual
~move_only() =
default
;
197
198
auto
member() ->
int
{
return
_member; }
199
[[nodiscard]]
auto
member()
const
->
int
{
return
_member; }
200
201
friend
auto
operator==(
const
move_only& a,
const
move_only& b) ->
bool
{
202
return
a._member == b._member;
203
}
204
friend
auto
operator!=(
const
move_only& a,
const
move_only& b) ->
bool
{
return
!(a == b); }
205
};
206
207
/**************************************************************************************************/
208
210
211
STLAB_VERSION_NAMESPACE_END()
212
}
// namespace stlab
213
214
/**************************************************************************************************/
215
216
#endif
217
218
/**************************************************************************************************/
await.hpp
Blocking wait helpers for futures (await, await_for, …).
stlab::invoke_waiting
auto invoke_waiting(F &&f)
Assumes f will block waiting; on the portable task system, wakes the pool or adds a worker (up to the...
Definition
await.hpp:56
stlab
Definition
reverse.hpp:28
stlab::annotate_counters
Shared counters for annotate special-member and comparison instrumentation.
Definition
model.hpp:45
stlab
test
model.hpp
Generated by
1.18.0