diff --git a/sprout/weed/parser/numeric.hpp b/sprout/weed/parser/numeric.hpp index b38c4962..638197eb 100644 --- a/sprout/weed/parser/numeric.hpp +++ b/sprout/weed/parser/numeric.hpp @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include #include #include diff --git a/sprout/weed/parser/numeric/int.hpp b/sprout/weed/parser/numeric/int.hpp new file mode 100644 index 00000000..f830bccd --- /dev/null +++ b/sprout/weed/parser/numeric/int.hpp @@ -0,0 +1,29 @@ +#ifndef SPROUT_WEED_PARSER_NUMERIC_INT_HPP +#define SPROUT_WEED_PARSER_NUMERIC_INT_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace weed { + // + // int_ + // + SPROUT_STATIC_CONSTEXPR auto int_ = sprout::weed::int_p(); + + // + // int8 + // int16 + // int32 + // int64 + // + SPROUT_STATIC_CONSTEXPR auto int8 = sprout::weed::int_p(); + SPROUT_STATIC_CONSTEXPR auto int16 = sprout::weed::int_p(); + SPROUT_STATIC_CONSTEXPR auto int32 = sprout::weed::int_p(); + SPROUT_STATIC_CONSTEXPR auto int64 = sprout::weed::int_p(); + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_PARSER_NUMERIC_INT_HPP diff --git a/sprout/weed/parser/numeric/int_p.hpp b/sprout/weed/parser/numeric/int_p.hpp new file mode 100644 index 00000000..aa6524b4 --- /dev/null +++ b/sprout/weed/parser/numeric/int_p.hpp @@ -0,0 +1,228 @@ +#ifndef SPROUT_WEED_PARSER_NUMERIC_INT_P_HPP +#define SPROUT_WEED_PARSER_NUMERIC_INT_P_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace weed { + // + // int_p + // + template< + typename IntType, + std::size_t Radix = 10, + std::size_t MinDigits = 1, + std::size_t MaxDigits = sprout::integer_digits::value + > + struct int_p + : public sprout::weed::parser_base + { + private: + SPROUT_STATIC_CONSTEXPR std::size_t limit_digits = MaxDigits <= sprout::integer_digits::value + ? MaxDigits + : sprout::integer_digits::value + ; + public: + template + struct attribute { + public: + typedef IntType type; + }; + template + struct result { + public: + typedef sprout::weed::parser_result::type> type; + }; + private: + template + SPROUT_CONSTEXPR typename result::type make_result( + typename result::type const& res, + int sign = 0 + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return res.success() && sign < 0 + ? result_type(true, res.current(), -res.attr()) + : res + ; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + N == limit_digits, + typename result::type + >::type call_1( + Iterator first, + Iterator last, + Iterator temp_first, + IntType t, + std::size_t n, + PResult const& res + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return sprout::tuples::get<1>(res) + ? n < MaxDigits + ? call_0( + sprout::next(first), + last, + temp_first, + static_cast(t * Radix + sprout::tuples::get<0>(res)), + n + ) + : result_type( + true, + sprout::next(first), + static_cast(t * Radix + sprout::tuples::get<0>(res)) + ) + : N < MinDigits + ? result_type(false, temp_first, attribute_type()) + : result_type(true, first, t) + ; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + N != limit_digits, + typename result::type + >::type call_1( + Iterator first, + Iterator last, + Iterator temp_first, + IntType t, + std::size_t n, + PResult const& res + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return sprout::tuples::get<1>(res) + ? call_0( + sprout::next(first), + last, + temp_first, + static_cast(t * Radix + sprout::tuples::get<0>(res)), + n + ) + : N < MinDigits + ? result_type(false, temp_first, attribute_type()) + : result_type(true, first, t) + ; + } + template + SPROUT_CONSTEXPR typename result::type call_0( + Iterator first, + Iterator last, + Iterator temp_first, + IntType t, + std::size_t n + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return first != last + ? call_1( + first, + last, + temp_first, + t, + n + 1, + sprout::weed::detail::from_ndigit(*first) + ) + : N < MinDigits + ? result_type(false, temp_first, attribute_type()) + : result_type(true, first, t) + ; + } + template + SPROUT_CONSTEXPR typename result::type call_i( + Iterator first, + Iterator last, + Iterator temp_first, + PResult const& res + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return sprout::tuples::get<1>(res) + ? call_0<1, Context>( + sprout::next(first), + last, + temp_first, + sprout::tuples::get<0>(res), + 1 + ) + : result_type(false, temp_first, attribute_type()) + ; + } + template + SPROUT_CONSTEXPR typename result::type call( + Iterator first, + Iterator last, + Iterator temp_first, + int sign = 0 + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return first != last + ? make_result( + call_i( + first, + last, + temp_first, + sprout::weed::detail::from_ndigit(*first) + ), + sign + ) + : result_type(false, temp_first, attribute_type()) + ; + } + public: + template + SPROUT_CONSTEXPR typename result::type operator()( + Iterator first, + Iterator last, + Context const& + ) const + { + typedef typename std::iterator_traits::value_type elem_type; + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return first != last + ? *first == elem_type('+') + ? call( + sprout::next(first), + last, + first, + 1 + ) + : *first == elem_type('-') + ? call( + sprout::next(first), + last, + first, + -1 + ) + : call( + first, + last, + first + ) + : result_type(false, first, attribute_type()) + ; + } + }; + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_PARSER_NUMERIC_INT_P_HPP + diff --git a/sprout/weed/parser/numeric/uint.hpp b/sprout/weed/parser/numeric/uint.hpp index 2bb583ad..ef78321e 100644 --- a/sprout/weed/parser/numeric/uint.hpp +++ b/sprout/weed/parser/numeric/uint.hpp @@ -9,9 +9,9 @@ namespace sprout { namespace weed { // - // uint + // uint_ // - SPROUT_STATIC_CONSTEXPR auto uint = sprout::weed::uint_p(); + SPROUT_STATIC_CONSTEXPR auto uint_ = sprout::weed::uint_p(); // // uint8 diff --git a/sprout/weed/parser/numeric/uint_p.hpp b/sprout/weed/parser/numeric/uint_p.hpp index 8595bc84..2d3d6fb8 100644 --- a/sprout/weed/parser/numeric/uint_p.hpp +++ b/sprout/weed/parser/numeric/uint_p.hpp @@ -17,19 +17,24 @@ namespace sprout { // uint_p // template< - typename IntType, - std::size_t Radix, + typename UIntType, + std::size_t Radix = 10, std::size_t MinDigits = 1, - std::size_t MaxDigits = sprout::integer_digits::value + std::size_t MaxDigits = sprout::integer_digits::value > struct uint_p : public sprout::weed::parser_base { + private: + SPROUT_STATIC_CONSTEXPR std::size_t limit_digits = MaxDigits <= sprout::integer_digits::value + ? MaxDigits + : sprout::integer_digits::value + ; public: template struct attribute { public: - typedef IntType type; + typedef UIntType type; }; template struct result { @@ -37,26 +42,48 @@ namespace sprout { typedef sprout::weed::parser_result::type> type; }; private: + template + SPROUT_CONSTEXPR typename result::type make_result( + typename result::type const& res, + int sign = 0 + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return res.success() && sign < 0 + ? result_type(true, res.current(), -res.attr()) + : res + ; + } template SPROUT_CONSTEXPR typename std::enable_if< - N == MaxDigits, + N == limit_digits, typename result::type >::type call_1( Iterator first, Iterator last, Iterator temp_first, - IntType t, + UIntType t, + std::size_t n, PResult const& res ) const { typedef typename result::type result_type; typedef typename attribute::type attribute_type; return sprout::tuples::get<1>(res) - ? result_type( - true, - sprout::next(first), - static_cast(t * Radix | sprout::tuples::get<0>(res)) - ) + ? n < MaxDigits + ? call_0( + sprout::next(first), + last, + temp_first, + static_cast(t * Radix + sprout::tuples::get<0>(res)), + n + ) + : result_type( + true, + sprout::next(first), + static_cast(t * Radix + sprout::tuples::get<0>(res)) + ) : N < MinDigits ? result_type(false, temp_first, attribute_type()) : result_type(true, first, t) @@ -64,13 +91,14 @@ namespace sprout { } template SPROUT_CONSTEXPR typename std::enable_if< - N != MaxDigits, + N != limit_digits, typename result::type >::type call_1( Iterator first, Iterator last, Iterator temp_first, - IntType t, + UIntType t, + std::size_t n, PResult const& res ) const { @@ -79,8 +107,10 @@ namespace sprout { return sprout::tuples::get<1>(res) ? call_0( sprout::next(first), - last, temp_first, - static_cast(t * Radix | sprout::tuples::get<0>(res)) + last, + temp_first, + static_cast(t * Radix + sprout::tuples::get<0>(res)), + n ) : N < MinDigits ? result_type(false, temp_first, attribute_type()) @@ -92,7 +122,8 @@ namespace sprout { Iterator first, Iterator last, Iterator temp_first, - IntType t + UIntType t, + std::size_t n ) const { typedef typename result::type result_type; @@ -103,7 +134,8 @@ namespace sprout { last, temp_first, t, - sprout::weed::detail::from_ndigit(*first) + n + 1, + sprout::weed::detail::from_ndigit(*first) ) : N < MinDigits ? result_type(false, temp_first, attribute_type()) @@ -111,7 +143,7 @@ namespace sprout { ; } template - SPROUT_CONSTEXPR typename result::type call( + SPROUT_CONSTEXPR typename result::type call_i( Iterator first, Iterator last, Iterator temp_first, @@ -125,11 +157,26 @@ namespace sprout { sprout::next(first), last, temp_first, - sprout::tuples::get<0>(res) + sprout::tuples::get<0>(res), + 1 ) : result_type(false, temp_first, attribute_type()) ; } + template + SPROUT_CONSTEXPR typename result::type call( + Iterator first, + Iterator last, + Iterator temp_first + ) const + { + return call_i( + first, + last, + temp_first, + sprout::weed::detail::from_ndigit(*first) + ); + } public: template SPROUT_CONSTEXPR typename result::type operator()( @@ -144,8 +191,7 @@ namespace sprout { ? call( first, last, - first, - sprout::weed::detail::from_ndigit(*first) + first ) : result_type(false, first, attribute_type()) ; @@ -155,3 +201,4 @@ namespace sprout { } // namespace sprout #endif // #ifndef SPROUT_WEED_PARSER_NUMERIC_UINT_P_HPP +