OpenMS
Loading...
Searching...
No Matches
StringConversions.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Timo Sachsenberg, Chris Bielow $
6// $Authors: Marc Sturm, Stephan Aiche, Chris Bielow $
7// --------------------------------------------------------------------------
8
9#pragma once
10
16
17#include <boost/spirit/include/qi.hpp>
18#include <boost/spirit/include/karma.hpp>
19#include <boost/type_traits.hpp>
20
21#include <boost/spirit/home/karma/numeric/detail/real_utils.hpp>
22
23#include <string>
24#include <vector>
25
26
27namespace OpenMS
28{
29 class String;
30
31 namespace StringConversions
32 {
33
34 namespace Detail
35 {
36 // Karma full precision float policy
37 template<typename T>
38 class BK_PrecPolicyFull : public boost::spirit::karma::real_policies<T>
39 {
40 typedef boost::spirit::karma::real_policies<T> base_policy_type;
41
42 public:
43 static unsigned precision(T /*n*/)
44 {
45 /* The following would be the only way for a lossless double-string-double
46 * roundtrip but:
47 * a) We only care about speed
48 * b) Many tests have to be changed
49 * c) In the end boost::karma is bugged and hard limits the fractional digits
50 * even though you have leading zeros (basically forcing scientific notation)
51 * for full precision https://github.com/boostorg/spirit/issues/585
52 if (BK_PrecPolicyFull::floatfield(n))
53 {
54 T abs_n = boost::spirit::traits::get_absolute_value(n);
55 if (abs_n >= 1)
56 {
57 return std::numeric_limits<T>::max_digits10 - (floor(log10(abs_n)) + 1);
58 }
59 else
60 {
61 return std::numeric_limits<T>::max_digits10 - (floor(log10(abs_n)));
62 }
63 }
64 else
65 {
66 return std::numeric_limits<T>::max_digits10 - 1;
67 }
68 */
69 return writtenDigits<T>();
70 }
71
72 // we want the numbers always to be in scientific format
73 static unsigned floatfield(T n)
74 {
75 if (boost::spirit::traits::test_zero(n)) return base_policy_type::fmtflags::fixed;
76
77 T abs_n = boost::spirit::traits::get_absolute_value(n);
78 // this is due to a bug in downstream thirdparty tools that only can read
79 // up to 19 digits. https://github.com/OpenMS/OpenMS/issues/4627
80 return (abs_n >= 1e4 || abs_n < 1e-2) ? base_policy_type::fmtflags::scientific : base_policy_type::fmtflags::fixed;
81 }
82
83 // we need this special 'NaN' since the default 'nan' is not recognized by downstream tools such as any Java-based tool (e.g. KNIME) trying to
84 // parse our output files
85 template<typename CharEncoding, typename Tag, typename OutputIterator>
86 static bool nan(OutputIterator& sink, T n, bool force_sign)
87 {
88 return boost::spirit::karma::sign_inserter::call(sink, false, boost::spirit::traits::test_negative(n), force_sign)
89 && boost::spirit::karma::string_inserter<CharEncoding, Tag>::call(sink, "NaN");
90 }
91 };
92
93 // Karma default (3-digits) precision float policy
94 template<typename T>
95 class BK_PrecPolicyShort : public boost::spirit::karma::real_policies<T>
96 {
97 typedef boost::spirit::karma::real_policies<T> base_policy_type;
98
99 public:
100 // we need this special 'NaN' since the default 'nan' is not recognized by downstream tools such as any Java-based tool (e.g. KNIME) trying to
101 // parse our output files
102 template<typename CharEncoding, typename Tag, typename OutputIterator>
103 static bool nan(OutputIterator& sink, T n, bool force_sign)
104 {
105 return boost::spirit::karma::sign_inserter::call(sink, false, boost::spirit::traits::test_negative(n), force_sign)
106 && boost::spirit::karma::string_inserter<CharEncoding, Tag>::call(sink, "NaN");
107 }
108 };
109
110 using BK_PrecPolicyFloatFull_type = boost::spirit::karma::real_generator<float, BK_PrecPolicyFull<float>>;
112 using BK_PrecPolicyDoubleFull_type = boost::spirit::karma::real_generator<double, BK_PrecPolicyFull<double>>;
114 using BK_PrecPolicyLongDoubleFull_type = boost::spirit::karma::real_generator<long double, BK_PrecPolicyFull<long double>>;
116
117 using BK_PrecPolicyFloatShort_type = boost::spirit::karma::real_generator<float, BK_PrecPolicyShort<float>>;
119 using BK_PrecPolicyDoubleShort_type = boost::spirit::karma::real_generator<double, BK_PrecPolicyShort<double>>;
121 using BK_PrecPolicyLongDoubleShort_type = boost::spirit::karma::real_generator<long double, BK_PrecPolicyShort<long double>>;
123
124 } // namespace Detail
125
126
127
128 // toString functions (single argument)
129
132 template <typename T>
133 inline void append(const T& i, String& target)
134 {
135 std::back_insert_iterator<std::string> sink(target);
136 boost::spirit::karma::generate(sink, i);
137 }
138
140 template <typename T>
141 inline String toString(const T& i)
142 {
143 //std::stringstream s;
144 //s << i;
145 //return s.str();
146 String str;
147 append(i, str);
148 return str;
149 }
150
151
154 inline void appendLowP(float f, String& target)
155 {
156 std::back_insert_iterator<std::string> sink(target);
157 boost::spirit::karma::generate(sink, Detail::BK_PrecPolicyFloatShort, f);
158 }
160 inline String toStringLowP(float f)
161 {
162 String str;
163 appendLowP(f, str);
164 return str;
165 }
166
167
170 inline void appendLowP(double d, String& target)
171 {
172 std::back_insert_iterator<std::string> sink(target);
173 boost::spirit::karma::generate(sink, Detail::BK_PrecPolicyDoubleShort, d);
174 }
176 inline String toStringLowP(double d)
177 {
178 String str;
179 appendLowP(d, str);
180 return str;
181 }
182
183
185 inline void appendLowP(long double ld, String& target)
186 {
187 std::back_insert_iterator<std::string> sink(target);
188 boost::spirit::karma::generate(sink, Detail::BK_PrecPolicyLongDoubleShort, ld);
189 }
191 inline String toStringLowP(long double ld)
192 {
193 String str;
194 appendLowP(ld, str);
195 return str;
196 }
197
198
199
201 inline void append(float f, String& target)
202 {
203 std::back_insert_iterator<std::string> sink(target);
204 boost::spirit::karma::generate(sink, Detail::BK_PrecPolicyFloatFull, f);
205 }
207 inline String toString(float f)
208 {
209 String str;
210 append(f, str);
211 return str;
212 }
213
214
215
217 inline void append(double d, String& target)
218 {
219 std::back_insert_iterator<std::string> sink(target);
220 boost::spirit::karma::generate(sink, Detail::BK_PrecPolicyDoubleFull, d);
221 }
223 inline String toString(double d)
224 {
225 String str;
226 append(d, str);
227 return str;
228 }
229
230
232 inline void append(long double ld, String& target)
233 {
234 std::back_insert_iterator<std::string> sink(target);
235 boost::spirit::karma::generate(sink, Detail::BK_PrecPolicyLongDoubleFull, ld);
236 }
238 inline String toString(long double ld)
239 {
240 String str;
241 append(ld, str);
242 return str;
243 }
244
245
246 inline void append(const DataValue& d, bool full_precision, String& target)
247 {
248 target += d.toString(full_precision);
249 }
250 inline String toString(const DataValue& d, bool full_precision)
251 {
252 return d.toString(full_precision);
253 }
254
255
256
257 inline String toString(const char c)
258 {
259 return std::string(1, c);
260 }
261
262 inline String toString(const std::string& s)
263 {
264 return s;
265 }
266
267 inline String toString(const char* s)
268 {
269 return std::string(s);
270 }
271
274 {
275 return String();
276 }
277
278 }
279
280} // namespace OPENMS
281
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition DataValue.h:34
String toString(bool full_precision=true) const
Conversion to String full_precision Controls number of fractional digits for all double types or list...
static unsigned precision(T)
Definition StringConversions.h:43
static unsigned floatfield(T n)
Definition StringConversions.h:73
static bool nan(OutputIterator &sink, T n, bool force_sign)
Definition StringConversions.h:86
boost::spirit::karma::real_policies< T > base_policy_type
Definition StringConversions.h:40
static bool nan(OutputIterator &sink, T n, bool force_sign)
Definition StringConversions.h:103
boost::spirit::karma::real_policies< T > base_policy_type
Definition StringConversions.h:97
A more convenient string class.
Definition String.h:34
const BK_PrecPolicyFloatShort_type BK_PrecPolicyFloatShort
Definition StringConversions.h:118
boost::spirit::karma::real_generator< double, BK_PrecPolicyFull< double > > BK_PrecPolicyDoubleFull_type
Definition StringConversions.h:112
const BK_PrecPolicyDoubleFull_type BK_PrecPolicyDoubleFull
Definition StringConversions.h:113
const BK_PrecPolicyDoubleShort_type BK_PrecPolicyDoubleShort
Definition StringConversions.h:120
const BK_PrecPolicyLongDoubleFull_type BK_PrecPolicyLongDoubleFull
Definition StringConversions.h:115
boost::spirit::karma::real_generator< double, BK_PrecPolicyShort< double > > BK_PrecPolicyDoubleShort_type
Definition StringConversions.h:119
boost::spirit::karma::real_generator< long double, BK_PrecPolicyFull< long double > > BK_PrecPolicyLongDoubleFull_type
Definition StringConversions.h:114
boost::spirit::karma::real_generator< float, BK_PrecPolicyShort< float > > BK_PrecPolicyFloatShort_type
Definition StringConversions.h:117
const BK_PrecPolicyFloatFull_type BK_PrecPolicyFloatFull
Definition StringConversions.h:111
boost::spirit::karma::real_generator< float, BK_PrecPolicyFull< float > > BK_PrecPolicyFloatFull_type
Definition StringConversions.h:110
const BK_PrecPolicyLongDoubleShort_type BK_PrecPolicyLongDoubleShort
Definition StringConversions.h:122
boost::spirit::karma::real_generator< long double, BK_PrecPolicyShort< long double > > BK_PrecPolicyLongDoubleShort_type
Definition StringConversions.h:121
void append(const T &i, String &target)
Definition StringConversions.h:133
void appendLowP(float f, String &target)
Definition StringConversions.h:154
String toStringLowP(float f)
low precision (3 fractional digits) conversion to string (Karma default)
Definition StringConversions.h:160
String toString()
Other toString functions (different number of arguments)
Definition StringConversions.h:273
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19