mirror of
https://github.com/boostorg/geometry.git
synced 2026-01-31 08:12:13 +00:00
[srs] Implement str_cast and use it instead of lexical_cast.
This commit is contained in:
@@ -41,18 +41,12 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#if !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#endif // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
|
||||
#include <boost/geometry/srs/projections/str_cast.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace projections
|
||||
@@ -145,11 +139,7 @@ struct dms_parser
|
||||
template <size_t I>
|
||||
static inline void assign_dms(dms_value& dms, std::string& value, bool& has_value)
|
||||
{
|
||||
#if !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
|
||||
dms.dms[I] = boost::lexical_cast<T>(value.c_str());
|
||||
#else // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
|
||||
dms.dms[I] = std::atof(value.c_str());
|
||||
#endif // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
|
||||
dms.dms[I] = geometry::str_cast<T>(value);
|
||||
dms.has_dms[I] = true;
|
||||
has_value = false;
|
||||
value.clear();
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
@@ -157,12 +156,12 @@ inline void pj_init_units(std::vector<pvalue<T> > const& params,
|
||||
std::size_t const pos = s.find('/');
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
to_meter = lexical_cast<T>(s);
|
||||
to_meter = geometry::str_cast<T>(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
T const numerator = lexical_cast<T>(s.substr(0, pos));
|
||||
T const denominator = lexical_cast<T>(s.substr(pos + 1));
|
||||
T const numerator = geometry::str_cast<T>(s.substr(0, pos));
|
||||
T const denominator = geometry::str_cast<T>(s.substr(pos + 1));
|
||||
if (numerator == 0.0 || denominator == 0.0)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) );
|
||||
@@ -316,8 +315,8 @@ inline parameters<T> pj_init(BGParams const& bg_params, R const& arguments, bool
|
||||
|
||||
dms_parser<T, true> parser;
|
||||
|
||||
// TODO: Handle case when lexical_cast is not used consistently.
|
||||
// This should probably be done in dms_parser.
|
||||
// TODO: Is this try-catch needed?
|
||||
// In other cases the bad_str_cast exception is simply thrown
|
||||
BOOST_TRY
|
||||
{
|
||||
if (value.empty()) {
|
||||
@@ -326,7 +325,7 @@ inline parameters<T> pj_init(BGParams const& bg_params, R const& arguments, bool
|
||||
pin.from_greenwich = parser.apply(value).angle();
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(boost::bad_lexical_cast const&)
|
||||
BOOST_CATCH(geometry::bad_str_cast const&)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_prime_meridian) );
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ inline bool pj_param_i(std::vector<pvalue<T> > const& pl, std::string const& nam
|
||||
typename std::vector<pvalue<T> >::const_iterator it = pj_param_find(pl, name);
|
||||
if (it != pl.end())
|
||||
{
|
||||
par = atoi(it->s.c_str());
|
||||
par = geometry::str_cast<int>(it->s);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -135,7 +135,7 @@ inline bool pj_param_f(std::vector<pvalue<T> > const& pl, std::string const& nam
|
||||
typename std::vector<pvalue<T> >::const_iterator it = pj_param_find(pl, name);
|
||||
if (it != pl.end())
|
||||
{
|
||||
par = atof(it->s.c_str());
|
||||
par = geometry::str_cast<T>(it->s);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
158
include/boost/geometry/srs/projections/str_cast.hpp
Normal file
158
include/boost/geometry/srs/projections/str_cast.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2018, 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 <boost/config.hpp>
|
||||
#include <boost/geometry/core/exception.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
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 = boost::is_integral<T>::value,
|
||||
bool IsSigned = boost::is_signed<T>::value
|
||||
>
|
||||
struct str_cast_traits_strtox
|
||||
{
|
||||
static inline T apply(const char *str, char **str_end)
|
||||
{
|
||||
return strtod(str, str_end);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct str_cast_traits_strtox<T, true, true>
|
||||
{
|
||||
static inline T apply(const char *str, char **str_end)
|
||||
{
|
||||
return strtol(str, str_end, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct str_cast_traits_strtox<T, true, false>
|
||||
{
|
||||
static inline T apply(const char *str, char **str_end)
|
||||
{
|
||||
return strtoul(str, str_end, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct str_cast_traits_strtox<T, false, false>
|
||||
{
|
||||
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
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <>
|
||||
struct str_cast_traits_strtox<long long, true, true>
|
||||
{
|
||||
static inline long long apply(const char *str, char **str_end)
|
||||
{
|
||||
return strtoll(str, str_end, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct str_cast_traits_strtox<unsigned long long, true, false>
|
||||
{
|
||||
static inline unsigned long long apply(const char *str, char **str_end)
|
||||
{
|
||||
return strtoull(str, str_end, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct str_cast_traits_strtox<float, false, false>
|
||||
{
|
||||
static inline float apply(const char *str, char **str_end)
|
||||
{
|
||||
return strtof(str, str_end);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct str_cast_traits_strtox<long double, false, false>
|
||||
{
|
||||
static inline long double apply(const char *str, char **str_end)
|
||||
{
|
||||
return strtold(str, str_end);
|
||||
}
|
||||
};
|
||||
#endif // C++11 strtox supported
|
||||
|
||||
template <typename T>
|
||||
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<T>::type
|
||||
>::apply(str, &str_end);
|
||||
if (str_end == str)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION( bad_str_cast() );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
template <typename T>
|
||||
struct str_cast_traits
|
||||
{
|
||||
template <typename String>
|
||||
static inline T apply(String const& str)
|
||||
{
|
||||
return detail::str_cast_traits_generic<T>::apply(str.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename String>
|
||||
inline T str_cast(String const& str)
|
||||
{
|
||||
return str_cast_traits<T>::apply(str);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP
|
||||
Reference in New Issue
Block a user