From: K. G. <kim...@gm...> - 2008-10-26 13:37:06
|
Hi Dean, I'm not John, but his code got me thinking... On Sun, Oct 26, 2008 at 15:14, Dean Michael Berris <mik...@gm...> wrote: > > On Fri, Oct 24, 2008 at 5:38 AM, John P. Feltz <jf...@ov...> wrote: >> >> I implemented this in a similar network client project some time ago: >> >> namespace rfc3986 { >> template < >> typename ParserInput = std::string, >> typename Scheme = std::string, >> typename Authority = std::string, >> typename Path = std::string, >> typename Query = std::string, >> typename Fragment =std::string >> > class URI { >> public: > > We use traits for these things, and have a simple 'Tag' template argument. What's interesting about John's approach is not that std::string is configurable, but that he can write a specific parser for each part of the URI, and maybe compose them in the full parse() function. >> private: >> typedef URI< ParserInput, Scheme, Authority, Path, Query, >> Fragment> Output; >> >> friend Output* parse< ParserInput, Output> >> (std::stack<std::string>& errors, const ParserInput& input); > > Why a friend class for the parsing? Friend function. Presumably because you can easily add new parsers. I think the main parser works something like this: template< class Input, class Output > Output* parse(const Input& input) { return NULL; } template< > URI<>* parse(const URI<>::ParserInput& input) { URI<>::Scheme_type scheme = parse<URI<>::ParserInput, URI<>::Scheme_type>(input); URI<>::Authority_type host = parse<URI<>::ParserInput, URI<>::Authority_type>(input); // ... return new URI<>(scheme, host, ...); } What I think is interesting about this is that we can let the authority be represented by a string where we don't care much about the details (e.g. mailto scheme) or a typed struct where we do (e.g. http scheme), and just provide a new type + corresponding parser to make it work. Not sure if I'm reading too many capabilities into John's design, but I figure this is its main benefit. - Kim |