mCRL2
Loading...
Searching...
No Matches
shared_reference.h
Go to the documentation of this file.
1// Author(s): Maurice Laveaux
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9
10#ifndef MCRL2_UTILITIES_SHARED_REFERENCE_H_
11#define MCRL2_UTILITIES_SHARED_REFERENCE_H_
12
13#include "tagged_pointer.h"
14
15#include <cassert>
16#include <atomic>
17#include <type_traits>
18
19#include "mcrl2/utilities/tagged_pointer.h"
20
21namespace mcrl2
22{
23namespace utilities
24{
25
26/// \brief Enable to count the number of reference count changes.
27constexpr static bool EnableReferenceCountMetrics = false;
28
29/// \brief Stores a reference count that can be incremented and decremented.
30/// \details The template variable is such that reference_count_changes corresponds
31/// to the amount of times the reference count of type T changed.
32template<typename T, bool ThreadSafe = false>
34{
35public:
38 {}
39
40 /// \brief Obtain the reference count.
41 std::size_t reference_count() const
42 {
43 return m_reference_count;
44 }
45
46 /// \brief Increment the reference count by one.
48 {
49 if constexpr (ThreadSafe)
50 {
51 m_reference_count.fetch_add(1, std::memory_order_relaxed);
52 }
53 else
54 {
56 }
58 }
59
60 /// \brief Decrement the reference count by one.
62 {
63 if constexpr (ThreadSafe)
64 {
65 m_reference_count.fetch_sub(1, std::memory_order_release);
66 }
67 else
68 {
70 }
72 }
73
74 /// \brief Obtain the number of times that this reference count has changed.
75 static std::atomic<std::size_t>& reference_count_changes()
76 {
77 static std::atomic<std::size_t> g_reference_count_changes;
78 return g_reference_count_changes;
79 }
80
81 /// \brief Increment the number of reference count changes.
83 {
84 if constexpr (EnableReferenceCountMetrics)
85 {
87 }
88 }
89
90protected:
91 using SizeType = typename std::conditional<ThreadSafe, std::atomic<std::size_t>, std::size_t>::type;
92
93 // The underlying reference counter can always be changed.
94 mutable SizeType m_reference_count;
95};
96
97/// \brief A reference counted reference to a shared_reference_counted object.
98/// \details Similar to a shared_ptr except that reference counts are only atomic when
99/// thread safety is desired and that it stores the reference count in the
100/// inherited object.
101template<typename T>
103{
104public:
105
106 /// \brief The default constructor.
108 : m_reference(nullptr)
109 {}
110
111 /// \brief Takes ownership of the passed reference, which means
112 /// that its reference count is incremented.
113 shared_reference(T* reference) noexcept
114 : m_reference(reference)
115 {
116 assert(defined());
117 m_reference->increment_reference_count();
118 }
119
120 /// \brief Copy constructor.
121 shared_reference(const shared_reference<T>& other) noexcept
122 : m_reference(other.m_reference)
123 {
124 if (defined())
125 {
126 m_reference->increment_reference_count();
127 }
128 }
129
130 /// \brief Move constructor.
132 : m_reference(other.m_reference)
133 {
134 other.m_reference = nullptr;
135 }
136
138 {
139 if (defined())
140 {
141 m_reference->decrement_reference_count();
142 }
143 }
144
145 /// \brief Copy assignment constructor.
146 shared_reference<T>& operator=(const shared_reference<T>& other) noexcept
147 {
148 // Increment first to prevent the same reference from getting a reference count of zero temporarily.
149 if (other.defined())
150 {
151 other.m_reference->increment_reference_count();
152 }
153
154 // Decrement the reference from the reference that is currently referred to.
155 if (defined())
156 {
157 m_reference->decrement_reference_count();
158 }
159
160 m_reference=other.m_reference;
161 return *this;
162 }
163
164 /// \brief Move assignment constructor.
166 {
167 if (defined())
168 {
169 m_reference->decrement_reference_count();
170 }
171
172 m_reference = other.m_reference;
173 other.m_reference = nullptr;
174 return *this;
175 }
176
177 /// \brief Check whether the shared_reference has a valid reference.
178 bool defined() const
179 {
180 return m_reference.get() != nullptr;
181 }
182
183 bool operator ==(const shared_reference<T>& other) const noexcept
184 {
185 return m_reference == other.m_reference;
186 }
187
188 bool operator <(const shared_reference<T>& other) const noexcept
189 {
190 return m_reference < other.m_reference;
191 }
192
193 // Comparison operators follow from equivalence and less than.
194 bool operator !=(const shared_reference<T>& other) const noexcept
195 {
196 return m_reference != other.m_reference;
197 }
198
199 bool operator <=(const shared_reference<T>& other) const noexcept
200 {
201 return m_reference <= other.m_reference;
202 }
203
204 bool operator >(const shared_reference<T>& other) const noexcept
205 {
206 return m_reference > other.m_reference;
207 }
208
209 bool operator >=(const shared_reference& other) const noexcept
210 {
211 return m_reference >= other.m_reference;
212 }
213
214 T* operator->() const noexcept
215 {
216 assert(defined());
217 return m_reference.get();
218 }
219
220 T* get() const noexcept
221 {
222 assert(defined());
223 return m_reference.get();
224 }
225
226 T& operator*() const noexcept
227 {
228 assert(defined());
229 return *m_reference;
230 }
231
232 /// \brief Swaps *this with the other shared reference.
233 void swap(shared_reference<T>& other)
234 {
235 m_reference.swap(other.m_reference);
236 }
237
238 bool tagged() const noexcept
239 {
240 return m_reference.tagged();
241 }
242
243 void tag() const
244 {
245 m_reference.tag();
246 }
247
248 void untag() const
249 {
250 m_reference.untag();
251 }
252
253private:
255};
256
257} // namespace utilities
258} // namespace mcrl2
259
260namespace std
261{
262
263template<typename T>
264void swap(mcrl2::utilities::shared_reference<T>& a, mcrl2::utilities::shared_reference<T>& b) noexcept
265{
266 a.swap(b);
267}
268
269} // namespace std
270
271#endif // MCRL2_UTILITIES_SHARED_REFERENCE_H_
aterm create_nested_function(const std::string &function_name, const std::string &leaf_name, std::size_t depth)
Create a nested function application f_depth. Where f_0 = c and f_i = f(f_i-1,...,...
aterm create_nested_function(const std::string &function_name, const std::string &leaf_name, std::size_t number_of_arguments, std::size_t depth)
Create a nested function application f_depth. Where f_0 = c and f_i = f(f_i-1,...,...
void benchmark_threads(std::size_t number_of_threads, F f)
The aterm_core base class that provides protection of the underlying shared terms.
Definition aterm_core.h:182
aterm_core & operator=(aterm_core &&other) noexcept
Move assignment operator.
~aterm_core() noexcept
Standard destructor.
aterm_core & operator=(const aterm_core &other) noexcept
Assignment operator.
aterm_core(const aterm_core &other) noexcept
Copy constructor.
aterm_core(aterm_core &&other) noexcept
Move constructor.
aterm_core() noexcept
Default constructor.
aterm_core & assign(const aterm_core &other, detail::thread_aterm_pool &pool) noexcept
Assignment operator, to be used if busy and forbidden flags are explicitly available.
aterm_core & unprotected_assign(const aterm_core &other) noexcept
Assignment operator, to be used when the busy flags do not need to be set.
aterm_core(const detail::_aterm *t) noexcept
Constructor based on an internal term data structure. This is not for public use.
aterm(aterm &&other) noexcept=default
aterm(const function_symbol &sym, InputIterator begin, InputIterator end, TermConverter converter)
Definition aterm.h:116
const_iterator end() const
Returns a const_iterator pointing past the last argument.
Definition aterm.h:172
aterm(const function_symbol &symbol, const Terms &...arguments)
Constructor for n-arity function application.
Definition aterm.h:137
const aterm & operator[](const size_type i) const
Returns the i-th argument.
Definition aterm.h:187
aterm()
Default constructor.
Definition aterm.h:48
const_iterator begin() const
Returns an iterator pointing to the first argument.
Definition aterm.h:165
aterm(const function_symbol &sym, InputIterator begin, InputIterator end)
Constructor that provides an aterm based on a function symbol and an input iterator providing the arg...
Definition aterm.h:96
aterm(const function_symbol &sym, ForwardIterator begin, ForwardIterator end)
Constructor that provides an aterm based on a function symbol and forward iterator providing the argu...
Definition aterm.h:75
aterm & operator=(const aterm &other) noexcept=default
const function_symbol & function() const
Returns the function symbol belonging to an aterm.
Definition aterm.h:144
std::size_t size_type
An unsigned integral type.
Definition aterm.h:36
aterm(const aterm &other) noexcept=default
This class has user-declared copy constructor so declare default copy and move operators.
aterm(detail::_term_appl *t)
Constructor.
Definition aterm.h:30
ptrdiff_t difference_type
A signed integral type.
Definition aterm.h:39
bool empty() const
Returns true if the term has no arguments.
Definition aterm.h:158
aterm & operator=(aterm &&other) noexcept=default
aterm(const function_symbol &sym)
Constructor.
Definition aterm.h:128
term_appl_iterator< aterm > iterator
Iterator used to iterate through an term_appl.
Definition aterm.h:42
size_type size() const
Returns the number of arguments of this term.
Definition aterm.h:151
term_appl_iterator< aterm > const_iterator
Const iterator used to iterate through an term_appl.
Definition aterm.h:45
constexpr size_type max_size() const
Returns the largest possible number of arguments.
Definition aterm.h:179
This is the class to which an aterm points.
Definition aterm_core.h:48
bool is_marked() const
Check if the term is already marked.
Definition aterm_core.h:73
_aterm(const function_symbol &symbol)
Create a term from a function symbol.
Definition aterm_core.h:51
function_symbol m_function_symbol
Definition aterm_core.h:79
const function_symbol & function() const noexcept
Definition aterm_core.h:55
void mark() const
Mark this term to be garbage collected.
Definition aterm_core.h:61
void unmark() const
Remove the mark from a term.
Definition aterm_core.h:67
Stores the data for a function symbol (name, arity) pair.
const std::string & name() const noexcept
bool operator==(const _function_symbol &f) const noexcept
std::size_t arity() const noexcept
void enable_garbage_collection(bool enable)
Enable garbage collection when passing true and disable otherwise.
Definition aterm_pool.h:130
This class stores a set of function symbols.
void create_term(aterm &term, const function_symbol &sym)
Generates unique function symbols with a given prefix.
bool operator!=(const function_symbol &f) const
Inequality test.
function_symbol & operator=(const function_symbol &other) noexcept=default
function_symbol(function_symbol &&other) noexcept=default
bool operator>=(const function_symbol &f) const
Comparison operation.
bool operator==(const function_symbol &f) const
Equality test.
function_symbol(detail::_function_symbol::ref &&f)
Constructor for internal use only.
bool operator<(const function_symbol &f) const
Comparison operation.
function_symbol(const function_symbol &other) noexcept=default
This class has non-trivial destructor so declare default copy and move operators.
void destroy()
Calls the function symbol pool to free our used memory.
void swap(function_symbol &f)
Swap this function with its argument.
function_symbol & operator=(function_symbol &&other) noexcept=default
std::size_t arity() const
Return the arity (number of arguments) of the function symbol (function_symbol).
detail::_function_symbol::ref m_function_symbol
The shared reference to the underlying function symbol.
const std::string & name() const
Return the name of the function_symbol.
bool operator>(const function_symbol &f) const
Comparison operation.
bool operator<=(const function_symbol &f) const
Comparison operation.
An unprotected term does not change the reference count of the shared term when it is copied or moved...
Definition aterm_core.h:32
bool operator<=(const unprotected_aterm_core &t) const
Comparison operator for two unprotected aterms.
Definition aterm_core.h:122
bool operator>=(const unprotected_aterm_core &t) const
Comparison operator for two unprotected aterms.
Definition aterm_core.h:131
bool type_is_list() const noexcept
Dynamic check whether the term is an aterm_list.
Definition aterm_core.h:72
void swap(unprotected_aterm_core &t) noexcept
Swaps this term with its argument.
Definition aterm_core.h:152
bool operator>(const unprotected_aterm_core &t) const
Comparison operator for two unprotected aterms.
Definition aterm_core.h:113
bool operator<(const unprotected_aterm_core &t) const
Comparison operator for two unprotected aterms.
Definition aterm_core.h:104
bool operator==(const unprotected_aterm_core &t) const
Comparison operator.
Definition aterm_core.h:83
unprotected_aterm_core() noexcept
Default constuctor.
Definition aterm_core.h:41
bool type_is_appl() const noexcept
Dynamic check whether the term is an aterm.
Definition aterm_core.h:55
bool defined() const
Returns true if this term is not equal to the term assigned by the default constructor of aterms,...
Definition aterm_core.h:143
friend detail::_aterm * detail::address(const unprotected_aterm_core &t)
const detail::_aterm * m_term
Definition aterm_core.h:36
bool operator!=(const unprotected_aterm_core &t) const
Inequality operator on two unprotected aterms.
Definition aterm_core.h:92
const function_symbol & function() const
Yields the function symbol in an aterm.
Definition aterm_core.h:161
bool type_is_int() const noexcept
Dynamic check whether the term is an aterm_int.
Definition aterm_core.h:63
unprotected_aterm_core(const detail::_aterm *term) noexcept
Constructor.
Definition aterm_core.h:47
Inherit from this class to prevent it from being copyable.
Definition noncopyable.h:21
noncopyable & operator=(const noncopyable &)=delete
noncopyable(const noncopyable &)=delete
Stores a reference count that can be incremented and decremented.
static void count_reference_count_changes()
Increment the number of reference count changes.
std::size_t reference_count() const
Obtain the reference count.
void increment_reference_count() const
Increment the reference count by one.
static std::atomic< std::size_t > & reference_count_changes()
Obtain the number of times that this reference count has changed.
void decrement_reference_count() const
Decrement the reference count by one.
A reference counted reference to a shared_reference_counted object.
bool operator==(const shared_reference< T > &other) const noexcept
bool operator>=(const shared_reference &other) const noexcept
shared_reference< T > & operator=(shared_reference< T > &&other) noexcept
Move assignment constructor.
bool defined() const
Check whether the shared_reference has a valid reference.
bool operator>(const shared_reference< T > &other) const noexcept
shared_reference() noexcept
The default constructor.
void swap(shared_reference< T > &other)
Swaps *this with the other shared reference.
utilities::tagged_pointer< T > m_reference
shared_reference< T > & operator=(const shared_reference< T > &other) noexcept
Copy assignment constructor.
bool operator!=(const shared_reference< T > &other) const noexcept
bool operator<=(const shared_reference< T > &other) const noexcept
shared_reference(shared_reference< T > &&other) noexcept
Move constructor.
shared_reference(const shared_reference< T > &other) noexcept
Copy constructor.
bool operator<(const shared_reference< T > &other) const noexcept
shared_reference(T *reference) noexcept
Takes ownership of the passed reference, which means that its reference count is incremented.
A pointer storage object that uses a least significant bit as a mark. Can be used by objects that are...
Implements a simple stopwatch that starts on construction.
Definition stopwatch.h:17
double seconds()
Definition stopwatch.h:37
function_symbol g_as_empty_list
thread_aterm_pool & g_thread_term_pool()
A reference to the thread local term pool storage.
function_symbol g_as_list
function_symbol g_as_int
These function symbols are used to indicate integer, list and empty list terms.
void debug_print(std::ostream &o, const _aterm *t, const std::size_t d=3)
The main namespace for the aterm++ library.
Definition algorithm.h:21
void make_term_appl(Term &target, const function_symbol &sym, InputIterator begin, InputIterator end, TermConverter converter)
Constructor an aterm in a variable based on a function symbol and an forward iterator providing the a...
Definition aterm.h:268
void make_term_appl(Term &target, const function_symbol &sym)
Make an term_appl consisting of a single function symbol.
Definition aterm.h:286
Derived & reference_cast(Derived &t)
A cast from one aterm based type to another, as a reference, allowing to assign to it.
Definition aterm.h:370
void(* term_callback)(const aterm &)
Definition aterm.h:194
std::string pp(const atermpp::aterm &t)
Transform an aterm to an ascii string.
Definition aterm.h:440
void make_term_appl(Term &target, const function_symbol &symbol, const Terms &...arguments)
Make an aterm application for n-arity function application.
Definition aterm.h:301
void make_term_appl(Term &target, const function_symbol &sym, ForwardIterator begin, ForwardIterator end)
Constructor an aterm in a variable based on a function symbol and an forward iterator providing the a...
Definition aterm.h:213
void make_term_appl(Term &target, const function_symbol &sym, InputIterator begin, InputIterator end)
Constructor an aterm in a variable based on a function symbol and an input iterator providing the arg...
Definition aterm.h:241
void add_deletion_hook(const function_symbol &, term_callback)
Check for reasonably sized aterm (32 bits, 4 bytes) This check might break on perfectly valid archite...
const DerivedCont & container_cast(const Cont< Base > &t, typename std::enable_if_t< is_container< DerivedCont, aterm >::value &&std::is_same_v< Cont< typename DerivedCont::value_type >, DerivedCont > &&!std::is_base_of_v< DerivedCont, Cont< Base > > &&is_convertible< Base, typename DerivedCont::value_type >::value > *=nullptr)
Definition aterm.h:379
void make_term_appl_with_index(aterm &target, const function_symbol &symbol, const Terms &...arguments)
Constructor for n-arity function application with an index.
Definition aterm.h:313
const Derived & vertical_cast(const Base &t, typename std::enable_if< is_convertible< Base, Derived >::value >::type *=nullptr)
A cast form an aterm derived class to a class that inherits in possibly multiple steps from this clas...
Definition aterm.h:399
const Derived & down_cast(const Base &t, typename std::enable_if< is_convertible< Base, Derived >::value &&!std::is_base_of< Derived, Base >::value >::type *=nullptr)
A cheap cast from one aterm based type to another When casting one aterm based type into another,...
Definition aterm.h:337
const DerivedCont & vertical_cast(const Cont< Base > &t, typename std::enable_if_t< is_container< DerivedCont, aterm >::value &&std::is_same_v< Cont< typename DerivedCont::value_type >, DerivedCont > &&is_convertible< Base, typename DerivedCont::value_type >::value > *=nullptr)
Definition aterm.h:409
Derived & reference_cast(Base &t, typename std::enable_if< is_convertible< Base, Derived >::value &&!std::is_base_of< Derived, Base >::value >::type *=nullptr)
A cast from one aterm based type to another, as a reference, allowing to assign to it.
Definition aterm.h:352
constexpr bool is_iterable_v
Definition type_traits.h:50
static constexpr bool EnableReferenceCountMetrics
Enable to count the number of reference count changes.
constexpr bool is_iterator_v
Definition type_traits.h:53
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
void swap(atermpp::aterm &t1, atermpp::aterm &t2) noexcept
Swaps two term_applss.
Definition aterm.h:475
void swap(mcrl2::utilities::shared_reference< T > &a, mcrl2::utilities::shared_reference< T > &b) noexcept
void swap(atermpp::unprotected_aterm_core &t1, atermpp::unprotected_aterm_core &t2) noexcept
Swaps two aterms.
Definition aterm.h:462
int main(int argc, char *argv[])
Checks whether condition holds for all types passed as variadic template.
Definition type_traits.h:41
A typetrait that is std::true_type iff std::begin() and std::end() can be called on type T.
Definition type_traits.h:21
A typetrait that is std::true_type iff the given type has the iterator traits.
Definition type_traits.h:31
std::size_t operator()(const atermpp::aterm &t) const
Definition aterm.h:483
std::size_t operator()(const atermpp::aterm_core &t) const
Definition aterm_hash.h:63
std::size_t operator()(const atermpp::detail::reference_aterm< T > &t) const