LCOV - code coverage report
Current view: top level - core/include/mcrl2/core - builder.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 42 42 100.0 %
Date: 2020-02-13 00:44:47 Functions: 1726 3574 48.3 %
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/core/builder.h
      10             : /// \brief add your file description here.
      11             : 
      12             : #ifndef MCRL2_CORE_BUILDER_H
      13             : #define MCRL2_CORE_BUILDER_H
      14             : 
      15             : #include "mcrl2/atermpp/aterm_list.h"
      16             : 
      17             : namespace mcrl2
      18             : {
      19             : 
      20             : namespace core
      21             : {
      22             : 
      23             : #ifdef MCRL2_DEBUG_EXPRESSION_BUILDER
      24             : inline void msg(const std::string& s)
      25             : {
      26             :   std::cout << "--- " << s << " ---" << std::endl;
      27             : }
      28             : #else
      29     2182781 : inline void msg(const std::string&)
      30     2182781 : {}
      31             : #endif
      32             : 
      33             : /**
      34             :  * \brief expression builder that visits all sub expressions
      35             :  *
      36             :  * Types:
      37             :  *  \arg Derived the type of a derived class, as per CRTP
      38             :  *
      39             :  **/
      40             : template <typename Derived>
      41             : struct builder
      42             : {
      43             :   // Enter object
      44             :   template <typename T>
      45    55106816 :   void enter(const T&)
      46    55106816 :   {}
      47             : 
      48             :   // Leave object
      49             :   template <typename T>
      50    55106204 :   void leave(const T&)
      51    55106204 :   {}
      52             : 
      53             :   template <typename T>
      54        3770 :   void update(T& x, typename atermpp::disable_if_container<T>::type* = nullptr)
      55             :   {
      56        3770 :     msg("non-container visit");
      57        3770 :     x = static_cast<Derived*>(this)->apply(x);
      58        3770 :   }
      59             : 
      60             :   // container visit
      61             :   template <typename T>
      62        8566 :   void update(T& x, typename atermpp::enable_if_container<T>::type* = nullptr)
      63             :   {
      64        8566 :     msg("container visit");
      65       25348 :     for (auto& v: x)
      66             :     {
      67       16782 :       static_cast<Derived*>(this)->update(v);
      68             :     }
      69        8566 :   }
      70             : 
      71             :   // aterm set visit
      72             :   template <typename T>
      73        1438 :   void update(std::set<T>& x)
      74             :   {
      75        1438 :     msg("set visit");
      76        2876 :     std::set<T> result;
      77        1587 :     for (T v: x)
      78             :     {
      79         149 :       static_cast<Derived*>(this)->update(v);
      80         149 :       result.insert(v);
      81             :     }
      82        1438 :     result.swap(x);
      83        1438 :   }
      84             : 
      85             :   // term_list visit copy
      86             :   template <typename T>
      87     2169007 :   atermpp::term_list<T> apply(const atermpp::term_list<T>& x)
      88             :   {
      89     2169007 :     msg("term_list traversal");
      90     5863783 :     return atermpp::term_list<T>(x.begin(), x.end(), [&](const T& v) { return atermpp::vertical_cast<T>(static_cast<Derived*>(this)->apply(v)); } );
      91             :   }
      92             : };
      93             : 
      94             : 
      95             : // apply a builder without additional template arguments
      96             : template <template <class> class Builder>
      97          14 : class apply_builder: public Builder<apply_builder<Builder> >
      98             : {
      99             :     typedef Builder<apply_builder<Builder> > super;
     100             : 
     101             :   public:
     102             : 
     103             :     using super::enter;
     104             :     using super::leave;
     105             :     using super::apply;
     106             :     using super::update;
     107             : };
     108             : 
     109             : template <template <class> class Builder>
     110             : apply_builder<Builder>
     111       25600 : make_apply_builder()
     112             : {
     113       25600 :   return apply_builder<Builder>();
     114             : }
     115             : 
     116             : // apply a builder with one additional template argument
     117             : template <template <class> class Builder, class Arg1>
     118          23 : class apply_builder_arg1: public Builder<apply_builder_arg1<Builder, Arg1> >
     119             : {
     120             :     typedef Builder<apply_builder_arg1<Builder, Arg1> > super;
     121             : 
     122             :   public:
     123             :     using super::enter;
     124             :     using super::leave;
     125             :     using super::apply;
     126             :     using super::update;
     127             : 
     128         104 :     apply_builder_arg1(const Arg1& arg1):
     129         104 :       super(arg1)
     130         104 :     {}
     131             : };
     132             : 
     133             : template <template <class> class Builder, class Arg1>
     134             : apply_builder_arg1<Builder, Arg1>
     135         104 : make_apply_builder_arg1(const Arg1& arg1)
     136             : {
     137         104 :   return apply_builder_arg1<Builder, Arg1>(arg1);
     138             : }
     139             : 
     140             : 
     141             : // apply a builder without additional template arguments
     142             : template <template <class> class Builder, class Function>
     143             : struct update_apply_builder: public Builder<update_apply_builder<Builder, Function> >
     144             : {
     145             :   typedef Builder<update_apply_builder<Builder, Function> > super;
     146             : 
     147             :   using super::enter;
     148             :   using super::leave;
     149             :   using super::apply;
     150             :   using super::update;
     151             : 
     152             :   using argument_type = typename Function::argument_type; ///< The argument_type is required to restrict the overloads of apply(x) to that type.
     153             :   const Function& f_;
     154             :   
     155    22099898 :   auto apply(const argument_type& x) -> decltype(f_(x))
     156             :   {
     157    22099898 :     return f_(x);
     158             :   }
     159             : 
     160     3664895 :   update_apply_builder(const Function& f)
     161     3664895 :     : f_(f)
     162     3664895 :   {}
     163             : };
     164             : 
     165             : template <template <class> class Builder, class Function>
     166             : update_apply_builder<Builder, Function>
     167     3664895 : make_update_apply_builder(const Function& f)
     168             : {
     169     3664895 :   return update_apply_builder<Builder, Function>(f);
     170             : }
     171             : 
     172             : // apply a builder with one additional template argument
     173             : template <template <class> class Builder, class Function, class Arg1>
     174             : class update_apply_builder_arg1: public Builder<update_apply_builder_arg1<Builder, Function, Arg1> >
     175             : {
     176             :   typedef Builder<update_apply_builder_arg1<Builder, Function, Arg1> > super;
     177             : 
     178             :   using super::enter;
     179             :   using super::leave;
     180             :         using super::apply;
     181             :   using super::update;
     182             :   
     183             :   using argument_type = typename Function::argument_type; ///< The argument_type is required to restrict the overloads of apply(x) to that type.
     184             :   const Function& f_;
     185             :   
     186             :   auto apply(const argument_type& x) -> decltype(f_(x))
     187             :   {
     188             :     return f_(x);
     189             :   }
     190             : 
     191             :   update_apply_builder_arg1(const Function& f, const Arg1& arg1):
     192             :     super(arg1),
     193             :     f_(f)
     194             :   {}
     195             : };
     196             : 
     197             : template <template <class> class Builder, class Function, class Arg1>
     198             : update_apply_builder_arg1<Builder, Function, Arg1>
     199             : make_update_apply_builder_arg1(const Function& f)
     200             : {
     201             :   return update_apply_builder_arg1<Builder, Function, Arg1>(f);
     202             : }
     203             : 
     204             : } // namespace core
     205             : 
     206             : } // namespace mcrl2
     207             : 
     208             : #endif // MCRL2_CORE_BUILDER_H

Generated by: LCOV version 1.13