LCOV - code coverage report
Current view: top level - core/include/mcrl2/core - print.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 73 79 92.4 %
Date: 2024-04-19 03:43:27 Functions: 117 297 39.4 %
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/print.h
      10             : /// \brief Functions for pretty printing ATerms.
      11             : 
      12             : #ifndef MCRL2_CORE_PRINT_H
      13             : #define MCRL2_CORE_PRINT_H
      14             : 
      15             : #include "mcrl2/core/print_format.h"
      16             : #include "mcrl2/core/traverser.h"
      17             : #include <cctype>
      18             : 
      19             : namespace mcrl2
      20             : {
      21             : namespace core
      22             : {
      23             : 
      24             : /// \cond INTERNAL_DOCS
      25             : namespace detail
      26             : {
      27             : 
      28             : const int max_precedence = 10000;
      29             : 
      30             : template <typename T>
      31             : int precedence(const T&)
      32             : {
      33             :   return max_precedence;
      34             : }
      35             : 
      36             : template <typename Derived>
      37             : struct printer: public core::traverser<Derived>
      38             : {
      39             :   typedef core::traverser<Derived> super;
      40             : 
      41             :   using super::enter;
      42             :   using super::leave;
      43             :   using super::apply;
      44             : 
      45             :   std::ostream* m_out;
      46             : 
      47     1207644 :   Derived& derived()
      48             :   {
      49     1207644 :     return static_cast<Derived&>(*this);
      50             :   }
      51             : 
      52      352846 :   std::ostream& out()
      53             :   {
      54      352846 :     return *m_out;
      55             :   }
      56             : 
      57      352846 :   void print(const std::string& s)
      58             :   {
      59      352846 :     out() << s;
      60      352846 :   }
      61             : 
      62             :   template <typename T>
      63       29613 :   void print_expression(const T& x, bool needs_parentheses)
      64             :   {
      65       29613 :     if (needs_parentheses)
      66             :     {
      67        3912 :       derived().print("(");
      68             :     }
      69       29613 :     derived().apply(x);
      70       29613 :     if (needs_parentheses)
      71             :     {
      72        3912 :       derived().print(")");
      73             :     }
      74       29613 :   }
      75             : 
      76             :   template <typename T, typename U>
      77        2368 :   void print_unary_operand(const T& x, const U& operand)
      78             :   {
      79        2368 :     print_expression(operand, precedence(operand) < precedence(x));
      80        2368 :   }
      81             : 
      82             :   template <typename T>
      83          24 :   void print_unary_left_operation(const T& x, const std::string& op)
      84             :   {
      85          24 :     derived().print(op);
      86          24 :     print_unary_operand(x, x.operand());
      87          24 :   }
      88             : 
      89             :   template <typename T>
      90          11 :   void print_unary_right_operation(const T& x, const std::string& op)
      91             :   {
      92          11 :     print_unary_operand(x, x.operand());
      93          11 :     derived().print(op);
      94          11 :   }
      95             : 
      96             :   template <typename T>
      97         110 :   void print_binary_operation(const T& x, const std::string& op)
      98             :   {
      99         110 :     const auto& x1 = x.left();
     100         110 :     const auto& x2 = x.right();
     101         110 :     auto p = precedence(x);
     102         110 :     auto p1 = precedence(x1);
     103         110 :     auto p2 = precedence(x2);
     104         110 :     print_expression(x1, (p1 < p) || (p1 == p && !is_left_associative(x)));
     105         110 :     derived().print(op);
     106         110 :     print_expression(x2, (p2 < p) || (p2 == p && !is_right_associative(x)));
     107         110 :   }
     108             : 
     109             :   template <typename Container>
     110       13722 :   void print_list(const Container& container,
     111             :                   const std::string& opener = "(",
     112             :                   const std::string& closer = ")",
     113             :                   const std::string& separator = ", ",
     114             :                   bool print_empty_container = false
     115             :                  )
     116             :   {
     117       13722 :     if (container.empty() && !print_empty_container)
     118             :     {
     119        1101 :       return;
     120             :     }
     121       12621 :     derived().print(opener);
     122       44377 :     for (auto i = container.begin(); i != container.end(); ++i)
     123             :     {
     124       31756 :       if (i != container.begin())
     125             :       {
     126       19135 :         derived().print(separator);
     127             :       }
     128       31756 :       derived().apply(*i);
     129             :     }
     130       12621 :     derived().print(closer);
     131             :   }
     132             : 
     133             :   template <typename T>
     134             :   void apply(const atermpp::term_appl<T>& x)
     135             :   {
     136             :     derived().enter(x);
     137             :     derived().print(utilities::to_string(x));
     138             :     derived().leave(x);
     139             :   }
     140             : 
     141             :   template <typename T>
     142             :   void apply(const std::list<T>& x)
     143             :   {
     144             :     derived().enter(x);
     145             :     print_list(x, "", "", ", ");
     146             :     derived().leave(x);
     147             :   }
     148             : 
     149             :   template <typename T>
     150         172 :   void apply(const atermpp::term_list<T>& x)
     151             :   {
     152         172 :     derived().enter(x);
     153         172 :     print_list(x, "", "", ", ");
     154         172 :     derived().leave(x);
     155         172 :   }
     156             : 
     157             :   template <typename T>
     158           0 :   void apply(const std::set<T>& x)
     159             :   {
     160           0 :     derived().enter(x);
     161           0 :     print_list(x, "", "", ", ");
     162           0 :     derived().leave(x);
     163           0 :   }
     164             : 
     165       76159 :   void apply(const core::identifier_string& x)
     166             :   {
     167       76159 :     derived().enter(x);
     168       76159 :     if (x == core::identifier_string())
     169             :     {
     170           0 :       derived().print("@NoValue");
     171             :     }
     172             :     else
     173             :     {
     174       76159 :       derived().print(std::string(x));
     175             :     }
     176       76159 :     derived().leave(x);
     177       76159 :   }
     178             : 
     179             :   void apply(const atermpp::aterm& x)
     180             :   {
     181             :     derived().enter(x);
     182             :     derived().print(utilities::to_string(x));
     183             :     derived().leave(x);
     184             :   }
     185             : 
     186             :   void apply(const atermpp::aterm_list& x)
     187             :   {
     188             :     derived().enter(x);
     189             :     derived().print(utilities::to_string(x));
     190             :     derived().leave(x);
     191             :   }
     192             : 
     193             :   void apply(const atermpp::aterm_appl& x)
     194             :   {
     195             :     derived().enter(x);
     196             :     derived().print(utilities::to_string(x));
     197             :     derived().leave(x);
     198             :   }
     199             : 
     200        2209 :   void apply(const atermpp::aterm_int& x)
     201             :   {
     202        2209 :     derived().enter(x);
     203        2209 :     derived().print(utilities::to_string(x));
     204        2209 :     derived().leave(x);
     205        2209 :   }
     206             : };
     207             : 
     208             : template <template <class> class Traverser>
     209             : struct apply_printer: public Traverser<apply_printer<Traverser>>
     210             : {
     211             :   typedef Traverser<apply_printer<Traverser>> super;
     212             : 
     213             :   using super::enter;
     214             :   using super::leave;
     215             :   using super::apply;
     216             : 
     217       40439 :   explicit apply_printer(std::ostream& out)
     218        1401 :   {
     219             :     typedef printer<apply_printer<Traverser> > Super;
     220       40439 :     static_cast<Super&>(*this).m_out = &out;
     221       40439 :   }
     222             : 
     223             : };
     224             : 
     225             : } // namespace detail
     226             : /// \endcond
     227             : 
     228             : /// \brief Prints the object x to a stream.
     229             : struct stream_printer
     230             : {
     231             :   template <typename T>
     232         468 :   void operator()(const T& x, std::ostream& out)
     233             :   {
     234         468 :     core::detail::apply_printer<core::detail::printer> printer(out);
     235         468 :     printer.apply(x);
     236         468 :   }
     237             : };
     238             : 
     239             : /// \brief Returns a string representation of the object x.
     240             : template <typename T>
     241         467 : std::string pp(const T& x)
     242             : {
     243         467 :   std::ostringstream out;
     244         467 :   stream_printer()(x, out);
     245         934 :   return out.str();
     246         467 : }
     247             : 
     248             : } // namespace core
     249             : 
     250             : } // namespace mcrl2
     251             : 
     252             : #endif // MCRL2_CORE_PRINT_H

Generated by: LCOV version 1.14