Coverage Report

Created: 2025-08-25 06:29

/src/jsoncons/include/jsoncons_ext/csv/csv_options.hpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2013-2025 Daniel Parker
2
// Distributed under the Boost license, Version 1.0.
3
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
5
// See https://github.com/danielaparker/jsoncons for latest version
6
7
#ifndef JSONCONS_EXT_CSV_CSV_OPTIONS_HPP
8
#define JSONCONS_EXT_CSV_CSV_OPTIONS_HPP
9
10
#include <cstdint>
11
#include <cwchar>
12
#include <limits> // std::numeric_limits
13
#include <map>
14
#include <string>
15
#include <unordered_map> // std::unordered_map
16
#include <utility> // std::pair
17
18
#include <jsoncons/json_options.hpp>
19
20
namespace jsoncons { 
21
namespace csv {
22
23
enum class csv_column_type : uint8_t 
24
{
25
    string_t,integer_t,float_t,boolean_t,repeat_t
26
};
27
28
enum class quote_style_kind : uint8_t 
29
{
30
    minimal,all,nonnumeric,none
31
};
32
33
enum class csv_mapping_kind : uint8_t 
34
{
35
    n_rows = 1, 
36
    n_objects, 
37
    m_columns
38
};
39
40
enum class column_state {sequence,label};
41
42
struct csv_type_info
43
{
44
    csv_type_info() = default;
45
    csv_type_info(const csv_type_info&) = default;
46
    csv_type_info(csv_type_info&&) = default;
47
48
    csv_type_info(csv_column_type ctype, std::size_t lev, std::size_t repcount = 0) noexcept
49
0
    {
50
0
        col_type = ctype;
51
0
        level = lev;
52
0
        rep_count = repcount;
53
0
    }
54
55
    csv_column_type col_type;
56
    std::size_t level;
57
    std::size_t rep_count;
58
};
59
60
namespace detail {
61
62
template <typename CharT,typename Container>
63
void parse_column_names(const std::basic_string<CharT>& names, 
64
                        Container& cont)
65
12.5k
{
66
12.5k
    column_state state = column_state::sequence;
67
12.5k
    typename Container::value_type buffer(cont.get_allocator());
68
69
12.5k
    auto p = names.begin();
70
12.5k
    while (p != names.end())
71
0
    {
72
0
        switch (state)
73
0
        {
74
0
            case column_state::sequence:
75
0
            {
76
0
                switch (*p)
77
0
                {
78
0
                    case ' ': case '\t':case '\r': case '\n':
79
0
                        ++p;
80
0
                        break;
81
0
                    default:
82
0
                        buffer.clear();
83
0
                        state = column_state::label;
84
0
                        break;
85
0
                }
86
0
                break;
87
0
            }
88
0
            case column_state::label:
89
0
            {
90
0
                switch (*p)
91
0
                {
92
0
                case ',':
93
0
                    cont.push_back(buffer);
94
0
                    buffer.clear();
95
0
                    ++p;
96
0
                    state = column_state::sequence;
97
0
                    break;
98
0
                default:
99
0
                    buffer.push_back(*p);
100
0
                    ++p;
101
0
                    break;
102
0
                }
103
0
                break;
104
0
            }
105
0
        }
106
0
    }
107
12.5k
    if (state == column_state::label)
108
0
    {
109
0
        cont.push_back(buffer);
110
0
        buffer.clear();
111
0
    }
112
113
12.5k
} // namespace detail
114
115
template <typename CharT,typename Container>
116
void parse_column_types(const std::basic_string<CharT>& types, 
117
                        Container& column_types)
118
6.26k
{
119
6.26k
    const std::map<jsoncons::basic_string_view<CharT>,csv_column_type> type_dictionary =
120
6.26k
    {
121
122
6.26k
        {JSONCONS_STRING_VIEW_CONSTANT(CharT,"string"),csv_column_type::string_t},
123
6.26k
        {JSONCONS_STRING_VIEW_CONSTANT(CharT,"integer"),csv_column_type::integer_t},
124
6.26k
        {JSONCONS_STRING_VIEW_CONSTANT(CharT,"float"),csv_column_type::float_t},
125
6.26k
        {JSONCONS_STRING_VIEW_CONSTANT(CharT,"boolean"),csv_column_type::boolean_t}
126
6.26k
    };
127
128
6.26k
    column_state state = column_state::sequence;
129
6.26k
    int depth = 0;
130
6.26k
    std::basic_string<CharT> buffer;
131
132
6.26k
    auto p = types.begin();
133
6.26k
    while (p != types.end())
134
0
    {
135
0
        switch (state)
136
0
        {
137
0
            case column_state::sequence:
138
0
            {
139
0
                switch (*p)
140
0
                {
141
0
                case ' ': case '\t':case '\r': case '\n':
142
0
                    ++p;
143
0
                    break;
144
0
                case '[':
145
0
                    ++depth;
146
0
                    ++p;
147
0
                    break;
148
0
                case ']':
149
0
                    JSONCONS_ASSERT(depth > 0);
150
0
                    --depth;
151
0
                    ++p;
152
0
                    break;
153
0
                case '*':
154
0
                    {
155
0
                        JSONCONS_ASSERT(column_types.size() != 0);
156
0
                        std::size_t offset = 0;
157
0
                        std::size_t level = column_types.size() > 0 ? column_types.back().level: 0;
158
0
                        if (level > 0)
159
0
                        {
160
0
                            for (auto it = column_types.rbegin();
161
0
                                 it != column_types.rend() && level == (*it).level;
162
0
                                 ++it)
163
0
                            {
164
0
                                ++offset;
165
0
                            }
166
0
                        }
167
0
                        else
168
0
                        {
169
0
                            offset = 1;
170
0
                        }
171
0
                        column_types.emplace_back(csv_column_type::repeat_t,depth,offset);
172
0
                        ++p;
173
0
                        break;
174
0
                    }
175
0
                default:
176
0
                    buffer.clear();
177
0
                    state = column_state::label;
178
0
                    break;
179
0
                }
180
0
                break;
181
0
            }
182
0
            case column_state::label:
183
0
            {
184
0
                switch (*p)
185
0
                {
186
0
                    case '*':
187
0
                    {
188
0
                        auto it = type_dictionary.find(buffer);
189
0
                        if (it != type_dictionary.end())
190
0
                        {
191
0
                            column_types.emplace_back((*it).second,depth);
192
0
                            buffer.clear();
193
0
                        }
194
0
                        else
195
0
                        {
196
0
                            JSONCONS_ASSERT(false);
197
0
                        }
198
0
                        state = column_state::sequence;
199
0
                        break;
200
0
                    }
201
0
                    case ',':
202
0
                    {
203
0
                        auto it = type_dictionary.find(buffer);
204
0
                        if (it != type_dictionary.end())
205
0
                        {
206
0
                            column_types.emplace_back((*it).second,depth);
207
0
                            buffer.clear();
208
0
                        }
209
0
                        else
210
0
                        {
211
0
                            JSONCONS_ASSERT(false);
212
0
                        }
213
0
                        ++p;
214
0
                        state = column_state::sequence;
215
0
                        break;
216
0
                    }
217
0
                    case ']':
218
0
                    {
219
0
                        JSONCONS_ASSERT(depth > 0);
220
0
                        auto it = type_dictionary.find(buffer);
221
0
                        if (it != type_dictionary.end())
222
0
                        {
223
0
                            column_types.emplace_back((*it).second,depth);
224
0
                            buffer.clear();
225
0
                        }
226
0
                        else
227
0
                        {
228
0
                            JSONCONS_ASSERT(false);
229
0
                        }
230
0
                        --depth;
231
0
                        ++p;
232
0
                        state = column_state::sequence;
233
0
                        break;
234
0
                    }
235
0
                    default:
236
0
                    {
237
0
                        buffer.push_back(*p);
238
0
                        ++p;
239
0
                        break;
240
0
                    }
241
0
                }
242
0
                break;
243
0
            }
244
0
        }
245
0
    }
246
6.26k
    if (state == column_state::label)
247
0
    {
248
0
        auto it = type_dictionary.find(buffer);
249
0
        if (it != type_dictionary.end())
250
0
        {
251
0
            column_types.emplace_back((*it).second,depth);
252
0
            buffer.clear();
253
0
        }
254
0
        else
255
0
        {
256
0
            JSONCONS_ASSERT(false);
257
0
        }
258
0
    }
259
6.26k
}
260
261
} // namespace detail
262
263
template <typename CharT>
264
class basic_csv_options;
265
266
template <typename CharT>
267
class basic_csv_options_common 
268
{
269
    friend class basic_csv_options<CharT>;
270
public:
271
    using char_type = CharT;
272
    using string_type = std::basic_string<CharT>;
273
private:
274
    char_type field_delimiter_{','};
275
    char_type quote_char_{'\"'};
276
    char_type quote_escape_char_{'\"'};
277
    char_type subfield_delimiter_{char_type{}};
278
279
    bool flat_:1;
280
    bool enable_nan_to_num_:1;
281
    bool enable_inf_to_num_:1;
282
    bool enable_neginf_to_num_:1;
283
    bool enable_nan_to_str_:1;
284
    bool enable_inf_to_str_:1;
285
    bool enable_neginf_to_str_:1;
286
    bool enable_str_to_nan_:1;
287
    bool enable_str_to_inf_:1;
288
    bool enable_str_to_neginf_:1;
289
290
    string_type nan_to_num_;
291
    string_type inf_to_num_;
292
    string_type neginf_to_num_;
293
    string_type nan_to_str_;
294
    string_type inf_to_str_;
295
    string_type neginf_to_str_;
296
    string_type column_names_;
297
    std::vector<std::pair<std::string,std::string>> column_mapping_; 
298
    std::size_t max_nesting_depth_{1024};
299
300
protected:
301
    basic_csv_options_common()
302
9.92k
      : flat_{true},                  
303
9.92k
        enable_nan_to_num_{false},    
304
9.92k
        enable_inf_to_num_{false},    
305
9.92k
        enable_neginf_to_num_{false}, 
306
9.92k
        enable_nan_to_str_{false},    
307
9.92k
        enable_inf_to_str_{false},    
308
9.92k
        enable_neginf_to_str_{false}, 
309
9.92k
        enable_str_to_nan_{false},    
310
9.92k
        enable_str_to_inf_{false},    
311
9.92k
        enable_str_to_neginf_{false}
312
9.92k
    {
313
9.92k
    }
314
315
2.60k
    basic_csv_options_common(const basic_csv_options_common&) = default;
316
    basic_csv_options_common& operator=(const basic_csv_options_common&) = default;
317
    //basic_csv_options_common& operator=(basic_csv_options_common&&) = default;
318
319
12.5k
    virtual ~basic_csv_options_common() = default;
320
public:
321
322
    bool flat() const 
323
3.66k
    {
324
3.66k
        return flat_;
325
3.66k
    }
326
327
    std::size_t max_nesting_depth() const 
328
3.66k
    {
329
3.66k
        return max_nesting_depth_;
330
3.66k
    }
331
332
    char_type field_delimiter() const 
333
9.92k
    {
334
9.92k
        return field_delimiter_;
335
9.92k
    }
336
337
    const char_type subfield_delimiter() const 
338
9.92k
    {
339
9.92k
        return subfield_delimiter_;
340
9.92k
    }
341
342
    char_type quote_char() const 
343
9.92k
    {
344
9.92k
        return quote_char_;
345
9.92k
    }
346
347
    char_type quote_escape_char() const 
348
9.92k
    {
349
9.92k
        return quote_escape_char_;
350
9.92k
    }
351
352
    const string_type& column_names() const 
353
13.5k
    {
354
13.5k
        return column_names_;
355
13.5k
    }
356
357
    const std::vector<std::pair<std::string,std::string>>& column_mapping() const 
358
3.66k
    {
359
3.66k
        return column_mapping_;
360
3.66k
    }
361
362
    bool enable_nan_to_num() const
363
3.66k
    {
364
3.66k
        return enable_nan_to_num_;
365
3.66k
    }
366
367
    bool enable_inf_to_num() const
368
3.66k
    {
369
3.66k
        return enable_inf_to_num_;
370
3.66k
    }
371
372
    bool enable_neginf_to_num() const
373
3.66k
    {
374
3.66k
        return enable_neginf_to_num_ || enable_inf_to_num_;
375
3.66k
    }
376
377
    bool enable_nan_to_str() const
378
3.66k
    {
379
3.66k
        return enable_nan_to_str_;
380
3.66k
    }
381
382
    bool enable_str_to_nan() const
383
6.26k
    {
384
6.26k
        return enable_str_to_nan_;
385
6.26k
    }
386
387
    bool enable_inf_to_str() const
388
3.66k
    {
389
3.66k
        return enable_inf_to_str_;
390
3.66k
    }
391
392
    bool enable_str_to_inf() const
393
6.26k
    {
394
6.26k
        return enable_str_to_inf_;
395
6.26k
    }
396
397
    bool enable_neginf_to_str() const
398
3.66k
    {
399
3.66k
        return enable_neginf_to_str_ || enable_inf_to_str_;
400
3.66k
    }
401
402
    bool enable_str_to_neginf() const
403
6.26k
    {
404
6.26k
        return enable_str_to_neginf_ || enable_str_to_inf_;
405
6.26k
    }
406
407
    string_type nan_to_num() const
408
3.66k
    {
409
3.66k
        return nan_to_num_; 
410
3.66k
    }
411
412
    string_type inf_to_num() const
413
3.66k
    {
414
3.66k
        return inf_to_num_; 
415
3.66k
    }
416
417
    string_type neginf_to_num() const
418
3.66k
    {
419
3.66k
        if (enable_neginf_to_num_)
420
0
        {
421
0
            return neginf_to_num_;
422
0
        }
423
3.66k
        else if (enable_inf_to_num_)
424
0
        {
425
0
            string_type s;
426
0
            s.push_back('-');
427
0
            s.append(inf_to_num_);
428
0
            return s;
429
0
        }
430
3.66k
        else
431
3.66k
        {
432
3.66k
            return neginf_to_num_; 
433
3.66k
        }
434
3.66k
    }
435
436
    string_type nan_to_str() const
437
3.66k
    {
438
3.66k
        return nan_to_str_;
439
3.66k
    }
440
441
    string_type inf_to_str() const
442
3.66k
    {
443
3.66k
        return inf_to_str_; 
444
3.66k
    }
445
446
    string_type neginf_to_str() const
447
3.66k
    {
448
3.66k
        if (enable_neginf_to_str_)
449
0
        {
450
0
            return neginf_to_str_;
451
0
        }
452
3.66k
        else if (enable_inf_to_str_)
453
0
        {
454
0
            string_type s;
455
0
            s.push_back('-');
456
0
            s.append(inf_to_str_);
457
0
            return s;
458
0
        }
459
3.66k
        else
460
3.66k
        {
461
3.66k
            return neginf_to_str_; // empty string
462
3.66k
        }
463
3.66k
    }
464
};
465
466
template <typename CharT>
467
class basic_csv_decode_options : public virtual basic_csv_options_common<CharT>
468
{
469
    friend class basic_csv_options<CharT>;
470
    using super_type = basic_csv_options_common<CharT>;
471
public:
472
    using typename super_type::char_type;
473
    using typename super_type::string_type;
474
475
private:
476
    bool assume_header_:1;
477
    bool ignore_empty_values_:1;
478
    bool ignore_empty_lines_:1;
479
    bool trim_leading_:1;
480
    bool trim_trailing_:1;
481
    bool trim_leading_inside_quotes_:1;
482
    bool trim_trailing_inside_quotes_:1;
483
    bool unquoted_empty_value_is_null_:1;
484
    bool infer_types_:1;
485
    bool lossless_number_:1;
486
    char_type comment_starter_{'\0'};
487
    csv_mapping_kind mapping_kind_{};
488
    std::size_t header_lines_{0};
489
    std::size_t max_lines_{(std::numeric_limits<std::size_t>::max)()};
490
    string_type column_types_;
491
    string_type column_defaults_;
492
public:
493
    basic_csv_decode_options()
494
6.26k
        : assume_header_(false),
495
6.26k
          ignore_empty_values_(false),
496
6.26k
          ignore_empty_lines_(true),
497
6.26k
          trim_leading_(false),
498
6.26k
          trim_trailing_(false),
499
6.26k
          trim_leading_inside_quotes_(false),
500
6.26k
          trim_trailing_inside_quotes_(false),
501
6.26k
          unquoted_empty_value_is_null_(false),
502
6.26k
          infer_types_(true),
503
6.26k
          lossless_number_(false)
504
6.26k
    {}
jsoncons::csv::basic_csv_decode_options<char>::basic_csv_decode_options()
Line
Count
Source
494
3.66k
        : assume_header_(false),
495
3.66k
          ignore_empty_values_(false),
496
3.66k
          ignore_empty_lines_(true),
497
3.66k
          trim_leading_(false),
498
3.66k
          trim_trailing_(false),
499
3.66k
          trim_leading_inside_quotes_(false),
500
3.66k
          trim_trailing_inside_quotes_(false),
501
3.66k
          unquoted_empty_value_is_null_(false),
502
3.66k
          infer_types_(true),
503
3.66k
          lossless_number_(false)
504
3.66k
    {}
jsoncons::csv::basic_csv_decode_options<char>::basic_csv_decode_options()
Line
Count
Source
494
2.60k
        : assume_header_(false),
495
2.60k
          ignore_empty_values_(false),
496
2.60k
          ignore_empty_lines_(true),
497
2.60k
          trim_leading_(false),
498
2.60k
          trim_trailing_(false),
499
2.60k
          trim_leading_inside_quotes_(false),
500
2.60k
          trim_trailing_inside_quotes_(false),
501
2.60k
          unquoted_empty_value_is_null_(false),
502
2.60k
          infer_types_(true),
503
2.60k
          lossless_number_(false)
504
2.60k
    {}
505
506
2.60k
    basic_csv_decode_options(const basic_csv_decode_options& other) = default;
507
508
    basic_csv_decode_options(basic_csv_decode_options&& other) noexcept
509
        : super_type(std::move(other)),
510
          assume_header_(other.assume_header_),
511
          ignore_empty_values_(other.ignore_empty_values_),
512
          ignore_empty_lines_(other.ignore_empty_lines_),
513
          trim_leading_(other.trim_leading_),
514
          trim_trailing_(other.trim_trailing_),
515
          trim_leading_inside_quotes_(other.trim_leading_inside_quotes_),
516
          trim_trailing_inside_quotes_(other.trim_trailing_inside_quotes_),
517
          unquoted_empty_value_is_null_(other.unquoted_empty_value_is_null_),
518
          infer_types_(other.infer_types_),
519
          lossless_number_(other.lossless_number_),
520
          comment_starter_(other.comment_starter_),
521
          mapping_kind_(other.mapping_kind_),
522
          header_lines_(other.header_lines_),
523
          max_lines_(other.max_lines_),
524
          column_types_(std::move(other.column_types_)),
525
          column_defaults_(std::move(other.column_defaults_))
526
    {}
527
    
528
protected:
529
    basic_csv_decode_options& operator=(const basic_csv_decode_options& other) = default;
530
    basic_csv_decode_options& operator=(basic_csv_decode_options&& other) = default;
531
public:
532
533
    std::size_t header_lines() const 
534
6.26k
    {
535
6.26k
        return (assume_header_ && header_lines_ <= 1) ? 1 : header_lines_;
536
6.26k
    }
537
538
    bool assume_header() const 
539
9.92k
    {
540
9.92k
        return assume_header_;
541
9.92k
    }
542
543
    bool ignore_empty_values() const 
544
6.26k
    {
545
6.26k
        return ignore_empty_values_;
546
6.26k
    }
547
548
    bool ignore_empty_lines() const 
549
6.26k
    {
550
6.26k
        return ignore_empty_lines_;
551
6.26k
    }
552
553
    bool trim_leading() const 
554
6.26k
    {
555
6.26k
        return trim_leading_;
556
6.26k
    }
557
558
    bool trim_trailing() const 
559
6.26k
    {
560
6.26k
        return trim_trailing_;
561
6.26k
    }
562
563
    bool trim_leading_inside_quotes() const 
564
6.26k
    {
565
6.26k
        return trim_leading_inside_quotes_;
566
6.26k
    }
567
568
    bool trim_trailing_inside_quotes() const 
569
6.26k
    {
570
6.26k
        return trim_trailing_inside_quotes_;
571
6.26k
    }
572
573
    bool trim() const 
574
    {
575
        return trim_leading_ && trim_trailing_;
576
    }
577
578
    bool trim_inside_quotes() const 
579
    {
580
        return trim_leading_inside_quotes_ && trim_trailing_inside_quotes_;
581
    }
582
583
    bool unquoted_empty_value_is_null() const 
584
6.26k
    {
585
6.26k
        return unquoted_empty_value_is_null_;
586
6.26k
    }
587
588
    bool infer_types() const 
589
6.26k
    {
590
6.26k
        return infer_types_;
591
6.26k
    }
592
593
    bool lossless_number() const 
594
6.26k
    {
595
6.26k
        return lossless_number_;
596
6.26k
    }
597
598
    char_type comment_starter() const 
599
6.26k
    {
600
6.26k
        return comment_starter_;
601
6.26k
    }
602
603
    csv_mapping_kind mapping_kind() const 
604
6.26k
    {
605
6.26k
        return mapping_kind_ != csv_mapping_kind() ? mapping_kind_ : (assume_header() || this->column_names().size() > 0 ? csv_mapping_kind::n_objects : csv_mapping_kind::n_rows);
606
6.26k
    }
607
608
    std::size_t max_lines() const 
609
6.26k
    {
610
6.26k
        return max_lines_;
611
6.26k
    }
612
613
    string_type column_types() const 
614
6.26k
    {
615
6.26k
        return column_types_;
616
6.26k
    }
617
618
    string_type column_defaults() const 
619
6.26k
    {
620
6.26k
        return column_defaults_;
621
6.26k
    }
622
};
623
624
template <typename CharT>
625
class basic_csv_encode_options : public virtual basic_csv_options_common<CharT>
626
{
627
    friend class basic_csv_options<CharT>;
628
    using super_type = basic_csv_options_common<CharT>;
629
public:
630
    using typename super_type::char_type;
631
    using typename super_type::string_type;
632
private:
633
    quote_style_kind quote_style_{quote_style_kind::minimal};
634
    float_chars_format float_format_{float_chars_format::general};
635
    int8_t precision_{0};
636
    string_type line_delimiter_;
637
public:
638
    basic_csv_encode_options()
639
6.26k
    {
640
6.26k
        line_delimiter_.push_back('\n');
641
6.26k
    }
jsoncons::csv::basic_csv_encode_options<char>::basic_csv_encode_options()
Line
Count
Source
639
3.66k
    {
640
3.66k
        line_delimiter_.push_back('\n');
641
3.66k
    }
jsoncons::csv::basic_csv_encode_options<char>::basic_csv_encode_options()
Line
Count
Source
639
2.60k
    {
640
2.60k
        line_delimiter_.push_back('\n');
641
2.60k
    }
642
643
2.60k
    basic_csv_encode_options(const basic_csv_encode_options& other) = default;
644
645
    basic_csv_encode_options(basic_csv_encode_options&& other) noexcept
646
        : super_type(std::move(other)),
647
          quote_style_(other.quote_style_),
648
          float_format_(other.float_format_),
649
          precision_(other.precision_),
650
          line_delimiter_(std::move(other.line_delimiter_))
651
    {
652
    }
653
    
654
protected:
655
    basic_csv_encode_options& operator=(const basic_csv_encode_options& other) = default;
656
    basic_csv_encode_options& operator=(basic_csv_encode_options&& other) = default;
657
public:
658
659
    quote_style_kind quote_style() const 
660
3.66k
    {
661
3.66k
        return quote_style_;
662
3.66k
    }
663
664
    float_chars_format float_format() const 
665
3.66k
    {
666
3.66k
        return float_format_;
667
3.66k
    }
668
669
    int8_t precision() const 
670
3.66k
    {
671
3.66k
        return precision_;
672
3.66k
    }
673
674
    string_type line_delimiter() const
675
3.66k
    {
676
3.66k
        return line_delimiter_;
677
3.66k
    }
678
};
679
680
template <typename CharT>
681
class basic_csv_options final : public basic_csv_decode_options<CharT>, public basic_csv_encode_options<CharT>  
682
{
683
    using char_type = CharT;
684
    using string_type = std::basic_string<CharT>;
685
686
public:
687
    using basic_csv_decode_options<CharT>::enable_str_to_nan;
688
    using basic_csv_decode_options<CharT>::enable_str_to_inf;
689
    using basic_csv_decode_options<CharT>::enable_str_to_neginf;
690
    using basic_csv_decode_options<CharT>::nan_to_str;
691
    using basic_csv_decode_options<CharT>::inf_to_str;
692
    using basic_csv_decode_options<CharT>::neginf_to_str;
693
    using basic_csv_decode_options<CharT>::nan_to_num;
694
    using basic_csv_decode_options<CharT>::inf_to_num;
695
    using basic_csv_decode_options<CharT>::neginf_to_num;
696
    using basic_csv_decode_options<CharT>::flat;
697
    using basic_csv_decode_options<CharT>::max_nesting_depth;
698
    using basic_csv_decode_options<CharT>::field_delimiter;
699
    using basic_csv_decode_options<CharT>::subfield_delimiter;
700
    using basic_csv_decode_options<CharT>::quote_char;
701
    using basic_csv_decode_options<CharT>::quote_escape_char;
702
    using basic_csv_decode_options<CharT>::column_names;
703
    using basic_csv_decode_options<CharT>::column_mapping;
704
    using basic_csv_decode_options<CharT>::header_lines; 
705
    using basic_csv_decode_options<CharT>::assume_header; 
706
    using basic_csv_decode_options<CharT>::ignore_empty_values; 
707
    using basic_csv_decode_options<CharT>::ignore_empty_lines; 
708
    using basic_csv_decode_options<CharT>::trim_leading; 
709
    using basic_csv_decode_options<CharT>::trim_trailing; 
710
    using basic_csv_decode_options<CharT>::trim_leading_inside_quotes; 
711
    using basic_csv_decode_options<CharT>::trim_trailing_inside_quotes; 
712
    using basic_csv_decode_options<CharT>::trim; 
713
    using basic_csv_decode_options<CharT>::trim_inside_quotes; 
714
    using basic_csv_decode_options<CharT>::unquoted_empty_value_is_null; 
715
    using basic_csv_decode_options<CharT>::infer_types; 
716
    using basic_csv_decode_options<CharT>::lossless_number; 
717
    using basic_csv_decode_options<CharT>::comment_starter; 
718
    using basic_csv_decode_options<CharT>::mapping_kind; 
719
    using basic_csv_decode_options<CharT>::max_lines; 
720
    using basic_csv_decode_options<CharT>::column_types; 
721
    using basic_csv_decode_options<CharT>::column_defaults; 
722
    using basic_csv_encode_options<CharT>::float_format;
723
    using basic_csv_encode_options<CharT>::precision;
724
    using basic_csv_encode_options<CharT>::line_delimiter;
725
    using basic_csv_encode_options<CharT>::quote_style;
726
727
    static constexpr size_t default_indent = 4;
728
729
//  Constructors
730
731
2.60k
    basic_csv_options() = default;
732
2.60k
    basic_csv_options(const basic_csv_options&) = default;
733
    basic_csv_options(basic_csv_options&&) = default;
734
    basic_csv_options& operator=(const basic_csv_options&) = default;
735
    basic_csv_options& operator=(basic_csv_options&&) = default;
736
737
    basic_csv_options& float_format(float_chars_format value)
738
    {
739
        this->float_format_ = value;
740
        return *this;
741
    }
742
743
    basic_csv_options& precision(int8_t value)
744
    {
745
        this->precision_ = value;
746
        return *this;
747
    }
748
749
    basic_csv_options& header_lines(std::size_t value)
750
    {
751
        this->header_lines_ = value;
752
        return *this;
753
    }
754
755
    basic_csv_options& assume_header(bool value)
756
2.60k
    {
757
2.60k
        this->assume_header_ = value;
758
2.60k
        return *this;
759
2.60k
    }
760
761
    basic_csv_options& ignore_empty_values(bool value)
762
    {
763
        this->ignore_empty_values_ = value;
764
        return *this;
765
    }
766
767
    basic_csv_options& ignore_empty_lines(bool value)
768
    {
769
        this->ignore_empty_lines_ = value;
770
        return *this;
771
    }
772
773
    basic_csv_options& trim_leading(bool value)
774
    {
775
        this->trim_leading_ = value;
776
        return *this;
777
    }
778
779
    basic_csv_options& trim_trailing(bool value)
780
    {
781
        this->trim_trailing_ = value;
782
        return *this;
783
    }
784
785
    basic_csv_options& trim_leading_inside_quotes(bool value)
786
    {
787
        this->trim_leading_inside_quotes_ = value;
788
        return *this;
789
    }
790
791
    basic_csv_options& trim_trailing_inside_quotes(bool value)
792
    {
793
        this->trim_trailing_inside_quotes_ = value;
794
        return *this;
795
    }
796
797
    basic_csv_options& trim(bool value)
798
    {
799
        this->trim_leading_ = value;
800
        this->trim_trailing_ = value;
801
        return *this;
802
    }
803
804
    basic_csv_options& trim_inside_quotes(bool value)
805
    {
806
        this->trim_leading_inside_quotes_ = value;
807
        this->trim_trailing_inside_quotes_ = value;
808
        return *this;
809
    }
810
811
    basic_csv_options& unquoted_empty_value_is_null(bool value)
812
    {
813
        this->unquoted_empty_value_is_null_ = value;
814
        return *this;
815
    }
816
817
    basic_csv_options& column_names(const string_type& value)
818
    {
819
        this->column_names_ = value;
820
        return *this;
821
    }
822
823
    basic_csv_options& column_mapping(const std::vector<std::pair<std::string,std::string>>& value)
824
    {
825
        this->column_mapping_ = value;
826
        return *this;
827
    }
828
829
    basic_csv_options& column_types(const string_type& value)
830
    {
831
        this->column_types_ = value;
832
        return *this;
833
    }
834
835
    basic_csv_options& column_defaults(const string_type& value)
836
    {
837
        this->column_defaults_ = value;
838
        return *this;
839
    }
840
841
    basic_csv_options& flat(bool value)
842
    {
843
        this->flat_ = value;
844
        return *this;
845
    }
846
847
    basic_csv_options& max_nesting_depth(std::size_t value)
848
    {
849
        this->max_nesting_depth_ = value;
850
        return *this;
851
    }
852
853
    basic_csv_options& field_delimiter(char_type value)
854
    {
855
        this->field_delimiter_ = value;
856
        return *this;
857
    }
858
859
    basic_csv_options& subfield_delimiter(char_type value)
860
    {
861
        this->subfield_delimiter_ = value;
862
        return *this;
863
    }
864
865
    basic_csv_options& line_delimiter(const string_type& value)
866
    {
867
        this->line_delimiter_ = value;
868
        return *this;
869
    }
870
871
    basic_csv_options& quote_char(char_type value)
872
    {
873
        this->quote_char_ = value;
874
        return *this;
875
    }
876
877
    basic_csv_options& infer_types(bool value)
878
    {
879
        this->infer_types_ = value;
880
        return *this;
881
    }
882
883
    basic_csv_options& lossless_number(bool value) 
884
    {
885
        this->lossless_number_ = value;
886
        return *this;
887
    }
888
889
    basic_csv_options& quote_escape_char(char_type value)
890
    {
891
        this->quote_escape_char_ = value;
892
        return *this;
893
    }
894
895
    basic_csv_options& comment_starter(char_type value)
896
    {
897
        this->comment_starter_ = value;
898
        return *this;
899
    }
900
901
    basic_csv_options& quote_style(quote_style_kind value)
902
    {
903
        this->quote_style_ = value;
904
        return *this;
905
    }
906
907
    basic_csv_options& mapping_kind(csv_mapping_kind value)
908
2.60k
    {
909
2.60k
        this->mapping_kind_ = value;
910
2.60k
        return *this;
911
2.60k
    }
912
913
    basic_csv_options& max_lines(std::size_t value)
914
    {
915
        this->max_lines_ = value;
916
        return *this;
917
    }
918
919
    basic_csv_options& nan_to_num(const string_type& value)
920
    {
921
        this->enable_nan_to_num_ = true;
922
        this->nan_to_str_.clear();
923
        this->nan_to_num_ = value;
924
        return *this;
925
    }
926
927
    basic_csv_options& inf_to_num(const string_type& value)
928
    {
929
        this->enable_inf_to_num_ = true;
930
        this->inf_to_str_.clear();
931
        this->inf_to_num_ = value;
932
        return *this;
933
    }
934
935
    basic_csv_options& neginf_to_num(const string_type& value)
936
    {
937
        this->enable_neginf_to_num_ = true;
938
        this->neginf_to_str_.clear();
939
        this->neginf_to_num_ = value;
940
        return *this;
941
    }
942
943
    basic_csv_options& nan_to_str(const string_type& value, bool enable_inverse = true)
944
    {
945
        this->enable_nan_to_str_ = true;
946
        this->enable_str_to_nan_ = enable_inverse;
947
        this->nan_to_num_.clear();
948
        this->nan_to_str_ = value;
949
        return *this;
950
    }
951
952
    basic_csv_options& inf_to_str(const string_type& value, bool enable_inverse = true)
953
    {
954
        this->enable_inf_to_str_ = true;
955
        this->enable_inf_to_str_ = enable_inverse;
956
        this->inf_to_num_.clear();
957
        this->inf_to_str_ = value;
958
        return *this;
959
    }
960
961
    basic_csv_options& neginf_to_str(const string_type& value, bool enable_inverse = true)
962
    {
963
        this->enable_neginf_to_str_ = true;
964
        this->enable_neginf_to_str_ = enable_inverse;
965
        this->neginf_to_num_.clear();
966
        this->neginf_to_str_ = value;
967
        return *this;
968
    }
969
970
};
971
972
using csv_options = basic_csv_options<char>;
973
using wcsv_options = basic_csv_options<wchar_t>;
974
975
} // namespace jsonpath
976
} // namespace jsoncons
977
978
#endif // JSONCONS_EXT_CSV_CSV_OPTIONS_HPP