10 #include <type_traits> 
   18         static int DECIMAL_PLACES = 5;
 
   23         template<
typename T = 
int>
 
   34         inline long int csv_abs(
long int x) {
 
   39         inline long long int csv_abs(
long long int x) {
 
   49         inline double csv_abs(
double x) {
 
   54         inline long double csv_abs(
long double x) {
 
   63             csv::enable_if_t<std::is_arithmetic<T>::value, 
int> = 0
 
   81             csv::enable_if_t<std::is_unsigned<T>::value, 
int> = 0>
 
   83             std::string digits_reverse = 
"";
 
   85             if (value == 0) 
return "0";
 
   88                 digits_reverse += (char)(
'0' + (value % 10));
 
   92             return std::string(digits_reverse.rbegin(), digits_reverse.rend());
 
   98             csv::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, 
int> = 0
 
  104             return "-" + 
to_string((
size_t)(value * -1));
 
  110             csv::enable_if_t<std::is_floating_point<T>::value, 
int> = 0
 
  117                 std::string result = 
"";
 
  120                 T fractional_part = std::abs(std::modf(value, &integral_part));
 
  121                 integral_part = std::abs(integral_part);
 
  124                 if (value < 0) result = 
"-";
 
  126                 if (integral_part == 0) {
 
  130                     for (
int n_digits = 
num_digits(integral_part); n_digits > 0; n_digits --) {
 
  131                         int digit = (int)(std::fmod(integral_part, 
pow10(n_digits)) / 
pow10(n_digits - 1));
 
  132                         result += (char)(
'0' + digit);
 
  139                 if (fractional_part > 0) {
 
  140                     fractional_part *= (T)(
pow10(DECIMAL_PLACES));
 
  141                     for (
int n_digits = DECIMAL_PLACES; n_digits > 0; n_digits--) {
 
  142                         int digit = (int)(std::fmod(fractional_part, 
pow10(n_digits)) / 
pow10(n_digits - 1));
 
  143                         result += (char)(
'0' + digit);
 
  160     inline static void set_decimal_places(
int precision) {
 
  161         internals::DECIMAL_PLACES = precision;
 
  192     template<
class OutputStream, 
char Delim, 
char Quote, 
bool Flush>
 
  202             : out(_out), quote_minimal(_quote_minimal) {};
 
  225         template<
typename T, 
size_t Size>
 
  227             for (
size_t i = 0; i < Size; i++) {
 
  228                 out << csv_escape(record[i]);
 
  229                 if (i + 1 != Size) out << Delim;
 
  237         template<
typename... T>
 
  239             this->write_tuple<0, T...>(record);
 
  249             typename T, 
typename Alloc, 
template <
typename, 
typename> 
class Container,
 
  252             csv::enable_if_t<std::is_class<Alloc>::value, 
int> = 0
 
  255             const size_t ilen = record.size();
 
  257             for (
const auto& field : record) {
 
  258                 out << csv_escape(field);
 
  259                 if (i + 1 != ilen) out << Delim;
 
  278                 !std::is_convertible<T, std::string>::value
 
  279                 && !std::is_convertible<T, csv::string_view>::value
 
  282         std::string csv_escape(T in) {
 
  289                 std::is_convertible<T, std::string>::value
 
  290                 || std::is_convertible<T, csv::string_view>::value
 
  293         std::string csv_escape(T in) {
 
  294             IF_CONSTEXPR(std::is_convertible<T, csv::string_view>::value) {
 
  295                 return _csv_escape(in);
 
  298             return _csv_escape(std::string(in));
 
  309             bool quote_escape = 
false;
 
  312                 if (ch == Quote || ch == Delim || ch == 
'\r' || ch == 
'\n') {
 
  319                 if (quote_minimal) 
return std::string(in);
 
  321                     std::string ret(1, Quote);
 
  329             std::string ret(1, Quote);
 
  331                 if (ch == Quote) ret += std::string(2, Quote);
 
  341         template<
size_t Index = 0, 
typename... T>
 
  342         typename std::enable_if<Index < 
sizeof...(T), 
void>::type write_tuple(
const std::tuple<T...>& record) {
 
  343             out << csv_escape(std::get<Index>(record));
 
  347             this->write_tuple<Index + 1>(record);
 
  351         template<
size_t Index = 0, 
typename... T>
 
  352         typename std::enable_if<Index == 
sizeof...(T), 
void>::type write_tuple(
const std::tuple<T...>& record) {
 
  374     template<
class OutputStream, 
bool Flush = true>
 
  385     template<
class OutputStream, 
bool Flush = true>
 
  389     template<
class OutputStream>
 
  395     template<
class OutputStream>
 
  401     template<
class OutputStream>
 
  407     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.
 
T csv_abs(T x)
Calculate the absolute value of a number.
 
int num_digits(T x)
Calculate the number of digits in a number.
 
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.