@@ -131,17 +131,100 @@ struct transform_attribute<
131131 static void post (optional<Exposed> &, Transformed const &) { }
132132};
133133#endif
134+
135+ template <>
136+ struct transform_attribute <
137+ boost::network::uri::detail::uri_parts_wide_base,
138+ boost::fusion::tuple<
139+ std::wstring &,
140+ boost::fusion::tuple<
141+ boost::optional<std::wstring>&,
142+ boost::optional<std::wstring>&,
143+ boost::optional<boost::uint16_t > &,
144+ std::wstring &
145+ >,
146+ optional<std::wstring>&,
147+ optional<std::wstring>&
148+ >
149+ #if SPIRIT_VERSION >= 0x2030
150+ , boost::spirit::qi::domain
151+ #endif
152+ >
153+ {
154+ typedef
155+ boost::fusion::tuple<
156+ std::wstring &,
157+ boost::fusion::tuple<
158+ boost::optional<std::wstring>&,
159+ boost::optional<std::wstring>&,
160+ boost::optional<boost::uint16_t > &,
161+ std::wstring &
162+ >,
163+ optional<std::wstring>&,
164+ optional<std::wstring>&
165+ > type;
166+
167+ static type pre (boost::network::uri::detail::uri_parts_wide_base & parts) {
168+ boost::fusion::tuple<
169+ boost::optional<std::wstring> &,
170+ boost::optional<std::wstring> &,
171+ boost::optional<boost::uint16_t > &,
172+ std::wstring &
173+ > hier_part =
174+ boost::fusion::tie (
175+ parts.user_info ,
176+ parts.host ,
177+ parts.port ,
178+ parts.path
179+ );
180+
181+ return boost::fusion::tie (
182+ parts.scheme ,
183+ hier_part,
184+ parts.query ,
185+ parts.fragment
186+ );
187+ }
188+
189+ static void post (boost::network::uri::detail::uri_parts_wide_base &, type const &) { }
190+
191+ #if SPIRIT_VERSION >= 0x2030
192+ static void fail (boost::network::uri::detail::uri_parts_wide_base & val) { }
193+ #endif
194+ };
195+
134196} // namespace traits
135197} // namespace spirit
136198} // namespace boost
137199
138200
139201namespace boost { namespace network { namespace uri { namespace detail {
202+
203+ template <class String >
204+ struct unsupported_string ;
205+
206+ template <class String , class Dummy = void >
207+ struct choose_uri_base
208+ {
209+ typedef unsupported_string<String> type;
210+ };
211+
212+ template <class Dummy >
213+ struct choose_uri_base <std::string, Dummy>
214+ {
215+ typedef uri_parts_default_base type;
216+ };
217+
218+ template <class Dummy >
219+ struct choose_uri_base <std::wstring, Dummy>
220+ {
221+ typedef uri_parts_wide_base type;
222+ };
140223
141224namespace qi = boost::spirit::qi;
142225
143- template <typename Iterator>
144- struct uri_grammar_default : qi::grammar<Iterator, uri_parts_default_base ()> {
226+ template <typename Iterator, typename String >
227+ struct uri_grammar_default : qi::grammar<Iterator, typename choose_uri_base<String>::type ()> {
145228 uri_grammar_default () : uri_grammar_default::base_type(start, " uri" ) {
146229 // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
147230 gen_delims %= qi::char_ (" :/?#[]@" );
@@ -223,8 +306,8 @@ struct uri_grammar_default : qi::grammar<Iterator, uri_parts_default_base()> {
223306 )
224307 |
225308 (
226- qi::attr (optional<std::string >())
227- >> qi::attr (optional<std::string >())
309+ qi::attr (optional<String >())
310+ >> qi::attr (optional<String >())
228311 >> qi::attr (optional<boost::uint16_t >())
229312 >> (
230313 path_absolute
@@ -242,7 +325,7 @@ struct uri_grammar_default : qi::grammar<Iterator, uri_parts_default_base()> {
242325 start %= uri.alias ();
243326 }
244327
245- typedef std::string string_type;
328+ typedef String string_type;
246329
247330 qi::rule<Iterator, typename string_type::value_type ()>
248331 gen_delims, sub_delims, reserved, unreserved;
@@ -268,7 +351,7 @@ struct uri_grammar_default : qi::grammar<Iterator, uri_parts_default_base()> {
268351 >()> hier_part;
269352
270353 // start rule of grammar
271- qi::rule<Iterator, uri_parts_default_base ()> start;
354+ qi::rule<Iterator, typename choose_uri_base<String>::type ()> start;
272355
273356 // actual uri parser
274357 qi::rule<
@@ -290,20 +373,28 @@ struct uri_grammar_default : qi::grammar<Iterator, uri_parts_default_base()> {
290373
291374BOOST_NETWORK_INLINE bool parse_uri_impl (boost::iterator_range<std::string::const_iterator> & range, uri_parts_default_base & parts, boost::network::tags::default_string) {
292375 // Qualified boost::begin and boost::end because MSVC complains
293- // of ambiguity on call to begin(range) and end(rand ).
376+ // of ambiguity on call to begin(range) and end(range ).
294377 std::string::const_iterator start_ = boost::begin (range);
295378 std::string::const_iterator end_ = boost::end (range);
296379
297- static uri_grammar_default<std::string::const_iterator> grammar;
380+ static uri_grammar_default<std::string::const_iterator, std::string > grammar;
298381
299382 bool ok = qi::parse (start_, end_, grammar, parts);
300383
301384 return ok && start_ == end_;
302385}
303386
304387BOOST_NETWORK_INLINE bool parse_uri_impl (boost::iterator_range<std::wstring::const_iterator> & range, uri_parts_wide_base & parts, boost::network::tags::default_wstring) {
305- // TODO implement the grammar that supports wide strings
306- return false ; // this always fails because it's not supported yet!
388+ // Qualified boost::begin and boost::end because MSVC complains
389+ // of ambiguity on call to begin(range) and end(range).
390+ std::wstring::const_iterator start_ = boost::begin (range);
391+ std::wstring::const_iterator end_ = boost::end (range);
392+
393+ static uri_grammar_default<std::wstring::const_iterator, std::wstring> grammar;
394+
395+ bool ok = qi::parse (start_, end_, grammar, parts);
396+
397+ return ok && start_ == end_;
307398}
308399
309400} /* detail */
0 commit comments