Vince's CSV Parser
Loading...
Searching...
No Matches
csv::DelimWriter< OutputStream, Delim, Quote > Class Template Reference

Class for writing delimiter separated values files. More...

#include <csv_writer.hpp>

Public Member Functions

 DelimWriter (OutputStream &_out, bool _quote_minimal=true)
 Construct a DelimWriter over the specified output stream.
 
template<typename T = OutputStream, csv::enable_if_t< std::is_same< T, std::ofstream >::value, int > = 0>
 DelimWriter (const std::string &filename, bool _quote_minimal=true)
 Construct a DelimWriter that owns an output file stream.
 
 DelimWriter (const DelimWriter &)=delete
 
DelimWriteroperator= (const DelimWriter &)=delete
 
 DelimWriter (DelimWriter &&other) noexcept
 
DelimWriteroperator= (DelimWriter &&other) noexcept
 
DelimWriterset_auto_flush (bool value) &noexcept
 Configure whether each write operation flushes the underlying stream.
 
DelimWriter && set_auto_flush (bool value) &&noexcept
 Configure whether each write operation flushes the underlying stream.
 
bool get_auto_flush () const noexcept
 Return whether each write operation flushes the underlying stream.
 
 ~DelimWriter ()
 Destructor will flush remaining data.
 
template<typename T , size_t N>
DelimWriteroperator<< (const T(&record)[N])
 Write a C-style array of strings as one delimited row.
 
template<typename T , size_t N>
DelimWriteroperator<< (const std::array< T, N > &record)
 Write a std::array of strings as one delimited row.
 
template<typename T >
auto write_row (T &&record) -> decltype(*this<< std::forward< T >(record))
 Write a row from any single argument accepted by operator<< (std::vector, std::array, std::tuple, C-array, C++20 range, etc.).
 
template<typename T , typename U , typename... Rest>
DelimWriterwrite_row (T &&first, U &&second, Rest &&... rest)
 Write a row from a variadic list of mixed-type values.
 
template<std::ranges::input_range Rows>
requires internals::csv_write_rows_input_range<Rows>
DelimWriterwrite_rows (Rows &&rows)
 Write many rows using a shared batch buffer.
 
template<std::ranges::input_range Range>
requires std::ranges::input_range<Range> && std::convertible_to<std::ranges::range_reference_t<Range>, csv::string_view>
DelimWriteroperator<< (Range &&container)
 Write a range of string-like fields as one delimited row.
 
template<typename RowLike >
requires internals::has_to_sv_range<RowLike> && (!internals::csv_string_field_range<RowLike>)
DelimWriteroperator<< (const RowLike &row)
 Write a row-like object that exposes to_sv_range().
 
template<typename... T>
DelimWriteroperator<< (const std::tuple< T... > &record)
 Write a C-style array of strings as one delimited row.
 
void flush ()
 Flushes the written data.
 

Detailed Description

template<class OutputStream, char Delim, char Quote>
class csv::DelimWriter< OutputStream, Delim, Quote >

Class for writing delimiter separated values files.

To write formatted strings, one should

  1. Initialize a DelimWriter with respect to some output stream
  2. Call write_row() on std::vector<std::string>s of unformatted text
Template Parameters
OutputStreamThe output stream, e.g. std::ofstream, std::stringstream
DelimThe delimiter character
QuoteThe quote character
Hint
Use the aliases csv::CSVWriter<OutputStream> to write CSV formatted strings and csv::TSVWriter<OutputStream> to write tab separated strings
Example w/ std::vector, std::deque, std::list
TEMPLATE_TEST_CASE("CSV/TSV Writer - operator <<", "[test_csv_operator<<]",
std::vector<std::string>, std::deque<std::string>, std::list<std::string>) {
std::stringstream output, correct_comma, correct_tab;
// Build correct strings
correct_comma << "A,B,C" << std::endl << "\"1,1\",2,3" << std::endl;
correct_tab << "A\tB\tC" << std::endl << "1,1\t2\t3" << std::endl;
// Test input
auto test_row_1 = TestType({ "A", "B", "C" }),
test_row_2 = TestType({ "1,1", "2", "3" });
SECTION("CSV Writer") {
auto csv_writer = make_csv_writer(output);
csv_writer << test_row_1 << test_row_2;
REQUIRE(output.str() == correct_comma.str());
}
SECTION("TSV Writer") {
auto tsv_writer = make_tsv_writer(output);
tsv_writer << test_row_1 << test_row_2;
REQUIRE(output.str() == correct_tab.str());
}
}
TSVWriter< OutputStream > make_tsv_writer(OutputStream &out, bool quote_minimal=true)
Return a csv::TSVWriter over the output stream.
CSVWriter< OutputStream > make_csv_writer(OutputStream &out, bool quote_minimal=true)
Return a csv::CSVWriter over the output stream.
Example w/ std::tuple
struct Time {
std::string hour;
std::string minute;
operator std::string() const {
std::string ret = hour;
ret += ":";
ret += minute;
return ret;
}
};
#ifndef __clang__
TEST_CASE("CSV Tuple", "[test_csv_tuple]") {
#ifdef CSV_HAS_CXX17
Time time = { "5", "30" };
#else
std::string time = "5:30";
#endif
std::stringstream output, correct_output;
auto csv_writer = make_csv_writer(output);
csv_writer << std::make_tuple("One", 2, "Three", 4.0, time)
<< std::make_tuple("One", (short)2, "Three", 4.0f, time)
<< std::make_tuple(-1, -2.0)
<< std::make_tuple(20.2, -20.3, -20.123)
<< std::make_tuple(0.0, 0.0f, 0);
correct_output << "One,2,Three,4.0,5:30" << std::endl
<< "One,2,Three,4.0,5:30" << std::endl
<< "-1,-2.0" << std::endl
<< "20.20000,-20.30000,-20.12300" << std::endl
<< "0.0,0.0,0" << std::endl;
REQUIRE(output.str() == correct_output.str());
}
#endif

Definition at line 255 of file csv_writer.hpp.

Constructor & Destructor Documentation

◆ DelimWriter() [1/3]

template<class OutputStream , char Delim, char Quote>
csv::DelimWriter< OutputStream, Delim, Quote >::DelimWriter ( OutputStream &  _out,
bool  _quote_minimal = true 
)
inline

Construct a DelimWriter over the specified output stream.

Definition at line 259 of file csv_writer.hpp.

◆ DelimWriter() [2/3]

template<class OutputStream , char Delim, char Quote>
template<typename T = OutputStream, csv::enable_if_t< std::is_same< T, std::ofstream >::value, int > = 0>
csv::DelimWriter< OutputStream, Delim, Quote >::DelimWriter ( const std::string &  filename,
bool  _quote_minimal = true 
)
inline

Construct a DelimWriter that owns an output file stream.

Definition at line 265 of file csv_writer.hpp.

◆ DelimWriter() [3/3]

template<class OutputStream , char Delim, char Quote>
csv::DelimWriter< OutputStream, Delim, Quote >::DelimWriter ( DelimWriter< OutputStream, Delim, Quote > &&  other)
inlinenoexcept

Definition at line 276 of file csv_writer.hpp.

◆ ~DelimWriter()

template<class OutputStream , char Delim, char Quote>
csv::DelimWriter< OutputStream, Delim, Quote >::~DelimWriter ( )
inline

Destructor will flush remaining data.

Definition at line 325 of file csv_writer.hpp.

Member Function Documentation

◆ flush()

template<class OutputStream , char Delim, char Quote>
void csv::DelimWriter< OutputStream, Delim, Quote >::flush ( )
inline

Flushes the written data.

Definition at line 456 of file csv_writer.hpp.

◆ get_auto_flush()

template<class OutputStream , char Delim, char Quote>
bool csv::DelimWriter< OutputStream, Delim, Quote >::get_auto_flush ( ) const
inlinenoexcept

Return whether each write operation flushes the underlying stream.

Definition at line 320 of file csv_writer.hpp.

◆ operator<<() [1/5]

template<class OutputStream , char Delim, char Quote>
template<typename RowLike >
requires internals::has_to_sv_range<RowLike> && (!internals::csv_string_field_range<RowLike>)
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::operator<< ( const RowLike &  row)
inline

Write a row-like object that exposes to_sv_range().

Definition at line 419 of file csv_writer.hpp.

◆ operator<<() [2/5]

template<class OutputStream , char Delim, char Quote>
template<typename T , size_t N>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::operator<< ( const std::array< T, N > &  record)
inline

Write a std::array of strings as one delimited row.

Definition at line 341 of file csv_writer.hpp.

◆ operator<<() [3/5]

template<class OutputStream , char Delim, char Quote>
template<typename... T>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::operator<< ( const std::tuple< T... > &  record)
inline

Write a C-style array of strings as one delimited row.

Definition at line 450 of file csv_writer.hpp.

◆ operator<<() [4/5]

template<class OutputStream , char Delim, char Quote>
template<typename T , size_t N>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::operator<< ( const T(&)  record[N])
inline

Write a C-style array of strings as one delimited row.

Definition at line 334 of file csv_writer.hpp.

◆ operator<<() [5/5]

template<class OutputStream , char Delim, char Quote>
template<std::ranges::input_range Range>
requires std::ranges::input_range<Range> && std::convertible_to<std::ranges::range_reference_t<Range>, csv::string_view>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::operator<< ( Range &&  container)
inline

Write a range of string-like fields as one delimited row.

Accepts any input_range whose elements are convertible to csv::string_view. This includes std::vector<std::string>, std::vector<csv::string_view>, std::array, C++20 views, etc.

Definition at line 410 of file csv_writer.hpp.

◆ operator=()

template<class OutputStream , char Delim, char Quote>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::operator= ( DelimWriter< OutputStream, Delim, Quote > &&  other)
inlinenoexcept

Definition at line 289 of file csv_writer.hpp.

◆ set_auto_flush() [1/2]

template<class OutputStream , char Delim, char Quote>
DelimWriter && csv::DelimWriter< OutputStream, Delim, Quote >::set_auto_flush ( bool  value) &&
inlinenoexcept

Configure whether each write operation flushes the underlying stream.

Definition at line 314 of file csv_writer.hpp.

◆ set_auto_flush() [2/2]

template<class OutputStream , char Delim, char Quote>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::set_auto_flush ( bool  value) &
inlinenoexcept

Configure whether each write operation flushes the underlying stream.

Definition at line 308 of file csv_writer.hpp.

◆ write_row() [1/2]

template<class OutputStream , char Delim, char Quote>
template<typename T , typename U , typename... Rest>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::write_row ( T &&  first,
U &&  second,
Rest &&...  rest 
)
inline

Write a row from a variadic list of mixed-type values.

Requires at least two arguments; for a single container or tuple, use the single-argument overload above.

writer.write_row("Alice", 30, 1.75, "Paris");

Definition at line 372 of file csv_writer.hpp.

◆ write_row() [2/2]

template<class OutputStream , char Delim, char Quote>
template<typename T >
auto csv::DelimWriter< OutputStream, Delim, Quote >::write_row ( T &&  record) -> decltype(*this << std::forward<T>(record))
inline

Write a row from any single argument accepted by operator<< (std::vector, std::array, std::tuple, C-array, C++20 range, etc.).

writer.write_row(my_vector);
writer.write_row(my_tuple);

SFINAE ensures this overload is only viable when the argument type is accepted by an existing operator<< overload.

Definition at line 358 of file csv_writer.hpp.

◆ write_rows()

template<class OutputStream , char Delim, char Quote>
template<std::ranges::input_range Rows>
requires internals::csv_write_rows_input_range<Rows>
DelimWriter & csv::DelimWriter< OutputStream, Delim, Quote >::write_rows ( Rows &&  rows)
inline

Write many rows using a shared batch buffer.

Accepts any input_range whose elements are either:

  • ranges of string-like fields, or
  • row-like objects exposing to_sv_range().

Buffered writers flush the batch when it grows large or when this call ends. Auto-flushing writers additionally flush the underlying stream once at the end of the bulk call.

Note
Requires C++20 or later.

Definition at line 393 of file csv_writer.hpp.


The documentation for this class was generated from the following file: