// Boost.Geometry // Copyright (c) 2018-2020, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP #define BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP #include #include #include #include #include #include namespace boost { namespace geometry { class bad_str_cast : public geometry::exception { virtual char const* what() const throw() { return "Unable to convert from string."; } }; #ifndef DOXYGEN_NO_DETAIL namespace detail { template < typename T, bool IsIntegral = std::is_integral::value, bool IsSigned = std::is_signed::value > struct str_cast_traits_strtox { static inline T apply(const char *str, char **str_end) { return strtod(str, str_end); } }; template struct str_cast_traits_strtox { static inline T apply(const char *str, char **str_end) { return strtol(str, str_end, 0); } }; template struct str_cast_traits_strtox { static inline T apply(const char *str, char **str_end) { return strtoul(str, str_end, 0); } }; template struct str_cast_traits_strtox { static inline T apply(const char *str, char **str_end) { return strtod(str, str_end); } }; // Assuming a compiler supporting r-value references // supports long long and strtoll, strtoull, strtof, strtold // If it's MSVC enable in MSVC++ 12.0 aka Visual Studio 2013 // TODO: in MSVC-11.0 _strtoi64() intrinsic could be used #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined(_MSC_VER) || (_MSC_VER >= 1800)) template <> struct str_cast_traits_strtox { static inline long long apply(const char *str, char **str_end) { return strtoll(str, str_end, 0); } }; template <> struct str_cast_traits_strtox { static inline unsigned long long apply(const char *str, char **str_end) { return strtoull(str, str_end, 0); } }; template <> struct str_cast_traits_strtox { static inline float apply(const char *str, char **str_end) { return strtof(str, str_end); } }; template <> struct str_cast_traits_strtox { static inline long double apply(const char *str, char **str_end) { return strtold(str, str_end); } }; #endif // C++11 strtox supported template struct str_cast_traits_generic { static inline T apply(const char *str) { char * str_end = (char*)(void*)str; T res = str_cast_traits_strtox < typename boost::remove_cv::type >::apply(str, &str_end); if (str_end == str) { BOOST_THROW_EXCEPTION( bad_str_cast() ); } return res; } }; } // namespace detail #endif // DOXYGEN_NO_DETAIL template struct str_cast_traits { template static inline T apply(String const& str) { return detail::str_cast_traits_generic::apply(str.c_str()); } }; template inline T str_cast(String const& str) { return str_cast_traits::apply(str); } }} // namespace boost::geometry #endif // BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP