Program Listing for File csv_sink.hpp
↰ Return to documentation for file (rcppsw/metrics/csv_sink.hpp
)
#pragma once
/*******************************************************************************
* Includes
******************************************************************************/
#include <boost/optional.hpp>
#include <list>
#include <string>
#include <filesystem>
#include <memory>
#include "rcppsw/metrics/file_sink.hpp"
#include "rcppsw/metrics/output_mode.hpp"
/*******************************************************************************
* Namespaces/Decls
******************************************************************************/
namespace rcppsw::metrics {
namespace fs = std::filesystem;
/*******************************************************************************
* Class Definitions
******************************************************************************/
class csv_sink : public rmetrics::file_sink,
public rer::client<csv_sink> {
public:
csv_sink(fs::path fpath,
const rmetrics::output_mode& mode,
const rtypes::timestep& interval);
virtual ~csv_sink(void) = default;
/* base metrics sink overrides */
void finalize(void) override;
void initialize(const rmetrics::base_data* data) override;
write_status flush(const rmetrics::base_data* data,
const rtypes::timestep& t) override;
protected:
virtual std::list<std::string> csv_header_cols(
const rmetrics::base_data* data) const = 0;
virtual boost::optional<std::string> csv_line_build(
const rmetrics::base_data* data,
const rtypes::timestep& t) = 0;
std::list<std::string> dflt_csv_header_cols(void) const { return { "clock" }; }
const std::string& separator(void) const { return mc_separator; }
template <class T, class U>
std::string
csv_entry_domavg(const T& sum, const U& count, bool last = false) const {
std::string tmp;
if (count > 0) {
/*
* If the thing we have summed is int, size_t, etc., casting the count to
* double makes sure we get good averages. This form also supports
* non-primitive types that are summable and define an appropriate
* operator/() and can be converted to a string.
*/
tmp = rcppsw::to_string(sum / static_cast<double>(count));
} else {
tmp = "0";
}
return tmp + ((last) ? "" : separator());
}
template <class T>
std::string csv_entry_intavg(const T& sum, bool last = false) const {
/*
* If the thing we have summed is int, size_t, etc., casting the count to
* double makes sure we get good averages. This form also supports
* non-primitive types that are summable and define an appropriate
* operator/() and can be converted to a string.
*/
return rcppsw::to_string(sum / static_cast<double>(output_interval().v())) +
((last) ? "" : separator());
}
template <class T>
std::string csv_entry_tsavg(const T& sum,
const rtypes::timestep& t,
bool last = false) const {
return rcppsw::to_string(sum / static_cast<double>(t.v())) +
((last) ? "" : separator());
}
void csv_header_write(const rmetrics::base_data* data);
/* clang-format off */
const std::string mc_separator{";"};
/* clang-format on */
};
} /* namespace rcppsw::metrics */