Skip to content

Commit 0be3ef5

Browse files
committed
Refactoring the common decorator/facade for directive function objects.
1 parent f5a7209 commit 0be3ef5

File tree

5 files changed

+152
-168
lines changed

5 files changed

+152
-168
lines changed

boost/network/message/directives/body.hpp

Lines changed: 9 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,38 @@
11

2-
// Copyright Dean Michael Berris 2007.
2+
// Copyright Dean Michael Berris 2007-2010.
33
// Distributed under the Boost Software License, Version 1.0.
44
// (See accompanying file LICENSE_1_0.txt or copy at
55
// http://www.boost.org/LICENSE_1_0.txt)
66

77
#ifndef __NETWORK_MESSAGE_DIRECTIVES_BODY_HPP__
88
#define __NETWORK_MESSAGE_DIRECTIVES_BODY_HPP__
99

10-
#include <boost/network/traits/string.hpp>
11-
#include <boost/network/support/is_async.hpp>
12-
#include <boost/network/support/is_sync.hpp>
13-
#include <boost/type_traits/is_same.hpp>
14-
#include <boost/variant/variant.hpp>
15-
#include <boost/variant/apply_visitor.hpp>
16-
#include <boost/variant/static_visitor.hpp>
17-
#include <boost/mpl/if.hpp>
18-
#include <boost/mpl/or.hpp>
10+
#include <boost/network/message/directives/detail/string_directive.hpp>
11+
#include <boost/network/message/directives/detail/string_value.hpp>
1912

2013
namespace boost { namespace network {
2114

2215
namespace impl {
2316

24-
struct body_directive {
25-
boost::variant<
26-
string<tags::default_string>::type,
27-
string<tags::default_wstring>::type,
28-
boost::shared_future<string<tags::default_string>::type>,
29-
boost::shared_future<string<tags::default_wstring>::type>
30-
> body_;
31-
32-
body_directive(string<tags::default_string>::type const & body)
33-
: body_(body) {}
34-
body_directive(string<tags::default_wstring>::type const & body)
35-
: body_(body) {}
36-
body_directive(boost::shared_future<string<tags::default_string>::type> const & body)
37-
: body_(body) {}
38-
body_directive(boost::shared_future<string<tags::default_wstring>::type> const & body)
39-
: body_(body) {}
40-
41-
body_directive(body_directive const & other)
42-
: body_(other.body_) {}
43-
44-
template <class Tag>
45-
struct value :
46-
mpl::if_<
47-
is_async<Tag>,
48-
boost::shared_future<typename string<Tag>::type>,
49-
typename mpl::if_<
50-
mpl::or_<
51-
is_sync<Tag>,
52-
is_same<Tag, tags::default_string>,
53-
is_same<Tag, tags::default_wstring>
54-
>,
55-
typename string<Tag>::type,
56-
unsupported_tag<Tag>
57-
>::type
58-
>
59-
{};
17+
struct body_directive_base {
6018

6119
template <class Message>
62-
struct body_visitor : boost::static_visitor<> {
20+
struct string_visitor : boost::static_visitor<> {
6321
Message const & message_;
64-
body_visitor(Message const & message)
22+
string_visitor(Message const & message)
6523
: message_(message) {}
66-
void operator()(typename value<typename Message::tag>::type const & body) const {
24+
void operator()(typename detail::string_value<typename Message::tag>::type const & body) const {
6725
message_.body(body);
6826
}
6927
template <class T> void operator()(T const &) const {
7028
// FIXME -- fail here
7129
}
7230
};
7331

74-
template <class Tag, template <class> class Message>
75-
void operator()(Message<Tag> const & message) const {
76-
apply_visitor(body_visitor<Message<Tag> >(message), body_);
77-
}
78-
7932
};
8033

34+
typedef detail::string_directive<body_directive_base> body_directive;
35+
8136
} // namespace impl
8237

8338

boost/network/message/directives/destination.hpp

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,37 @@
11

2-
// Copyright Dean Michael Berris 2007.
2+
// Copyright Dean Michael Berris 2007-2010.
33
// Distributed under the Boost Software License, Version 1.0.
44
// (See accompanying file LICENSE_1_0.txt or copy at
55
// http://www.boost.org/LICENSE_1_0.txt)
66

77
#ifndef __NETWORK_MESSAGE_DIRECTIVES_DESTINATION_HPP__
88
#define __NETWORK_MESSAGE_DIRECTIVES_DESTINATION_HPP__
99

10-
#include <boost/network/traits/string.hpp>
11-
#include <boost/network/support/is_async.hpp>
12-
#include <boost/network/support/is_sync.hpp>
13-
#include <boost/type_traits/is_same.hpp>
14-
#include <boost/variant/variant.hpp>
15-
#include <boost/variant/apply_visitor.hpp>
16-
#include <boost/variant/static_visitor.hpp>
17-
#include <boost/mpl/if.hpp>
18-
#include <boost/mpl/or.hpp>
10+
#include <boost/network/message/directives/detail/string_directive.hpp>
11+
#include <boost/network/message/directives/detail/string_value.hpp>
1912

2013
namespace boost { namespace network {
2114

2215
namespace impl {
2316

24-
struct destination_directive {
25-
boost::variant<
26-
string<tags::default_string>::type,
27-
string<tags::default_wstring>::type,
28-
boost::shared_future<string<tags::default_string>::type>,
29-
boost::shared_future<string<tags::default_wstring>::type>
30-
> destination_;
31-
32-
destination_directive(string<tags::default_string>::type const & destination)
33-
: destination_(destination) {}
34-
destination_directive(string<tags::default_wstring>::type const & destination)
35-
: destination_(destination) {}
36-
destination_directive(boost::shared_future<string<tags::default_string>::type> const & destination)
37-
: destination_(destination) {}
38-
destination_directive(boost::shared_future<string<tags::default_wstring>::type> const & destination)
39-
: destination_(destination) {}
40-
41-
destination_directive(destination_directive const & other)
42-
: destination_(other.destination_) {}
43-
44-
template <class Tag>
45-
struct value :
46-
mpl::if_<
47-
is_async<Tag>,
48-
boost::shared_future<typename string<Tag>::type>,
49-
typename mpl::if_<
50-
mpl::or_<
51-
is_sync<Tag>,
52-
is_same<Tag, tags::default_string>,
53-
is_same<Tag, tags::default_wstring>
54-
>,
55-
typename string<Tag>::type,
56-
unsupported_tag<Tag>
57-
>::type
58-
>
59-
{};
17+
struct destination_directive_base {
6018

6119
template <class Message>
62-
struct destination_visitor : boost::static_visitor<> {
20+
struct string_visitor : boost::static_visitor<> {
6321
Message const & message_;
64-
destination_visitor(Message const & message)
22+
string_visitor(Message const & message)
6523
: message_(message) {}
66-
void operator()(typename value<typename Message::tag>::type const & destination) const {
24+
void operator()(typename detail::string_value<typename Message::tag>::type const & destination) const {
6725
message_.destination(destination);
6826
}
6927
template <class T> void operator() (T const &) const {
7028
// FIXME -- fail here!
7129
}
7230
};
7331

74-
template <class Tag, template <class> class Message>
75-
void operator()(Message<Tag> const & message) const {
76-
apply_visitor(destination_visitor<Message<Tag> >(message), destination_);
77-
}
7832
};
33+
34+
typedef detail::string_directive<destination_directive_base> destination_directive;
7935

8036
} // namespace impl
8137

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#ifndef BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_DIRECTIVE_HPP_20100915
2+
#define BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_DIRECTIVE_HPP_20100915
3+
4+
// Copyright Dean Michael Berris 2010.
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// (See accompanying file LICENSE_1_0.txt or copy at
7+
// http://www.boost.org/LICENSE_1_0.txt)
8+
9+
#include <boost/network/traits/string.hpp>
10+
#include <boost/variant/variant.hpp>
11+
#include <boost/variant/apply_visitor.hpp>
12+
#include <boost/variant/static_visitor.hpp>
13+
#include <boost/mpl/if.hpp>
14+
#include <boost/mpl/or.hpp>
15+
16+
namespace boost { namespace network { namespace detail {
17+
18+
/** This directive template technically implements a decorator pattern
19+
* which takes a concrete implementation and uses that as a base. This
20+
* particular directive template requires the Base type to just include
21+
* a nested template named `string_visitor` that takes a single template
22+
* class parameter which is supposed to be a Message class/struct.
23+
*
24+
* A typical directive implementation of the visitor will take a reference
25+
* to a message as the constructor parameter and then performs operations
26+
* on that message. An example implementation of a directive base is given
27+
* below:
28+
*
29+
* struct foo_directive_base {
30+
* template <class Message>
31+
* struct string_visitor : boost::static_visitor<> {
32+
* Message const & message_;
33+
* string_visitor(Message const & message)
34+
* : message_(message) {}
35+
*
36+
* void operator()(
37+
* typename detail::string_value<typename Message::tag>::type
38+
* const & foo)
39+
* const {
40+
* // do something to message_ here.
41+
* }
42+
*
43+
* template <class T> void operator()(T const &) const {
44+
* // fail at runtime?
45+
* }
46+
* };
47+
* };
48+
*
49+
* TODO -- distill this pattern into a preprocessor macro.
50+
*/
51+
template <class Base>
52+
struct string_directive : public Base {
53+
boost::variant<
54+
string<tags::default_string>::type,
55+
string<tags::default_wstring>::type,
56+
boost::shared_future<string<tags::default_string>::type>,
57+
boost::shared_future<string<tags::default_wstring>::type>
58+
> string_;
59+
60+
explicit string_directive(string<tags::default_string>::type const & input)
61+
: string_(input) {}
62+
explicit string_directive(string<tags::default_wstring>::type const & input)
63+
: string_(input) {}
64+
explicit string_directive(boost::shared_future<string<tags::default_string>::type> const & input)
65+
: string_(input) {}
66+
explicit string_directive(boost::shared_future<string<tags::default_wstring>::type> const & input)
67+
: string_(input) {}
68+
69+
string_directive(string_directive const & other)
70+
: string_(other.string_) {}
71+
72+
template <class Tag, template <class> class Message>
73+
void operator()(Message<Tag> const & message) const {
74+
apply_visitor(typename Base::template string_visitor<Message<Tag> >(message), string_);
75+
}
76+
};
77+
78+
} /* detail */
79+
80+
} /* network */
81+
82+
} /* boost */
83+
84+
#endif /* BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_DIRECTIVE_HPP_20100915 */
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_VALUE_HPP_20100915
2+
#define BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_VALUE_HPP_20100915
3+
4+
// Copyright Dean Michael Berris 2010.
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// (See accompanying file LICENSE_1_0.txt or copy at
7+
// http://www.boost.org/LICENSE_1_0.txt)
8+
9+
#include <boost/network/traits/string.hpp>
10+
#include <boost/network/support/is_async.hpp>
11+
#include <boost/network/support/is_sync.hpp>
12+
#include <boost/thread/future.hpp>
13+
#include <boost/type_traits/is_same.hpp>
14+
#include <boost/mpl/if.hpp>
15+
#include <boost/mpl/or.hpp>
16+
17+
namespace boost { namespace network { namespace detail {
18+
19+
template <class Tag>
20+
struct string_value :
21+
mpl::if_<
22+
is_async<Tag>,
23+
boost::shared_future<typename string<Tag>::type>,
24+
typename mpl::if_<
25+
mpl::or_<
26+
is_sync<Tag>,
27+
is_same<Tag, tags::default_string>,
28+
is_same<Tag, tags::default_wstring>
29+
>,
30+
typename string<Tag>::type,
31+
unsupported_tag<Tag>
32+
>::type
33+
>
34+
{};
35+
36+
} /* detail */
37+
} /* network */
38+
} /* boost */
39+
40+
#endif /* BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_VALUE_HPP_20100915 */

0 commit comments

Comments
 (0)