1.. Metafunctions/Concepts//Tag Dispatched Metafunction |50
2
3Tag Dispatched Metafunction
4===========================
5
6Summary
7-------
8
9A |Tag Dispatched Metafunction| is a |Metafunction| that employs a
10*tag dispatching* technique in its implementation to build an
11infrastructure for easy overriding/extenstion of the metafunction's
12behavior.
13
14
15Notation
16--------
17
18.. _`tag-metafunction`:
19
20+---------------------------+-----------------------------------------------------------+
21| Symbol                    | Legend                                                    |
22+===========================+===========================================================+
23| |``name``|                | A placeholder token for the specific metafunction's name. |
24+---------------------------+-----------------------------------------------------------+
25| |``tag-metafunction``|    | A placeholder token for the tag metafunction's name.      |
26+---------------------------+-----------------------------------------------------------+
27| |``tag``|                 | A placeholder token for one of possible tag types         |
28|                           | returned by the tag metafunction.                         |
29+---------------------------+-----------------------------------------------------------+
30
31.. |``name``| replace:: *name*
32.. |``tag-metafunction``| replace:: *tag-metafunction*
33.. |``tag``| replace:: *tag*
34
35
36Synopsis
37--------
38
39.. parsed-literal::
40
41    template< typename Tag > struct *name*\_impl;
42
43    template<
44          typename X
45        *[, ...]*
46        >
47    struct *name*
48        : *name*\_impl< typename *tag-metafunction*\<X>::type >
49            ::template apply<X *[, ...]*>
50    {
51    };
52
53    template< typename Tag > struct *name*\_impl
54    {
55        template< typename X *[, ...]* > struct apply
56        {
57            // *default implementation*
58        };
59    };
60
61    template<> struct *name*\_impl<*tag*>
62    {
63        template< typename X *[, ...]* > struct apply
64        {
65            // *tag-specific implementation*
66        };
67    };
68
69
70Description
71-----------
72
73The usual mechanism for overriding a metafunction's behavior is class
74template specialization |--| given a library-defined metafunction ``f``,
75it's possible to write a specialization of ``f`` for a specific type
76``user_type`` that would have the required semantics [#spec]_.
77
78While this mechanism is always available, it's not always the most
79convenient one, especially if it is desirable to specialize a
80metafunction's behavior for a *family* of related types. A typical
81example of it is numbered forms of sequence classes in MPL itself
82(``list0``, ..., ``list50``, et al.), and sequence classes in general.
83
84A |Tag Dispatched Metafunction| is a concept name for an instance of
85the metafunction implementation infrastructure being employed by the
86library to make it easier for users and implementors to override the
87behavior of library's metafunctions operating on families of specific
88types.
89
90The infrastructure is built on a variation of the technique commonly
91known as *tag dispatching* (hence the concept name),
92and involves three entities: a metafunction itself, an associated
93tag-producing |tag-metafunction|, and the metafunction's
94implementation, in the form of a |Metafunction Class| template
95parametrized by a ``Tag`` type parameter. The metafunction redirects
96to its implementation class template by invoking its specialization
97on a tag type produced by the tag metafunction with the original
98metafunction's parameters.
99
100
101.. [#spec] Usually such user-defined specialization is still required
102   to preserve the ``f``'s original invariants and complexity requirements.
103
104
105Example
106-------
107
108.. parsed-literal::
109
110   #include <boost/mpl/size.hpp>
111
112   namespace user {
113
114   struct bitset_tag;
115
116   struct bitset0
117   {
118       typedef bitset_tag tag;
119       // ...
120   };
121
122   template< typename B0 > struct bitset1
123   {
124       typedef bitset_tag tag;
125       // ...
126   };
127
128   template< typename B0, *...,* typename B\ *n* > struct bitset\ *n*
129   {
130       typedef bitset_tag tag;
131       // ...
132   };
133
134   } // namespace user
135
136   namespace boost { namespace mpl {
137   template<> struct size_impl<user::bitset_tag>
138   {
139       template< typename Bitset > struct apply
140       {
141           typedef typename Bitset::size type;
142       };
143   };
144   }}
145
146
147Models
148-------
149
150* |sequence_tag|
151
152
153See also
154--------
155
156|Metafunction|, |Metafunction Class|, |Numeric Metafunction|
157
158
159.. |tag-metafunction| replace:: `tag metafunctions`_
160.. _`tag metafunctions`: `tag-metafunction`_
161
162.. |tag dispatched| replace:: `tag dispatched`_
163.. _`tag dispatched`: `Tag Dispatched Metafunction`_
164
165
166.. copyright:: Copyright �  2001-2009 Aleksey Gurtovoy and David Abrahams
167   Distributed under the Boost Software License, Version 1.0. (See accompanying
168   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
169