Alexandria  2.16
Please provide a description of the project.
Row.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2020 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 <algorithm>
26 // The std regex library is not fully implemented in GCC 4.8. The following lines
27 // make use of the BOOST library and can be modified if GCC 4.9 will be used in
28 // the future.
29 // #include <regex>
30 #include <boost/regex.hpp>
31 using boost::regex;
32 using boost::regex_match;
33 #include <boost/algorithm/string/join.hpp>
35 #include "Table/Row.h"
36 
37 #if BOOST_VERSION < 105600
38 #include <boost/units/detail/utility.hpp>
39 using boost::units::detail::demangle;
40 #else
41 using boost::core::demangle;
42 #endif
43 
44 namespace std {
45 
46 template <typename T>
47 std::ostream& operator<< (std::ostream& s, const std::vector<T>& v) {
48  auto it = v.begin();
49  if (it != v.end()) {
50  s << *it;
51  }
52  while (++it != v.end()) {
53  s << ',' << *it;
54  }
55  return s;
56 }
57 
60 template std::ostream& operator<< <std::int64_t> (std::ostream& s, const std::vector<std::int64_t>& v);
61 template std::ostream& operator<< <std::int32_t> (std::ostream& s, const std::vector<std::int32_t>& v);
63 
64 }
65 
66 namespace Euclid {
67 namespace Table {
68 
70  : m_values(std::move(values)), m_column_info{column_info} {
71  if (!m_column_info) {
72  throw Elements::Exception() << "Row construction with nullptr column_info";
73  }
74  if (m_values.size() != m_column_info->size()) {
75  throw Elements::Exception() << "Wrong number of row values (" << m_values.size()
76  << " instead of " << m_column_info->size();
77  }
78  for (std::size_t i=0; i<m_values.size(); ++i) {
79  auto& value_type = m_values[i].type();
80  auto& column_type = column_info->getDescription(i).type;
81  auto& column_name = column_info->getDescription(i).name;
82  if (std::type_index{value_type} != column_type) {
83  throw Elements::Exception() << "Incompatible cell type for " << column_name << ": expected "
84  << demangle(column_type.name())
85  << ", got " << demangle(value_type.name());
86  }
87  }
88  regex vertical_whitespace {".*\\v.*"}; // Checks if input contains any vertical whitespace characters
89  for (auto cell : m_values) {
90  if (cell.type() == typeid(std::string)) {
91  std::string value = boost::get<std::string>(cell);
92  if (value.empty()) {
93  throw Elements::Exception() << "Empty string cell values are not allowed";
94  }
95  if (regex_match(value, vertical_whitespace)) {
96  throw Elements::Exception() << "Cell value '" << value << "' contains "
97  << "vertical whitespace characters";
98  }
99  }
100  }
101 }
102 
104  return m_column_info;
105 }
106 
107 size_t Row::size() const {
108  return m_values.size();
109 }
110 
111 const Row::cell_type& Row::operator [](const size_t index) const {
112  if (index >= m_values.size()) {
113  throw Elements::Exception("Index out of bounds");
114  }
115  return m_values[index];
116 }
117 
118 const Row::cell_type& Row::operator [](const std::string& column) const {
119  auto index = m_column_info->find(column);
120  if (!index) {
121  throw Elements::Exception() << "Row does not contain column with name " << column;
122  }
123  return m_values[*index];
124 }
125 
127  return m_values.cbegin();
128 }
129 
131  return m_values.cend();
132 }
133 
134 }
135 } // end of namespace Euclid
std::vector< cell_type > m_values
Definition: Row.h:170
template std::ostream & operator<<< bool >(std::ostream &s, const std::vector< bool > &v)
T empty(T... args)
T regex_match(T... args)
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< bool >, NdArray::NdArray< int32_t >, NdArray::NdArray< int64_t >, NdArray::NdArray< float >, NdArray::NdArray< double > > cell_type
The possible cell types.
Definition: Row.h:84
size_t size() const
Returns the number of cells in the row.
Definition: Row.cpp:107
const_iterator end() const
Returns a const iterator to the past-the-end cell of the row.
Definition: Row.cpp:130
constexpr double s
STL namespace.
const_iterator begin() const
Returns a const iterator to the first cell of the row.
Definition: Row.cpp:126
T cend(T... args)
std::vector< cell_type >::const_iterator const_iterator
Definition: Row.h:86
std::shared_ptr< ColumnInfo > m_column_info
Definition: Row.h:171
STL class.
const cell_type & operator[](const size_t index) const
Returns the value of the column with the given index (zero based)
Definition: Row.cpp:111
template std::ostream & operator<<< float >(std::ostream &s, const std::vector< float > &v)
std::shared_ptr< ColumnInfo > getColumnInfo() const
Returns a ColumnInfo object describing the columns of the Row.
Definition: Row.cpp:103
T size(T... args)
T cbegin(T... args)
template std::ostream & operator<<< double >(std::ostream &s, const std::vector< double > &v)
STL class.