20 static int DECIMAL_PLACES = 5;
25 template<
typename T =
int>
36 inline long int csv_abs(
long int x) {
41 inline long long int csv_abs(
long long int x) {
56 inline long double csv_abs(
long double x) {
65 csv::enable_if_t<std::is_arithmetic<T>::value,
int> = 0
83 csv::enable_if_t<std::is_unsigned<T>::value,
int> = 0>
87 if (value == 0)
return "0";
100 csv::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value,
int> = 0
106 return "-" +
to_string((
size_t)(value * -1));
112 csv::enable_if_t<std::is_floating_point<T>::value,
int> = 0
116 return std::to_string(value);
126 if (value < 0)
result =
"-";
162 inline static void set_decimal_places(
int precision) {
163 internals::DECIMAL_PLACES = precision;
194 template<
class OutputStream,
char Delim,
char Quote,
bool Flush>
204 : out(&_out), quote_minimal(_quote_minimal) {}
210 template<
typename T = OutputStream,
211 csv::enable_if_t<std::is_same<T, std::ofstream>::value,
int> = 0>
212 DelimWriter(
const std::string& filename,
bool _quote_minimal =
true)
213 : owned_out(new std::ofstream(filename, std::ios::out)),
214 out(owned_out.get()),
215 quote_minimal(_quote_minimal) {
216 if (!owned_out->is_open())
217 throw std::runtime_error(
"Failed to open file for writing: " + filename);
235 template<
typename T,
size_t Size>
237 for (
size_t i = 0; i < Size; i++) {
238 (*out) << csv_escape(record[i]);
239 if (i + 1 != Size) (*out) << Delim;
247 template<
typename... T>
249 this->write_tuple<0, T...>(record);
259 typename T,
typename Alloc,
template <
typename,
typename>
class Container,
262 csv::enable_if_t<std::is_class<Alloc>::value,
int> = 0
265 const size_t ilen = record.size();
267 for (
const auto& field : record) {
268 (*out) << csv_escape(field);
269 if (i + 1 != ilen) (*out) << Delim;
288 !std::is_convertible<T, std::string>::value
289 && !std::is_convertible<T, csv::string_view>::value
292 std::string csv_escape(T in) {
299 std::is_convertible<T, std::string>::value
300 || std::is_convertible<T, csv::string_view>::value
303 std::string csv_escape(T in) {
304 IF_CONSTEXPR(std::is_convertible<T, csv::string_view>::value) {
305 return _csv_escape(in);
308 return _csv_escape(std::string(in));
320 bool quote_escape =
false;
323 if (ch == Quote || ch == Delim || ch ==
'\r' || ch ==
'\n') {
330 if (quote_minimal)
return std::string(in);
332 std::string ret(1, Quote);
340 std::string ret(1, Quote);
342 if (ch == Quote) ret += std::string(2, Quote);
352 template<
size_t Index = 0,
typename... T>
353 typename std::enable_if<Index <
sizeof...(T),
void>::type write_tuple(
const std::tuple<T...>& record) {
354 (*out) << csv_escape(std::get<Index>(record));
356 IF_CONSTEXPR (Index + 1 <
sizeof...(T)) (*out) << Delim;
358 this->write_tuple<Index + 1>(record);
362 template<
size_t Index = 0,
typename... T>
363 typename std::enable_if<Index ==
sizeof...(T),
void>::type write_tuple(
const std::tuple<T...>& record) {
379 std::unique_ptr<OutputStream> owned_out;
394 template<
class OutputStream,
bool Flush = true>
405 template<
class OutputStream,
bool Flush = true>
409 template<
class OutputStream>
415 template<
class OutputStream>
421 template<
class OutputStream>
427 template<
class OutputStream>
Class for writing delimiter separated values files.
DelimWriter & operator<<(const Container< T, Alloc > &record)
void flush()
Flushes the written data.
DelimWriter & operator<<(const std::array< T, Size > &record)
Format a sequence of strings and write to CSV according to RFC 4180.
DelimWriter(OutputStream &_out, bool _quote_minimal=true)
Construct a DelimWriter over the specified output stream.
~DelimWriter()
Destructor will flush remaining data.
DelimWriter(const std::string &filename, bool _quote_minimal=true)
Construct a DelimWriter over the file.
DelimWriter & operator<<(const std::tuple< T... > &record)
Format a sequence of strings and write to CSV according to RFC 4180.
A standalone header file containing shared code.
#define IF_CONSTEXPR
Expands to if constexpr in C++17 and if otherwise.
Implements data type parsing functionality.
T csv_abs(T x)
Calculate the absolute value of a number.
CSV_CONST CONSTEXPR_14 long double pow10(const T &n) noexcept
Compute 10 to the power of n.
int num_digits(T x)
Calculate the number of digits in a number.
CSV_CONST CONSTEXPR_17 OutArray arrayToDefault(T &&value)
Helper constexpr function to initialize an array with all the elements set to value.
std::string to_string(T value)
to_string() for unsigned integers
The all encompassing namespace.
TSVWriter< OutputStream, false > make_tsv_writer_buffered(OutputStream &out, bool quote_minimal=true)
Return a buffered csv::TSVWriter over the output stream (does not auto flush)
TSVWriter< OutputStream > make_tsv_writer(OutputStream &out, bool quote_minimal=true)
Return a csv::TSVWriter over the output stream.
CSVWriter< OutputStream, false > make_csv_writer_buffered(OutputStream &out, bool quote_minimal=true)
Return a buffered csv::CSVWriter over the output stream (does not auto flush)
CSVWriter< OutputStream > make_csv_writer(OutputStream &out, bool quote_minimal=true)
Return a csv::CSVWriter over the output stream.
nonstd::string_view string_view
The string_view class used by this library.