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: 50 50 100.0 %
Date: 2024-04-26 03:18:02 Functions: 1847 4841 38.2 %
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     2854372 : inline void msg(const std::string&)
      30     2854372 : {}
      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    75565250 :   void enter(const T&)
      46    75565250 :   {}
      47             : 
      48             :   // Leave object
      49             :   template <typename T>
      50    75564747 :   void leave(const T&)
      51    75564747 :   {}
      52             : 
      53             :   template <typename T>
      54        3504 :   void update(T& x, typename atermpp::disable_if_container<T>::type* = nullptr)
      55             :   {
      56        3504 :     msg("non-container visit");
      57        3504 :     T result;
      58        3504 :     static_cast<Derived*>(this)->apply(result, x);
      59        3504 :     x = result;
      60        3504 :   }
      61             : 
      62             :   // container visit
      63             :   template <typename T>
      64        8469 :   void update(T& x, typename atermpp::enable_if_container<T>::type* = nullptr)
      65             :   {
      66        8469 :     msg("container visit");
      67       23711 :     for (auto& v: x)
      68             :     {
      69       15242 :       static_cast<Derived*>(this)->update(v);
      70             :     }
      71        8469 :   }
      72             : 
      73             :   // aterm set visit
      74             :   template <typename T>
      75        1638 :   void update(std::set<T>& x)
      76             :   {
      77        1638 :     msg("set visit");
      78        1638 :     std::set<T> result;
      79        1793 :     for (T v: x)
      80             :     {
      81         155 :       static_cast<Derived*>(this)->update(v);
      82         155 :       result.insert(v);
      83             :     }
      84        1638 :     result.swap(x);
      85        1638 :   }
      86             : 
      87             :   // term_list visit copy
      88             :   template <typename T, typename U>
      89     2840761 :   void apply(atermpp::term_list<T>& result, const atermpp::term_list<U>& x)
      90             :   {
      91     2840761 :     msg("term_list traversal");
      92     2840761 :     atermpp::make_term_list<T>(static_cast<atermpp::term_list<T>&>(result), 
      93             :                                x.begin(), 
      94             :                                x.end(), 
      95     4937508 :                                [&](T& result, const U& v) { static_cast<Derived*>(this)->apply(result, v); } );
      96     2840761 :   }
      97             : };
      98             : 
      99             : 
     100             : // apply a builder without additional template arguments
     101             : template <template <class> class Builder>
     102             : class apply_builder: public Builder<apply_builder<Builder> >
     103             : {
     104             :   typedef Builder<apply_builder<Builder> > super;
     105             : 
     106             :   public:
     107             : 
     108             :     using super::enter;
     109             :     using super::leave;
     110             :     using super::apply;
     111             :     using super::update;
     112             : };
     113             : 
     114             : template <template <class> class Builder>
     115             : apply_builder<Builder>
     116       24974 : make_apply_builder()
     117             : {
     118       24974 :   return apply_builder<Builder>();
     119             : }
     120             : 
     121             : // apply a builder with one additional template argument
     122             : template <template <class> class Builder, class Arg1>
     123             : class apply_builder_arg1: public Builder<apply_builder_arg1<Builder, Arg1> >
     124             : {
     125             :   typedef Builder<apply_builder_arg1<Builder, Arg1> > super;
     126             : 
     127             :   public:
     128             :     using super::enter;
     129             :     using super::leave;
     130             :     using super::apply;
     131             :     using super::update;
     132             : 
     133          81 :     apply_builder_arg1(const Arg1& arg1):
     134          81 :       super(arg1)
     135          81 :     {}
     136             : };
     137             : 
     138             : template <template <class> class Builder, class Arg1>
     139             : apply_builder_arg1<Builder, Arg1>
     140          81 : make_apply_builder_arg1(const Arg1& arg1)
     141             : {
     142          81 :   return apply_builder_arg1<Builder, Arg1>(arg1);
     143             : }
     144             : 
     145             : // apply a builder with two additional template arguments
     146             : template <template <class> class Builder, class Arg1, class Arg2>
     147             : class apply_builder_arg2: public Builder<apply_builder_arg2<Builder, Arg1, Arg2> >
     148             : {
     149             :   typedef Builder<apply_builder_arg2<Builder, Arg1, Arg2> > super;
     150             : 
     151             :   public:
     152             :     using super::enter;
     153             :     using super::leave;
     154             :     using super::apply;
     155             :     using super::update;
     156             : 
     157          39 :     apply_builder_arg2(const Arg1& arg1, const Arg2& arg2):
     158          39 :       super(arg1, arg2)
     159          39 :     {}
     160             : };
     161             : 
     162             : template <template <class> class Builder, class Arg1, class Arg2>
     163             : apply_builder_arg2<Builder, Arg1, Arg2>
     164          39 : make_apply_builder_arg2(const Arg1& arg1, const Arg2& arg2)
     165             : {
     166          39 :   return apply_builder_arg2<Builder, Arg1, Arg2>(arg1, arg2);
     167             : }
     168             : 
     169             : 
     170             : // apply a builder without additional template arguments
     171             : template <template <class> class Builder, class Function>
     172             : struct update_apply_builder: public Builder<update_apply_builder<Builder, Function> >
     173             : {
     174             :   typedef Builder<update_apply_builder<Builder, Function> > super;
     175             : 
     176             :   using super::enter;
     177             :   using super::leave;
     178             :   using super::apply;
     179             :   using super::update;
     180             : 
     181             :   using argument_type = typename Function::argument_type; ///< The argument_type is required to restrict the overloads of apply(x) to that type.
     182             :   using result_type = typename Function::result_type; ///< The argument_type is required to restrict the overloads of apply(x) to that type.
     183             :   const Function& f_;
     184             :   
     185             :   template <class T>
     186    29946341 :   void apply(T& result, const argument_type& x) // -> decltype(f_(x))
     187             :   {
     188             :     // static_cast<result_type&>(result) = f_(x);
     189    29946341 :     result = static_cast<T>(f_(x));
     190    29946341 :   }
     191             : 
     192     4786155 :   update_apply_builder(const Function& f)
     193     4786155 :     : f_(f)
     194     4786155 :   {}
     195             : };
     196             : 
     197             : template <template <class> class Builder, class Function>
     198             : update_apply_builder<Builder, Function>
     199     4786155 : make_update_apply_builder(const Function& f)
     200             : {
     201     4786155 :   return update_apply_builder<Builder, Function>(f);
     202             : }
     203             : 
     204             : // apply a builder with one additional template argument
     205             : template <template <class> class Builder, class Function, class Arg1>
     206             : class update_apply_builder_arg1: public Builder<update_apply_builder_arg1<Builder, Function, Arg1> >
     207             : {
     208             :   typedef Builder<update_apply_builder_arg1<Builder, Function, Arg1> > super;
     209             : 
     210             :   using super::enter;
     211             :   using super::leave;
     212             :   using super::apply;
     213             :   using super::update;
     214             :   
     215             :   using argument_type = typename Function::argument_type; ///< The argument_type is required to restrict the overloads of apply(x) to that type.
     216             :   using result_type = typename Function::result_type;
     217             :   const Function& f_;
     218             :   
     219             :   template <class T>
     220             :   void apply(T& result, const argument_type& x) // -> decltype(f_(x))
     221             :   {
     222             :     result = f_(x);
     223             :   }
     224             : 
     225             :   update_apply_builder_arg1(const Function& f, const Arg1& arg1):
     226             :     super(arg1),
     227             :     f_(f)
     228             :   {}
     229             : };
     230             : 
     231             : template <template <class> class Builder, class Function, class Arg1>
     232             : update_apply_builder_arg1<Builder, Function, Arg1>
     233             : make_update_apply_builder_arg1(const Function& f)
     234             : {
     235             :   return update_apply_builder_arg1<Builder, Function, Arg1>(f);
     236             : }
     237             : 
     238             : } // namespace core
     239             : 
     240             : } // namespace mcrl2
     241             : 
     242             : #endif // MCRL2_CORE_BUILDER_H

Generated by: LCOV version 1.14