1 //******************************************************************
3 // Copyright 2014 Intel Corporation All Rights Reserved.
4 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 /* To avoid confusion: These are not unit tests, these are "test programs". */
17 #include "OCReflect.h"
19 using namespace OC::OCReflect;
21 // Convert a native type to a property:
25 using namespace OC::OCReflect;
29 property_signature ps(property_type::nil);
30 named_property_binding npb("nil_property", ps);
36 OC::OCReflect::property my_bool = OC::OCReflect::make_property::apply(true, "my_bool");
37 OC::OCReflect::property my_bool_too = make_property::apply(false, "my_bool_too");
39 cout << my_bool << '\n' << my_bool_too << '\n';
41 auto x = concretize<bool>(my_bool);
42 auto y = concretize<bool>(my_bool_too);
44 cout << "got back: " << x << '\n';
45 cout << "got back: " << y << '\n';
53 const int64_t input { 1024 };
54 auto my_int = make_property::apply(input, "my int");
56 cout << my_int << '\n';
58 auto x = concretize<int64_t>(my_int);
65 // Rational (JSON: number):
67 const double input { 1024.0 };
68 auto my_float = make_property::apply(input, "my float");
70 cout << my_float << '\n';
72 auto x = concretize<double>(my_float);
81 const std::string input { "Hello, World!" };
83 auto my_string = make_property::apply(input, "my string");
85 cout << my_string << '\n';
87 auto x = concretize<std::string>(my_string);
95 // List (JSON: array):
97 property_signature(property_type::list);
101 // Dictionary (JSON: object):
103 property_signature(property_type::dictionary);
107 // test with attributes:
110 typedef property return_property;
113 return_property make_return_property(const InT& in)
115 return OC::OCReflect::make_property::apply(in, "__RETURN_VALUE__"); // ugly-- avert your eyes!
118 typedef std::function<return_property(const property_vector&)> bound_call;
122 std::map<std::string, bound_call> methods;
125 std::string test_fn(const std::string s0, const std::string s1)
127 return s0 + " " + s1;
131 template <class ...ParamsT>
132 void check_signature(const property_signature_vector& param_types, ParamsT ...params)
139 template <class ...ParamsT>
140 static return_property operator()(bound_call& f, const property_signature return_type, const property_signature_vector& param_types, ParamsT ...params)
142 check_signature(param_types, params...);
144 auto result = f(params...);
146 check_signature(return_type, result);
153 - if type is concrete type
154 - return curried function for that thing
155 - this binds eventually to property(property_list), but calls underlying fn
158 OC::OCReflect::property_signature head(const OC::OCReflect::property_signature_vector& psv)
163 // sloooow, but it will suit our purpose:
164 OC::OCReflect::property_signature_vector tail(const OC::OCReflect::property_signature_vector psv)
166 return OC::OCReflect::property_signature_vector(1 + psv.begin(), psv.end());
169 bool type_matches(const OC::OCReflect::property_type& expected_pt, const OC::OCReflect::property_data& in)
171 auto begin = in.begin();
173 auto found_pt = static_cast<OC::OCReflect::property_type>(*begin);
175 std::cout << "val ept=" << (int)expected_pt << ", ept: " << (int)found_pt << '\n';
177 return expected_pt == found_pt;
180 bool type_matches(const OC::OCReflect::property_type expected_pt, const OC::OCReflect::property& in)
182 return type_matches(expected_pt, std::get<1>(in));
185 bool signature_matches(const OC::OCReflect::property_signature&)
192 bool signature_matches(const OC::OCReflect::property_signature& expected, X x)
194 return type_matches(expected.type, OC::OCReflect::make_property::apply(x, "_"));
197 template <class X, class ...XS>
198 bool signature_matches(const OC::OCReflect::property_signature_vector expected, X x, XS ...xs)
200 return signature_matches(head(expected), x) && signature_matches(tail(expected), xs...);
203 template <class ...XS>
204 bool signature_matches(const OC::OCReflect::property_signature_vector expected, XS ...xs)
206 return signature_matches(head(expected), x) && signature_matches(tail(expected), xs...);
207 // return signature_matches(expected, xs...);
215 s.methods["test_fn"] =
216 [](const property_vector& in) -> return_property
218 for(const auto& p : in)
219 std::cout << p << '\n';
221 auto s0 = concretize<std::string>(in[0]);
222 auto s1 = concretize<std::string>(in[1]);
224 return make_return_property(test_fn(s0, s1));
228 pv.emplace_back(make_property::apply("Hello", "s0"));
229 pv.emplace_back(make_property::apply("World", "s1"));
231 std::cout << "INPUT:\n" << pv << '\n';
233 auto result = s.methods["test_fn"](pv);
235 std::cout << concretize<std::string>(std::get<1>(result));
237 using namespace OC::OCReflect;
241 auto foo = make_property::apply("Hi there", "s0");
242 assert(false == type_matches(property_type::boolean, foo));
243 assert(true == type_matches(property_type::string, foo));
247 // signature typechecking:
249 property_signature_vector sig {
250 { property_type::string },
251 { property_type::integer }
254 assert(false == signature_matches(sig, 5, "Hello"));
255 assert(true == signature_matches(sig, "Hello", 5));
260 auto sig = make_fun_sig(property_type::string, // result
261 property_type::string, property_type::string); // params
262 std::cout << sig << '\n';
265 auto f = make_fun(test_fn,
266 property_type::string, // result
267 property_type::string, property_type::string); // params
271 // Demo of how to generate OCStack stuff:
274 using OC::OCReflect::property_type;
275 using OC::OCReflect::named_property_binding;
277 named_property_binding_vector sigs {
278 named_property_binding("state", property_type::boolean),
279 named_property_binding("power", property_type::integer)
282 using namespace OC::OCReflect::to_OCStack;
285 char *LEDrep[] = { "state;b", "power;i", NULL};
287 char **LEDrep = convert(convert(sigs));
292 CREATE_RESOURCE_TYPE(LED, "core.led", LEDrep);
294 std::vector<std::string> reps { convert(sigs) };
295 for(const auto& r : reps)
296 std::cout << r << '\n';
298 // Example of flattening to a single string:
299 char *flattened = flatten(reps);
300 std::cout << "FLATTENED: " << flattened << '\n';
302 // Example of converting to an array of char*s:
303 char **handle = convert(reps);
305 if(nullptr == handle)
306 throw std::runtime_error("handle is a nullptr");
308 std::for_each(handle, handle + length(handle), [](const char *s) { std::cout << s << '\n'; });
310 /* ...or, you could do it this way (sad panda!):
311 for(char **cursor = handle; nullptr != *cursor; ++cursor)
312 printf("%s\n", *cursor);
315 release(handle); // remember to free the memory!
322 std::cout << "from_rep_test() doesn't do much yet :-)\n";
324 const char *LEDrep[] = { "state;b", "power;i", NULL };
326 named_property_binding_vector npbv(LEDrep);
328 cout << npbv << '\n';
334 using namespace OC::OCReflect;