#ifndef SPROUT_CSTDLIB_STR_TO_INT_HPP #define SPROUT_CSTDLIB_STR_TO_INT_HPP #include #include #if !defined(_MSC_VER) # include #endif #include #include #include #include #include #include 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(CStrIterator str, int base, IntType val, IntType x, bool negative) { return x == static_cast(-1) ? (negative ? -1 * val : val) : val > (std::numeric_limits::max() - x - (negative ? 1 : 0)) / base ? (negative ? std::numeric_limits::min() : std::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(CStrIterator str, int base, bool negative) { return *str == static_cast::value_type>('0') ? *sprout::next(str) == static_cast::value_type>('x') || *sprout::next(str) == static_cast::value_type>('X') ? 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< std::is_unsigned::value, IntType >::type str_to_int(CStrIterator str, int base) { return sprout::ascii::isspace(*str) ? sprout::detail::str_to_int(sprout::next(str), base) : *str == static_cast::value_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< std::is_signed::value, IntType >::type str_to_int(CStrIterator str, int base) { return sprout::ascii::isspace(*str) ? sprout::detail::str_to_int(sprout::next(str), base) : *str == static_cast::value_type>('-') ? sprout::detail::str_to_int_impl(sprout::next(str), base, true) : *str == static_cast::value_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(CStrIterator str, CharPtr* endptr, int base) { #if defined(_MSC_VER) return !endptr ? sprout::detail::str_to_int(str, base) : std::is_signed::value ? static_cast(std::strtol(&*str, endptr, base)) : static_cast(std::strtoul(&*str, endptr, base)) ; #else return !endptr ? sprout::detail::str_to_int(str, base) : std::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