From: Dean M. B. <mik...@gm...> - 2008-10-26 15:04:05
|
Hi Kim, On Sun, Oct 26, 2008 at 10:31 PM, Kim Gräsman <kim...@gm...> wrote: > Hi Dean, > > On Sun, Oct 26, 2008 at 15:48, Dean Michael Berris > <mik...@gm...> wrote: >> >> So for instance I need a uri<http::url> to construct an http::request, >> then the parser of the uri<http::url> would take into consideration >> everything that needs to be included in a uri<http::url>. > > You mean we should specialize the whole uri depending on a > protocol-specific tag? Or push the parsing code out to another > tag-dependent type (http::url, even)? > I won't go as far as pushing the parsing code out to another tag-dependent type, but I'm thinking more about putting the parsing code in the constructor of a uri<> by passing in a simple string and setting the internal variables of the uri<> appropriately using the parser. Modifying parts of the uri<> can be done with the accessor functions -- and serializing the uri from an instance into a string representation is yet to be done either which should give interesting challenges (normalization, encoding, etc.). > Coming from a more tired object-oriented background, I think all these > generic constructs are really counter-intuitive. I've learned to read > the stuff more or less (much thanks to guidance from this list), but I > still don't write it natively. It's like learning a new language -- > reading/listening comes much faster than the ability to express > yourself confidently. > > It'd be interesting to see a mapping chart from OO construct <-> > generic construct, most of them have a counterpart on the other side. > I don't think there is one chart depicting the OO construct <-> generic construct relationships (I'm not sure there is a mapping anyway), more because the type of generic programming that's happening here occurs in compile time by leveraging the C++ type/template system to enforce rules for us. It's not really generic programming per se, but a very low level of template metaprogramming (our use of traits is already one use of template metaprogramming as well as using tag dispatching on the directives and the constructor of the http::basic_client). It's really more about avoiding as much of the decisions from reaching runtime -- and putting in the decisions in the design. For instance, an HTTP URL has waaaaay different parts from an email address (where both can be depicted as a URI). Another thing you can think of is the conversion from one URI type to a different URI (or URL) can happen with explicit compile-time rules: template <class TargetTag, class SourceTag> uri<TargetTag> convert(uri<SourceTag> const & source) { BOOST_STATIC_ASSERT( valid_conversion<SourceTag, TargetTag> ); return uri<TargetType>(source.str()); }; This way conversion is explicit. It's even easier to do a guard parser if you're using tags: template <class Tag> uri<Tag> parse(string<Tag>::type const str) { if (protocol_id<Tag>::value() != str.substr(0, protocol_id<Tag>::length())) throw invalid_uri<Tag>(str); return uri<Tag>(str); }; So to use this you then have something like: parse<http::url>("http://www.boost.org/"); // won't throw parse<http::url>("mailto:dmb...@fr..."); // will throw This way you're being explicit about the behavior you expect. HTH -- Dean Michael C. Berris Software Engineer, Friendster, Inc. |