OSDN Git Service

boost.type_erasureを使う実装に変更
[gikomona/libcore.git] / include / communication / message.hpp
1
2 #ifndef GIKOMONA_CORE_COMMUNICATION_MESSAGE_HPP
3 #define GIKOMONA_CORE_COMMUNICATION_MESSAGE_HPP
4
5 #include <sstream>
6
7 #include <boost/type_erasure/any.hpp>
8 #include <boost/type_erasure/constructible.hpp>
9 #include <boost/type_erasure/member.hpp>
10 #include <boost/mpl/vector.hpp>
11
12 #include "string.hpp"
13
14 namespace monazilla { namespace GikoMona { namespace core { namespace communication {
15     
16 BOOST_TYPE_ERASURE_MEMBER(has_to_raw, to_raw, 0)
17 BOOST_TYPE_ERASURE_MEMBER(has_msg_type, get_type, 0)
18
19 typedef mona_string raw_message;
20     
21 enum class message_type {
22     FAILURE,
23     REQUEST,
24     SUCCEED
25 };
26
27 typedef
28     boost::mpl::vector<
29         has_to_raw<raw_message()>,
30         has_msg_type<message_type()>
31     > message_requirements
32     ;
33     
34 typedef boost::type_erasure::any<message_requirements> message;
35
36 #define DEFINE_MESSAGE(type_, name, message)            \
37     class name {                                        \
38     public:                                             \
39         explicit                                        \
40         name (const mona_string& str) : detail(str) {}  \
41         ~name() = default;                              \
42         raw_message to_raw() const {                    \
43             std::ostringstream str_builder;             \
44             str_builder << #type_ << ":"                \
45                         << message << "("               \
46                         << detail  << ").";             \
47             return static_cast<raw_message>(            \
48                 convert_from(str_builder.str())         \
49             );                                          \
50         }                                               \
51         message_type get_type() { return type; }        \
52     private:                                            \
53         const mona_string detail;                       \
54         const message_type type = message_type::type_;  \
55 };
56
57 } } } }
58
59 #endif // GIKOMONA_CORE_COMMUNICATION_MESSAGE_HPP