Real Time Open Sound Control librtosc: include/rtosc/typed-message.h Source File

Real Time Open Sound Control librtosc

typed-message.h
1 #ifndef RTOSC_TYPED_MESSAGE_H
2 #define RTOSC_TYPED_MESSAGE_H
3 #include <rtosc/typestring.hh>
4 #include <rtosc/rtosc.h>
5 #include <type_traits>
6 #include <stdexcept>
7
8 namespace rtosc
9 {
10 struct match_exact{};
11 struct match_partial{};
12
13 template<class... Types> class rtMsg;
14
15 // empty tuple
16 template<> class rtMsg<>
17 {
18 public:
19 rtMsg(const char *arg = NULL, const char *spec=NULL, bool _=false)
20 :msg(arg)
21 {
22 if(arg && spec && !rtosc_match_path(spec, arg, NULL))
23 msg = NULL;
24 (void)_;
25 }
26
27 operator bool(void){return this->msg;}
28
29 const char *msg;
30 };
31
32 template<class T>
33 struct advance_size
34 {
35 static std::true_type size;
36 };
37
38 template<char ... C>
39 struct advance_size<irqus::typestring<C...>>
40 {
41 static std::false_type size;
42 };
43
44 template<class T>
45 bool valid_char(char) { return false;}
46
47 template<>
48 bool valid_char<const char*>(char c) { return c=='s' || c=='S'; };
49
50 template<>
51 bool valid_char<int32_t>(char c) { return c=='i'; };
52
53 template<>
54 bool valid_char<float>(char c) { return c=='f'; };
55
56 template<int i>
57 bool validate(const char *arg)
58 {
59 return rtosc_narguments(arg) == i;
60 }
61
62 template<class T>
63 bool match_path(std::false_type, const char *arg)
64 {
65 return rtosc_match_path(T::data(), arg, NULL);
66 }
67
68 template<class T>
69 bool match_path(std::true_type, const char *)
70 {
71 return true;
72 }
73
74 template<int i, class This, class... Rest>
75 bool validate(const char *arg)
76 {
77 auto size = advance_size<This>::size;
78 if(size && !valid_char<This>(rtosc_type(arg,i)))
79 return false;
80 else if(!size && !match_path<This>(size, arg))
81 return false;
82 else
83 return validate<i+advance_size<This>::size,Rest...>(arg);
84 }
85
86 //Tuple Like Template Class Definition
87 template<class This, class... Rest>
88 class rtMsg<This, Rest...>:public rtMsg<Rest...>
89 {
90 public:
91 typedef This This_;
92 typedef rtMsg<Rest...> T;
93 rtMsg(const char *arg = NULL, const char *spec=NULL)
94 :T(arg, spec, false)
95 {
96 if(this->msg && !validate<0,This,Rest...>(this->msg))
97 this->msg = NULL;
98 }
99
100 rtMsg(const char *arg, const char *spec, bool)
101 :T(arg, spec, false)
102 {}
103
104 };
105
106
107 // tuple_element
108 template<size_t Index, class Tuple> struct osc_element;
109
110 // select first element
111 template<class This, class... Rest>
112 struct osc_element<0, rtMsg<This, Rest...>>
113 {
114 typedef This type;
115 };
116
117 // recursive tuple_element definition
118 template <size_t Index, class This, class... Rest>
119 struct osc_element<Index, rtMsg<This, Rest...>>
120 : public osc_element<Index - 1, rtMsg<Rest...>>
121 {
122 };
123
124 template<class T>
125 T rt_get_impl(const char *msg, size_t i);
126
127 template<>
128 const char *rt_get_impl(const char *msg, size_t i)
129 {
130 return rtosc_argument(msg,i).s;
131 }
132
133 template<>
134 int32_t rt_get_impl(const char *msg, size_t i)
135 {
136 return rtosc_argument(msg,i).i;
137 }
138
139 // get reference to _Index element of tuple
140 template<size_t Index, class... Types> inline
141 typename osc_element<Index, rtMsg<Types...>>::type
142 get(rtMsg<Types...>& Tuple)
143 {
144 if(!Tuple.msg)
145 throw std::invalid_argument("Message Does Not Match Spec");
146 typedef typename std::remove_reference<typename osc_element<Index, rtMsg<Types...>>::type>::type T;
147 return rt_get_impl<T>(Tuple.msg, Index);
148 }
149
150 template<class... Types> inline
151 typename osc_element<0, rtMsg<Types...>>::type
152 first(rtMsg<Types...>&Tuple)
153 {
154 return get<0>(Tuple);
155 }
156
157 template<class... Types> inline
158 typename osc_element<1, rtMsg<Types...>>::type
159 second(rtMsg<Types...>&Tuple)
160 {
161 return get<1>(Tuple);
162 }
163
164 };
165 #endif
rtosc_argument
rtosc_arg_t rtosc_argument(const char *msg, unsigned i)
Blob data may be safely written to.
rtosc::match_exact
Definition: typed-message.h:10
rtosc::advance_size
Definition: typed-message.h:34
rtosc::osc_element
Definition: typed-message.h:108
rtosc_match_path
const char * rtosc_match_path(const char *pattern, const char *msg, const char **path_end)
Attempt to match a rtosc style path while ignoring arguments.
rtosc_narguments
unsigned rtosc_narguments(const char *msg)
Returns the number of arguments found in a given message.
rtosc::match_partial
Definition: typed-message.h:11
rtosc::rtMsg
Definition: typed-message.h:13
rtosc.h
Functions handling messages and arguments.
rtosc_type
char rtosc_type(const char *msg, unsigned i)