25 #ifndef CARGO_FIELDS_UNION_HPP
26 #define CARGO_FIELDS_UNION_HPP
32 #include <boost/any.hpp>
39 : boost::any(static_cast<const boost::any&>(any)) {};
42 static_cast<boost::any&
>(*this) =
static_cast<const boost::any&
>(any);
107 #define CARGO_DECLARE_UNION(...) \
109 DisableMoveAnyWrapper mCargoDeclareField; \
111 template<typename Visitor> \
112 void visitOption(Visitor& v, const std::string& name) { \
113 GENERATE_CODE(GENERATE_UNION_VISIT__, __VA_ARGS__) \
114 throw cargo::CargoException("Union type error. Unsupported type"); \
116 template<typename Visitor> \
117 void visitOption(Visitor& v, const std::string& name) const { \
118 GENERATE_CODE(GENERATE_UNION_VISIT_CONST__, __VA_ARGS__) \
119 throw cargo::CargoException("Union type error. Unsupported type"); \
121 std::string getOptionName() const { \
122 GENERATE_CODE(GENERATE_UNION_NAME__, __VA_ARGS__) \
123 return std::string(); \
125 boost::any& getHolder() { \
126 return static_cast<boost::any&>(mCargoDeclareField); \
128 const boost::any& getHolder() const { \
129 return static_cast<const boost::any&>(mCargoDeclareField); \
133 template<typename Visitor> \
134 void accept(Visitor v) { \
136 v.visit("type", name); \
137 visitOption(v, name); \
140 template<typename Visitor> \
141 void accept(Visitor v) const { \
142 const std::string name = getOptionName(); \
143 if (name.empty()) { \
144 throw cargo::CargoException("Type is not set"); \
146 v.visit("type", name); \
147 visitOption(v, name); \
150 template<typename Type> \
152 return boost::any_cast<Type>(&getHolder()) != NULL; \
154 template<typename Type> \
155 typename std::enable_if<!std::is_const<Type>::value, Type>::type& as() { \
156 if (getHolder().empty()) { \
157 throw cargo::CargoException("Type is not set"); \
159 return boost::any_cast<Type&>(getHolder()); \
161 template<typename Type> \
162 const Type& as() const { \
163 if (getHolder().empty()) { \
164 throw cargo::CargoException("Type is not set"); \
166 return boost::any_cast<const Type&>(getHolder()); \
169 return !getOptionName().empty(); \
171 template<typename Type> \
172 Type& set(const Type& src) { \
173 getHolder() = std::forward<const Type>(src); \
174 if (getOptionName().empty()) { \
175 throw cargo::CargoException("Unsupported type"); \
180 #define GENERATE_CODE(MACRO, ...) \
181 BOOST_PP_LIST_FOR_EACH(MACRO, _, BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__))
183 #define GENERATE_UNION_VISIT__(r, _, TYPE_) \
184 if (#TYPE_ == name) { \
185 v.visit("value", set(std::move(TYPE_()))); \
189 #define GENERATE_UNION_VISIT_CONST__(r, _, TYPE_) \
190 if (#TYPE_ == name) { \
191 v.visit("value", as<const TYPE_>()); \
195 #define GENERATE_UNION_NAME__(r, _, TYPE_) \
200 #endif // CARGO_FIELDS_UNION_HPP
DisableMoveAnyWrapper & operator=(DisableMoveAnyWrapper &&any)=delete
DisableMoveAnyWrapper()
Definition: fields-union.hpp:37
DisableMoveAnyWrapper(const DisableMoveAnyWrapper &any)
Definition: fields-union.hpp:38
DisableMoveAnyWrapper & operator=(const DisableMoveAnyWrapper &any)
Definition: fields-union.hpp:41
Definition: fields-union.hpp:34