Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3a49b0d

Browse files
committed
Edit of the techniques used for tag metafunction, reflecting whats happening in 0.7 using Boost.MPL.
1 parentd9a0d47 commit3a49b0d

File tree

5 files changed

+165
-38
lines changed

5 files changed

+165
-38
lines changed

‎_sources/tag_metafunctions.txt

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ defining type traits. In the :mod:`cpp-netlib` however the type traits
1313
are defined on opaque tag types which serve to associate results to a
1414
family of metafunctions.
1515

16+
Template Specialization
17+
-----------------------
18+
1619
To illustrate this point, let's define a tag ``default_`` which we use
1720
to denote the default implementation of a certain type ``foo``. For
1821
instance 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+
>::type default_;
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
43117
the string type in the context of the type ``foo``. In code this would
44118
translate into:
@@ -55,10 +129,9 @@ translate into:
55129
Using this approach we can support different types of strings for
56130
different tags on the type ``foo``. In case we want to use a different
57131
type 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

63136
The approach also allows for the control of the structure and features
64137
of types like ``foo`` based on the specialization of the tag. Whole
@@ -97,16 +170,3 @@ definition of extension points that ensures type-safety and
97170
invariants. This keeps the whole extension mechanism static and yet
98171
flexible.
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.

‎_sources/whats_new.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
---------------------
99

1010
* Radical documentation overhaul
11-
* Asynchronous HTPP client
11+
* Asynchronous HTTP client
12+
* Tag dispatch overhaul, using Boost.MPL
13+
* HTTP Client Facade refactoring
14+
* Bug fixes for HTTP 1.1 response parsing
1215

1316
:mod:`cpp-netlib` 0.6
1417
---------------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp