Skip to content

Commit f734b3f

Browse files
committed
SFINAE-ization of Tag Dispatch System
Thanks to Thomas Heller for the tips on the dramatic reduction of compile times in the cpp-netlib implementation, this commit is now generally considered a major compile-time enhancement over previous versions/iterations of the library. In this particular case the compile time reduction is actually significant just by using SFINAE and partial specialization over (ab)use of the Boost.MPL facilities.
1 parent d8f04ea commit f734b3f

26 files changed

+262
-254
lines changed

boost/network/protocol/http/message/traits/version.hpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,32 @@ namespace boost { namespace network { namespace http {
2020
template <class Tag>
2121
struct unsupported_tag;
2222

23-
template <class Message>
23+
template <class Message, class Enable = void>
2424
struct version
25-
: mpl::if_<
26-
is_async<typename Message::tag>,
27-
boost::shared_future<typename string<typename Message::tag>::type>,
28-
typename mpl::if_<
25+
{
26+
typedef unsupported_tag<typename Message::tag> type;
27+
};
28+
29+
template <class Message>
30+
struct version<Message, typename enable_if<is_async<typename Message::tag> >::type>
31+
{
32+
typedef boost::shared_future<typename string<typename Message::tag>::type> type;
33+
};
34+
35+
template <class Message>
36+
struct version<Message,
37+
typename enable_if<
2938
mpl::or_<
3039
is_sync<typename Message::tag>,
31-
is_same<typename Message::tag, tags::default_string>,
32-
is_same<typename Message::tag, tags::default_wstring>
33-
>,
34-
typename string<typename Message::tag>::type,
35-
unsupported_tag<typename Message::tag>
36-
>::type
37-
>
38-
{};
39-
40+
is_default_string<typename Message::tag>,
41+
is_default_wstring<typename Message::tag>
42+
>
43+
>::type
44+
>
45+
{
46+
typedef typename string<typename Message::tag>::type type;
47+
};
48+
4049
} /* traits */
4150

4251
} /* http */

boost/network/protocol/http/support/client_or_server.hpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,27 @@
1111
#include <boost/mpl/if.hpp>
1212

1313
namespace boost { namespace network { namespace http {
14-
14+
1515
template <class Tag>
16-
struct client_or_server :
17-
mpl::if_<
18-
is_server<Tag>,
19-
tags::server,
20-
typename mpl::if_<
21-
is_client<Tag>,
22-
tags::client,
23-
unsupported_tag<Tag>
24-
>::type
25-
>
26-
{};
27-
16+
struct unsupported_tag;
17+
18+
template <class Tag, class Enable = void>
19+
struct client_or_server
20+
{
21+
typedef unsupported_tag<Tag> type;
22+
};
23+
24+
template <class Tag>
25+
struct client_or_server<Tag, typename enable_if<is_server<Tag> >::type>
26+
{
27+
typedef tags::server type;
28+
};
29+
30+
template <class Tag>
31+
struct client_or_server<Tag, typename enable_if<is_client<Tag> >::type>
32+
{
33+
typedef tags::client type;
34+
};
2835

2936
} /* http */
3037

boost/network/protocol/http/support/is_client.hpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,15 @@
77
// http://www.boost.org/LICENSE_1_0.txt)
88

99
#include <boost/network/protocol/http/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network { namespace http {
1313

14+
template <class Tag, class Enable = void>
15+
struct is_client : mpl::false_ {};
16+
1417
template <class Tag>
15-
struct is_client :
16-
is_base_of<
17-
tags::client,
18-
Tag
19-
>
20-
{};
18+
struct is_client<Tag, typename enable_if<typename Tag::is_client>::type> : mpl::true_ {};
2119

2220
} /* http */
2321

boost/network/protocol/http/support/is_http.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@
77
// http://www.boost.org/LICENSE_1_0.txt)
88

99
#include <boost/network/protocol/http/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network { namespace http {
1313

14+
template <class Tag, class Enable = void>
15+
struct is_http : mpl::false_ {};
16+
1417
template <class Tag>
15-
struct is_http :
16-
is_base_of<
17-
tags::http,
18-
Tag
19-
>
20-
{};
21-
18+
struct is_http<Tag, typename enable_if<typename Tag::is_http>::type> : mpl::true_ {};
19+
2220
} // namespace http
2321

2422
} // namespace network

boost/network/protocol/http/support/is_keepalive.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,19 @@
77
// http://www.boost.org/LICENSE_1_0.txt)
88

99
#include <boost/network/protocol/http/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network { namespace http {
1313

1414
template <class Tag>
1515
struct unsupported_tag;
1616

17+
template <class Tag, class Enable = void>
18+
struct is_keepalive : mpl::false_ {};
19+
1720
template <class Tag>
18-
struct is_keepalive :
19-
is_base_of<
20-
http::tags::keepalive
21-
, Tag
22-
>
23-
{};
24-
21+
struct is_keepalive<Tag, typename enable_if<typename Tag::is_keepalive>::type> : mpl::true_ {};
22+
2523
} /* http */
2624

2725
} /* network */

boost/network/protocol/http/support/is_server.hpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,15 @@
77
// http://www.boost.org/LICENSE_1_0.txt)
88

99
#include <boost/network/protocol/http/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network { namespace http {
1313

14+
template <class Tag, class Enable = void>
15+
struct is_server : mpl::false_ {};
16+
1417
template <class Tag>
15-
struct is_server :
16-
is_base_of<
17-
tags::server,
18-
Tag
19-
>
20-
{};
18+
struct is_server<Tag, typename enable_if<typename Tag::is_server>::type> : mpl::true_ {};
2119

2220
} /* http */
2321

boost/network/protocol/http/support/is_simple.hpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,16 @@
77
// http://www.boost.org/LICENSE_1_0.txt)
88

99
#include <boost/network/protocol/http/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network { namespace http {
1313

14+
template <class Tag, class Enable = void>
15+
struct is_simple : mpl::false_ {};
16+
1417
template <class Tag>
15-
struct unsupported_tag;
16-
17-
template <class Tag>
18-
struct is_simple :
19-
is_base_of<
20-
tags::simple
21-
, Tag
22-
>
23-
{};
24-
18+
struct is_simple<Tag, typename enable_if<typename Tag::is_simple>::type> : mpl::true_ {};
19+
2520
} /* http */
2621

2722
} /* network */

boost/network/protocol/http/tags.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
namespace boost { namespace network { namespace http { namespace tags {
1212

13-
struct http {};
14-
struct keepalive {};
15-
struct simple {};
16-
struct server {};
17-
struct client {};
13+
struct http { typedef mpl::true_::type is_http; };
14+
struct keepalive { typedef mpl::true_::type is_keepalive; };
15+
struct simple { typedef mpl::true_::type is_simple; };
16+
struct server { typedef mpl::true_::type is_server; };
17+
struct client { typedef mpl::true_::type is_client; };
1818

1919
using namespace boost::network::tags;
2020

boost/network/protocol/http/traits/connection_policy.hpp

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,37 @@
1313
#include <boost/network/protocol/http/support/is_simple.hpp>
1414
#include <boost/network/protocol/http/support/is_keepalive.hpp>
1515
#include <boost/network/support/is_async.hpp>
16+
#include <boost/mpl/and.hpp>
17+
#include <boost/mpl/not.hpp>
1618

1719
namespace boost { namespace network { namespace http {
1820

1921
template <class Tag>
2022
struct unsupported_tag;
2123

24+
template <class Tag, unsigned version_major, unsigned version_minor, class Enable = void>
25+
struct connection_policy
26+
{
27+
typedef unsupported_tag<Tag> type;
28+
};
29+
2230
template <class Tag, unsigned version_major, unsigned version_minor>
23-
struct connection_policy :
24-
mpl::if_<
25-
is_async<Tag>,
26-
async_connection_policy<Tag,version_major,version_minor>,
27-
typename mpl::if_<
28-
is_simple<Tag>,
29-
simple_connection_policy<Tag,version_major,version_minor>,
30-
typename mpl::if_<
31-
is_keepalive<Tag>,
32-
pooled_connection_policy<Tag,version_major,version_minor>,
33-
unsupported_tag<Tag>
34-
>::type
35-
>::type
36-
>
37-
{};
31+
struct connection_policy<Tag, version_major, version_minor, typename enable_if<is_async<Tag> >::type>
32+
{
33+
typedef async_connection_policy<Tag, version_major, version_minor> type;
34+
};
35+
36+
template <class Tag, unsigned version_major, unsigned version_minor>
37+
struct connection_policy<Tag, version_major, version_minor, typename enable_if<mpl::and_<is_simple<Tag>, mpl::not_<is_async<Tag> > > >::type>
38+
{
39+
typedef simple_connection_policy<Tag, version_major, version_minor> type;
40+
};
41+
42+
template <class Tag, unsigned version_major, unsigned version_minor>
43+
struct connection_policy<Tag, version_major, version_minor, typename enable_if<mpl::and_<is_keepalive<Tag>, mpl::not_<is_async<Tag> > > >::type>
44+
{
45+
typedef pooled_connection_policy<Tag, version_major, version_minor> type;
46+
};
3847

3948
} // namespace http
4049

boost/network/support/is_async.hpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,15 @@
88
// http://www.boost.org/LICENSE_1_0.txt)
99

1010
#include <boost/network/tags.hpp>
11-
#include <boost/mpl/if.hpp>
12-
#include <boost/type_traits/is_base_of.hpp>
11+
#include <boost/utility/enable_if.hpp>
1312

1413
namespace boost { namespace network {
1514

15+
template <class Tag, class Enable = void>
16+
struct is_async : mpl::false_ {};
17+
1618
template <class Tag>
17-
struct is_async :
18-
is_base_of<
19-
tags::async,
20-
Tag
21-
>
22-
{};
19+
struct is_async<Tag, typename enable_if<typename Tag::is_async>::type> : mpl::true_ {};
2320

2421
} // namespace network
2522

boost/network/support/is_default_string.hpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@
77
#define BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808
88

99
#include <boost/network/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network {
13-
13+
14+
template <class Tag, class Enable = void>
15+
struct is_default_string : mpl::false_ {};
16+
1417
template <class Tag>
15-
struct is_default_string :
16-
is_base_of<
17-
tags::default_string,
18-
Tag
19-
>
20-
{};
21-
18+
struct is_default_string<Tag, typename enable_if<typename Tag::is_default_string>::type> : mpl::true_ {};
19+
2220
} // namespace network
2321

2422
} // namespace boost

boost/network/support/is_default_wstring.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@
77
#define BOOST_NETWORK_SUPPORT_WSTRING_CHECK_20100808
88

99
#include <boost/network/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network {
1313

14+
template <class Tag, class Enable = void>
15+
struct is_default_wstring : mpl::false_ {};
16+
1417
template <class Tag>
15-
struct is_default_wstring :
16-
is_base_of<
17-
tags::default_wstring,
18-
Tag
19-
>
20-
{};
21-
18+
struct is_default_wstring<Tag, typename enable_if<typename Tag::is_default_wstring>::type> : mpl::true_ {};
19+
2220
} // namespace network
2321

2422
} // namespace boost

boost/network/support/is_http.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@
77
// http://www.boost.org/LICENSE_1_0.txt)
88

99
#include <boost/network/tags.hpp>
10-
#include <boost/type_traits/is_base_of.hpp>
10+
#include <boost/utility/enable_if.hpp>
1111

1212
namespace boost { namespace network {
1313

14+
template <class Tag, class Enable = void>
15+
struct is_http : mpl::false_ {};
16+
1417
template <class Tag>
15-
struct is_http :
16-
is_base_of<
17-
tags::http,
18-
Tag
19-
>
20-
{};
21-
18+
struct is_http<Tag, typename enable_if<typename Tag::is_http>::type> : mpl::true_ {};
19+
2220
} // namespace network
2321

2422
} // namespace boost

0 commit comments

Comments
 (0)