10 #include <type_traits>
18 static int DECIMAL_PLACES = 5;
22 csv::enable_if_t<std::is_unsigned<T>::value,
int> = 0>
24 std::string digits_reverse =
"";
26 if (value == 0)
return "0";
29 digits_reverse += (char)(
'0' + (value % 10));
33 return std::string(digits_reverse.rbegin(), digits_reverse.rend());
39 csv::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value,
int> = 0
45 return "-" +
to_string((
size_t)(value * -1));
51 csv::enable_if_t<std::is_floating_point<T>::value,
int> = 0
61 T fractional_part = std::abs(std::modf(value, &integral_part));
62 integral_part = std::abs(integral_part);
65 if (value < 0) result =
"-";
67 if (integral_part == 0) {
71 for (
int n_digits = (
int)(std::log(integral_part) / std::log(10));
72 n_digits + 1 > 0; n_digits --) {
73 int digit = (int)(std::fmod(integral_part,
pow10(n_digits + 1)) /
pow10(n_digits));
74 result += (char)(
'0' + digit);
81 if (fractional_part > 0) {
82 fractional_part *= (T)(
pow10(DECIMAL_PLACES));
83 for (
int n_digits = DECIMAL_PLACES; n_digits > 0; n_digits--) {
84 int digit = (int)(std::fmod(fractional_part,
pow10(n_digits)) /
pow10(n_digits - 1));
85 result += (char)(
'0' + digit);
102 inline static void set_decimal_places(
int precision) {
103 internals::DECIMAL_PLACES = precision;
134 template<
class OutputStream,
char Delim,
char Quote,
bool Flush>
144 : out(_out), quote_minimal(_quote_minimal) {};
167 template<
typename T,
size_t Size>
169 for (
size_t i = 0; i < Size; i++) {
170 out << csv_escape(record[i]);
171 if (i + 1 != Size) out << Delim;
179 template<
typename... T>
181 this->write_tuple<0, T...>(record);
191 typename T,
typename Alloc,
template <
typename,
typename>
class Container,
194 csv::enable_if_t<std::is_class<Alloc>::value,
int> = 0
197 const size_t ilen = record.size();
199 for (
const auto& field : record) {
200 out << csv_escape(field);
201 if (i + 1 != ilen) out << Delim;
220 !std::is_convertible<T, std::string>::value
221 && !std::is_convertible<T, csv::string_view>::value
224 std::string csv_escape(T in) {
231 std::is_convertible<T, std::string>::value
232 || std::is_convertible<T, csv::string_view>::value
235 std::string csv_escape(T in) {
236 IF_CONSTEXPR(std::is_convertible<T, csv::string_view>::value) {
237 return _csv_escape(in);
240 return _csv_escape(std::string(in));
251 bool quote_escape =
false;
254 if (ch == Quote || ch == Delim || ch ==
'\r' || ch ==
'\n') {
261 if (quote_minimal)
return std::string(in);
263 std::string ret(1, Quote);
271 std::string ret(1, Quote);
273 if (ch == Quote) ret += std::string(2, Quote);
283 template<
size_t Index = 0,
typename... T>
284 typename std::enable_if<Index <
sizeof...(T),
void>::type write_tuple(
const std::tuple<T...>& record) {
285 out << csv_escape(std::get<Index>(record));
289 this->write_tuple<Index + 1>(record);
293 template<
size_t Index = 0,
typename... T>
294 typename std::enable_if<Index ==
sizeof...(T),
void>::type write_tuple(
const std::tuple<T...>& record) {
316 template<
class OutputStream,
bool Flush = true>
327 template<
class OutputStream,
bool Flush = true>
331 template<
class OutputStream>
337 template<
class OutputStream>
343 template<
class OutputStream>
349 template<
class OutputStream>
Class for writing delimiter separated values files.
DelimWriter & operator<<(const std::tuple< T... > &record)
Format a sequence of strings and write to CSV according to RFC 4180.
void flush()
Flushes the written data.
DelimWriter(OutputStream &_out, bool _quote_minimal=true)
Construct a DelimWriter over the specified output stream.
DelimWriter(const std::string &filename)
Construct a DelimWriter over the file.
~DelimWriter()
Destructor will flush remaining data.
DelimWriter & operator<<(const Container< T, Alloc > &record)
Format a sequence of strings and write to CSV according to RFC 4180.
DelimWriter & operator<<(const std::array< T, Size > &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.
HEDLEY_CONST CONSTEXPR_14 long double pow10(const T &n) noexcept
Compute 10 to the power of n.
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)
CSVWriter< OutputStream > make_csv_writer(OutputStream &out, bool quote_minimal=true)
Return a csv::CSVWriter 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)
TSVWriter< OutputStream > make_tsv_writer(OutputStream &out, bool quote_minimal=true)
Return a csv::TSVWriter over the output stream.
nonstd::string_view string_view
The string_view class used by this library.