LCOV - code coverage report
Current view: top level - atermpp/include/mcrl2/atermpp - aterm_io.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 52 52 100.0 %
Date: 2020-09-16 00:45:56 Functions: 44 46 95.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): 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_IO_H
      11             : #define MCRL2_ATERMPP_ATERM_IO_H
      12             : 
      13             : #include "mcrl2/atermpp/aterm_list.h"
      14             : #include "mcrl2/atermpp/aterm_int.h"
      15             : #include "mcrl2/utilities/type_traits.h"
      16             : 
      17             : namespace atermpp
      18             : {
      19             : 
      20             : /// \brief A function that is applied to all terms. The resulting term should only use
      21             : ///        a subset of the original arguments (i.e. not introduce new terms).
      22             : /// \details Typical usage is removing the index traits from function symbols that represent operators.
      23             : using aterm_transformer = aterm_appl(const aterm_appl&);
      24             : 
      25             : /// \brief The default transformer that maps each term to itself.
      26      423286 : inline aterm_appl identity(const aterm_appl& x) { return x; }
      27             : 
      28             : /// \brief The general aterm stream interface, which enables the use of a transformer to
      29             : ///        change the written/read terms.
      30       22885 : class aterm_stream
      31             : {
      32             : public:
      33             :   virtual ~aterm_stream();
      34             : 
      35             :   /// \brief Sets the given transformer to be applied to following writes.
      36         898 :   void set_transformer(aterm_transformer transformer) { m_transformer = transformer; }
      37             : 
      38             :   /// \returns The currently assigned transformer function.
      39         390 :   aterm_transformer* get_transformer() const { return m_transformer; }
      40             : 
      41             : protected:
      42             :   aterm_transformer* m_transformer = identity;
      43             : };
      44             : 
      45             : /// \brief The interface for a class that writes aterm to a stream.
      46             : ///        Every written term is retrieved by the corresponding aterm_istream::get() call.
      47       12645 : class aterm_ostream : public aterm_stream
      48             : {
      49             : public:
      50             :   virtual ~aterm_ostream();
      51             : 
      52             :   /// \brief Write the given term to the stream.
      53             :   virtual void put(const aterm& term) = 0;
      54             : };
      55             : 
      56             : /// \brief The interface for a class that reads aterm from a stream.
      57             : ///        The default constructed term aterm() indicates the end of the stream.
      58       10240 : class aterm_istream : public aterm_stream
      59             : {
      60             : public:
      61             :   virtual ~aterm_istream();
      62             : 
      63             :   /// \brief Reads an aterm from this stream.
      64             :   virtual aterm get() = 0;
      65             : };
      66             : 
      67             : // These free functions provide input/output operators for these streams.
      68             : 
      69             : /// \brief Sets the given transformer to be applied to following reads.
      70         254 : inline aterm_istream& operator>>(aterm_istream& stream, aterm_transformer transformer) { stream.set_transformer(transformer); return stream; }
      71         254 : inline aterm_ostream& operator<<(aterm_ostream& stream, aterm_transformer transformer) { stream.set_transformer(transformer); return stream; }
      72             : 
      73             : /// \brief Write the given term to the stream.
      74       22115 : inline aterm_ostream& operator<<(aterm_ostream& stream, const aterm& term) { stream.put(term); return stream; }
      75             : 
      76             : /// \brief Read the given term from the stream, but for aterm_list we want to use a specific one that performs validation (defined below).
      77        7089 : inline aterm_istream& operator>>(aterm_istream& stream, aterm& term) { term = stream.get(); return stream; }
      78             : 
      79             : // Utility functions
      80             : 
      81             : /// \brief A helper class to restore the state of the aterm_{i,o}stream objects upon destruction. Currently, onlt
      82             : ///        preserves the transformer object.
      83             : class aterm_stream_state
      84             : {
      85             : public:
      86         390 :   aterm_stream_state(aterm_stream& stream)
      87         390 :     : m_stream(stream)
      88             :   {
      89         390 :     m_transformer = stream.get_transformer();
      90         390 :   }
      91             : 
      92         390 :   ~aterm_stream_state()
      93         390 :   {
      94         390 :     m_stream.set_transformer(m_transformer);
      95         390 :   }
      96             : 
      97             : private:
      98             :   aterm_stream& m_stream;
      99             :   aterm_transformer* m_transformer;
     100             : };
     101             : 
     102             : /// \brief Write any container (that is not an aterm itself) to the stream.
     103             : template<typename T,
     104             :   typename std::enable_if_t<mcrl2::utilities::is_iterable_v<T>, int> = 0,
     105             :   typename std::enable_if_t<!std::is_base_of<aterm, T>::value, int> = 0>
     106         628 : inline aterm_ostream& operator<<(aterm_ostream& stream, const T& container)
     107             : {
     108             :   // Write the number of elements, followed by each element in the container.
     109         628 :   stream << aterm_int(std::distance(container.begin(), container.end()));
     110             : 
     111         812 :   for (const auto& element : container)
     112             :   {
     113         184 :     stream << element;
     114             :   }
     115             : 
     116         628 :   return stream;
     117             : }
     118             : 
     119             : /// \brief Read any container (that is not an aterm itself) from the stream.
     120             : template<typename T,
     121             :   typename std::enable_if_t<mcrl2::utilities::is_iterable_v<T>, int> = 0,
     122             :   typename std::enable_if_t<!std::is_base_of<aterm, T>::value, int> = 0>
     123         649 : inline aterm_istream& operator>>(aterm_istream& stream, T& container)
     124             : {
     125             :   // Insert the next nof_elements into the container.
     126        1298 :   aterm_int nof_elements;
     127         649 :   stream >> nof_elements;
     128             : 
     129         649 :   auto it = std::inserter(container, container.end());
     130         869 :   for (std::size_t i = 0; i < nof_elements.value(); ++i)
     131             :   {
     132         440 :     typename T::value_type element;
     133         220 :     stream >> element;
     134         220 :     it = element;
     135             :   }
     136             : 
     137        1298 :   return stream;
     138             : }
     139             : 
     140             : template<typename T>
     141       12526 : inline aterm_ostream& operator<<(aterm_ostream&& stream, const T& t) { stream << t; return stream; }
     142             : 
     143             : template<typename T>
     144          11 : inline aterm_istream& operator>>(aterm_istream&& stream, T& t) { stream >> t; return stream; }
     145             : 
     146             : /// \brief Send the term in textual form to the ostream.
     147             : std::ostream& operator<<(std::ostream& out, const aterm& t);
     148             : 
     149             : /// \param t The input aterm.
     150             : /// \return A string representation of the given term derived from an aterm.
     151       10029 : inline std::string pp(const aterm& t)
     152             : {
     153       20058 :   std::ostringstream oss;
     154       10029 :   oss << t;
     155       20058 :   return oss.str();
     156             : }
     157             : 
     158             : /// \brief Sends the name of a function symbol to an ostream.
     159             : /// \param out The out stream.
     160             : /// \param f The function symbol to be output.
     161             : /// \return The stream.
     162             : inline
     163           2 : std::ostream& operator<<(std::ostream& out, const function_symbol& f)
     164             : {
     165           2 :   return out << f.name();
     166             : }
     167             : 
     168             : /// \brief Prints the name of a function symbol as a string.
     169             : /// \param f The function symbol.
     170             : /// \return The string representation of r.
     171             : inline const std::string& pp(const function_symbol& f)
     172             : {
     173             :   return f.name();
     174             : }
     175             : 
     176             : /// \brief Writes term t to a stream in binary aterm format.
     177             : void write_term_to_binary_stream(const aterm& t, std::ostream& os);
     178             : 
     179             : /// \brief Reads a term from a stream in binary aterm format.
     180             : aterm read_term_from_binary_stream(std::istream& is);
     181             : 
     182             : /// \brief Writes term t to a stream in textual format.
     183             : void write_term_to_text_stream(const aterm& t, std::ostream& os);
     184             : 
     185             : /// \brief Reads a term from a stream which contains the term in textual format.
     186             : aterm read_term_from_text_stream(std::istream& is);
     187             : 
     188             : /// \brief Reads an aterm from a string. The string can be in either binary or text format.
     189             : aterm read_term_from_string(const std::string& s);
     190             : 
     191             : /// \brief Reads an aterm_list from a string. The string can be in either binary or text format.
     192             : /// \details If the input is not a string, an aterm is returned of the wrong type.
     193             : /// \return The term corresponding to the string.
     194          15 : inline aterm_list read_list_from_string(const std::string& s)
     195             : {
     196          15 :   const aterm_list l = down_cast<aterm_list>(read_term_from_string(s));
     197          15 :   assert(l.type_is_list());
     198          15 :   return l;
     199             : }
     200             : 
     201             : /// \brief Reads an aterm_int from a string. The string can be in either binary or text format.
     202             : /// \details If the input is not an int, an aterm is returned of the wrong type.
     203             : /// \return The aterm_int corresponding to the string.
     204           2 : inline aterm_int read_int_from_string(const std::string& s)
     205             : {
     206           2 :   const aterm_int n = down_cast<aterm_int>(read_term_from_string(s));
     207           2 :   assert(n.type_is_int());
     208           2 :   return n;
     209             : }
     210             : 
     211             : /// \brief Reads an aterm_appl from a string. The string can be in either binary or text format.
     212             : /// \details If the input is not an aterm_appl, an aterm is returned of the wrong type.
     213             : /// \return The term corresponding to the string.
     214          29 : inline aterm_appl read_appl_from_string(const std::string& s)
     215             : {
     216          29 :   const aterm_appl a = down_cast<aterm_appl>(read_term_from_string(s));
     217          29 :   assert(a.type_is_appl());
     218          29 :   return a;
     219             : }
     220             : 
     221             : 
     222             : } // namespace atermpp
     223             : 
     224             : #endif // MCRL2_ATERMPP_ATERM_IO_H

Generated by: LCOV version 1.13