LCOV - code coverage report
Current view: top level - atermpp/include/mcrl2/atermpp/detail - algorithm_impl.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 43 56 76.8 %
Date: 2024-04-21 03:44:01 Functions: 11 13 84.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): 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             : /// \file mcrl2/atermpp/detail/algorithm_impl.h
      10             : /// \brief Implementations of algorithms.
      11             : 
      12             : #ifndef MCRL2_ATERMPP_DETAIL_ALGORITHM_IMPL_H
      13             : #define MCRL2_ATERMPP_DETAIL_ALGORITHM_IMPL_H
      14             : 
      15             : #include "mcrl2/atermpp/aterm_list.h"
      16             : 
      17             : namespace atermpp
      18             : {
      19             : 
      20             : namespace detail
      21             : {
      22             : /// \brief Applies the function f to all children of a.
      23             : /// \param a A term
      24             : /// \param f A function on terms
      25             : /// \return The transformed term
      26             : template <typename Term, typename Function>
      27             : aterm_appl appl_apply(const term_appl<Term>& a, const Function f)
      28             : {
      29             :   return term_appl<Term>(a.function(), a.begin(), a.end(), f);
      30             : }
      31             : 
      32             : //--- find ----------------------------------------------------------------//
      33             : 
      34             : // we need to use our own traits classes to extract the value type from insert iterators
      35             : template <class Iterator>
      36             : struct iterator_value
      37             : {
      38             :   typedef typename std::iterator_traits<Iterator>::value_type type;
      39             : };
      40             : 
      41             : template <class Container>
      42             : struct iterator_value<std::insert_iterator<Container> >
      43             : {
      44             :   typedef typename Container::value_type type;
      45             : };
      46             : 
      47             : template <class Container>
      48             : struct iterator_value<std::back_insert_iterator<Container> >
      49             : {
      50             :   typedef typename Container::value_type type;
      51             : };
      52             : 
      53             : template <class Container>
      54             : struct iterator_value<std::front_insert_iterator<Container> >
      55             : {
      56             :   typedef typename Container::value_type type;
      57             : };
      58             : 
      59             : /// \internal
      60             : // used to abort the recursive find
      61             : struct found_term_exception
      62             : {
      63             :   aterm_appl t;
      64             : 
      65             :   found_term_exception(const aterm_appl& t_)
      66             :     : t(t_)
      67             :   {}
      68             : };
      69             : 
      70             : /// \brief Implements the for_each algorithm
      71             : /// \param t A term
      72             : /// \param op A unary function on terms
      73             : /// \return The result of the algorithm
      74             : template <typename UnaryFunction>
      75           5 : UnaryFunction for_each_impl(aterm t, UnaryFunction op)
      76             : {
      77           5 :   if (t.type_is_list())
      78             :   {
      79           0 :     const aterm_list& l = down_cast<aterm_list>(t);
      80           0 :     for (const aterm& x: l)
      81             :     {
      82           0 :       for_each_impl(x, op);
      83             :     }
      84             :   }
      85           5 :   else if (t.type_is_appl())
      86             :   {
      87           5 :     const aterm_appl& a = down_cast<aterm_appl>(t);
      88           5 :     if (op(t))
      89             :     {
      90          14 :       for (const aterm& x: a)
      91             :       {
      92           4 :         for_each_impl(x, op);
      93             :       }
      94             :     }
      95             :   }
      96           5 :   return op;
      97             : }
      98             : 
      99             : /// \brief Implements the find_if algorithm
     100             : /// If the term t is found, it is stored in output and true is returned
     101             : /// \param t A term
     102             : /// \param match A predicate function on terms
     103             : /// \param output The variable to store the match in
     104             : /// \return true if a match was found, false otherwise
     105             : template <typename MatchPredicate>
     106       47471 : bool find_if_impl(const aterm& t, MatchPredicate match, aterm_appl& output)
     107             : {
     108       47471 :   if (t.type_is_appl())
     109             :   {
     110       42236 :     const aterm_appl& a = down_cast<aterm_appl>(t);
     111       42236 :     if (match(a))
     112             :     {
     113        1556 :       output = a;
     114        1556 :       return true;
     115             :     }
     116      115706 :     for (const aterm& x: a)
     117             :     {
     118       40358 :       if (find_if_impl(x, match, output))
     119        6012 :         return true;
     120             :     }
     121             :   }
     122        5235 :   else if (t.type_is_list())
     123             :   {
     124        2971 :     const aterm_list& l = down_cast<aterm_list>(t);
     125       11210 :     for (const aterm& x: l)
     126             :     {
     127        5268 :       if (find_if_impl(x, match, output))
     128             :       {
     129           0 :         return true;
     130             :       }
     131             :     }
     132             :   }
     133       39903 :   return false;
     134             : }
     135             : 
     136             : /// \brief Implements the find_all_if algorithm
     137             : /// \param t A term
     138             : /// \param op A predicate function on terms
     139             : /// \param destBegin The beginning of a range to where the results are written
     140             : template <typename MatchPredicate, typename OutputIterator>
     141          24 : void find_all_if_impl(const aterm& t, MatchPredicate op, OutputIterator& destBegin)
     142             : {
     143             :   typedef typename iterator_value<OutputIterator>::type value_type;
     144             : 
     145          24 :   if (t.type_is_list())
     146             :   {
     147           0 :     const aterm_list& l = down_cast<aterm_list>(t);
     148           0 :     for (const aterm& x: l)
     149             :     {
     150           0 :       find_all_if_impl<MatchPredicate>(x, op, destBegin);
     151             :     }
     152             :   }
     153          24 :   else if (t.type_is_appl())
     154             :   {
     155          24 :     const aterm_appl& a = down_cast<aterm_appl>(t);
     156          24 :     if (op(a))
     157             :     {
     158           4 :       *destBegin++ = vertical_cast<value_type>(a);
     159             :     }
     160          70 :     for (const aterm& x: a)
     161             :     {
     162          22 :       find_all_if_impl<MatchPredicate>(x, op, destBegin);
     163             :     }
     164             :   }
     165             :   else
     166             :   {
     167           0 :     return;
     168             :   }
     169             : }
     170             : 
     171             : //--- partial find --------------------------------------------------------//
     172             : 
     173             : /// \brief Implements the partial_find_if_impl algorithm
     174             : /// \param t A term
     175             : /// \param match A predicate function on terms
     176             : /// \param stop A predicate function on terms
     177             : template <typename MatchPredicate, typename StopPredicate>
     178           8 : aterm_appl partial_find_if_impl(const aterm& t, MatchPredicate match, StopPredicate stop)
     179             : {
     180           8 :   if (t.type_is_appl())
     181             :   {
     182           8 :     const aterm_appl& a = down_cast<aterm_appl>(t);
     183           8 :     if (match(a))
     184             :     {
     185           1 :       return a; // report the match
     186             :     }
     187           7 :     if (stop(a))
     188             :     {
     189           2 :       return aterm_appl(); // nothing was found
     190             :     }
     191          20 :     for (const aterm& x: a)
     192             :     {
     193           6 :       aterm_appl result = partial_find_if_impl<MatchPredicate, StopPredicate>(x, match, stop);
     194           6 :       if (result != aterm_appl())
     195             :       {
     196           2 :         return result;
     197             :       }
     198             :     }
     199             :   }
     200             : 
     201           3 :   if (t.type_is_list())
     202             :   {
     203           0 :     const aterm_list& l = down_cast<aterm_list>(t);
     204           0 :     for (const aterm& x: l)
     205             :     {
     206           0 :       aterm_appl result = partial_find_if_impl<MatchPredicate, StopPredicate>(x, match, stop);
     207           0 :       if (result != aterm_appl())
     208             :       {
     209           0 :         return result;
     210             :       }
     211             :     }
     212             :   }
     213           3 :   return aterm_appl();
     214             : }
     215             : 
     216             : /// \brief Implements the partial_find_all_if algorithm
     217             : /// \param t A term
     218             : /// \param match A predicate function on terms
     219             : /// \param stop A predicate function on terms
     220             : /// \param destBegin The beginning of a range to where the results are written
     221             : template <typename MatchPredicate, typename StopPredicate, typename OutputIterator>
     222             : void partial_find_all_if_impl(const aterm& t, MatchPredicate match, StopPredicate stop, OutputIterator& destBegin)
     223             : {
     224             :   if (t.type_is_appl())
     225             :   {
     226             :     const aterm_appl& a = down_cast<aterm_appl>(t);
     227             :     if (match(a))
     228             :     {
     229             :       *destBegin++ = down_cast<aterm_appl>(t);
     230             :     }
     231             :     if (stop(a))
     232             :     {
     233             :       return;
     234             :     }
     235             :     for (const aterm& x: a)
     236             :     {
     237             :       partial_find_all_if_impl<MatchPredicate, StopPredicate>(x, match, stop, destBegin);
     238             :     }
     239             :   }
     240             : 
     241             :   if (t.type_is_list())
     242             :   {
     243             :     const aterm_list& l = down_cast<aterm_list>(t);
     244             :     for (const aterm& x: l)
     245             :     {
     246             :       partial_find_all_if_impl<MatchPredicate, StopPredicate>(x, match, stop, destBegin);
     247             :     }
     248             :   }
     249             : }
     250             : 
     251             : } // namespace detail
     252             : 
     253             : } // namespace atermpp
     254             : 
     255             : #endif // MCRL2_ATERMPP_DETAIL_ALGORITHM_IMPL_H

Generated by: LCOV version 1.14