Core Library 1.7.0.0 Library containing core utilities and tools for threading, networking, logging, INI and CSV file management etc.

CsvGridRow.h
Go to the documentation of this file.
1 // This file is part of CoreLibrary containing useful reusable utility
2 // classes.
3 //
4 // Copyright (C) 2014 to present, Duncan Crutchley
5 // Contact <dac1976github@outlook.com>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Lesser General Public License as published
9 // by the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License and GNU Lesser General Public License
16 // for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // and GNU Lesser General Public License along with this program. If
20 // not, see <http://www.gnu.org/licenses/>.
21
27 #ifndef CSVGRIDROW
28 #define CSVGRIDROW
29
30 #include <initializer_list>
31 #include <ostream>
32 #include <algorithm>
33 #include <iterator>
34 #include <stdexcept>
35 #ifdef USE_EXPLICIT_MOVE_
36 #include <utility>
37 #endif
38 #include <boost/tokenizer.hpp>
39 #include <boost/algorithm/string/trim.hpp>
40 #include <boost/throw_exception.hpp>
41 #include "CoreLibraryDllGlobal.h"
42 #include "Platform/PlatformDefines.h"
43 #include "StringUtils/StringUtils.h"
44 #include "CsvGridCell.h"
45 #include "CsvGridCellDouble.h"
46
48 namespace core_lib
49 {
51 namespace csv_grid
52 {
53
61 enum class eCellFormatOptions
62 {
67 simpleCells,
73 doubleQuotedCells
74 };
75
77 namespace reserver
78 {
79
81 template <template <class, class> class C, class T> class ContainerReserver
82 {
83 public:
85 using container_type = C<T, std::allocator<T>>;
95 void operator()(container_type& container, size_t size) const
96 {
97 (void)container;
98 (void)size;
99
100 // Do nothing.
101 }
102 };
103
105 template <class T> class ContainerReserver<std::vector, T>
106 {
107 public:
109 using container_type = std::vector<T>;
118 void operator()(container_type& container, size_t size) const
119 {
120 container.reserve(size);
121 }
122 };
123
124 } // namespace reserver
125
126 // forward declaration for using in Row class.
127 template <template <class, class> class C, class T> class TCsvGrid;
128
136 template <template <class, class> class C, class T = Cell> class TRow final
137 {
138 public:
140 using container_type = C<T, std::allocator<T>>;
142 using cell_type = T;
144 friend class TCsvGrid<C, T>;
146 TRow() = default;
148 TRow(const TRow&) = default;
149 #ifdef USE_EXPLICIT_MOVE_
150
151 TRow(TRow&& row)
152 {
153 *this = std::move(row);
154 }
155 #else
156
157 TRow(TRow&&) = default;
158 #endif
159
165 explicit TRow(size_t numCols)
166 : m_cells(numCols)
167 {
168 }
177 TRow(const std::string& line, eCellFormatOptions options)
178 {
179 LoadRowFromCsvFileLine(line, options);
180 }
187 // cppcheck-suppress noExplicitConstructor
188 TRow(std::initializer_list<T> cells)
189 : m_cells(cells)
190 {
191 }
193 ~TRow() = default;
195 TRow& operator=(const TRow&) = default;
196 #ifdef USE_EXPLICIT_MOVE_
197
198 TRow& operator=(TRow&& row)
199 {
200 std::swap(m_cells, row.m_cells);
201 return *this;
202 }
203 #else
204
205 TRow& operator=(TRow&&) = default;
206 #endif
207
218 cell_type& operator[](size_t col)
219 {
220 if (col >= GetSize())
221 {
222 BOOST_THROW_EXCEPTION(std::out_of_range("col out of range"));
223 }
224
225 return *std::next(m_cells.begin(), col);
226 }
238 const cell_type& operator[](size_t col) const
239 {
240 if (col >= GetSize())
241 {
242 BOOST_THROW_EXCEPTION(std::out_of_range("col out of range"));
243 }
244
245 return *std::next(m_cells.begin(), col);
246 }
251 bool Empty() const
252 {
253 return m_cells.empty();
254 }
259 size_t GetSize() const
260 {
261 return std::distance(m_cells.begin(), m_cells.end());
262 }
271 void SetSize(size_t cols)
272 {
273 m_cells.resize(cols);
274 }
282 template <typename V> void AddColumn(V value)
283 {
284 m_cells.emplace_back(value);
285 }
292 void AddColumn()
293 {
294 m_cells.emplace_back();
295 }
308 template <typename V> void InsertColumn(size_t col, V value)
309 {
310 if (col >= GetSize())
311 {
312 BOOST_THROW_EXCEPTION(std::out_of_range("col out of range"));
313 }
314
315 m_cells.emplace(std::next(m_cells.begin(), col), value);
316 }
328 void InsertColumn(size_t col)
329 {
330 if (col >= GetSize())
331 {
332 BOOST_THROW_EXCEPTION(std::out_of_range("col out of range"));
333 }
334
335 m_cells.emplace(std::next(m_cells.begin(), col));
336 }
343 void ClearCells()
344 {
345 std::fill(m_cells.begin(), m_cells.end(), Cell());
346 }
353 void ResetRow()
354 {
355 m_cells.clear();
356 }
357
358 private:
367 void LoadRowFromCsvFileLine(const std::string& line, eCellFormatOptions options)
368 {
369 if (options == eCellFormatOptions::doubleQuotedCells)
370 {
371 TokenizeLineQuoted(line);
372 }
373 else
374 {
375 TokenizeLine(line);
376 }
377 }
385 void OutputRowToStream(std::ostream& os) const
386 {
387 // for each row loop over its columns...
388 size_t col = 0;
389
390 for (const auto& cellItem : m_cells)
391 {
392 // let's get our cell value...
393 std::string cell{static_cast<std::string>(cellItem)};
394
395 // if string contains quotes, insert an
396 // extra quote...
397 size_t pos{cell.find('"')};
398
399 while (pos < cell.length())
400 {
401 cell.insert(pos, "\"");
402 pos = cell.find('"', pos + 2);
403 }
404
405 // if cell contains ',', '\n' or '\r' wrap it in quotes...
406 if (cell.find_first_of(",\r\n") != std::string::npos)
407 {
408 std::string temp = "\"";
409 temp.append(cell);
410 temp.append("\"");
411 cell.swap(temp);
412 }
413
414 // output corrected cell...
415 os << cell;
416
417 // add ',' if not last cell on current row...
418 if (col++ < GetSize() - 1)
419 {
420 os << ",";
421 }
422 }
423 }
431 void TokenizeLineQuoted(const std::string& line)
432 {
433 using Tokenizer = boost::tokenizer<boost::escaped_list_separator<char>>;
434 Tokenizer tokzr{line};
435 Tokenizer::const_iterator tokIter{tokzr.begin()};
436
437 while (tokIter != tokzr.end())
438 {
439 // cppcheck-suppress eraseDereference
440 std::string tok{*tokIter++};
441 boost::trim(tok);
442 m_cells.emplace_back(tok);
443 }
444 }
453 void TokenizeLine(const std::string& line)
454 {
455 std::stringstream line_ss{line};
456 std::string tok;
457
458 while (std::getline(line_ss, tok, ','))
459 {
460 string_utils::PackStdString(tok);
461 boost::trim(tok);
462 m_cells.emplace_back(tok);
463 }
464 }
465
466 private:
468 reserver::ContainerReserver<C, T> m_reserve{};
470 container_type m_cells{};
471 };
472
473 } // namespace csv_grid
474 } // namespace core_lib
475
476 #endif // CSVGRIDROW
core_lib::csv_grid::TRow::InsertColumn
void InsertColumn(size_t col, V value)
Insert a new cell.
Definition: CsvGridRow.h:308
core_lib::csv_grid::TCsvGrid
Grid class with CSV file capabilities.
Definition: CsvGridMain.h:81
core_lib::csv_grid::TRow::ClearCells
void ClearCells()
Clear the cells&#39; contents.
Definition: CsvGridRow.h:343
core_lib::csv_grid::TRow
Class defining a row of the grid.
Definition: CsvGridRow.h:136
std
The std namespace.
Definition: DebugLog.h:81
core_lib::csv_grid::reserver::ContainerReserver< std::vector, T >::operator()
void operator()(container_type &container, size_t size) const
Function operator.
Definition: CsvGridRow.h:118
core_lib::csv_grid::TRow::TRow
TRow(const std::string &line, eCellFormatOptions options)
Initializing constructor.
Definition: CsvGridRow.h:177
core_lib::csv_grid::TRow::TRow
TRow(std::initializer_list< T > cells)
Initializer list constructor.
Definition: CsvGridRow.h:188
core_lib::csv_grid::TRow::AddColumn
void AddColumn()
Add a column with default value.
Definition: CsvGridRow.h:292
core_lib::csv_grid::TRow::GetSize
size_t GetSize() const
Get the number of columns.
Definition: CsvGridRow.h:259
core_lib::csv_grid::TRow::InsertColumn
void InsertColumn(size_t col)
Insert a new cell.
Definition: CsvGridRow.h:328
core_lib::csv_grid::TRow::TRow
TRow(size_t numCols)
Initializing constructor.
Definition: CsvGridRow.h:165
core_lib::csv_grid::TRow::TokenizeLine
void TokenizeLine(const std::string &line)
Tokenize a row with simple cells.
Definition: CsvGridRow.h:453
CsvGridCellDouble.h
File containing declarations relating the CellDouble class.
core_lib::csv_grid::TRow::SetSize
void SetSize(size_t cols)
Set the number of columns in the row.
Definition: CsvGridRow.h:271
core_lib::csv_grid::reserver::ContainerReserver::operator()
void operator()(container_type &container, size_t size) const
Function operator.
Definition: CsvGridRow.h:95
core_lib::csv_grid::TRow::AddColumn
void AddColumn(V value)
Add a column with the given value.
Definition: CsvGridRow.h:282
core_lib::csv_grid::reserver::ContainerReserver< std::vector, T >::container_type
std::vector< T > container_type
Typedef to container type.
Definition: CsvGridRow.h:109
core_lib
The core_lib namespace.
Definition: AsioDefines.h:59
core_lib::csv_grid::Cell
Class defining a single cell within a row of the grid.
Definition: CsvGridCell.h:49
core_lib::csv_grid::eCellFormatOptions::simpleCells
All cells are simple and not wrapped in double quotes, e.g. x1,x2,x3. This format is faster than usin...
core_lib::csv_grid::TRow::TokenizeLineQuoted
void TokenizeLineQuoted(const std::string &line)
Tokenize a row with double quoted cells.
Definition: CsvGridRow.h:431
core_lib::csv_grid::TRow::Empty
bool Empty() const
Get empty state of row.
Definition: CsvGridRow.h:251
core_lib::csv_grid::TRow::container_type
C< T, std::allocator< T > > container_type
typedef for container type
Definition: CsvGridRow.h:140
StringUtils.h
File containing declarations relating various string utilities.
core_lib::csv_grid::eCellFormatOptions::doubleQuotedCells
Cells may contain special, escaped, characters and are in double qoutes, e.g. "x1","x2","x3". This format is slower than simple formatting as care has to be taken with parsing special characters.
core_lib::csv_grid::TRow::operator[]
const cell_type & operator[](size_t col) const
Const subscript operator.
Definition: CsvGridRow.h:238
core_lib::csv_grid::reserver::ContainerReserver::container_type
C< T, std::allocator< T > > container_type
Typedef to container type.
Definition: CsvGridRow.h:85
CoreLibraryDllGlobal.h
File containing declaration of DLL import/export control defines.
core_lib::string_utils::PackStdString
void CORE_LIBRARY_DLL_SHARED_API PackStdString(std::string &line)
Tidy a string obtained from getline function.
Definition: StringUtils.cpp:47
core_lib::csv_grid::TRow::OutputRowToStream
void OutputRowToStream(std::ostream &os) const
Write the row&#39;s contents to a stream object.
Definition: CsvGridRow.h:385
core_lib::csv_grid::TRow::operator[]
cell_type & operator[](size_t col)
Subscript operator.
Definition: CsvGridRow.h:218
core_lib::csv_grid::TRow::ResetRow
void ResetRow()
Clear the entire row.
Definition: CsvGridRow.h:353
PlatformDefines.h
File containing platform specific definitions.
core_lib::csv_grid::TRow::LoadRowFromCsvFileLine
void LoadRowFromCsvFileLine(const std::string &line, eCellFormatOptions options)
Load a row from a line in a CSV file.
Definition: CsvGridRow.h:367
core_lib::csv_grid::eCellFormatOptions
eCellFormatOptions
Cell format options enumeration.
Definition: CsvGridRow.h:61
core_lib::csv_grid::TRow::cell_type
T cell_type
typedef for container type
Definition: CsvGridRow.h:142
CsvGridCell.h
File containing declarations relating the Cell class.
core_lib::csv_grid::reserver::ContainerReserver
Default container reserver functor.
Definition: CsvGridRow.h:81