Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2011 Jan Frederick Eick
|
Chris@16
|
4
|
Chris@16
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 ==============================================================================*/
|
Chris@16
|
8 #if !defined(BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM)
|
Chris@16
|
9 #define BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM
|
Chris@16
|
10
|
Chris@16
|
11 #if defined(_MSC_VER)
|
Chris@16
|
12 #pragma once
|
Chris@16
|
13 #endif
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/spirit/home/support/assert_msg.hpp>
|
Chris@16
|
16 #include <boost/spirit/home/qi/detail/assign_to.hpp>
|
Chris@16
|
17 #include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp>
|
Chris@16
|
18 #include <boost/assert.hpp>
|
Chris@16
|
19 #include <boost/mpl/assert.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost { namespace spirit { namespace qi
|
Chris@16
|
22 {
|
Chris@16
|
23 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
24 // Extract the prefix sign (- or +), return true if a '-' was found
|
Chris@16
|
25 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
26 template <typename Iterator>
|
Chris@16
|
27 inline bool
|
Chris@16
|
28 extract_sign(Iterator& first, Iterator const& last)
|
Chris@16
|
29 {
|
Chris@16
|
30 (void)last; // silence unused warnings
|
Chris@16
|
31 BOOST_ASSERT(first != last); // precondition
|
Chris@16
|
32
|
Chris@16
|
33 // Extract the sign
|
Chris@16
|
34 bool neg = *first == '-';
|
Chris@16
|
35 if (neg || (*first == '+'))
|
Chris@16
|
36 {
|
Chris@16
|
37 ++first;
|
Chris@16
|
38 return neg;
|
Chris@16
|
39 }
|
Chris@16
|
40 return false;
|
Chris@16
|
41 }
|
Chris@16
|
42
|
Chris@16
|
43 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
44 // Low level unsigned integer parser
|
Chris@16
|
45 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
46 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
Chris@16
|
47 , bool Accumulate = false>
|
Chris@16
|
48 struct extract_uint
|
Chris@16
|
49 {
|
Chris@16
|
50 // check template parameter 'Radix' for validity
|
Chris@16
|
51 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
52 Radix >= 2 && Radix <= 36,
|
Chris@16
|
53 not_supported_radix, ());
|
Chris@16
|
54
|
Chris@16
|
55 template <typename Iterator>
|
Chris@16
|
56 inline static bool call(Iterator& first, Iterator const& last, T& attr_)
|
Chris@16
|
57 {
|
Chris@16
|
58 if (first == last)
|
Chris@16
|
59 return false;
|
Chris@16
|
60
|
Chris@16
|
61 typedef detail::extract_int<
|
Chris@16
|
62 T
|
Chris@16
|
63 , Radix
|
Chris@16
|
64 , MinDigits
|
Chris@16
|
65 , MaxDigits
|
Chris@16
|
66 , detail::positive_accumulator<Radix>
|
Chris@16
|
67 , Accumulate>
|
Chris@16
|
68 extract_type;
|
Chris@16
|
69
|
Chris@16
|
70 Iterator save = first;
|
Chris@16
|
71 if (!extract_type::parse(first, last,
|
Chris@16
|
72 detail::cast_unsigned<T>::call(attr_)))
|
Chris@16
|
73 {
|
Chris@16
|
74 first = save;
|
Chris@16
|
75 return false;
|
Chris@16
|
76 }
|
Chris@16
|
77 return true;
|
Chris@16
|
78 }
|
Chris@16
|
79
|
Chris@16
|
80 template <typename Iterator, typename Attribute>
|
Chris@16
|
81 inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
|
Chris@16
|
82 {
|
Chris@16
|
83 // this case is called when Attribute is not T
|
Chris@16
|
84 T attr_local;
|
Chris@16
|
85 if (call(first, last, attr_local))
|
Chris@16
|
86 {
|
Chris@16
|
87 traits::assign_to(attr_local, attr_);
|
Chris@16
|
88 return true;
|
Chris@16
|
89 }
|
Chris@16
|
90 return false;
|
Chris@16
|
91 }
|
Chris@16
|
92 };
|
Chris@16
|
93
|
Chris@16
|
94 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
95 // Low level signed integer parser
|
Chris@16
|
96 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
97 template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
Chris@16
|
98 struct extract_int
|
Chris@16
|
99 {
|
Chris@16
|
100 // check template parameter 'Radix' for validity
|
Chris@16
|
101 BOOST_SPIRIT_ASSERT_MSG(
|
Chris@16
|
102 Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
Chris@16
|
103 not_supported_radix, ());
|
Chris@16
|
104
|
Chris@16
|
105 template <typename Iterator>
|
Chris@16
|
106 inline static bool call(Iterator& first, Iterator const& last, T& attr_)
|
Chris@16
|
107 {
|
Chris@16
|
108 if (first == last)
|
Chris@16
|
109 return false;
|
Chris@16
|
110
|
Chris@16
|
111 typedef detail::extract_int<
|
Chris@16
|
112 T, Radix, MinDigits, MaxDigits>
|
Chris@16
|
113 extract_pos_type;
|
Chris@16
|
114
|
Chris@16
|
115 typedef detail::extract_int<
|
Chris@16
|
116 T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
|
Chris@16
|
117 extract_neg_type;
|
Chris@16
|
118
|
Chris@16
|
119 Iterator save = first;
|
Chris@16
|
120 bool hit = extract_sign(first, last);
|
Chris@16
|
121 if (hit)
|
Chris@16
|
122 hit = extract_neg_type::parse(first, last, attr_);
|
Chris@16
|
123 else
|
Chris@16
|
124 hit = extract_pos_type::parse(first, last, attr_);
|
Chris@16
|
125
|
Chris@16
|
126 if (!hit)
|
Chris@16
|
127 {
|
Chris@16
|
128 first = save;
|
Chris@16
|
129 return false;
|
Chris@16
|
130 }
|
Chris@16
|
131 return true;
|
Chris@16
|
132 }
|
Chris@16
|
133
|
Chris@16
|
134 template <typename Iterator, typename Attribute>
|
Chris@16
|
135 inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
|
Chris@16
|
136 {
|
Chris@16
|
137 // this case is called when Attribute is not T
|
Chris@16
|
138 T attr_local;
|
Chris@16
|
139 if (call(first, last, attr_local))
|
Chris@16
|
140 {
|
Chris@16
|
141 traits::assign_to(attr_local, attr_);
|
Chris@16
|
142 return true;
|
Chris@16
|
143 }
|
Chris@16
|
144 return false;
|
Chris@16
|
145 }
|
Chris@16
|
146 };
|
Chris@16
|
147 }}}
|
Chris@16
|
148
|
Chris@16
|
149 #endif
|