@@ -13,6 +13,9 @@ defining type traits. In the :mod:`cpp-netlib` however the type traits
1313are defined on opaque tag types which serve to associate results to a
1414family of metafunctions.
1515
16+ Template Specialization
17+ -----------------------
18+
1619To illustrate this point, let's define a tag ``default_ `` which we use
1720to denote the default implementation of a certain type ``foo ``. For
1821instance we decide that the default string type we will use for
@@ -38,7 +41,78 @@ translate to:
3841 typedef std::string type;
3942 };
4043
41- Then in the definition of the type ``foo `` we use this type function
44+ Template Metaprogramming
45+ ------------------------
46+
47+ Starting with version 0.7, the tag dispatch mechanism changed slightly to use
48+ Boost.MPL _. The idea is still the same, although we can get a little smarter
49+ than just using template specializations. Instead of just defining an opaque
50+ type ``default_ ``, we use the Boost.MPL equivalent of a vector to define which
51+ root types of properties this ``default_ `` tag supports. The idea is to make the
52+ opaque type ``default_ `` inherit property tags which the library supports
53+ internally as definite extension points.
54+
55+ .. _Boost.MPL :http://www.boost.org/libs/mpl/index.html
56+
57+ Our definition of the ``default_ `` tag will then look something like the
58+ following:
59+
60+ ..code-block ::c++
61+
62+ typedef mpl::vector<default_string> default_tags;
63+
64+ template <class Tag>
65+ struct components;
66+
67+ typedef mpl::inherit_linearly<
68+ default_tags,
69+ mpl::inherit<mpl::placeholders: :_1, mpl::placeholders: :_2>
70+ >::typedefault _;
71+
72+ template <class Tag>
73+ struct components<default _> {
74+ typedef default_tags type;
75+ };
76+
77+ In the above listing, ``default_string `` is what we call a "root" tag which is
78+ meant to be combined with other "root" tags to form composite tags. In this case
79+ our composite tag is the tag ``default_ ``. There are a number of these "root"
80+ tags that:mod: `cpp-netlib ` provides. These are in the namespace
81+ ``boost::network::tags `` and are defined in ``boost/network/tags.hpp ``.
82+
83+ Using this technique we change slightly our definition of the ``string ``
84+ metafunction class into this:
85+
86+ ..code-block ::c++
87+
88+ template <class Tag>
89+ struct unsupported_tag;
90+
91+ template <class Tag>
92+ struct string :
93+ mpl::if_<
94+ is_base_of<
95+ Tag,
96+ tags::default_string
97+ >,
98+ std::string,
99+ unsupported_tag<Tag>
100+ >
101+ {};
102+
103+ Notice that we don't have the typedef for ``type `` in the body of ``string ``
104+ anymore, but we do inherit from ``mpl::if_ ``. Since ``mpl::if_ `` is a template
105+ metafunction itself, it contains a definition of the resulting ``type `` which
106+ ``string `` inherits.
107+
108+ You can see the real definition of the ``string `` metafunction in
109+ ``boost/network/traits/string.hpp ``.
110+
111+ Using Tags
112+ ----------
113+
114+ Once we have the defined tag, we can then use this in the definition of our
115+ types. In the definition of the type ``foo `` we use this type function
42116``string `` and pass the tag type parameter to determine what to use as
43117the string type in the context of the type ``foo ``. In code this would
44118translate into:
@@ -55,10 +129,9 @@ translate into:
55129Using this approach we can support different types of strings for
56130different tags on the type ``foo ``. In case we want to use a different
57131type of string for the tag ``default_ `` we only change the
58- specialization of ``string<default_> ``. In the other case that we want
59- to use a different tag to define the functionality of ``foo ``, all we
60- have to do is implement specializations of the type functions like
61- ``string `` for that different tag.
132+ composition of the ``string_tags `` MPL vector. For example, in:mod: `cpp-netlib `
133+ there is a root tag ``default_wstring `` which causes the ``string `` metafunction
134+ to define ``std::wstring `` as the resulting type.
62135
63136The approach also allows for the control of the structure and features
64137of types like ``foo `` based on the specialization of the tag. Whole
@@ -97,16 +170,3 @@ definition of extension points that ensures type-safety and
97170invariants. This keeps the whole extension mechanism static and yet
98171flexible.
99172
100- One drawback with this approach is the verbosity at which extensions
101- and specializations are to be done which introduces additional
102- pressure on the compiler at compile-time computations. Because this
103- technique relies heavily on the C++ template mechanism, compile times
104- may be greatly increased.
105-
106- The potential for tag and implementation explosion is also high. If
107- the implementor is not careful in controlling the number of tags and
108- type functions that take the tag as an input, it can get out of hand
109- quickly. The suggestion is to define acceptable defaults and leverage
110- re-use of existing tags as much as possible. Using Boost.MPL data
111- structures like map's and/or control structures like ``if_ `` and
112- ``switch_ `` can also help with heavily-used type functions.