Goby3  3.1.4
2024.02.22
as.h
Go to the documentation of this file.
1 // Copyright 2010-2021:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 //
8 //
9 // This file is part of the Goby Underwater Autonomy Project Libraries
10 // ("The Goby Libraries").
11 //
12 // The Goby Libraries are free software: you can redistribute them and/or modify
13 // them under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation, either version 2.1 of the License, or
15 // (at your option) any later version.
16 //
17 // The Goby Libraries are distributed in the hope that they will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef GOBY_UTIL_AS_H
26 #define GOBY_UTIL_AS_H
27 
28 #include <iomanip>
29 #include <iostream>
30 #include <limits>
31 #include <sstream>
32 #include <string>
33 #include <vector>
34 
35 #include <boost/algorithm/string.hpp>
36 #include <boost/lexical_cast.hpp>
37 #include <boost/mpl/and.hpp>
38 #include <boost/mpl/logical.hpp>
39 #include <boost/numeric/conversion/cast.hpp>
40 #include <boost/type_traits.hpp>
41 #include <boost/utility.hpp>
42 
43 namespace goby
44 {
45 namespace util
46 {
48 
49 
50 template <typename To>
51 typename boost::enable_if<boost::is_arithmetic<To>, To>::type
52 _as_from_string(const std::string& from)
53 {
54  try
55  {
56  return boost::lexical_cast<To>(from);
57  }
58  catch (boost::bad_lexical_cast&)
59  {
60  // return NaN or maximum value supported by the type
61  return std::numeric_limits<To>::has_quiet_NaN ? std::numeric_limits<To>::quiet_NaN()
62  : std::numeric_limits<To>::max();
63  }
64 }
65 
66 // only works properly for enums with a defined 0 value
67 template <typename To>
68 typename boost::enable_if<boost::is_enum<To>, To>::type _as_from_string(const std::string& from)
69 {
70  try
71  {
72  return static_cast<To>(boost::lexical_cast<int>(from));
73  }
74  catch (boost::bad_lexical_cast&)
75  {
76  return static_cast<To>(0);
77  }
78 }
79 
80 template <typename To>
81 typename boost::enable_if<boost::is_class<To>, To>::type _as_from_string(const std::string& from)
82 {
83  try
84  {
85  return boost::lexical_cast<To>(from);
86  }
87  catch (boost::bad_lexical_cast&)
88  {
89  return To();
90  }
91 }
92 
93 template <> inline bool _as_from_string<bool>(const std::string& from)
94 {
95  return (boost::iequals(from, "true") || boost::iequals(from, "1"));
96 }
97 
98 template <> inline std::string _as_from_string<std::string>(const std::string& from)
99 {
100  return from;
101 }
102 
103 template <typename To, typename From> std::string _as_to_string(const From& from)
104 {
105  try
106  {
107  return boost::lexical_cast<std::string>(from);
108  }
109  catch (boost::bad_lexical_cast&)
110  {
111  return std::string();
112  }
113 }
114 
116 template <> inline std::string _as_to_string<std::string, bool>(const bool& from)
117 {
118  return from ? "true" : "false";
119 }
120 
121 template <> inline std::string _as_to_string<std::string, std::string>(const std::string& from)
122 {
123  return from;
124 }
125 
126 template <typename To, typename From>
127 typename boost::disable_if<boost::is_same<To, From>, To>::type _as_numeric(const From& from)
128 {
129  try
130  {
131  return boost::numeric_cast<To>(from);
132  }
133  catch (boost::bad_numeric_cast&)
134  {
135  // return NaN or maximum value supported by the type
136  return std::numeric_limits<To>::has_quiet_NaN ? std::numeric_limits<To>::quiet_NaN()
137  : std::numeric_limits<To>::max();
138  }
139 }
140 
141 template <typename To, typename From>
142 typename boost::enable_if<boost::is_same<To, From>, To>::type _as_numeric(const From& from)
143 {
144  return from;
145 }
146 
147 template <typename To> To as(const std::string& from) { return _as_from_string<To>(from); }
148 
149 template <typename To, typename From>
150 typename boost::enable_if<boost::is_same<To, std::string>, To>::type as(const From& from)
151 {
152  return _as_to_string<To, From>(from);
153 }
154 
155 template <typename To, typename From>
156 typename boost::enable_if<boost::mpl::and_<boost::is_arithmetic<To>, boost::is_arithmetic<From> >,
157  To>::type
158 as(const From& from)
159 {
160  return _as_numeric<To, From>(from);
161 }
162 
163 // not much better we can do for enums than static cast them ...
164 template <typename To, typename From>
165 typename boost::enable_if<boost::mpl::and_<boost::is_enum<To>, boost::is_arithmetic<From> >,
166  To>::type
167 as(const From& from)
168 {
169  return static_cast<To>(from);
170 }
171 
173 {
177 };
178 
179 template <typename To, typename From>
180 To as(const From& from, int precision, FloatRepresentation rep = FLOAT_DEFAULT)
181 {
182  return as<To>(from);
183 }
184 
185 template <>
186 inline std::string as<std::string, double>(const double& from, int precision,
188 {
189  std::stringstream out;
190  switch (rep)
191  {
192  case FLOAT_DEFAULT: break;
193 
194  case FLOAT_FIXED: out << std::fixed; break;
195  case FLOAT_SCIENTIFIC: out << std::scientific; break;
196  }
197 
198  out << std::setprecision(precision) << from;
199  return out.str();
200 }
201 
202 template <>
203 inline std::string as<std::string, float>(const float& from, int precision, FloatRepresentation rep)
204 {
205  std::stringstream out;
206  switch (rep)
207  {
208  case FLOAT_DEFAULT: break;
209 
210  case FLOAT_FIXED: out << std::fixed; break;
211  case FLOAT_SCIENTIFIC: out << std::scientific; break;
212  }
213 
214  out << std::setprecision(precision) << from;
215  return out.str();
216 }
217 
218 } // namespace util
219 } // namespace goby
220 #endif
goby::util::FloatRepresentation
FloatRepresentation
Definition: as.h:172
goby::util::_as_to_string
std::string _as_to_string(const From &from)
Definition: as.h:103
goby::util::as
boost::enable_if< boost::mpl::and_< boost::is_same< To, double >, boost::is_same< From, boost::posix_time::ptime > >, To >::type as(const From &from)
Definition: legacy.h:74
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
goby::util::_as_from_string< bool >
bool _as_from_string< bool >(const std::string &from)
Definition: as.h:93
jwt::json::type
type
Generic JSON types used in JWTs.
Definition: jwt.h:2071
goby::util::_as_numeric
boost::disable_if< boost::is_same< To, From >, To >::type _as_numeric(const From &from)
Definition: as.h:127
goby::util::_as_from_string
boost::enable_if< boost::is_arithmetic< To >, To >::type _as_from_string(const std::string &from)
Definition: as.h:52
goby::util::FLOAT_FIXED
@ FLOAT_FIXED
Definition: as.h:175
goby::util::FLOAT_SCIENTIFIC
@ FLOAT_SCIENTIFIC
Definition: as.h:176
goby::util::FLOAT_DEFAULT
@ FLOAT_DEFAULT
Definition: as.h:174