Alexandria 2.31.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
CastVisitor.h
Go to the documentation of this file.
1
25#ifndef _TABLE_CASTVISITOR_H
26#define _TABLE_CASTVISITOR_H
27
29#include <boost/tokenizer.hpp>
30#include <boost/variant/static_visitor.hpp>
31#include <cmath>
32#include <sstream>
33#include <type_traits>
34#include <typeinfo>
35#include <vector>
36
37namespace Euclid {
38namespace Table {
39
40template <typename To>
41class CastVisitor : public boost::static_visitor<To> {
42
43public:
44 template <typename From>
45 To operator()(const From& from, typename std::enable_if<std::is_same<From, To>::value>::type* = 0) const {
46 return from;
47 }
48
49 template <typename From>
50 To operator()(const From&, typename std::enable_if<!std::is_same<From, To>::value>::type* = 0) const {
51 throw Elements::Exception() << "CastVisitor cannot convert " << typeid(From).name() << " type to "
52 << typeid(To).name();
53 }
54};
55
56template <>
57class CastVisitor<std::string> : public boost::static_visitor<std::string> {
58
59public:
60 template <typename T>
62 std::stringstream result{};
63 auto it = v.begin();
64 if (it != v.end()) {
65 result << *it;
66 ++it;
67 }
68 while (it != v.end()) {
69 result << ',' << *it;
70 ++it;
71 }
72 return result.str();
73 }
74
75 template <typename From>
76 std::string operator()(const From& from) const {
77 std::stringstream result{};
78 result << from;
79 return result.str();
80 }
81};
82
83template <>
84class CastVisitor<double> : public boost::static_visitor<double> {
85
86 template <typename From>
87 static constexpr bool generic() {
89 }
90
91public:
92 template <typename From>
93 double operator()(const From&, typename std::enable_if<!generic<From>()>::type* = 0) const {
94 throw Elements::Exception() << "CastVisitor cannot convert " << typeid(From).name() << " type to "
95 << typeid(double).name();
96 }
97
98 template <typename From>
99 double operator()(const From& from, typename std::enable_if<generic<From>()>::type* = 0) const {
100 return from;
101 }
102
103 double operator()(const std::string& from) const {
104 char* endptr = nullptr;
105 double value = std::strtod(from.c_str(), &endptr);
106 if (endptr == from.c_str()) {
107 throw Elements::Exception() << "CastVisitor cannot convert the string '" << from << "' to "
108 << typeid(double).name();
109 }
110 if (value == HUGE_VAL || value == -HUGE_VAL) {
111 throw Elements::Exception() << "CastVisitor overflows converting the string '" << from << "' to "
112 << typeid(double).name();
113 }
114 return value;
115 }
116};
117
118template <>
119class CastVisitor<float> : public boost::static_visitor<float> {
120
121 template <typename From>
126
127public:
128 template <typename From>
129 double operator()(const From&, typename std::enable_if<!generic<From>()>::type* = 0) const {
130 throw Elements::Exception() << "CastVisitor cannot convert " << typeid(From).name() << " type to "
131 << typeid(float).name();
132 }
133
134 template <typename From>
135 float operator()(const From& from, typename std::enable_if<generic<From>()>::type* = 0) const {
136 return from;
137 }
138
139 float operator()(const std::string& from) const {
140 char* endptr = nullptr;
141 float value = std::strtof(from.c_str(), &endptr);
142 if (endptr == from.c_str()) {
143 throw Elements::Exception() << "CastVisitor cannot convert the string '" << from << "' to "
144 << typeid(float).name();
145 }
146 if (value == HUGE_VALF || value == -HUGE_VALF) {
147 throw Elements::Exception() << "CastVisitor overflows converting the string '" << from << "' to "
148 << typeid(float).name();
149 }
150 return value;
151 }
152};
153
154template <>
155class CastVisitor<int64_t> : public boost::static_visitor<int64_t> {
156
157 template <typename From>
158 static constexpr bool generic() {
160 }
161
162public:
163 template <typename From>
164 double operator()(const From&, typename std::enable_if<!generic<From>()>::type* = 0) const {
165 throw Elements::Exception() << "CastVisitor cannot convert " << typeid(From).name() << " type to "
166 << typeid(int64_t).name();
167 }
168
169 template <typename From>
170 int64_t operator()(const From& from, typename std::enable_if<generic<From>()>::type* = 0) const {
171 return from;
172 }
173
174 int64_t operator()(const std::string& from) const {
175 char* endptr = nullptr;
176 int64_t value = std::strtoll(from.c_str(), &endptr, 10);
177 if (endptr == from.c_str()) {
178 throw Elements::Exception() << "CastVisitor cannot convert the string '" << from << "' to "
179 << typeid(int64_t).name();
180 }
181 return value;
182 }
183};
184
185template <>
186class CastVisitor<int32_t> : public boost::static_visitor<int32_t> {
187
188 template <typename From>
193
194public:
195 template <typename From>
196 double operator()(const From&, typename std::enable_if<!generic<From>()>::type* = 0) const {
197 throw Elements::Exception() << "CastVisitor cannot convert " << typeid(From).name() << " type to "
198 << typeid(int32_t).name();
199 }
200
201 template <typename From>
202 int32_t operator()(const From& from, typename std::enable_if<generic<From>()>::type* = 0) const {
203 return from;
204 }
205
206 int32_t operator()(const std::string& from) const {
207 char* endptr = nullptr;
208 int64_t value = std::strtoll(from.c_str(), &endptr, 10);
209 if (endptr == from.c_str()) {
210 throw Elements::Exception() << "CastVisitor cannot convert the string '" << from << "' to "
211 << typeid(int32_t).name();
212 }
213 if (value > INT32_MAX || value < INT32_MIN) {
214 throw Elements::Exception() << "CastVisitor overflows converting the string '" << from << "' to "
215 << typeid(int32_t).name();
216 }
217 return static_cast<int32_t>(value);
218 }
219};
220
221template <typename VectorType>
222class CastVisitor<std::vector<VectorType>> : public boost::static_visitor<std::vector<VectorType>> {
223
224public:
225 template <typename From>
226 std::vector<VectorType> operator()(const From& from) const {
228 result.push_back(CastVisitor<VectorType>{}(from));
229 return result;
230 }
231
232 template <typename From>
235 for (auto v : from) {
237 }
238 return result;
239 }
240
243 boost::char_separator<char> sep{","};
244 boost::tokenizer<boost::char_separator<char>> tok{from, sep};
245 for (auto& s : tok) {
247 }
248 return result;
249 }
250
251 // If the types match exactly we avoid an expensive copying
253 return from;
254 }
255};
256
257} /* namespace Table */
258} /* namespace Euclid */
259
260#endif
T begin(T... args)
T c_str(T... args)
double operator()(const From &, typename std::enable_if<!generic< From >()>::type *=0) const
Definition CastVisitor.h:93
double operator()(const std::string &from) const
double operator()(const From &from, typename std::enable_if< generic< From >()>::type *=0) const
Definition CastVisitor.h:99
float operator()(const From &from, typename std::enable_if< generic< From >()>::type *=0) const
double operator()(const From &, typename std::enable_if<!generic< From >()>::type *=0) const
float operator()(const std::string &from) const
double operator()(const From &, typename std::enable_if<!generic< From >()>::type *=0) const
int32_t operator()(const std::string &from) const
int32_t operator()(const From &from, typename std::enable_if< generic< From >()>::type *=0) const
int64_t operator()(const std::string &from) const
int64_t operator()(const From &from, typename std::enable_if< generic< From >()>::type *=0) const
double operator()(const From &, typename std::enable_if<!generic< From >()>::type *=0) const
std::string operator()(const std::vector< T > &v) const
Definition CastVisitor.h:61
std::string operator()(const From &from) const
Definition CastVisitor.h:76
std::vector< VectorType > operator()(const std::string &from) const
std::vector< VectorType > operator()(const std::vector< From > &from) const
std::vector< VectorType > operator()(const From &from) const
const std::vector< VectorType > & operator()(const std::vector< VectorType > &from) const
To operator()(const From &, typename std::enable_if<!std::is_same< From, To >::value >::type *=0) const
Definition CastVisitor.h:50
To operator()(const From &from, typename std::enable_if< std::is_same< From, To >::value >::type *=0) const
Definition CastVisitor.h:45
T end(T... args)
STL namespace.
T push_back(T... args)
T str(T... args)
T strtod(T... args)
T strtoll(T... args)