diff --git a/include/rosa/support/csv/CSVWriter.hpp b/include/rosa/support/csv/CSVWriter.hpp index 5eb21ee..9d68543 100755 --- a/include/rosa/support/csv/CSVWriter.hpp +++ b/include/rosa/support/csv/CSVWriter.hpp @@ -1,180 +1,210 @@ //===-- rosa/support/csv/CSVWriter.hpp --------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/support/csv/CSVWriter.hpp /// /// \authors David Juhasz (david.juhasz@tuwien.ac.at) /// Edwin Willegger (edwin.willegger@tuwien.ac.at) /// /// \date 2017-2019 /// /// \brief Facitilities to write CSV files. /// //===----------------------------------------------------------------------===// #ifndef ROSA_SUPPORT_CSV_CSVWRITER_HPP #define ROSA_SUPPORT_CSV_CSVWRITER_HPP #include #include #include #include #include +#include "../log.h" + namespace rosa { namespace csv { /// Provides facilities to write values into a CSV file. /// /// The writer emits a comma, the character `,`, between each written values. /// The resulted stream is a flat CSV file as it consists of onlyone row, no new /// line is emitted. /// /// \tparam T type of values to write template class CSVWriter { public: /// Creates a new instance. /// /// \param [in,out] S output stream to write to /// /// \note The writer operates on non-binary outputs as long as \p S is in /// good state. CSVWriter(std::ostream &S) : Str(S.good() && !(S.flags() & std::ios::binary) ? &S : nullptr), IsFirst(true) {} /// Tells if the last operation was successful. /// /// \return if the last operation was successful bool good(void) const noexcept { return Str != nullptr; } /// Writes an entry to the output stream. /// /// The implementation does anything only if the last operation was /// successful. If so, \p V is written to \c rosa::csv::CSVWriter::Str. /// The emitted value is preceded with a comma if the actual call is not the /// first one for \p this object. Success of the operation is checked at the /// end. /// /// \param V value to write void write(const T &V) { if (Str) { if (!IsFirst) { *Str << ','; } else { IsFirst = false; } *Str << V; if (!Str->good()) { Str = nullptr; } } } private: std::ostream *Str; ///< Output stream to write to. bool IsFirst; ///< Denotes if the next write would be the first one. }; /// Writes a tuple of values into a CSV file /// -/// \tparam Ts tpyes of values to write +/// \tparam Ts types of values to write template class CSVTupleWriter { public: /// Creates a new instance. /// /// \param [in,out] S output stream to write to /// /// \note The writer operates on non-binary outputs as long as \p S is in /// good state. CSVTupleWriter(std::ostream &S) : Str(S.good() && !(S.flags() & std::ios::binary) ? &S : nullptr), IsFirst(true) {} /// Tells if the last operation was successful. /// /// \return if the last operation was successful bool good(void) const noexcept { return Str != nullptr; } + + /// Write the values of a tuple to a CSV file with \c rosa::csv::CSVWriter. + /// + /// \see rosa::csv::CSVWriter + /// + /// + /// \param [in,out] values tuple, which values are written in a recusive fashion into a stream. + /// template void write(std::tuple values) { size_t size = 0; - std::cout << "Writing tuple values into file" << std::endl; - std::cout << "Tuple has "; - std::cout << std::tuple_size::value; - std::cout << " elements." << std::endl; + std::string message = ""; + + LOG_TRACE("Writing tuple values into file \n"); + message = " Tuple has " + std::to_string(std::tuple_size::value) + " elements. \n"; + LOG_TRACE(message); size = std::tuple_size::value; - std::cout << std::get(values) << std::endl; + message = " Value is "; + LOG_TRACE(message); + LOG_TRACE(std::get(values)); if(Str){ + /// Write the current element of the tuple into the stream and add a separtor after it, + /// and call the function for the next element in the tuple. if constexpr(i+1 != sizeof...(Ts)){ *Str << std::get(values) << ", "; write(values); + /// If the last element is written into the stream than begin a new line. }else if constexpr(i + 1 == sizeof...(Ts)){ *Str << std::get(values) << '\n'; } } } + + /// Write the header values to a CSV file with \c rosa::csv::CSVWriter. + /// + /// \see rosa::csv::CSVWriter + /// + + /// + /// \param header the content of the header line. + /// void writeHeader(std::array header){ size_t index = 0; + /// write into the stream only, if it is not a nullptr. if(Str){ index = 0; for (auto i = header.begin(); i != header.end(); ++i){ index = index + 1; + /// write into the stream every entry with a delimeter, in this case ", " until + /// the last entry if(index != header.size()){ *Str << *i << ", "; + /// write the last entry into the stream, without any delimeter }else { *Str << *i; } } + /// finish the header line and start a new line. *Str << '\n'; } } private: std::ostream *Str; ///< Output stream to write to. bool IsFirst; ///< Denotes if the next write would be the first one. const size_t tupleSize = sizeof...(Ts); /// explicitly the number of elements of the tuple. }; template CSVTupleWriter &operator<<(CSVTupleWriter &W, const std::tuple V) { W.write(V); return W; } /// Writes a value to a CSV file with \c rosa::csv::CSVWriter. /// /// \see rosa::csv::CSVWriter /// /// \tparam T type of value to write /// /// \param [in,out] W object to write with /// \param V value to write /// /// \return \p W after writing \p V with it template CSVWriter &operator<<(CSVWriter &W, const T& V) { W.write(V); return W; } } // End namespace csv } // End namespace rosa #endif // ROSA_SUPPORT_CSV_CSVWRITER_HPP