Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Copyright (c) 2011 Jan Frederick Eick Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM) Chris@16: #define BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace spirit { namespace qi Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Extract the prefix sign (- or +), return true if a '-' was found Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline bool Chris@16: extract_sign(Iterator& first, Iterator const& last) Chris@16: { Chris@16: (void)last; // silence unused warnings Chris@16: BOOST_ASSERT(first != last); // precondition Chris@16: Chris@16: // Extract the sign Chris@16: bool neg = *first == '-'; Chris@16: if (neg || (*first == '+')) Chris@16: { Chris@16: ++first; Chris@16: return neg; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Low level unsigned integer parser Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct extract_uint Chris@16: { Chris@16: // check template parameter 'Radix' for validity Chris@16: BOOST_SPIRIT_ASSERT_MSG( Chris@16: Radix >= 2 && Radix <= 36, Chris@16: not_supported_radix, ()); Chris@16: Chris@16: template Chris@16: inline static bool call(Iterator& first, Iterator const& last, T& attr_) Chris@16: { Chris@16: if (first == last) Chris@16: return false; Chris@16: Chris@16: typedef detail::extract_int< Chris@16: T Chris@16: , Radix Chris@16: , MinDigits Chris@16: , MaxDigits Chris@16: , detail::positive_accumulator Chris@16: , Accumulate> Chris@16: extract_type; Chris@16: Chris@16: Iterator save = first; Chris@16: if (!extract_type::parse(first, last, Chris@16: detail::cast_unsigned::call(attr_))) Chris@16: { Chris@16: first = save; Chris@16: return false; Chris@16: } Chris@16: return true; Chris@16: } Chris@16: Chris@16: template Chris@16: inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_) Chris@16: { Chris@16: // this case is called when Attribute is not T Chris@16: T attr_local; Chris@16: if (call(first, last, attr_local)) Chris@16: { Chris@16: traits::assign_to(attr_local, attr_); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Low level signed integer parser Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct extract_int Chris@16: { Chris@16: // check template parameter 'Radix' for validity Chris@16: BOOST_SPIRIT_ASSERT_MSG( Chris@16: Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16, Chris@16: not_supported_radix, ()); Chris@16: Chris@16: template Chris@16: inline static bool call(Iterator& first, Iterator const& last, T& attr_) Chris@16: { Chris@16: if (first == last) Chris@16: return false; Chris@16: Chris@16: typedef detail::extract_int< Chris@16: T, Radix, MinDigits, MaxDigits> Chris@16: extract_pos_type; Chris@16: Chris@16: typedef detail::extract_int< Chris@16: T, Radix, MinDigits, MaxDigits, detail::negative_accumulator > Chris@16: extract_neg_type; Chris@16: Chris@16: Iterator save = first; Chris@16: bool hit = extract_sign(first, last); Chris@16: if (hit) Chris@16: hit = extract_neg_type::parse(first, last, attr_); Chris@16: else Chris@16: hit = extract_pos_type::parse(first, last, attr_); Chris@16: Chris@16: if (!hit) Chris@16: { Chris@16: first = save; Chris@16: return false; Chris@16: } Chris@16: return true; Chris@16: } Chris@16: Chris@16: template Chris@16: inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_) Chris@16: { Chris@16: // this case is called when Attribute is not T Chris@16: T attr_local; Chris@16: if (call(first, last, attr_local)) Chris@16: { Chris@16: traits::assign_to(attr_local, attr_); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: }; Chris@16: }}} Chris@16: Chris@16: #endif