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"
44 #include "CsvGridCell.h"
45 #include "CsvGridCellDouble.h"
46 
48 namespace core_lib
49 {
51 namespace csv_grid
52 {
53 
62 {
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  {
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  {
461  boost::trim(tok);
462  m_cells.emplace_back(tok);
463  }
464  }
465 
466 private:
470  container_type m_cells{};
471 };
472 
473 } // namespace csv_grid
474 } // namespace core_lib
475 
476 #endif // CSVGRIDROW
void InsertColumn(size_t col, V value)
Insert a new cell.
Definition: CsvGridRow.h:308
Grid class with CSV file capabilities.
Definition: CsvGridMain.h:81
void ClearCells()
Clear the cells&#39; contents.
Definition: CsvGridRow.h:343
Class defining a row of the grid.
Definition: CsvGridRow.h:136
The std namespace.
Definition: DebugLog.h:81
void operator()(container_type &container, size_t size) const
Function operator.
Definition: CsvGridRow.h:118
TRow(const std::string &line, eCellFormatOptions options)
Initializing constructor.
Definition: CsvGridRow.h:177
TRow(std::initializer_list< T > cells)
Initializer list constructor.
Definition: CsvGridRow.h:188
void AddColumn()
Add a column with default value.
Definition: CsvGridRow.h:292
size_t GetSize() const
Get the number of columns.
Definition: CsvGridRow.h:259
void InsertColumn(size_t col)
Insert a new cell.
Definition: CsvGridRow.h:328
TRow(size_t numCols)
Initializing constructor.
Definition: CsvGridRow.h:165
void TokenizeLine(const std::string &line)
Tokenize a row with simple cells.
Definition: CsvGridRow.h:453
File containing declarations relating the CellDouble class.
void SetSize(size_t cols)
Set the number of columns in the row.
Definition: CsvGridRow.h:271
void operator()(container_type &container, size_t size) const
Function operator.
Definition: CsvGridRow.h:95
void AddColumn(V value)
Add a column with the given value.
Definition: CsvGridRow.h:282
std::vector< T > container_type
Typedef to container type.
Definition: CsvGridRow.h:109
The core_lib namespace.
Definition: AsioDefines.h:59
Class defining a single cell within a row of the grid.
Definition: CsvGridCell.h:49
All cells are simple and not wrapped in double quotes, e.g. x1,x2,x3. This format is faster than usin...
void TokenizeLineQuoted(const std::string &line)
Tokenize a row with double quoted cells.
Definition: CsvGridRow.h:431
bool Empty() const
Get empty state of row.
Definition: CsvGridRow.h:251
C< T, std::allocator< T > > container_type
typedef for container type
Definition: CsvGridRow.h:140
File containing declarations relating various string utilities.
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.
const cell_type & operator[](size_t col) const
Const subscript operator.
Definition: CsvGridRow.h:238
C< T, std::allocator< T > > container_type
Typedef to container type.
Definition: CsvGridRow.h:85
File containing declaration of DLL import/export control defines.
void CORE_LIBRARY_DLL_SHARED_API PackStdString(std::string &line)
Tidy a string obtained from getline function.
Definition: StringUtils.cpp:47
void OutputRowToStream(std::ostream &os) const
Write the row&#39;s contents to a stream object.
Definition: CsvGridRow.h:385
cell_type & operator[](size_t col)
Subscript operator.
Definition: CsvGridRow.h:218
void ResetRow()
Clear the entire row.
Definition: CsvGridRow.h:353
File containing platform specific definitions.
void LoadRowFromCsvFileLine(const std::string &line, eCellFormatOptions options)
Load a row from a line in a CSV file.
Definition: CsvGridRow.h:367
eCellFormatOptions
Cell format options enumeration.
Definition: CsvGridRow.h:61
T cell_type
typedef for container type
Definition: CsvGridRow.h:142
File containing declarations relating the Cell class.
Default container reserver functor.
Definition: CsvGridRow.h:81