Merge "Patch 1 : Adding Arduino WiFi support. This requires updated Arduino WiFi...
[platform/upstream/iotivity.git] / include / OCPropertyTypes.h
1
2 #ifndef __INTEL_OCPROPERTY_TYPES_H_20140723
3  #define __INTEL_OCPROPERTY_TYPES_H_20140723
4
5 #include <tuple>
6 #include <vector>
7 #include <algorithm>
8 #include <functional>
9
10 namespace OC { namespace OCReflect {
11
12 enum class property_type : uint8_t {
13     nil                 = 1,
14     boolean,
15     integer,
16     rational,
17     string,     
18     list,
19
20         INVALID
21 };
22
23 enum class property_attribute : uint8_t {
24     r,
25     w,
26     rw
27 };
28
29 struct property_signature
30 {
31  OC::OCReflect::property_type       type;
32  OC::OCReflect::property_attribute  attribute;
33
34  public:
35  property_signature()
36   : type(OC::OCReflect::property_type::nil),
37     attribute(OC::OCReflect::property_attribute::rw)
38  {}
39
40  property_signature(const OC::OCReflect::property_type& type_)
41   : type(type_),
42     attribute(OC::OCReflect::property_attribute::rw)
43  {}
44
45  property_signature(const OC::OCReflect::property_type type_, const OC::OCReflect::property_attribute attribute_)
46   : type(type_),
47     attribute(attribute_)
48  {}
49 };
50
51 typedef std::vector<property_type>                                                      property_type_vector;
52
53 typedef std::vector<property_signature>                     property_signature_vector;
54
55 typedef std::vector<char>                                   property_data;
56
57 typedef std::tuple<std::string, property_signature>         property_binding;        // ie. name + signature
58 typedef std::vector<property_binding>                                       property_binding_vector;
59
60 typedef std::tuple<property_binding, property_data>         property;
61 typedef std::tuple<property_signature, property_data>       tagged_property;         // eg. a return value
62
63 typedef std::vector<property>                               property_vector;
64
65 typedef std::function<property(property_vector)>            bound_function;
66
67
68 }} // namespace OC::OCReflect
69
70 namespace OC { namespace OCReflect {
71
72 namespace detail {
73
74 // zip a property type vector against an attribute:
75 inline property_signature_vector typev2signaturev(const property_type_vector& ptv, const property_attribute pa = property_attribute::rw)
76 {
77  property_signature_vector psv(ptv.size());
78
79  std::transform(std::begin(ptv), std::end(ptv), std::back_inserter(psv),
80                 [&pa](const property_type& pt) -> property_signature { return property_signature(pt, pa); });
81
82  return psv;
83 }
84
85 // Helper for constructing sequences (like vector<property>) from a parameter pack:
86 template <typename SeqT, typename T>
87 SeqT make_seq(const T& x)
88 {
89  return SeqT { x };
90 }
91
92 template <typename SeqT, typename T, typename ...TS>
93 SeqT make_seq(const T& x, const TS&... xs)
94 {
95  SeqT s { x };
96
97  auto vs = make_seq<SeqT>(xs...);
98
99  s.insert(s.end(), std::make_move_iterator(vs.begin()), std::make_move_iterator(vs.end()));
100
101  return s;
102 }
103
104 } // namespace OC::OCReflect::detail
105
106 struct method_signature
107 {
108  property_signature           ret_signature;
109  property_signature_vector    param_signatures;
110
111  public:
112  method_signature(const property_type& return_type, const property_signature_vector& param_types_)
113   : ret_signature(return_type, OC::OCReflect::property_attribute::r),
114     param_signatures(param_types_)
115  {}
116
117  method_signature(const property_type& return_type, const property_type_vector& param_types_)
118   : ret_signature(return_type, OC::OCReflect::property_attribute::r),
119     param_signatures(detail::typev2signaturev(param_types_))
120  {}
121
122  template <typename ...ParameterT>
123  method_signature(const property_type& return_type, const ParameterT& ...params_)
124   : ret_signature(return_type, OC::OCReflect::property_attribute::r),
125     param_signatures { detail::make_seq<property_signature_vector>(params_...) }
126  {}
127 };
128
129 }} // namespace OC::OCReflect
130
131 namespace OC { namespace OCReflect {
132
133 struct method_binding
134 {
135  friend std::ostream& operator<<(std::ostream& os, const OC::OCReflect::method_binding& mb);
136
137  public:
138  std::string            name;
139  bound_function         f;
140  method_signature       signature;
141
142  private:
143  static unsigned long long anon;
144
145  public: 
146  method_binding() 
147   : name("__ANONYMOUS__"), 
148     signature { property_type::nil, {{ property_type::nil, property_attribute::r }} }
149  {}
150
151  method_binding(bound_function& f,
152                 method_signature& signature_)
153   : signature(signature_)
154  {}
155
156  method_binding(const std::string& name_, bound_function& f_, 
157                 const property_type& return_type_, const property_type_vector& param_types_)
158   : name(name_),
159     f(f_),
160     signature { return_type_, param_types_ } 
161  {}
162
163  method_binding(const std::string& name_, bound_function& f_,
164                 const method_signature& signature_)
165   : name(name_),
166     f(f_),
167    signature(signature_)
168  {}
169 };
170
171 }} // namespace OC::OCReflect
172
173
174 // Map concerete to property type enumerations (used for returning runtime types from compile time types):
175 namespace OC { namespace OCReflect {
176
177 template <typename T>
178 struct map_property_type
179 {
180  static const uint8_t value = static_cast<const uint8_t>(OC::OCReflect::property_type::INVALID);
181 };
182
183 template <>
184 struct map_property_type<bool>
185 {
186  static const uint8_t value = static_cast<const uint8_t>(OC::OCReflect::property_type::boolean);
187 };
188
189 template <>
190 struct map_property_type<int64_t>
191 {
192  static const uint8_t value = static_cast<const uint8_t>(OC::OCReflect::property_type::integer);
193 };
194
195 template <>
196 struct map_property_type<double>
197 {
198  static const uint8_t value = static_cast<const uint8_t>(OC::OCReflect::property_type::rational);
199 };
200
201 template <>
202 struct map_property_type<std::string>
203 {
204  static const uint8_t value = static_cast<const uint8_t>(OC::OCReflect::property_type::string);
205 };
206
207 template <>
208 struct map_property_type<const char *>
209 {
210  static const uint8_t value = static_cast<const uint8_t>(OC::OCReflect::property_type::string);
211 };
212
213 /*
214 // Sequence containers:
215 template <>
216 struct map_property_type< template <class T, class A> >
217 {
218  static const uint8_t value = static_const<const uint8_t>(OC::OCReflect::property_type::list);
219 };
220
221 template <>
222 struct map_property_type<std::vector>
223 {
224  static const uint8_t value = static_const<const uint8_t>(OC::OCReflect::property_type::list);
225 };
226
227 template <>
228 struct map_property_type<std::list>
229 {
230  static const uint8_t value = static_const<const uint8_t>(OC::OCReflect::property_type::list);
231 };
232
233 template <>
234 struct map_property_type<std::forward_list>
235 {
236  static const uint8_t value = static_const<const uint8_t>(OC::OCReflect::property_type::list);
237 };
238
239 template <>
240 struct map_property_type<std::deque>
241 {
242  static const uint8_t value = static_const<const uint8_t>(OC::OCReflect::property_type::list);
243 };
244 */
245
246 }} // namespace OC::OCReflect
247
248 #endif