@@ -157,64 +157,83 @@ namespace adm {
157
157
}
158
158
};
159
159
160
+ // / base class which has methods for each type in a variant parameter.
161
+ // /
162
+ // / This should be used in HasParameters, with Parameter being a
163
+ // / parameter like OptionalParameter<V>, where V is a boost::variant.
164
+ // /
165
+ // / When using this with OptionalParameter<V>, the following classes should
166
+ // / be explicitly instantiated:
167
+ // / - OptionalParameter<V>
168
+ // / - One VariantTypeParameter<OptionalParameter<V>, T> for each T in V.
169
+ // / - VariantParameter<OptionalParameter<V>>
170
+ template <typename Parameter,
171
+ typename Variant = typename Parameter::ParameterType>
172
+ class VariantParameter ;
173
+
160
174
// / Base class for one type within a variant.
161
175
// /
162
- // / VariantParam should be a parameter type like
176
+ // / Parameter should be a parameter type like
163
177
// / OptionalParameter<boost::variant<...>>, and T should be one of the
164
178
// / types of the variant.
165
- template <typename VariantParam, typename T>
166
- class VariantTypeParameter : public virtual VariantParam {
167
- using Variant = typename VariantParam::ParameterType;
179
+ // /
180
+ // / this uses CRTP with VariantParameter to access the Variant type
181
+ template <typename Parameter, typename T>
182
+ class VariantTypeParameter {
183
+ using Base = VariantParameter<Parameter>;
168
184
using Tag = typename detail::ParameterTraits<T>::tag;
169
- using VariantTag = typename detail::ParameterTraits<Variant>::tag;
185
+
186
+ Base& base () { return static_cast <Base&>(*this ); }
187
+
188
+ const Base& base () const { return static_cast <const Base&>(*this ); }
170
189
171
190
public:
172
- using VariantParam::get;
173
191
ADM_BASE_EXPORT T get (Tag) const {
174
- return boost::get<T>(get (VariantTag{}));
192
+ return boost::get<T>(base (). get (typename Base:: VariantTag{}));
175
193
}
176
194
177
- using VariantParam::set;
178
195
ADM_BASE_EXPORT void set (T value) {
179
- return VariantParam:: set (std::move (value));
196
+ return base (). set (typename Base::Variant{ std::move (value)} );
180
197
}
181
198
182
- using VariantParam::has;
183
199
ADM_BASE_EXPORT bool has (Tag) const {
184
- return has (VariantTag{}) && get (VariantTag ()).type () == typeid (T);
200
+ return base ().has (typename Base::VariantTag{}) &&
201
+ base ().get (typename Base::VariantTag{}).type () == typeid (T);
185
202
}
186
203
187
- using VariantParam::isDefault;
188
204
ADM_BASE_EXPORT bool isDefault (Tag) const {
189
- return isDefault (VariantTag ()) && get (VariantTag ()).type () == typeid (T);
205
+ return base ().isDefault (typename Base::VariantTag{}) &&
206
+ base ().get (typename Base::VariantTag{}).type () == typeid (T);
190
207
}
191
208
192
- using VariantParam::unset;
193
209
ADM_BASE_EXPORT void unset (Tag) {
194
- if (has (Tag{})) unset (VariantTag{});
210
+ if (has (Tag{})) base (). unset (typename Base:: VariantTag{});
195
211
}
196
212
};
197
213
198
- template <typename VariantParam, typename VariantParameter>
199
- struct VariantParameterHelper ;
214
+ // implementation of VariantParameter; see above
215
+ template <typename Parameter, typename ... Options>
216
+ class VariantParameter <Parameter, boost::variant<Options...>>
217
+ : public Parameter, public VariantTypeParameter<Parameter, Options>... {
218
+ public:
219
+ using Variant = boost::variant<Options...>;
220
+ using VariantTag = typename detail::ParameterTraits<Variant>::tag;
221
+
222
+ using Parameter::get;
223
+ using VariantTypeParameter<Parameter, Options>::get...;
200
224
201
- template <typename VariantParam, typename ... Ts>
202
- struct VariantParameterHelper <VariantParam, boost::variant<Ts...>> {
203
- using type = HasParameters<VariantTypeParameter<VariantParam, Ts>...>;
204
- };
225
+ using Parameter::set;
226
+ using VariantTypeParameter<Parameter, Options>::set...;
205
227
206
- // / Wrapper which has methods for each type in a variant parameter.
207
- // /
208
- // / This should be used in HasParameters, with VariantParam being a
209
- // / parameter like OptionalParameter<V>, where V is a boost::variant.
210
- // /
211
- // / When using this with OptionalParameter<V>, the following classes should
212
- // / be explicitly instantiated:
213
- // / - OptionalParameter<V> (not VariantParameter<...>)
214
- // / - One VariantTypeParameter<OptionalParameter<V>, T> for each T in V.
215
- template <typename VariantParam>
216
- using VariantParameter = typename VariantParameterHelper<
217
- VariantParam, typename VariantParam::ParameterType>::type;
228
+ using Parameter::has;
229
+ using VariantTypeParameter<Parameter, Options>::has...;
230
+
231
+ using Parameter::isDefault;
232
+ using VariantTypeParameter<Parameter, Options>::isDefault...;
233
+
234
+ using Parameter::unset;
235
+ using VariantTypeParameter<Parameter, Options>::unset...;
236
+ };
218
237
219
238
// / Helper containing templated wrapper methods like `has<Param>()` around
220
239
// / overloaded `has(ParamTag)` type methods defined in T.
0 commit comments