LCOV - code coverage report
Current view: top level - atermpp/include/mcrl2/atermpp - aterm_list.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 88 88 100.0 %
Date: 2024-04-21 03:44:01 Functions: 570 821 69.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Wieger Wesselink, Jan Friso Groote
       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_LIST_H
      11             : #define MCRL2_ATERMPP_ATERM_LIST_H
      12             : 
      13             : #include "mcrl2/atermpp/detail/aterm_list.h"
      14             : #include "mcrl2/atermpp/detail/aterm_list_iterator.h"
      15             : #include "mcrl2/atermpp/type_traits.h"
      16             : 
      17             : namespace atermpp
      18             : {
      19             : 
      20             : /// \brief A list of aterm objects.
      21             : template <typename Term>
      22             : class term_list: public aterm
      23             : {
      24             : protected:
      25             :   /// \brief Constructor for term lists from internally constructed terms delivered as reference.
      26             :   explicit term_list(detail::_aterm* t) noexcept :aterm(t)
      27             :   {
      28             :     assert(!defined() || type_is_list());
      29             :   }
      30             : 
      31             : public:
      32             :   /// The type of object, T stored in the term_list.
      33             :   typedef Term value_type;
      34             : 
      35             :   /// Pointer to T.
      36             :   typedef Term* pointer;
      37             : 
      38             :   /// Reference to T.
      39             :   typedef Term& reference;
      40             : 
      41             :   /// Const reference to T.
      42             :   typedef const Term& const_reference;
      43             : 
      44             :   /// An unsigned integral type.
      45             :   typedef std::size_t size_type;
      46             : 
      47             :   /// A signed integral type.
      48             :   typedef ptrdiff_t difference_type;
      49             : 
      50             :   /// Iterator used to iterate through an term_list.
      51             :   typedef term_list_iterator<Term> iterator;
      52             : 
      53             :   /// Const iterator used to iterate through an term_list.
      54             :   typedef term_list_iterator<Term> const_iterator;
      55             : 
      56             :   /// Const iterator used to iterate through an term_list.
      57             :   typedef reverse_term_list_iterator<Term> const_reverse_iterator;
      58             : 
      59             :   /// \brief Default constructor. Creates an empty list.
      60    44108317 :   term_list() noexcept
      61    44108317 :     : aterm(detail::g_term_pool().empty_list())
      62    44108317 :   {}
      63             : 
      64             :   /// \brief Constructor from an aterm.
      65             :   /// \param t A list.
      66   642568389 :   explicit term_list(const aterm& t) noexcept
      67   642568389 :     : aterm(t)
      68             :   {
      69             :     // assert(!defined() || type_is_list());
      70   642568389 :     assert(type_is_list());  // A list should not be a default aterm. 
      71   642568389 :   }
      72             : 
      73             :   /// \brief Copy constructor.
      74             :   /// \param t A list.
      75    15651661 :   term_list(const term_list<Term>& t) noexcept
      76    15651661 :     : aterm(t)
      77             :   {
      78    15651661 :     assert(!defined() || type_is_list());
      79    15651661 :   }
      80             : 
      81             :   /// \brief Move constructor.
      82             :   /// \param t A list.
      83     1538025 :   term_list(term_list<Term>&& t) noexcept
      84     1538025 :     : aterm(std::move(t))
      85             :   {
      86     1538025 :     assert(!defined() || type_is_list());
      87     1538025 :   }
      88             : 
      89             :   /// This class has user-declared copy constructor so declare copy and move assignment.
      90     8550652 :   term_list& operator=(const term_list& other) noexcept = default;
      91     3449665 :   term_list& operator=(term_list&& other) noexcept = default;
      92             : 
      93             :   /// \brief Creates a term_list with the elements from first to last.
      94             :   /// \details It is assumed that the range can be traversed from last to first.
      95             :   /// \param first The start of a range of elements.
      96             :   /// \param last The end of a range of elements.
      97             :   template <class Iter>
      98    16669682 :   explicit term_list(Iter first, Iter last, typename std::enable_if<std::is_base_of<
      99             :                 std::bidirectional_iterator_tag,
     100             :                 typename std::iterator_traits<Iter>::iterator_category
     101             :             >::value>::type* = nullptr) :
     102             :       aterm(detail::make_list_backward<Term,Iter,
     103    16669682 :                 detail::do_not_convert_term<Term> >(first, last,detail::do_not_convert_term<Term>()))
     104             :   {
     105    16669682 :     assert(!defined() || type_is_list());
     106    16669682 :   }
     107             : 
     108             :   /// \brief Creates a term_list with the elements from first to last converting the elements before inserting.
     109             :   /// \details It is assumed that the range can be traversed from last to first. The operator () in the class
     110             :   ///          ATermConverter is applied to each element before inserting it in the list.
     111             :   /// \param first The start of a range of elements.
     112             :   /// \param last The end of a range of elements.
     113             :   /// \param convert_to_aterm A class with a () operation, which is applied to each element
     114             :   ///                   before it is put into the list.
     115             :   template <class Iter, class ATermConverter>
     116         535 :   explicit term_list(Iter first, Iter last, const ATermConverter& convert_to_aterm,
     117             :             typename std::enable_if<std::is_base_of<
     118             :               std::bidirectional_iterator_tag,
     119             :               typename std::iterator_traits<Iter>::iterator_category
     120             :             >::value>::type* = 0):
     121         535 :        aterm(detail::make_list_backward<Term,Iter,ATermConverter>(first, last, convert_to_aterm))
     122             :   {
     123         535 :     assert(!defined() || type_is_list());
     124         535 :   }
     125             : 
     126             :   /// \brief Creates a term_list with the elements from first to last, converting and filtering the list.
     127             :   /// \details It is assumed that the range can be traversed from last to first. The operator () in the class
     128             :   ///          ATermConverter is applied to each element before inserting it in the list. Elements are only
     129             :   ///          inserted if the operator () of the class ATermFilter yields true when applied to such an element.
     130             :   /// \param first The start of a range of elements.
     131             :   /// \param last The end of a range of elements.
     132             :   /// \param convert_to_aterm A class with a () operation, which is applied to each element
     133             :   ///                   before it is put into the list.
     134             :   /// \param aterm_filter A class with an operator () that is used to determine whether elements can be inserted in the list.
     135             :   template <class Iter, class ATermConverter, class ATermFilter>
     136           1 :   explicit term_list(Iter first, Iter last, const ATermConverter& convert_to_aterm, const ATermFilter& aterm_filter,
     137             :             typename std::enable_if<std::is_base_of<
     138             :               std::bidirectional_iterator_tag,
     139             :               typename std::iterator_traits<Iter>::iterator_category
     140             :             >::value>::type* = 0):
     141           1 :        aterm(detail::make_list_backward<Term,Iter,ATermConverter,ATermFilter>(first, last, convert_to_aterm, aterm_filter))
     142             :   {
     143           1 :     assert(!defined() || type_is_list());
     144           1 :   }
     145             : 
     146             :   /// \brief Creates a term_list from the elements from first to last.
     147             :   /// \details The range is traversed from first to last. This requires
     148             :   ///           to copy the elements internally, which is less efficient
     149             :   ///           than this function with random access iterators as arguments.
     150             :   /// \param first The start of a range of elements.
     151             :   /// \param last The end of a range of elements.
     152             :   template <class Iter>
     153     2555678 :   explicit term_list(Iter first, Iter last,
     154             :                      typename std::enable_if< !std::is_base_of<
     155             :                        std::bidirectional_iterator_tag,
     156             :                        typename std::iterator_traits<Iter>::iterator_category
     157             :                      >::value>::type* = nullptr):
     158             :        aterm(detail::make_list_forward<Term,Iter,detail::do_not_convert_term<Term> >
     159     2555678 :                                (first, last, detail::do_not_convert_term<Term>()))
     160             :   {
     161     2555678 :     assert(!defined() || type_is_list());
     162     2555678 :   }
     163             : 
     164             :   /// \brief Creates a term_list from the elements from first to last converting the elements before inserting.
     165             :   /// \details The range is traversed from first to last. This requires
     166             :   ///           to copy the elements internally, which is less efficient
     167             :   ///           than this function with random access iterators as arguments.
     168             :   ///           The operator () in the class
     169             :   ///           ATermConverter is applied to each element before inserting it in the list.
     170             :   /// \param first The start of a range of elements.
     171             :   /// \param last The end of a range of elements.
     172             :   /// \param convert_to_aterm A class with a () operation, whic is applied to each element
     173             :   ///                      before it is put into the list.
     174             :   template <class Iter, class  ATermConverter>
     175       26082 :   explicit term_list(Iter first, Iter last, const ATermConverter& convert_to_aterm,
     176             :                      typename std::enable_if< !std::is_base_of<
     177             :                        std::bidirectional_iterator_tag,
     178             :                        typename std::iterator_traits<Iter>::iterator_category
     179             :                      >::value>::type* = nullptr):
     180             :        aterm(detail::make_list_forward<Term,Iter,ATermConverter>
     181       26082 :                                (first, last, convert_to_aterm))
     182             :   {
     183       26082 :     assert(!defined() || type_is_list());
     184       26082 :   }
     185             : 
     186             :   /// \brief Creates a term_list from the elements from first to last converting and filtering the elements before inserting.
     187             :   /// \details The range is traversed from first to last. This requires
     188             :   ///           to copy the elements internally, which is less efficient
     189             :   ///           than this function with random access iterators as arguments.
     190             :   ///           The operator () in the class ATermConverter is applied to
     191             :   ///           each element before inserting it in the list. Elements are only
     192             :   ///           inserted if the operator () of the class ATermFilter yields true when applied to such an element.
     193             :   /// \param first The start of a range of elements.
     194             :   /// \param last The end of a range of elements.
     195             :   /// \param convert_to_aterm A class with a () operation, whic is applied to each element
     196             :   ///                      before it is put into the list.
     197             :   /// \param aterm_filter A class with an operator () that is used to determine whether elements can be inserted in the list.
     198             :   template <class Iter, class  ATermConverter, class ATermFilter>
     199          14 :   explicit term_list(Iter first, Iter last, const ATermConverter& convert_to_aterm, const ATermFilter& aterm_filter,
     200             :                      typename std::enable_if< !std::is_base_of<
     201             :                        std::random_access_iterator_tag,
     202             :                        typename std::iterator_traits<Iter>::iterator_category
     203             :                      >::value>::type* = nullptr):
     204             :        aterm(detail::make_list_forward<Term,Iter,ATermConverter>
     205          14 :                                (first, last, convert_to_aterm, aterm_filter))
     206             :   {
     207          14 :     assert(!defined() || type_is_list());
     208          14 :   }
     209             : 
     210             :   /// \brief A constructor based on an initializer list.
     211             :   /// \details This constructor is not made explicit to conform to initializer lists in standard containers.
     212             :   /// \param init The initialiser list.
     213     9518056 :   term_list(std::initializer_list<Term> init)
     214             :     : aterm(detail::make_list_backward<Term,
     215             :                                        typename std::initializer_list<Term>::const_iterator,
     216             :                                        detail::do_not_convert_term<Term> >
     217     9518056 :                 (init.begin(), init.end(), detail::do_not_convert_term<Term>()))
     218             :   {
     219     9518056 :     assert(!defined() || type_is_list());
     220     9518056 :   }
     221             : 
     222             :   /// \brief Returns the tail of the list.
     223             :   /// \return The tail of the list.
     224     1191404 :   const term_list<Term>& tail() const
     225             :   {
     226     1191404 :     assert(!empty());
     227     1191404 :     return (static_cast<const detail::_aterm_list<Term>&>(*m_term)).tail();
     228             :   }
     229             : 
     230             :   /// \brief Removes the first element of the list.
     231      213688 :   void pop_front()
     232             :   {
     233      213688 :     *this = tail();
     234      213688 :   }
     235             : 
     236             :   /// \brief Returns the first element of the list.
     237             :   /// \return The term at the head of the list.
     238     1286719 :   const Term& front() const
     239             :   {
     240     1286719 :     return static_cast<const detail::_aterm_list<Term>&>(*m_term).head();
     241             :   }
     242             : 
     243             :   /// \brief Inserts a new element at the beginning of the current list.
     244             :   /// \param el The term that is added.
     245             :   void push_front(const Term& el);
     246             : 
     247             :   /// \brief Construct and insert a new element at the beginning of the current list.
     248             :   /// \param el The term that is added.
     249             :   template<typename ...Args>
     250             :   void emplace_front(Args&&... arguments);
     251             : 
     252             :   /// \brief Returns the size of the term_list.
     253             :   /// \details The complexity of this function is linear in the size of the list.
     254             :   /// \return The size of the list.
     255   621680273 :   size_type size() const
     256             :   {
     257   621680273 :     std::size_t size=0;
     258  1680143606 :     for(const_iterator i=begin(); i!=end(); ++i)
     259             :     {
     260  1058463333 :       ++size;
     261             :     }
     262   621680273 :     return size;
     263             :   }
     264             : 
     265             :   /// \brief Returns true if the list's size is 0.
     266             :   /// \return True iff the list is empty.
     267     4666861 :   bool empty() const
     268             :   {
     269     4666861 :     return m_term->function() == detail::g_term_pool().as_empty_list();
     270             :   }
     271             : 
     272             :   /// \brief Returns a const_iterator pointing to the beginning of the term_list.
     273             :   /// \return The beginning of the list.
     274  1262706391 :   const_iterator begin() const
     275             :   {
     276  1262706391 :     return const_iterator(m_term);
     277             :   }
     278             : 
     279             :   /// \brief Returns a const_iterator pointing to the end of the term_list.
     280             :   /// \return The end of the list.
     281  2332820937 :   const_iterator end() const
     282             :   {
     283  2332820937 :     return const_iterator(detail::address(detail::g_term_pool().empty_list()));
     284             :   }
     285             : 
     286             :   /// \brief Returns a const_reverse_iterator pointing to the end of the term_list.
     287             :   /// \details This operator requires linear time and memory in the size of the list to yield the iterator.
     288             :   /// \return The end of the list.
     289        2595 :   const_reverse_iterator rbegin() const
     290             :   {
     291        2595 :     return const_reverse_iterator(m_term);
     292             :   }
     293             : 
     294             :   /// \brief Returns a const_iterator pointing to the end of the term_list.
     295             :   /// \return The end of the list.
     296        5197 :   const_reverse_iterator rend() const
     297             :   {
     298        5197 :     return const_reverse_iterator();
     299             :   }
     300             : 
     301             :   /// \brief Returns the largest possible size of the term_list.
     302             :   /// \return The largest possible size of the list.
     303             :   size_type max_size() const
     304             :   {
     305             :     return std::numeric_limits<std::size_t>::max();
     306             :   }
     307             : };
     308             : 
     309             : 
     310             : /// \brief Make an empty list and put it in target;
     311             : /// \param target The variable to which the empty list is assigned. 
     312             : template <class Term>
     313     5454056 : void make_term_list(term_list<Term>& target)
     314             : {
     315     5454056 :   target=atermpp::down_cast<term_list<Term>>(detail::g_term_pool().empty_list());
     316     5454056 : }
     317             : 
     318             : /// \brief Creates a term_list with the elements from first to last.
     319             : /// \details It is assumed that the range can be traversed from last to first.
     320             : /// \param target The variable to which the list is assigned. 
     321             : /// \param first The start of a range of elements.
     322             : /// \param last The end of a range of elements.
     323             : template <class Term, class Iter>
     324             : void make_term_list(term_list<Term>& target, Iter first, Iter last, typename std::enable_if<std::is_base_of<
     325             :                                          std::bidirectional_iterator_tag,
     326             :                                          typename std::iterator_traits<Iter>::iterator_category >::value>::type* = nullptr)
     327             : {
     328             :   detail::make_list_backward<Term,Iter,
     329             :               detail::do_not_convert_term<Term> >(target, first, last,detail::do_not_convert_term<Term>());
     330             :   assert(!target.defined() || target.type_is_list());
     331             : }
     332             : 
     333             : /// \brief Creates a term_list with the elements from first to last converting the elements before inserting.
     334             : /// \details It is assumed that the range can be traversed from last to first. The operator () in the class
     335             : ///          ATermConverter is applied to each element before inserting it in the list.
     336             : /// \param target The variable to which the list is assigned. 
     337             : /// \param first The start of a range of elements.
     338             : /// \param last The end of a range of elements.
     339             : /// \param convert_to_aterm A class with a () operation, which is applied to each element
     340             : ///                   before it is put into the list.
     341             : template <class Term, class Iter, class ATermConverter>
     342             : void make_term_list(term_list<Term>& target, Iter first, Iter last, const ATermConverter& convert_to_aterm,
     343             :                             typename std::enable_if<std::is_base_of<
     344             :                               std::bidirectional_iterator_tag,
     345             :                               typename std::iterator_traits<Iter>::iterator_category
     346             :                             >::value>::type* = 0)
     347             : {
     348             :   detail::make_list_backward<Term,Iter,ATermConverter>(target, first, last, convert_to_aterm);
     349             :   assert(!target.defined() || target.type_is_list());
     350             : }
     351             : 
     352             : /// \brief Creates a term_list with the elements from first to last, converting and filtering the list.
     353             : /// \details It is assumed that the range can be traversed from last to first. The operator () in the class
     354             : ///          ATermConverter is applied to each element before inserting it in the list. Elements are only
     355             : ///          inserted if the operator () of the class ATermFilter yields true when applied to such an element.
     356             : /// \param target The variable to which the list is assigned. 
     357             : /// \param first The start of a range of elements.
     358             : /// \param last The end of a range of elements.
     359             : /// \param convert_to_aterm A class with a () operation, which is applied to each element
     360             : ///                   before it is put into the list.
     361             : /// \param aterm_filter A class with an operator () that is used to determine whether elements can be inserted in the list.
     362             : template <class Term, class Iter, class ATermConverter, class ATermFilter>
     363             : void make_term_list(term_list<Term>& target, Iter first, Iter last, const ATermConverter& convert_to_aterm, const ATermFilter& aterm_filter,
     364             :                             typename std::enable_if<std::is_base_of<
     365             :                               std::bidirectional_iterator_tag,
     366             :                               typename std::iterator_traits<Iter>::iterator_category
     367             :                             >::value>::type* = 0)
     368             : {
     369             :   detail::make_list_backward<Term,Iter,ATermConverter,ATermFilter>(target, first, last, convert_to_aterm, aterm_filter);
     370             :   assert(!target.defined() || target.type_is_list());
     371             : }
     372             : 
     373             : /// \brief Creates a term_list from the elements from first to last.
     374             : /// \details The range is traversed from first to last. This requires
     375             : ///           to copy the elements internally, which is less efficient
     376             : ///           than this function with random access iterators as arguments.
     377             : /// \param target The variable to which the list is assigned. 
     378             : /// \param first The start of a range of elements.
     379             : /// \param last The end of a range of elements.
     380             : template <class Term, class Iter>
     381             : void make_term_list(term_list<Term>& target, Iter first, Iter last,
     382             :                              typename std::enable_if< !std::is_base_of<
     383             :                                std::bidirectional_iterator_tag,
     384             :                                typename std::iterator_traits<Iter>::iterator_category
     385             :                              >::value>::type* = nullptr)
     386             : {
     387             :   detail::make_list_forward<Term,Iter,detail::do_not_convert_term<Term> >
     388             :                              (target, first, last, detail::do_not_convert_term<Term>());
     389             :   assert(!target.defined() || target.type_is_list());
     390             : }
     391             : 
     392             : /// \brief Creates a term_list from the elements from first to last converting the elements before inserting.
     393             : /// \details The range is traversed from first to last. This requires
     394             : ///           to copy the elements internally, which is less efficient
     395             : ///           than this function with random access iterators as arguments.
     396             : ///           The operator () in the class
     397             : ///           ATermConverter is applied to each element before inserting it in the list.
     398             : /// \param target The variable to which the list is assigned. 
     399             : /// \param first The start of a range of elements.
     400             : /// \param last The end of a range of elements.
     401             : /// \param convert_to_aterm A class with a () operation, which is applied to each element
     402             : ///                      before it is put into the list.
     403             : template <class Term, class Iter, class  ATermConverter>
     404     2872296 : void make_term_list(term_list<Term>& target, Iter first, Iter last, const ATermConverter& convert_to_aterm,
     405             :                               typename std::enable_if< !std::is_base_of<
     406             :                                 std::bidirectional_iterator_tag,
     407             :                                 typename std::iterator_traits<Iter>::iterator_category
     408             :                               >::value>::type* = nullptr)
     409             : {
     410             :   detail::make_list_forward<Term,Iter,ATermConverter>
     411     2872296 :                              (target, first, last, convert_to_aterm);
     412     2872296 :   assert(!target.defined() || target.type_is_list());
     413     2872296 : }
     414             : 
     415             : /// \brief Creates a term_list from the elements from first to last converting and filtering the elements before inserting.
     416             : /// \details The range is traversed from first to last. This requires
     417             : ///           to copy the elements internally, which is less efficient
     418             : ///           than this function with random access iterators as arguments.
     419             : ///           The operator () in the class ATermConverter is applied to
     420             : ///           each element before inserting it in the list. Elements are only
     421             : ///           inserted if the operator () of the class ATermFilter yields true when applied to such an element.
     422             : /// \param target The variable to which the list is assigned. 
     423             : /// \param first The start of a range of elements.
     424             : /// \param last The end of a range of elements.
     425             : /// \param convert_to_aterm A class with a () operation, whic is applied to each element
     426             : ///                      before it is put into the list.
     427             : /// \param aterm_filter A class with an operator () that is used to determine whether elements can be inserted in the list.
     428             : template <class Term, class Iter, class  ATermConverter, class ATermFilter>
     429             : void make_term_list(term_list<Term>& target, Iter first, Iter last, const ATermConverter& convert_to_aterm, const ATermFilter& aterm_filter,
     430             :                                typename std::enable_if< !std::is_base_of<
     431             :                                  std::random_access_iterator_tag,
     432             :                                  typename std::iterator_traits<Iter>::iterator_category
     433             :                                >::value>::type* = nullptr)
     434             : {
     435             :   detail::make_list_forward<Term,Iter,ATermConverter>
     436             :                              (target, first, last, convert_to_aterm, aterm_filter);
     437             :   assert(!target.defined() || target.type_is_list());
     438             : }
     439             : 
     440             : /// \brief A constructor based on an initializer list.
     441             : /// \details This constructor is not made explicit to conform to initializer lists in standard containers.
     442             : /// \param target The variable to which the list is assigned. 
     443             : /// \param init The initialiser list.
     444             : template <class Term>
     445             : void make_term_list(term_list<Term>& target, std::initializer_list<Term> init)
     446             : {
     447             :   target=detail::make_list_backward<Term,
     448             :                                     typename std::initializer_list<Term>::const_iterator,
     449             :                                     detail::do_not_convert_term<Term> >
     450             :               (init.begin(), init.end(), detail::do_not_convert_term<Term>());
     451             :   assert(!target.defined() || target.type_is_list());
     452             : }
     453             : 
     454             : 
     455             : 
     456             : /// \cond INTERNAL_DOCS
     457             : namespace detail
     458             : {
     459             : 
     460             : /// \brief Template specialization to make a term_list recognizable as a container type (see
     461             : ///        type_traits.h and detail/type_traits_impl.h).
     462             : template < typename T >
     463             : struct is_container_impl< atermpp::term_list< T > > : public std::true_type
     464             : { };
     465             : 
     466             : 
     467             : template <class Term>
     468             : class _aterm_list : public _aterm_appl<2>
     469             : {
     470             : public:
     471             :   /// \returns A reference to the head of the list.
     472  1095462939 :   const Term& head() const { return static_cast<const Term&>(arg(0)); }
     473             : 
     474             :   /// \returns A reference to the tail of the list.
     475  2160204987 :   const term_list<Term>& tail() const { return static_cast<const term_list<Term>&>(arg(1)); }
     476             : 
     477        2595 :   std::size_t size() const
     478             :   {
     479        2595 :     std::size_t size=0;
     480        2595 :     for(_aterm_list const* i=this; 
     481        5197 :         i->function()!=detail::g_term_pool().as_empty_list(); 
     482        2602 :         i=static_cast<_aterm_list const*>(address(i->tail())))
     483             :     {
     484        2602 :       ++size;
     485             :     }
     486        2595 :     return size;
     487             :   }
     488             : 
     489             : };
     490             : 
     491             : } // namespace detail
     492             : /// \endcond
     493             : 
     494             : 
     495             : /// \brief A term_list with elements of type aterm.
     496             : typedef term_list<aterm> aterm_list;
     497             : 
     498             : 
     499             : /// \brief Returns the list with the elements in reversed order.
     500             : /// \param l A list.
     501             : /// \details This operator is linear in the size of the list.
     502             : /// \return The reversed list.
     503             : template <typename Term>
     504             : inline
     505             : term_list<Term> reverse(const term_list<Term>& l);
     506             : 
     507             : /// \brief Returns the list with the elements sorted according to the <-operator on the addresses of terms. 
     508             : /// \param l A list.
     509             : /// \param ordering An total orderings relation on Term, by default the ordering relation on Terms. 
     510             : /// \details This operator has complexity nlog n where n is the size of the list.
     511             : /// \return The sorted list.
     512             : template <typename Term>
     513             : inline
     514             : term_list<Term> sort_list(const term_list<Term>& l, 
     515             :                           const std::function<bool(const Term&, const Term&)>& ordering 
     516          18 :                                       = [](const Term& t1, const Term& t2){ return t1<t2;});
     517             : 
     518             : 
     519             : /// \brief Returns the concatenation of two lists with convertible element types.
     520             : ///  \details The type of the result is either the type of l, if the elements of m
     521             : ///           can be converted implicitly to the type of the elements of l. Otherwise if the
     522             : ///           elements of l can be converted implicitly to the type of the elements
     523             : ///           of m, the result type is that or m.
     524             : /// \param l A list.
     525             : /// \param m A list.
     526             : /// \details The complexity of this operator is linear in the length of l.
     527             : /// \return The concatenation of the lists l followed by m.
     528             : 
     529             : template <typename Term1, typename Term2>
     530             : inline
     531             : typename std::conditional<std::is_convertible<Term2,Term1>::value,term_list<Term1>,term_list<Term2>>::type
     532             : operator+(const term_list<Term1>& l, const term_list<Term2>& m);
     533             : 
     534             : 
     535             : /// \brief Appends a new element at the end of the list. Note
     536             : ///        that the complexity of this function is O(n), with n the number of
     537             : ///        elements in the list!!!
     538             : /// \param l The list to which the term is appended.
     539             : /// \param el A term.
     540             : /// \return The list l with elem appended at the end.
     541             : template <typename Term>
     542             : inline
     543             : term_list<Term> push_back(const term_list<Term>& l, const Term& el);
     544             : 
     545             : /// \brief Converts the given term list to a vector.
     546             : template <typename T>
     547             : std::vector<T> as_vector(const atermpp::term_list<T>& x)
     548             : {
     549             :   return std::vector<T>(x.begin(), x.end());
     550             : }
     551             : 
     552             : /// \brief Converts the given term list to a set.
     553             : template <typename T>
     554             : std::set<T> as_set(const atermpp::term_list<T>& x)
     555             : {
     556             :   return std::set<T>(x.begin(), x.end());
     557             : }
     558             : 
     559             : } // namespace atermpp
     560             : 
     561             : 
     562             : namespace std
     563             : {
     564             : //
     565             : /// \brief Swaps two term_lists.
     566             : /// \details This operation is more efficient than exchanging terms by an assignment,
     567             : ///          as swapping does not require to change the protection of terms.
     568             : /// \param t1 The first term
     569             : /// \param t2 The second term
     570             : template <class T>
     571        1153 : inline void swap(atermpp::term_list<T>& t1, atermpp::term_list<T>& t2) noexcept
     572             : {
     573        1153 :   t1.swap(t2);
     574        1153 : }
     575             : 
     576             : /// \brief The standard hash class.
     577             : template <class Term>
     578             : struct hash<atermpp::term_list<Term> >
     579             : {
     580             :   /// \brief A specialization of the standard std::hash function.
     581             :   /// \param l The list for which a hash value is calculated.
     582             :   /// \return A hash value for l.
     583             :   std::size_t operator()(const atermpp::term_list<Term>& l) const
     584             :   {
     585             :     std::hash<atermpp::aterm> hasher;
     586             :     return hasher(l);
     587             :   }
     588             : };
     589             : 
     590             : } // namespace std
     591             : 
     592             : #include "mcrl2/atermpp/detail/aterm_list_implementation.h"
     593             : 
     594             : #endif // MCRL2_ATERMPP_ATERM_LIST_H

Generated by: LCOV version 1.14