mCRL2
Loading...
Searching...
No Matches
aterm.h
Go to the documentation of this file.
1// Author(s): Jan Friso Groote, Maurice Laveaux, Wieger Wesselink.
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_ATERMPP_ATERM_H
11#define MCRL2_ATERMPP_ATERM_H
12
13#include <algorithm>
14#include <assert.h>
15#include <sstream>
18
20namespace atermpp
21{
22
23typedef void(*term_callback)(const aterm&);
24
26
27// Forward declaration
28namespace detail
29{
30 class thread_aterm_pool;
31}
32
36{
38
39protected:
41
42public:
43
46 : m_term(nullptr)
47 {}
48
51 unprotected_aterm(const detail::_aterm* term) noexcept
52 : m_term(term)
53 {}
54
59 bool type_is_appl() const noexcept
60 {
61 return !type_is_int() && !type_is_list();
62 }
63
67 bool type_is_int() const noexcept
68 {
70 return f == detail::g_as_int;
71 }
72
76 bool type_is_list() const noexcept
77 {
80 }
81
87 bool operator ==(const unprotected_aterm& t) const
88 {
89 return m_term == t.m_term;
90 }
91
96 bool operator !=(const unprotected_aterm& t) const
97 {
98 return m_term!=t.m_term;
99 }
100
108 bool operator <(const unprotected_aterm& t) const
109 {
110 return m_term<t.m_term;
111 }
112
117 bool operator >(const unprotected_aterm& t) const
118 {
119 return m_term>t.m_term;
120 }
121
126 bool operator <=(const unprotected_aterm& t) const
127 {
128 return m_term<=t.m_term;
129 }
130
135 bool operator >=(const unprotected_aterm& t) const
136 {
137 return m_term>=t.m_term;
138 }
139
147 bool defined() const
148 {
149 return m_term != nullptr;
150 }
151
156 void swap(unprotected_aterm& t) noexcept
157 {
158 std::swap(m_term, t.m_term);
159 }
160
166 {
167 return m_term->function();
168 }
169};
170
184//
186{
187public:
188
190 aterm() noexcept;
191
193 ~aterm() noexcept;
194
200 explicit aterm(const detail::_aterm *t) noexcept;
201
205 aterm(const aterm& other) noexcept;
206
211 aterm(aterm&& other) noexcept;
212
216 aterm& operator=(const aterm& other) noexcept;
217
219 // \detail This can be used as an optimisation, because it avoids getting access to thread local variables,
220 // which is as it stands relatively expensive. The effect is equal to the assignment operator =.
222 aterm& assign(const aterm& other,
224
231 template <bool CHECK_BUSY_FLAG=true>
232 aterm& unprotected_assign(const aterm& other) noexcept;
233
237 aterm& operator=(aterm&& other) noexcept;
238};
239
240template <class Term1, class Term2>
241struct is_convertible : public
242 std::conditional<std::is_base_of<aterm, Term1>::value &&
243 std::is_base_of<aterm, Term2>::value && (
244 std::is_convertible<Term1, Term2>::value ||
245 std::is_convertible<Term2, Term1>::value),
246 std::true_type, std::false_type>::type
247{ };
248
258template <class Derived, class Base>
259const Derived& down_cast(const Base& t,
260 typename std::enable_if<is_convertible<Base, Derived>::value &&
261 !std::is_base_of<Derived, Base>::value>::type* = nullptr)
262{
263 static_assert(sizeof(Derived) == sizeof(aterm),
264 "aterm cast can only be applied ot types derived from aterms where no extra fields are added");
265 assert(Derived(static_cast<const aterm&>(t)) != aterm());
266 return reinterpret_cast<const Derived&>(t);
267}
268
270// This can be useful when assigning to a term type that contains the derived term type.
273template <class Derived, class Base>
274Derived& reference_cast(Base& t,
275 typename std::enable_if<is_convertible<Base, Derived>::value &&
276 !std::is_base_of<Derived, Base>::value >::type* = nullptr)
277{
278 static_assert(sizeof(Base) == sizeof(aterm),
279 "aterm cast can only be applied to terms directly derived from aterms");
280 static_assert(sizeof(Derived) == sizeof(aterm),
281 "aterm cast can only be applied to types derived from aterms where no extra fields are added");
282 // We do not check types as the content of the term t is likely to be overwritten shortly.
283 return reinterpret_cast<Derived&>(t);
284}
285
287// This can be useful when assigning to a term type that contains the derived term type.
288// In case Derived and Base are equal, nothing needs to be done.
291template <class Derived>
292Derived& reference_cast(Derived& t)
293{
294 static_assert(sizeof(Derived) == sizeof(aterm),
295 "aterm cast can only be applied to terms directly derived from aterms");
296 // We do not check types as the content of the term t is likely to be overwritten shortly.
297 return t;
298}
299
300template < typename DerivedCont, typename Base, template <typename Elem> class Cont >
301const DerivedCont& container_cast(const Cont<Base>& t,
302 typename std::enable_if_t<
304 std::is_same_v<Cont<typename DerivedCont::value_type>, DerivedCont> &&
305 !std::is_base_of_v<DerivedCont, Cont<Base> > &&
307 >* = nullptr)
308{
309 static_assert(sizeof(typename DerivedCont::value_type) == sizeof(aterm),
310 "aterm cast cannot be applied types derived from aterms where extra fields are added");
311 assert(std::all_of(t.begin(),t.end(),[](const Base& u){ return typename DerivedCont::value_type(static_cast<const aterm&>(u)) != aterm();} ));
312 return reinterpret_cast<const DerivedCont&>(t);
313}
314
320template <class Derived, class Base>
321const Derived& vertical_cast(const Base& t,
322 typename std::enable_if<is_convertible<Base, Derived>::value>::type* = nullptr)
323{
324 static_assert(sizeof(Derived) == sizeof(aterm),
325 "aterm cast cannot be applied types derived from aterms where extra fields are added");
326 assert(Derived(static_cast<const aterm&>(t)) != aterm());
327 return reinterpret_cast<const Derived&>(t);
328}
329
330template < typename DerivedCont, typename Base, template <typename Elem> class Cont >
331const DerivedCont& vertical_cast(const Cont<Base>& t,
332 typename std::enable_if_t<
334 std::is_same_v<Cont<typename DerivedCont::value_type>, DerivedCont> &&
336 >* = nullptr)
337{
338 static_assert(sizeof(typename DerivedCont::value_type) == sizeof(aterm),
339 "aterm cast cannot be applied types derived from aterms where extra fields are added");
340 assert(std::all_of(t.begin(),t.end(),[](const Base& u){ return typename DerivedCont::value_type(static_cast<const aterm&>(u)) != aterm();} ));
341 return reinterpret_cast<const DerivedCont&>(t);
342}
343
344namespace detail
345{
348 {
349 return const_cast<_aterm*>(t.m_term);
350 }
351}
352
357std::ostream& operator<<(std::ostream& out, const atermpp::aterm& t);
358
362inline std::string pp(const atermpp::aterm& t)
363{
364 std::ostringstream oss;
365 oss << t;
366 return oss.str();
367}
368
369} // namespace atermpp
370
371namespace std
372{
373
383template <>
385{
386 t1.swap(t2);
387}
388} // namespace std
389
390#endif // MCRL2_ATERMPP_ATERM_H
A class containing some type traits.
The aterm base class that provides protection of the underlying shared terms.
Definition aterm.h:186
aterm() noexcept
Default constructor.
aterm & operator=(const aterm &other) noexcept
Assignment operator.
aterm & assign(const aterm &other, detail::thread_aterm_pool &pool) noexcept
Assignment operator, to be used if busy and forbidden flags are explicitly available.
aterm & unprotected_assign(const aterm &other) noexcept
Assignment operator, to be used when the busy flags do not need to be set.
~aterm() noexcept
Standard destructor.
This is the class to which an aterm points.
Definition aterm.h:48
const function_symbol & function() const noexcept
Definition aterm.h:55
This is a thread's specific access to the global aterm pool which ensures that garbage collection and...
An unprotected term does not change the reference count of the shared term when it is copied or moved...
Definition aterm.h:36
bool operator<(const unprotected_aterm &t) const
Comparison operator for two unprotected aterms.
Definition aterm.h:108
bool type_is_list() const noexcept
Dynamic check whether the term is an aterm_list.
Definition aterm.h:76
bool operator>(const unprotected_aterm &t) const
Comparison operator for two unprotected aterms.
Definition aterm.h:117
unprotected_aterm() noexcept
Default constuctor.
Definition aterm.h:45
bool operator==(const unprotected_aterm &t) const
Comparison operator.
Definition aterm.h:87
const function_symbol & function() const
Yields the function symbol in an aterm.
Definition aterm.h:165
unprotected_aterm(const detail::_aterm *term) noexcept
Constructor.
Definition aterm.h:51
bool type_is_int() const noexcept
Dynamic check whether the term is an aterm_int.
Definition aterm.h:67
const detail::_aterm * m_term
Definition aterm.h:40
bool defined() const
Returns true if this term is not equal to the term assigned by the default constructor of aterms,...
Definition aterm.h:147
bool operator!=(const unprotected_aterm &t) const
Inequality operator on two unprotected aterms.
Definition aterm.h:96
bool operator<=(const unprotected_aterm &t) const
Comparison operator for two unprotected aterms.
Definition aterm.h:126
void swap(unprotected_aterm &t) noexcept
Swaps this term with its argument.
Definition aterm.h:156
bool operator>=(const unprotected_aterm &t) const
Comparison operator for two unprotected aterms.
Definition aterm.h:135
bool type_is_appl() const noexcept
Dynamic check whether the term is an aterm_appl.
Definition aterm.h:59
a pool allocator class
function_symbol g_as_empty_list
function_symbol g_as_list
_aterm * address(const unprotected_aterm &t)
Definition aterm.h:347
function_symbol g_as_int
These function symbols are used to indicate integer, list and empty list terms.
The main namespace for the aterm++ library.
Definition algorithm.h:21
std::string pp(const atermpp::aterm &t)
Transform an aterm to an ascii string.
Definition aterm.h:362
std::ostream & operator<<(std::ostream &out, const atermpp::aterm &t)
Send the term in textual form to the ostream.
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...
void(* term_callback)(const aterm &)
Definition aterm.h:23
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:301
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:321
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:259
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:274
STL namespace.
void swap(atermpp::unprotected_aterm &t1, atermpp::unprotected_aterm &t2) noexcept
Swaps two aterms.
Definition aterm.h:384