]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2001-2014 Joel de Guzman | |
3 | ||
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ==============================================================================*/ | |
7 | #if !defined(BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM) | |
8 | #define BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM | |
9 | ||
10 | #include <boost/spirit/home/x3/char/char_parser.hpp> | |
11 | #include <boost/spirit/home/x3/char/detail/cast_char.hpp> | |
12 | #include <boost/spirit/home/x3/support/traits/string_traits.hpp> | |
13 | #include <boost/spirit/home/x3/support/utility/utf8.hpp> | |
14 | #include <boost/spirit/home/x3/support/no_case.hpp> | |
15 | #include <boost/spirit/home/support/char_set/basic_chset.hpp> | |
16 | ||
17 | #include <boost/type_traits/is_same.hpp> | |
18 | ||
19 | namespace boost { namespace spirit { namespace x3 | |
20 | { | |
21 | /////////////////////////////////////////////////////////////////////////// | |
22 | // Parser for a character range | |
23 | /////////////////////////////////////////////////////////////////////////// | |
24 | template <typename Encoding, typename Attribute = typename Encoding::char_type> | |
25 | struct char_range | |
26 | : char_parser< char_range<Encoding, Attribute> > | |
27 | { | |
28 | ||
29 | typedef typename Encoding::char_type char_type; | |
30 | typedef Encoding encoding; | |
31 | typedef Attribute attribute_type; | |
32 | static bool const has_attribute = | |
33 | !is_same<unused_type, attribute_type>::value; | |
34 | ||
35 | ||
36 | char_range(char_type from_, char_type to_) | |
37 | : from(from_), to(to_) {} | |
38 | ||
39 | template <typename Char, typename Context> | |
40 | bool test(Char ch_, Context& context) const | |
41 | { | |
42 | ||
43 | char_type ch = char_type(ch_); // optimize for token based parsing | |
44 | return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_)) | |
45 | && (get_case_compare<encoding>(context)(ch, from) >= 0 ) | |
46 | && (get_case_compare<encoding>(context)(ch , to) <= 0 ); | |
47 | } | |
48 | ||
49 | char_type from, to; | |
50 | }; | |
51 | ||
52 | ||
53 | /////////////////////////////////////////////////////////////////////////// | |
54 | // Parser for a character set | |
55 | /////////////////////////////////////////////////////////////////////////// | |
56 | template <typename Encoding, typename Attribute = typename Encoding::char_type> | |
57 | struct char_set : char_parser<char_set<Encoding, Attribute>> | |
58 | { | |
59 | typedef typename Encoding::char_type char_type; | |
60 | typedef Encoding encoding; | |
61 | typedef Attribute attribute_type; | |
62 | static bool const has_attribute = | |
63 | !is_same<unused_type, attribute_type>::value; | |
64 | ||
65 | template <typename String> | |
66 | char_set(String const& str) | |
67 | { | |
68 | using spirit::x3::detail::cast_char; | |
69 | ||
70 | typedef typename | |
71 | remove_const< | |
72 | typename traits::char_type_of<String>::type | |
73 | >::type | |
74 | in_type; | |
75 | ||
76 | in_type const* definition = | |
77 | (in_type const*)traits::get_c_string(str); | |
78 | in_type ch = *definition++; | |
79 | while (ch) | |
80 | { | |
81 | in_type next = *definition++; | |
82 | if (next == '-') | |
83 | { | |
84 | next = *definition++; | |
85 | if (next == 0) | |
86 | { | |
87 | chset.set(cast_char<char_type>(ch)); | |
88 | chset.set('-'); | |
89 | break; | |
90 | } | |
91 | chset.set( | |
92 | cast_char<char_type>(ch), | |
93 | cast_char<char_type>(next) | |
94 | ); | |
95 | } | |
96 | else | |
97 | { | |
98 | chset.set(cast_char<char_type>(ch)); | |
99 | } | |
100 | ch = next; | |
101 | } | |
102 | } | |
103 | ||
104 | template <typename Char, typename Context> | |
105 | bool test(Char ch_, Context const& context) const | |
106 | { | |
107 | return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_)) | |
108 | && get_case_compare<encoding>(context).in_set(ch_,chset); | |
109 | } | |
110 | ||
111 | support::detail::basic_chset<char_type> chset; | |
112 | }; | |
113 | ||
114 | template <typename Encoding, typename Attribute> | |
115 | struct get_info<char_set<Encoding, Attribute>> | |
116 | { | |
117 | typedef std::string result_type; | |
118 | std::string operator()(char_set<Encoding, Attribute> const& p) const | |
119 | { | |
120 | return "char-set"; | |
121 | } | |
122 | }; | |
123 | ||
124 | template <typename Encoding, typename Attribute> | |
125 | struct get_info<char_range<Encoding, Attribute>> | |
126 | { | |
127 | typedef std::string result_type; | |
128 | std::string operator()(char_range<Encoding, Attribute> const& p) const | |
129 | { | |
130 | return "char_range \"" + to_utf8(Encoding::toucs4(p.from)) + '-' + to_utf8(Encoding::toucs4(p.to))+ '"'; | |
131 | } | |
132 | }; | |
133 | ||
134 | }}} | |
135 | ||
136 | #endif |