• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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