Alexandria  2.25.0
SDC-CH common library for the Euclid project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Row.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2021 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
25 #include "Table/Row.h"
28 #include <algorithm>
29 #include <boost/algorithm/string/join.hpp>
30 
31 #if BOOST_VERSION < 105600
32 #include <boost/units/detail/utility.hpp>
33 using boost::units::detail::demangle;
34 #else
35 using boost::core::demangle;
36 #endif
37 
38 namespace std {
39 
40 template <typename T>
41 std::ostream& operator<<(std::ostream& s, const std::vector<T>& v) {
42  auto it = v.begin();
43  if (it != v.end()) {
44  s << *it;
45  ++it;
46  }
47  while (it != v.end()) {
48  s << ',' << *it;
49  ++it;
50  }
51  return s;
52 }
53 
54 template std::ostream& operator<<<double>(std::ostream& s, const std::vector<double>& v);
55 template std::ostream& operator<<<float>(std::ostream& s, const std::vector<float>& v);
56 template std::ostream& operator<<<std::int64_t>(std::ostream& s, const std::vector<std::int64_t>& v);
57 template std::ostream& operator<<<std::int32_t>(std::ostream& s, const std::vector<std::int32_t>& v);
58 template std::ostream& operator<<<bool>(std::ostream& s, const std::vector<bool>& v);
59 
60 } // namespace std
61 
62 namespace Euclid {
63 namespace Table {
64 
66  : m_values(std::move(values)), m_column_info{column_info} {
67  if (!m_column_info) {
68  throw Elements::Exception() << "Row construction with nullptr column_info";
69  }
70  if (m_values.size() != m_column_info->size()) {
71  throw Elements::Exception() << "Wrong number of row values (" << m_values.size() << " instead of "
72  << m_column_info->size();
73  }
74  for (std::size_t i = 0; i < m_values.size(); ++i) {
75  auto& value_type = m_values[i].type();
76  auto& column_type = column_info->getDescription(i).type;
77  auto& column_name = column_info->getDescription(i).name;
78  if (std::type_index{value_type} != column_type) {
79  throw Elements::Exception() << "Incompatible cell type for " << column_name << ": expected "
80  << demangle(column_type.name()) << ", got " << demangle(value_type.name());
81  }
82  }
83  static const regex::regex vertical_whitespace{".*[\\n\\v\\f\\r].*"}; // Checks if input contains any whitespace characters
84  for (auto cell : m_values) {
85  if (cell.type() == typeid(std::string)) {
86  std::string value = boost::get<std::string>(cell);
87  if (value.empty()) {
88  throw Elements::Exception() << "Empty string cell values are not allowed";
89  }
90  if (regex_match(value, vertical_whitespace)) {
91  throw Elements::Exception() << "Cell value '" << value << "' contains "
92  << "vertical whitespace characters";
93  }
94  }
95  }
96 }
97 
99  return m_column_info;
100 }
101 
102 size_t Row::size() const {
103  return m_values.size();
104 }
105 
106 const Row::cell_type& Row::operator[](const size_t index) const {
107  if (index >= m_values.size()) {
108  throw Elements::Exception("Index out of bounds");
109  }
110  return m_values[index];
111 }
112 
113 const Row::cell_type& Row::operator[](const std::string& column) const {
114  auto index = m_column_info->find(column);
115  if (!index) {
116  throw Elements::Exception() << "Row does not contain column with name " << column;
117  }
118  return m_values[*index];
119 }
120 
122  return m_values.cbegin();
123 }
124 
126  return m_values.cend();
127 }
128 
129 } // namespace Table
130 } // end of namespace Euclid
T empty(T...args)
T regex_match(T...args)
const_iterator end() const
Returns a const iterator to the past-the-end cell of the row.
Definition: Row.cpp:125
std::vector< cell_type >::const_iterator const_iterator
Definition: Row.h:73
std::shared_ptr< ColumnInfo > m_column_info
Definition: Row.h:158
STL class.
constexpr double s
boost::variant< bool, int32_t, int64_t, float, double, std::string, std::vector< bool >, std::vector< int32_t >, std::vector< int64_t >, std::vector< float >, std::vector< double >, NdArray::NdArray< int32_t >, NdArray::NdArray< int64_t >, NdArray::NdArray< float >, NdArray::NdArray< double > > cell_type
The possible cell types.
Definition: Row.h:71
const_iterator begin() const
Returns a const iterator to the first cell of the row.
Definition: Row.cpp:121
size_t size() const
Returns the number of cells in the row.
Definition: Row.cpp:102
const cell_type & operator[](const size_t index) const
Returns the value of the column with the given index (zero based)
Definition: Row.cpp:106
STL class.
std::shared_ptr< ColumnInfo > getColumnInfo() const
Returns a ColumnInfo object describing the columns of the Row.
Definition: Row.cpp:98