diff --git a/sprout/cstdlib.hpp b/sprout/cstdlib.hpp index 961c26b9..42e5a085 100644 --- a/sprout/cstdlib.hpp +++ b/sprout/cstdlib.hpp @@ -2,7 +2,7 @@ #define SPROUT_CSTDLIB_HPP #include -#include -#include +#include +#include #endif // #ifndef SPROUT_CSTDLIB_HPP diff --git a/sprout/cstdlib/arithmetic.hpp b/sprout/cstdlib/arithmetic.hpp new file mode 100644 index 00000000..7cb35ca9 --- /dev/null +++ b/sprout/cstdlib/arithmetic.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_CSTDLIB_ARITHMETIC_HPP +#define SPROUT_CSTDLIB_ARITHMETIC_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_CSTDLIB_ARITHMETIC_HPP diff --git a/sprout/cstdlib/atoi.hpp b/sprout/cstdlib/atoi.hpp new file mode 100644 index 00000000..d8745310 --- /dev/null +++ b/sprout/cstdlib/atoi.hpp @@ -0,0 +1,20 @@ +#ifndef SPROUT_CSTDLIB_ATOI_HPP +#define SPROUT_CSTDLIB_ATOI_HPP + +#include +#include + +namespace sprout { + // + // atoi + // + inline SPROUT_CONSTEXPR int atoi(char const* str) { + return sprout::decimal_to_int(str); + } + template + inline SPROUT_CONSTEXPR int atoi(Char const* str) { + return sprout::decimal_to_int(str); + } +} // namespace sprout + +#endif // #ifndef SPROUT_CSTDLIB_ATOI_HPP diff --git a/sprout/cstdlib/atol.hpp b/sprout/cstdlib/atol.hpp new file mode 100644 index 00000000..81cbf6bd --- /dev/null +++ b/sprout/cstdlib/atol.hpp @@ -0,0 +1,20 @@ +#ifndef SPROUT_CSTDLIB_ATOL_HPP +#define SPROUT_CSTDLIB_ATOL_HPP + +#include +#include + +namespace sprout { + // + // atol + // + inline SPROUT_CONSTEXPR long atol(char const* str) { + return sprout::decimal_to_int(str); + } + template + inline SPROUT_CONSTEXPR int atol(Char const* str) { + return sprout::decimal_to_int(str); + } +} // namespace sprout + +#endif // #ifndef SPROUT_CSTDLIB_ATOL_HPP diff --git a/sprout/cstdlib/conversion.hpp b/sprout/cstdlib/conversion.hpp new file mode 100644 index 00000000..a4ad07a5 --- /dev/null +++ b/sprout/cstdlib/conversion.hpp @@ -0,0 +1,11 @@ +#ifndef SPROUT_CSTDLIB_CONVERSION_HPP +#define SPROUT_CSTDLIB_CONVERSION_HPP + +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_CSTDLIB_CONVERSION_HPP diff --git a/sprout/cstdlib/decimal_to_int.hpp b/sprout/cstdlib/decimal_to_int.hpp new file mode 100644 index 00000000..7ef60f27 --- /dev/null +++ b/sprout/cstdlib/decimal_to_int.hpp @@ -0,0 +1,51 @@ +#ifndef SPROUT_CSTDLIB_DECIMAL_TO_INT_HPP +#define SPROUT_CSTDLIB_DECIMAL_TO_INT_HPP + +#include +#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 decimal_to_int_impl(CStrIterator str, IntType val, bool negative) { + return !sprout::ascii::isdigit(*str) + ? negative ? -val : val + : val > (std::numeric_limits::max() - (*str - static_cast::value_type>('0')) - (negative ? 1 : 0)) / 10 + ? (negative ? std::numeric_limits::min() : std::numeric_limits::max()) + : sprout::detail::decimal_to_int_impl( + sprout::next(str), + val * 10 + (*str - static_cast::value_type>('0')), + negative + ) + ; + } + template + inline SPROUT_CONSTEXPR IntType decimal_to_int(CStrIterator str) { + return sprout::ascii::isspace(*str) + ? sprout::detail::decimal_to_int(sprout::next(str)) + : *str == static_cast::value_type>('-') + ? sprout::detail::decimal_to_int_impl(sprout::next(str), IntType(), true) + : *str == static_cast::value_type>('+') + ? sprout::detail::decimal_to_int_impl(sprout::next(str), IntType(), false) + : sprout::detail::decimal_to_int_impl(str, IntType(), false) + ; + } + } // namespace detail + + // + // decimal_to_int + // + template::value>::type = sprout::enabler> + inline SPROUT_CONSTEXPR IntType decimal_to_int(Char const* str) { + return sprout::detail::decimal_to_int(str); + } +} // namespace sprout + +#endif // #ifndef SPROUT_CSTDLIB_DECIMAL_TO_INT_HPP diff --git a/sprout/cstdlib/str_to_int.hpp b/sprout/cstdlib/str_to_int.hpp new file mode 100644 index 00000000..3f899b51 --- /dev/null +++ b/sprout/cstdlib/str_to_int.hpp @@ -0,0 +1,95 @@ +#ifndef SPROUT_CSTDLIB_STR_TO_INT_HPP +#define SPROUT_CSTDLIB_STR_TO_INT_HPP + +#include +#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 ? -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), + negative + ) + : sprout::detail::str_to_int_impl_1( + sprout::next(str), + base ? base : 8, + IntType(), + sprout::detail::char_to_int(*sprout::next(str), base), + negative + ) + : sprout::detail::str_to_int_impl_1( + str, + base ? base : 10, + IntType(), + sprout::detail::char_to_int(*str, base), + negative + ) + ; + } + template + inline SPROUT_CONSTEXPR IntType 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) { + return !endptr ? sprout::detail::str_to_int(str, base) + : std::strtol(str, endptr, base) + ; + } + } // namespace detail + + // + // str_to_int + // + template::value>::type = sprout::enabler> + inline SPROUT_CONSTEXPR IntType str_to_int(Char const* str, Char** endptr, int base = 10) { + return sprout::detail::str_to_int(str, endptr, base); + } + template::value>::type = sprout::enabler> + inline SPROUT_CONSTEXPR IntType str_to_int(Char const* str, std::nullptr_t endptr, int base = 10) { + return sprout::detail::str_to_int(str, base); + } + template::value>::type = sprout::enabler> + inline SPROUT_CONSTEXPR IntType 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 diff --git a/sprout/cstdlib/strtol.hpp b/sprout/cstdlib/strtol.hpp new file mode 100644 index 00000000..3ac23064 --- /dev/null +++ b/sprout/cstdlib/strtol.hpp @@ -0,0 +1,29 @@ +#ifndef SPROUT_CSTDLIB_STRTOL_HPP +#define SPROUT_CSTDLIB_STRTOL_HPP + +#include +#include +#include + +namespace sprout { + // + // strtol + // + inline SPROUT_CONSTEXPR long strtol(char const* str, char** endptr, int base = 10){ + return sprout::str_to_int(str, endptr, base); + } + template + inline SPROUT_CONSTEXPR long strtol(Char const* str, Char** endptr, int base = 10){ + return sprout::str_to_int(str, endptr, base); + } + template + inline SPROUT_CONSTEXPR long strtol(Char const* str, std::nullptr_t endptr, int base = 10){ + return sprout::str_to_int(str, base); + } + template + inline SPROUT_CONSTEXPR long strtol(Char const* str, int base = 10){ + return sprout::str_to_int(str, base); + } +} // namespace sprout + +#endif // #ifndef SPROUT_CSTDLIB_STRTOL_HPP diff --git a/sprout/detail/char_conversion.hpp b/sprout/detail/char_conversion.hpp new file mode 100644 index 00000000..de4b64d6 --- /dev/null +++ b/sprout/detail/char_conversion.hpp @@ -0,0 +1,41 @@ +#ifndef SPROUT_DETAIL_CHAR_CONVERSION_HPP +#define SPROUT_DETAIL_CHAR_CONVERSION_HPP + +#include +#include +#include + +namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR Elem int_to_char(IntType val, std::size_t base){ + return val >= 0 && val < 10 ? static_cast('0') + val + : val >= 10 && val < base ? static_cast('a') + (val - 10) + : throw std::invalid_argument("value out of bounds") + ; + } + template + inline SPROUT_CONSTEXPR Elem int_to_char(IntType val){ + return val >= 0 && val < 10 ? static_cast('0') + val + : throw std::invalid_argument("value out of bounds") + ; + } + + template + inline SPROUT_CONSTEXPR IntType char_to_int(Elem c, std::size_t base){ + return c >= static_cast('0') && c <= static_cast('9') ? c - static_cast('0') + : c >= static_cast('a') && c <= static_cast('a' + (base - 11)) ? c - static_cast('a') + 10 + : c >= static_cast('A') && c <= static_cast('A' + (base - 11)) ? c - static_cast('A') + 10 + : static_cast(-1) + ; + } + template + inline SPROUT_CONSTEXPR IntType char_to_int(Elem c){ + return c >= static_cast('0') && c <= static_cast('9') ? c - static_cast('0') + : static_cast(-1) + ; + } + } // namespace detail +} // namespace sprout + +#endif // #ifndef SPROUT_DETAIL_CHAR_CONVERSION_HPP diff --git a/sprout/detail/param_at.hpp b/sprout/detail/param_at.hpp index 4e3551dc..27b33bc1 100644 --- a/sprout/detail/param_at.hpp +++ b/sprout/detail/param_at.hpp @@ -6,32 +6,32 @@ #include namespace sprout { - namespace detail { - template - inline SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Values) == 0, - R - >::type param_at( - std::size_t n, - T const& v, - Values const&... values - ) - { - return v; - } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Values) != 0, - R - >::type param_at( - std::size_t n, - T const& v, - Values const&... values - ) - { - return n == 0 ? v : sprout::detail::param_at(n - 1, values...); - } - } // namespace detail + namespace detail { + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Values) == 0, + R + >::type param_at( + std::size_t n, + T const& v, + Values const&... values + ) + { + return v; + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Values) != 0, + R + >::type param_at( + std::size_t n, + T const& v, + Values const&... values + ) + { + return n == 0 ? v : sprout::detail::param_at(n - 1, values...); + } + } // namespace detail } // namespace sprout #endif // #ifndef SPROUT_DETAIL_PARAM_AT_HPP diff --git a/sprout/string/to_string.hpp b/sprout/string/to_string.hpp index 61cdace5..edb8c748 100644 --- a/sprout/string/to_string.hpp +++ b/sprout/string/to_string.hpp @@ -2,39 +2,16 @@ #define SPROUT_STRING_TO_STRING_HPP #include -#include #include +#include #include #include #include #include +#include namespace sprout { namespace detail { - template< - typename Elem, - std::size_t Base, - typename IntType, - typename sprout::enabler_if<(Base < 10)>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR Elem int_to_char(IntType val){ - return val >= 0 && val < 10 ? static_cast('0') + val - : throw std::invalid_argument("value out of bounds") - ; - } - template< - typename Elem, - std::size_t Base, - typename IntType, - typename sprout::enabler_if<(Base >= 10 && Base < 36)>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR Elem int_to_char(IntType val){ - return val >= 0 && val < 10 ? static_cast('0') + val - : val >= 10 && val < 36 ? static_cast('a') + (val - 10) - : throw std::invalid_argument("value out of bounds") - ; - } - template< typename Elem, std::size_t Base, @@ -64,7 +41,7 @@ namespace sprout { : sprout::detail::int_to_string_impl_1( val / Base, negative, - sprout::detail::int_to_char(val % Base), + sprout::detail::int_to_char(val % Base, Base), args... ) ; @@ -102,7 +79,7 @@ namespace sprout { ? sprout::make_string_as(args...) : sprout::detail::uint_to_string_impl_1( val / Base, - sprout::detail::int_to_char(val % Base), + sprout::detail::int_to_char(val % Base, Base), args... ) ;