1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2011 Jan Frederick Eick
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #if !defined(BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM)
9 #define BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM
15 #include <boost/spirit/home/support/assert_msg.hpp>
16 #include <boost/spirit/home/qi/detail/assign_to.hpp>
17 #include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp>
18 #include <boost/assert.hpp>
19 #include <boost/mpl/assert.hpp>
21 namespace boost { namespace spirit { namespace qi
23 ///////////////////////////////////////////////////////////////////////////
24 // Extract the prefix sign (- or +), return true if a '-' was found
25 ///////////////////////////////////////////////////////////////////////////
26 template <typename Iterator>
28 extract_sign(Iterator& first, Iterator const& last)
30 (void)last; // silence unused warnings
31 BOOST_ASSERT(first != last); // precondition
34 bool neg = *first == '-';
35 if (neg || (*first == '+'))
43 ///////////////////////////////////////////////////////////////////////////
44 // Low level unsigned integer parser
45 ///////////////////////////////////////////////////////////////////////////
46 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
47 , bool Accumulate = false, bool IgnoreOverflowDigits = false>
50 // check template parameter 'Radix' for validity
51 BOOST_SPIRIT_ASSERT_MSG(
52 Radix >= 2 && Radix <= 36,
53 not_supported_radix, ());
55 template <typename Iterator>
56 inline static bool call(Iterator& first, Iterator const& last, T& attr_)
61 typedef detail::extract_int<
66 , detail::positive_accumulator<Radix>
68 , IgnoreOverflowDigits>
71 Iterator save = first;
72 if (!extract_type::parse(first, last,
73 detail::cast_unsigned<T>::call(attr_)))
81 template <typename Iterator, typename Attribute>
82 inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
84 // this case is called when Attribute is not T
86 if (call(first, last, attr_local))
88 traits::assign_to(attr_local, attr_);
95 ///////////////////////////////////////////////////////////////////////////
96 // Low level signed integer parser
97 ///////////////////////////////////////////////////////////////////////////
98 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
101 // check template parameter 'Radix' for validity
102 BOOST_SPIRIT_ASSERT_MSG(
103 Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
104 not_supported_radix, ());
106 template <typename Iterator>
107 inline static bool call(Iterator& first, Iterator const& last, T& attr_)
112 typedef detail::extract_int<
113 T, Radix, MinDigits, MaxDigits>
116 typedef detail::extract_int<
117 T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
120 Iterator save = first;
121 bool hit = extract_sign(first, last);
123 hit = extract_neg_type::parse(first, last, attr_);
125 hit = extract_pos_type::parse(first, last, attr_);
135 template <typename Iterator, typename Attribute>
136 inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
138 // this case is called when Attribute is not T
140 if (call(first, last, attr_local))
142 traits::assign_to(attr_local, attr_);