Skip to content

Commit bad7550

Browse files
committed
Figured out what was wrong with clang & CSVWriter
Also add variadic write_row() method
1 parent 95e304b commit bad7550

1 file changed

Lines changed: 59 additions & 33 deletions

File tree

include/internal/csv_writer.hpp

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
*/
44

55
#pragma once
6+
#include <cmath>
67
#include <fstream>
8+
#include <initializer_list>
79
#include <iostream>
810
#include <memory>
911
#ifdef CSV_HAS_CXX20
@@ -115,54 +117,47 @@ namespace csv {
115117
csv::enable_if_t<std::is_floating_point<T>::value, int> = 0
116118
>
117119
inline std::string to_string(T value) {
118-
#ifdef __clang__
119-
return std::to_string(value);
120-
#else
121-
// TODO: Figure out why the below code doesn't work on clang
122-
std::string result = "";
120+
std::string result = "";
123121

124-
T integral_part;
125-
T fractional_part = std::abs(std::modf(value, &integral_part));
126-
integral_part = std::abs(integral_part);
122+
T integral_part;
123+
T fractional_part = csv_abs(std::modf(value, &integral_part));
124+
integral_part = csv_abs(integral_part);
127125

128-
// Integral part
129-
if (value < 0) result = "-";
126+
// Integral part
127+
if (value < 0) result = "-";
130128

131-
if (integral_part == 0) {
132-
result += "0";
133-
}
134-
else {
135-
for (int n_digits = num_digits(integral_part); n_digits > 0; n_digits --) {
136-
int digit = (int)(std::fmod(integral_part, pow10(n_digits)) / pow10(n_digits - 1));
137-
result += (char)('0' + digit);
138-
}
129+
if (integral_part == 0) {
130+
result += "0";
131+
}
132+
else {
133+
for (int n_digits = num_digits(integral_part); n_digits > 0; n_digits --) {
134+
int digit = (int)(std::fmod(integral_part, pow10(n_digits)) / pow10(n_digits - 1));
135+
result += (char)('0' + digit);
139136
}
137+
}
140138

141-
// Decimal part
142-
result += ".";
139+
// Decimal part
140+
result += ".";
143141

144-
if (fractional_part > 0) {
145-
fractional_part *= (T)(pow10(DECIMAL_PLACES));
146-
for (int n_digits = DECIMAL_PLACES; n_digits > 0; n_digits--) {
147-
int digit = (int)(std::fmod(fractional_part, pow10(n_digits)) / pow10(n_digits - 1));
148-
result += (char)('0' + digit);
149-
}
150-
}
151-
else {
152-
result += "0";
142+
if (fractional_part > 0) {
143+
fractional_part *= (T)(pow10(DECIMAL_PLACES));
144+
for (int n_digits = DECIMAL_PLACES; n_digits > 0; n_digits--) {
145+
int digit = (int)(std::fmod(fractional_part, pow10(n_digits)) / pow10(n_digits - 1));
146+
result += (char)('0' + digit);
153147
}
148+
}
149+
else {
150+
result += "0";
151+
}
154152

155-
return result;
156-
#endif
153+
return result;
157154
}
158155
}
159156

160157
/** Sets how many places after the decimal will be written for floating point numbers. */
161-
#ifndef __clang__
162158
inline static void set_decimal_places(int precision) {
163159
internals::DECIMAL_PLACES = precision;
164160
}
165-
#endif
166161

167162
namespace internals {
168163
/** SFINAE trait: detects if a type is iterable (has std::begin/end). */
@@ -295,6 +290,37 @@ namespace csv {
295290
return *this;
296291
}
297292

293+
/** Write a row from a braced initializer list of string fields.
294+
*
295+
* This is the most concise syntax for all-string rows:
296+
* @code
297+
* writer << {"Name", "Age", "City"};
298+
* writer << {"Alice", "30", "Paris"};
299+
* @endcode
300+
*
301+
* For rows with mixed numeric and string fields, use write_row():
302+
* @code
303+
* writer.write_row("Alice", 30, 1.75);
304+
* @endcode
305+
*/
306+
DelimWriter& operator<<(std::initializer_list<csv::string_view> record) {
307+
write_range_impl(record);
308+
return *this;
309+
}
310+
311+
/** Write a row from a variadic argument list.
312+
*
313+
* Accepts any mix of string and numeric types:
314+
* @code
315+
* writer.write_row("Alice", 30, 1.75, "Paris");
316+
* @endcode
317+
*/
318+
template<typename... Args>
319+
DelimWriter& write_row(Args&&... args) {
320+
this->write_tuple<0>(std::forward_as_tuple(std::forward<Args>(args)...));
321+
return *this;
322+
}
323+
298324
#ifdef CSV_HAS_CXX20
299325
/** Write a range of string-like fields as one delimited row.
300326
*

0 commit comments

Comments
 (0)