/*============================================================================= Copyright (c) 2011-2017 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under 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 SPROUT_CSTDLIB_STR_TO_INT_HPP #define SPROUT_CSTDLIB_STR_TO_INT_HPP #include #include #include #include #include #include #include #include #include #include #include #if !defined(_MSC_VER) # include #endif namespace sprout { namespace detail { // Copyright (c) 2011 osyo-manga : http://d.hatena.ne.jp/osyo-manga/ template inline SPROUT_CONSTEXPR IntType str_to_int_impl_1(NullTerminatedIterator const& str, int base, IntType val, IntType x, bool negative) { return x == static_cast(-1) ? (negative ? -1 * val : val) : val > (sprout::numeric_limits::max() - x - (negative ? 1 : 0)) / base ? (negative ? sprout::numeric_limits::min() : sprout::numeric_limits::max()) : sprout::detail::str_to_int_impl_1( sprout::next(str), base, val * base + x, sprout::detail::char_to_int(*sprout::next(str), base), negative ) ; } template inline SPROUT_CONSTEXPR IntType str_to_int_impl(NullTerminatedIterator const& str, int base, bool negative) { typedef typename std::iterator_traits::value_type char_type; return *str == SPROUT_CHAR_LITERAL('0', char_type) ? *sprout::next(str) == SPROUT_CHAR_LITERAL('x', char_type) || *sprout::next(str) == SPROUT_CHAR_LITERAL('X', char_type) ? sprout::detail::str_to_int_impl_1( sprout::next(str, 2), base ? base : 16, IntType(), sprout::detail::char_to_int(*sprout::next(str, 2), base ? base : 16), negative ) : sprout::detail::str_to_int_impl_1( sprout::next(str), base ? base : 8, IntType(), sprout::detail::char_to_int(*sprout::next(str), base ? base : 8), negative ) : sprout::detail::str_to_int_impl_1( str, base ? base : 10, IntType(), sprout::detail::char_to_int(*str, base ? base : 10), negative ) ; } template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::is_unsigned::value, IntType >::type str_to_int(NullTerminatedIterator const& str, int base) { typedef typename std::iterator_traits::value_type char_type; return sprout::ascii::isspace(*str) ? sprout::detail::str_to_int(sprout::next(str), base) : *str == SPROUT_CHAR_LITERAL('+', char_type) ? sprout::detail::str_to_int_impl(sprout::next(str), base, false) : sprout::detail::str_to_int_impl(str, base, false) ; } template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::is_signed::value, IntType >::type str_to_int(NullTerminatedIterator const& str, int base) { typedef typename std::iterator_traits::value_type char_type; return sprout::ascii::isspace(*str) ? sprout::detail::str_to_int(sprout::next(str), base) : *str == SPROUT_CHAR_LITERAL('-', char_type) ? sprout::detail::str_to_int_impl(sprout::next(str), base, true) : *str == SPROUT_CHAR_LITERAL('+', char_type) ? sprout::detail::str_to_int_impl(sprout::next(str), base, false) : sprout::detail::str_to_int_impl(str, base, false) ; } template inline SPROUT_CONSTEXPR IntType str_to_int(NullTerminatedIterator const& str, CharPtr* endptr, int base) { return !endptr ? sprout::detail::str_to_int(str, base) #if defined(_MSC_VER) : sprout::is_signed::value ? static_cast(std::strtol(&*str, endptr, base)) : static_cast(std::strtoul(&*str, endptr, base)) #elif defined(__MINGW32__) : sprout::is_signed::value ? sizeof(IntType) <= sizeof(long) ? static_cast(std::strtol(&*str, endptr, base)) : sizeof(IntType) <= sizeof(long long) ? static_cast(::strtoll(&*str, endptr, base)) : static_cast(std::strtoimax(&*str, endptr, base)) : sizeof(IntType) <= sizeof(unsigned long) ? static_cast(std::strtoul(&*str, endptr, base)) : sizeof(IntType) <= sizeof(unsigned long long) ? static_cast(::strtoull(&*str, endptr, base)) : static_cast(std::strtoumax(&*str, endptr, base)) #else : sprout::is_signed::value ? sizeof(IntType) <= sizeof(long) ? static_cast(std::strtol(&*str, endptr, base)) : sizeof(IntType) <= sizeof(long long) ? static_cast(std::strtoll(&*str, endptr, base)) : static_cast(std::strtoimax(&*str, endptr, base)) : sizeof(IntType) <= sizeof(unsigned long) ? static_cast(std::strtoul(&*str, endptr, base)) : sizeof(IntType) <= sizeof(unsigned long long) ? static_cast(std::strtoull(&*str, endptr, base)) : static_cast(std::strtoumax(&*str, endptr, base)) #endif ; } } // namespace detail // // str_to_int // template inline SPROUT_CONSTEXPR typename std::enable_if< std::is_integral::value, IntType >::type str_to_int(Char const* str, Char** endptr, int base = 10) { return sprout::detail::str_to_int(str, endptr, base); } template inline SPROUT_CONSTEXPR typename std::enable_if< std::is_integral::value, IntType >::type str_to_int(Char const* str, std::nullptr_t, int base = 10) { return sprout::detail::str_to_int(str, base); } template inline SPROUT_CONSTEXPR typename std::enable_if< std::is_integral::value, IntType >::type str_to_int(Char const* str, int base = 10) { return sprout::detail::str_to_int(str, base); } } // namespace sprout #endif // #ifndef SPROUT_CSTDLIB_STR_TO_INT_HPP