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