1 // Boost.Geometry
2
3 // Copyright (c) 2018, Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
5
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9
10 #ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP
11 #define BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP
12
13 #include <boost/config.hpp>
14 #include <boost/geometry/core/exception.hpp>
15 #include <boost/throw_exception.hpp>
16 #include <boost/type_traits/is_integral.hpp>
17 #include <boost/type_traits/is_signed.hpp>
18
19 #include <cstdlib>
20 #include <string>
21
22 namespace boost { namespace geometry
23 {
24
25 class bad_str_cast : public geometry::exception
26 {
what() const27 virtual char const* what() const throw()
28 {
29 return "Unable to convert from string.";
30 }
31 };
32
33 #ifndef DOXYGEN_NO_DETAIL
34 namespace detail
35 {
36
37 template
38 <
39 typename T,
40 bool IsIntegral = boost::is_integral<T>::value,
41 bool IsSigned = boost::is_signed<T>::value
42 >
43 struct str_cast_traits_strtox
44 {
applyboost::geometry::detail::str_cast_traits_strtox45 static inline T apply(const char *str, char **str_end)
46 {
47 return strtod(str, str_end);
48 }
49 };
50
51 template <typename T>
52 struct str_cast_traits_strtox<T, true, true>
53 {
applyboost::geometry::detail::str_cast_traits_strtox54 static inline T apply(const char *str, char **str_end)
55 {
56 return strtol(str, str_end, 0);
57 }
58 };
59
60 template <typename T>
61 struct str_cast_traits_strtox<T, true, false>
62 {
applyboost::geometry::detail::str_cast_traits_strtox63 static inline T apply(const char *str, char **str_end)
64 {
65 return strtoul(str, str_end, 0);
66 }
67 };
68
69 template <typename T>
70 struct str_cast_traits_strtox<T, false, false>
71 {
applyboost::geometry::detail::str_cast_traits_strtox72 static inline T apply(const char *str, char **str_end)
73 {
74 return strtod(str, str_end);
75 }
76 };
77
78 // Assuming a compiler supporting r-value references
79 // supports long long and strtoll, strtoull, strtof, strtold
80 // If it's MSVC enable in MSVC++ 12.0 aka Visual Studio 2013
81 // TODO: in MSVC-11.0 _strtoi64() intrinsic could be used
82 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined(_MSC_VER) || (_MSC_VER >= 1800))
83 template <>
84 struct str_cast_traits_strtox<long long, true, true>
85 {
applyboost::geometry::detail::str_cast_traits_strtox86 static inline long long apply(const char *str, char **str_end)
87 {
88 return strtoll(str, str_end, 0);
89 }
90 };
91
92 template <>
93 struct str_cast_traits_strtox<unsigned long long, true, false>
94 {
applyboost::geometry::detail::str_cast_traits_strtox95 static inline unsigned long long apply(const char *str, char **str_end)
96 {
97 return strtoull(str, str_end, 0);
98 }
99 };
100
101 template <>
102 struct str_cast_traits_strtox<float, false, false>
103 {
applyboost::geometry::detail::str_cast_traits_strtox104 static inline float apply(const char *str, char **str_end)
105 {
106 return strtof(str, str_end);
107 }
108 };
109
110 template <>
111 struct str_cast_traits_strtox<long double, false, false>
112 {
applyboost::geometry::detail::str_cast_traits_strtox113 static inline long double apply(const char *str, char **str_end)
114 {
115 return strtold(str, str_end);
116 }
117 };
118 #endif // C++11 strtox supported
119
120 template <typename T>
121 struct str_cast_traits_generic
122 {
applyboost::geometry::detail::str_cast_traits_generic123 static inline T apply(const char *str)
124 {
125 char * str_end = (char*)(void*)str;
126 T res = str_cast_traits_strtox
127 <
128 typename boost::remove_cv<T>::type
129 >::apply(str, &str_end);
130 if (str_end == str)
131 {
132 BOOST_THROW_EXCEPTION( bad_str_cast() );
133 }
134 return res;
135 }
136 };
137
138 } // namespace detail
139 #endif // DOXYGEN_NO_DETAIL
140
141 template <typename T>
142 struct str_cast_traits
143 {
144 template <typename String>
applyboost::geometry::str_cast_traits145 static inline T apply(String const& str)
146 {
147 return detail::str_cast_traits_generic<T>::apply(str.c_str());
148 }
149 };
150
151 template <typename T, typename String>
str_cast(String const & str)152 inline T str_cast(String const& str)
153 {
154 return str_cast_traits<T>::apply(str);
155 }
156
157
158 }} // namespace boost::geometry
159
160 #endif // BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP
161