1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20 #ifndef __INTEL_OCPROPERTIES_H_20140708
21 #define __INTEL_OCPROPERTIES_H_20140708
35 #include <type_traits>
37 #include "OCException.h"
38 #include "OCPropertyTypes.h"
41 namespace OC { namespace OCReflect {
43 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_type& pt);
44 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_attribute& pa);
45 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_signature& ps);
46 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_binding& pb);
47 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property& p);
49 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_type_vector& pv);
50 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::property_vector& p);
52 std::ostream& operator<<(std::ostream& os, const OC::OCReflect::method_binding& mb);
54 }} // namespace OC::OCReflect
56 // Convert from a concrete type to a property:
57 namespace OC { namespace OCReflect { namespace to_property {
59 OC::OCReflect::tagged_property convert(const bool& in);
60 OC::OCReflect::tagged_property convert(const int& in);
61 OC::OCReflect::tagged_property convert(const int64_t& in);
62 OC::OCReflect::tagged_property convert(const double& in);
63 OC::OCReflect::tagged_property convert(const std::string& in);
65 }}} // namespace OC::OCReflect::to_property
67 // Convert from a property to a concrete type:
68 namespace OC { namespace OCReflect { namespace from_property {
70 typedef OC::OCReflect::property_data::const_iterator pdci;
71 typedef std::tuple<pdci, pdci> pd_iter_pair;
73 /* We need to use a struct to get around the fact that we can't partially specialize against a
74 free function's signature-- nothing else special happening here: */
77 static void convert(const pd_iter_pair& in, bool& out)
79 out = static_cast<bool>(static_cast<int>(*(std::get<0>(in))));
82 static void convert(const pd_iter_pair& in, int64_t& out)
84 std::copy(std::get<0>(in), std::get<1>(in), reinterpret_cast<char *>(&out));
87 static void convert(const pd_iter_pair& in, double& out)
89 std::copy(std::get<0>(in), std::get<1>(in), reinterpret_cast<char *>(&out));
92 static void convert(const pd_iter_pair& in, std::string& out)
94 out.assign(std::get<0>(in), std::get<1>(in));
99 }}} // namespace OC::OCReflect::from_property
101 // Run-time typechecking:
102 namespace OC { namespace OCReflect {
104 typedef std::tuple<OC::OCReflect::property_data::const_iterator, OC::OCReflect::property_data::const_iterator> pd_iter_tuple;
105 pd_iter_tuple consume_typecheck(const OC::OCReflect::property_type expected_pt, const OC::OCReflect::property_data& in);
107 }} // namespace OC::OCReflect
109 // Property binding factory:
110 namespace OC { namespace OCReflect {
112 inline OC::OCReflect::property_binding make_property_binding(const std::string& name, const OC::OCReflect::property_signature ps)
114 return OC::OCReflect::property_binding { name, ps };
117 inline OC::OCReflect::property_binding make_property_binding(const std::string& name, const OC::OCReflect::property_type pt, const OC::OCReflect::property_attribute pa = OC::OCReflect::property_attribute::rw)
119 return OC::OCReflect::property_binding { name, { pt, pa } };
122 }} // namespace OC::OCReflect
124 // ...probably not-so-efficent, but we want it "working" for now:
125 namespace OC { namespace OCReflect {
127 // ...a class just to facilitate the usual ADL trick:
128 struct make_property {
130 // ...work around array->bool conversion:
131 static OC::OCReflect::property apply(const char *in, const std::string& name)
133 return apply(std::string(in), name);
137 static OC::OCReflect::property apply(const InT& in, const std::string& name)
139 OC::OCReflect::tagged_property tp { OC::OCReflect::to_property::convert(in) };
140 OC::OCReflect::property_binding npb { OC::OCReflect::make_property_binding(name, std::get<0>(tp)) };
142 OC::OCReflect::property_data& tp_data = std::get<1>(tp);
144 // Encode the type, followed by the data:
145 OC::OCReflect::property_data encoded_data;
147 encoded_data.push_back(OC::OCReflect::map_property_type<InT>::value);
148 std::copy(std::begin(tp_data), std::end(tp_data), std::back_inserter(encoded_data));
150 return OC::OCReflect::property(npb, encoded_data);
153 }; // struct make_property
155 }} // namespace OC::OCReflect
157 namespace OC { namespace OCReflect {
159 template <class OutT>
160 OutT concretize(const OC::OCReflect::property_data& pd)
164 OC::OCReflect::from_property::conversion::convert(
166 static_cast<OC::OCReflect::property_type>(
167 OC::OCReflect::map_property_type<OutT>::value), pd), ret);
172 template <class OutT>
173 OutT concretize(const OC::OCReflect::tagged_property& tp)
175 return concretize<OutT>(std::get<1>(tp));
178 template <class OutT>
179 OutT concretize(const OC::OCReflect::property& p)
181 return concretize<OutT>(std::get<1>(p));
184 }} // namespace OC::OCReflect
186 /* JFW: We are using concretize<> to fill this niche-- candidate for removal:
187 namespace OC { namespace OCReflect {
189 // Runtime dynamic cast from entities to concrete types:
190 template <class OutT>
191 OutT narrow(const entity& e)
193 return OutT(); // placeholder
196 }} // namespace OC::OCReflect