| /*============================================================================= |
| Copyright (c) 2001-2010 Joel de Guzman |
| |
| 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) |
| ==============================================================================*/ |
| #if !defined(BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM) |
| #define BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM |
| |
| #if defined(_MSC_VER) |
| #pragma once |
| #endif |
| |
| #include <boost/spirit/home/support/assert_msg.hpp> |
| #include <boost/spirit/home/qi/detail/assign_to.hpp> |
| #include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp> |
| #include <boost/assert.hpp> |
| #include <boost/mpl/assert.hpp> |
| |
| namespace boost { namespace spirit { namespace qi |
| { |
| /////////////////////////////////////////////////////////////////////////// |
| // Extract the prefix sign (- or +), return true if a '-' was found |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename Iterator> |
| inline bool |
| extract_sign(Iterator& first, Iterator const& last) |
| { |
| (void)last; // silence unused warnings |
| BOOST_ASSERT(first != last); // precondition |
| |
| // Extract the sign |
| bool neg = *first == '-'; |
| if (neg || (*first == '+')) |
| { |
| ++first; |
| return neg; |
| } |
| return false; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // Low level unsigned integer parser |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits |
| , bool Accumulate = false> |
| struct extract_uint |
| { |
| // check template parameter 'Radix' for validity |
| BOOST_SPIRIT_ASSERT_MSG( |
| Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16, |
| not_supported_radix, ()); |
| |
| template <typename Iterator> |
| static bool call(Iterator& first, Iterator const& last, T& attr) |
| { |
| if (first == last) |
| return false; |
| |
| typedef detail::extract_int< |
| T |
| , Radix |
| , MinDigits |
| , MaxDigits |
| , detail::positive_accumulator<Radix> |
| , Accumulate> |
| extract_type; |
| |
| Iterator save = first; |
| if (!extract_type::parse(first, last, |
| detail::cast_unsigned<T>::call(attr))) |
| { |
| first = save; |
| return false; |
| } |
| return true; |
| } |
| |
| template <typename Iterator, typename Attribute> |
| static bool call(Iterator& first, Iterator const& last, Attribute& attr_) |
| { |
| // this case is called when Attribute is not T |
| T attr; |
| if (call(first, last, attr)) |
| { |
| traits::assign_to(attr, attr_); |
| return true; |
| } |
| return false; |
| } |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // Low level signed integer parser |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits> |
| struct extract_int |
| { |
| // check template parameter 'Radix' for validity |
| BOOST_SPIRIT_ASSERT_MSG( |
| Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16, |
| not_supported_radix, ()); |
| |
| template <typename Iterator> |
| static bool call(Iterator& first, Iterator const& last, T& attr) |
| { |
| if (first == last) |
| return false; |
| |
| typedef detail::extract_int< |
| T, Radix, MinDigits, MaxDigits> |
| extract_pos_type; |
| |
| typedef detail::extract_int< |
| T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> > |
| extract_neg_type; |
| |
| Iterator save = first; |
| bool hit = extract_sign(first, last); |
| if (hit) |
| hit = extract_neg_type::parse(first, last, attr); |
| else |
| hit = extract_pos_type::parse(first, last, attr); |
| |
| if (!hit) |
| { |
| first = save; |
| return false; |
| } |
| return true; |
| } |
| |
| template <typename Iterator, typename Attribute> |
| static bool call(Iterator& first, Iterator const& last, Attribute& attr_) |
| { |
| // this case is called when Attribute is not T |
| T attr; |
| if (call(first, last, attr)) |
| { |
| traits::assign_to(attr, attr_); |
| return true; |
| } |
| return false; |
| } |
| }; |
| }}} |
| |
| #endif |