OpenMS  2.8.0
StringConversions.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2021.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Timo Sachsenberg, Chris Bielow $
32 // $Authors: Marc Sturm, Stephan Aiche, Chris Bielow $
33 // --------------------------------------------------------------------------
34 
35 #pragma once
36 
37 #include <OpenMS/CONCEPT/Types.h>
42 
43 #include <boost/spirit/include/qi.hpp>
44 #include <boost/spirit/include/karma.hpp>
45 #include <boost/type_traits.hpp>
46 
47 #include <string>
48 #include <vector>
49 
50 
51 namespace OpenMS
52 {
53  class String;
54 
55  namespace StringConversions
56  {
57 
58  // Karma full precision float policy
59  template <typename T>
60  class BK_PrecPolicy : public boost::spirit::karma::real_policies<T>
61  {
62  typedef boost::spirit::karma::real_policies<T> base_policy_type;
63  public:
64  static unsigned precision(T /*n*/)
65  {
66  /* The following would be the only way for a lossless double-string-double
67  * roundtrip but:
68  * a) We only care about speed
69  * b) Many tests have to be changed
70  * c) In the end boost::karma is bugged and hard limits the fractional digits
71  * even though you have leading zeros (basically forcing scientific notation)
72  * for full precision https://github.com/boostorg/spirit/issues/585
73  if (BK_PrecPolicy::floatfield(n))
74  {
75  T abs_n = boost::spirit::traits::get_absolute_value(n);
76  if (abs_n >= 1)
77  {
78  return std::numeric_limits<T>::max_digits10 - (floor(log10(abs_n)) + 1);
79  }
80  else
81  {
82  return std::numeric_limits<T>::max_digits10 - (floor(log10(abs_n)));
83  }
84  }
85  else
86  {
87  return std::numeric_limits<T>::max_digits10 - 1;
88  }
89  */
90  return writtenDigits<T>();
91  }
92 
93  // we want the numbers always to be in scientific format
94  static unsigned floatfield(T n)
95  {
96  if (boost::spirit::traits::test_zero(n))
97  return base_policy_type::fmtflags::fixed;
98 
99  T abs_n = boost::spirit::traits::get_absolute_value(n);
100  // this is due to a bug in downstream thirdparty tools that only can read
101  // up to 19 digits. https://github.com/OpenMS/OpenMS/issues/4627
102  return (abs_n >= 1e4 || abs_n < 1e-2)
103  ? base_policy_type::fmtflags::scientific : base_policy_type::fmtflags::fixed;
104  }
105  };
106  typedef boost::spirit::karma::real_generator<float, BK_PrecPolicy<float> > BK_PrecPolicyFloat_type;
108  typedef boost::spirit::karma::real_generator<double, BK_PrecPolicy<double> > BK_PrecPolicyDouble_type;
110  typedef boost::spirit::karma::real_generator<long double, BK_PrecPolicy<long double> > BK_PrecPolicyLongDouble_type;
112 
113  // toString functions (single argument)
114 
117  template <typename T>
118  inline void append(const T& i, String& target)
119  {
120  std::back_insert_iterator<std::string> sink(target);
121  boost::spirit::karma::generate(sink, i);
122  }
123 
125  template <typename T>
126  inline String toString(const T& i)
127  {
128  //std::stringstream s;
129  //s << i;
130  //return s.str();
131  String str;
132  append(i, str);
133  return str;
134  }
135 
136 
139  inline void appendLowP(float f, String& target)
140  {
141  std::back_insert_iterator<std::string> sink(target);
142  boost::spirit::karma::generate(sink, f);
143  }
145  inline String toStringLowP(float f)
146  {
147  String str;
148  appendLowP(f, str);
149  return str;
150  }
151 
152 
155  inline void appendLowP(double d, String& target)
156  {
157  std::back_insert_iterator<std::string> sink(target);
158  boost::spirit::karma::generate(sink, d);
159  }
161  inline String toStringLowP(double d)
162  {
163  String str;
164  appendLowP(d, str);
165  return str;
166  }
167 
168 
170  inline void appendLowP(long double ld, String& target)
171  {
172  std::back_insert_iterator<std::string> sink(target);
173  boost::spirit::karma::generate(sink, ld);
174  }
176  inline String toStringLowP(long double ld)
177  {
178  String str;
179  appendLowP(ld, str);
180  return str;
181  }
182 
183 
184 
186  inline void append(float f, String& target)
187  {
188  std::back_insert_iterator<std::string> sink(target);
189  boost::spirit::karma::generate(sink, BK_PrecPolicyFloat, f);
190  }
192  inline String toString(float f)
193  {
194  String str;
195  append(f, str);
196  return str;
197  }
198 
199 
200 
202  inline void append(double d, String& target)
203  {
204  std::back_insert_iterator<std::string> sink(target);
205  boost::spirit::karma::generate(sink, BK_PrecPolicyDouble, d);
206  }
208  inline String toString(double d)
209  {
210  String str;
211  append(d, str);
212  return str;
213  }
214 
215 
217  inline void append(long double ld, String& target)
218  {
219  std::back_insert_iterator<std::string> sink(target);
220  boost::spirit::karma::generate(sink, BK_PrecPolicyLongDouble, ld);
221  }
223  inline String toString(long double ld)
224  {
225  String str;
226  append(ld, str);
227  return str;
228  }
229 
230 
231  inline void append(const DataValue& d, bool full_precision, String& target)
232  {
233  target += d.toString(full_precision);
234  }
235  inline String toString(const DataValue& d, bool full_precision)
236  {
237  return d.toString(full_precision);
238  }
239 
240 
241 
242  inline String toString(const char c)
243  {
244  return std::string(1, c);
245  }
246 
247  inline String toString(const std::string& s)
248  {
249  return s;
250  }
251 
252  inline String toString(const char* s)
253  {
254  return std::string(s);
255  }
256 
258  inline String toString()
259  {
260  return String();
261  }
262 
263  inline String toString(const char* s, size_t length)
264  {
265  String res;
266  size_t count = 0;
267  while (count < length)
268  {
269  res += *(s + count);
270  ++count;
271  }
272  return res;
273  }
274  }
275 
276 } // namespace OPENMS
277 
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition: DataValue.h:59
String toString(bool full_precision=true) const
Conversion to String full_precision Controls number of fractional digits for all double types or list...
Definition: StringConversions.h:61
static unsigned precision(T)
Definition: StringConversions.h:64
static unsigned floatfield(T n)
Definition: StringConversions.h:94
boost::spirit::karma::real_policies< T > base_policy_type
Definition: StringConversions.h:62
A more convenient string class.
Definition: String.h:60
const double c
Definition: Constants.h:209
boost::spirit::karma::real_generator< long double, BK_PrecPolicy< long double > > BK_PrecPolicyLongDouble_type
Definition: StringConversions.h:110
boost::spirit::karma::real_generator< float, BK_PrecPolicy< float > > BK_PrecPolicyFloat_type
Definition: StringConversions.h:106
const BK_PrecPolicyLongDouble_type BK_PrecPolicyLongDouble
Definition: StringConversions.h:111
String toStringLowP(float f)
low precision (3 fractional digits) conversion to string (Karma default)
Definition: StringConversions.h:145
void appendLowP(float f, String &target)
Definition: StringConversions.h:139
const BK_PrecPolicyDouble_type BK_PrecPolicyDouble
Definition: StringConversions.h:109
String toString(const T &i)
fallback template for general purpose using Boost::Karma; more specializations below
Definition: StringConversions.h:126
void append(const T &i, String &target)
Definition: StringConversions.h:118
const BK_PrecPolicyFloat_type BK_PrecPolicyFloat
Definition: StringConversions.h:107
boost::spirit::karma::real_generator< double, BK_PrecPolicy< double > > BK_PrecPolicyDouble_type
Definition: StringConversions.h:108
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47