2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Mateusz Malicki (m.malicki2@samsung.com)
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
21 * @author Mateusz Malicki (m.malicki2@samsung.com)
22 * @brief Macros for declare configuration fields
25 #ifndef CONFIG_FIELDS_UNION_HPP
26 #define CONFIG_FIELDS_UNION_HPP
28 #include "config/fields.hpp"
33 * Use this macro to declare and register config fields
47 * CONFIG_DECLARE_UNION
54 * Example of valid configuration:
57 * "value": { "bar": "some string" }
67 * if (config.is<Foo>()) {
68 * Foo& foo = config.as<Foo>();
71 * if (config.is<int>())) {
72 * int field = config.as<int>();
78 #define CONFIG_DECLARE_UNION(...) \
79 struct TypeWrapperBase \
81 virtual ~TypeWrapperBase() {} \
84 template<typename Class> \
85 struct TypeWrapper : TypeWrapperBase \
91 std::unique_ptr<TypeWrapperBase> mConfigDeclareField__; \
93 template<typename Visitor> \
94 void accept(Visitor v) { \
96 v.visit("type", name); \
97 visitOption(v, name); \
100 template<typename Visitor> \
101 void accept(Visitor v) const { \
102 const std::string name = getOptionName(); \
103 if (!name.empty()) { \
104 v.visit("type", name); \
105 visitOption(v, name); \
107 /* Unsupported type in config file */ \
111 template<typename Visitor> \
112 void visitOption(Visitor& v, const std::string& name) { \
113 GENERATE_CODE(GENERATE_UNION_VISIT__, __VA_ARGS__) \
115 template<typename Visitor> \
116 void visitOption(Visitor& v, const std::string& name) const { \
117 GENERATE_CODE(GENERATE_UNION_VISIT_CONST__, __VA_ARGS__) \
119 std::string getOptionName() const { \
120 GENERATE_CODE(GENERATE_UNION_NAME__, __VA_ARGS__) \
121 return std::string(); \
124 template<typename Type> \
126 return dynamic_cast<TypeWrapper<Type>*>(mConfigDeclareField__.get()) != NULL; \
128 template<typename Type> \
130 assert(mConfigDeclareField__.get()); \
131 return dynamic_cast<TypeWrapper<Type>&>(*mConfigDeclareField__.get()).value; \
133 template<typename Type> \
134 const Type& as() const { \
135 assert(mConfigDeclareField__.get()); \
136 return dynamic_cast<const TypeWrapper<Type>&>(*mConfigDeclareField__.get()).value; \
139 #define GENERATE_CODE(MACRO, ...) \
140 BOOST_PP_LIST_FOR_EACH(MACRO, _, BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__))
142 #define GENERATE_UNION_VISIT__(r, _, TYPE_) \
143 if (#TYPE_ == name) { \
144 mConfigDeclareField__.reset(new TypeWrapper<TYPE_>()); \
145 v.visit("value", as<TYPE_>()); \
148 #define GENERATE_UNION_VISIT_CONST__(r, _, TYPE_) \
149 if (#TYPE_ == name) { \
150 v.visit("value", as<TYPE_>()); \
153 #define GENERATE_UNION_NAME__(r, _, TYPE_) \
158 #endif /* CONFIG_FIELDS_UNION_HPP */