I would be happy to get and advice how to deal with boost::variant in "two dimensional manner". Sounds strange but let my code say more (hopefully):
I have coded a class called Parameter:
template<typename PARAM_TYPE, typename DATA_TYPE=double>
class Parameter : public quantity<PARAM_TYPE, DATA_TYPE>
{
...
}
Example usage of my Parameter as defined above:
Parameter<si::length, double> SampleParameter1;
Parameter<si::dimensionless, short> SampleParameter2;
As I tried to explain by example above, I can define several Parameter types using the boost::units::si::???
and different data type like double, short, int
etc.
My GOAL is to construct a std::map
container which can store instances of any Parameter
type (as sampled above).
Therefore I have declared:
typedef boost::variant<Parameter<si::dimensionless, short>, Parameter<si::length, double> > SupportedParameterTypes;
std::map<int, SupportedParameterTypes> myMapStorage;
This works pretty well but have one big disadvantage I would like to solve - I have to define every single combination of Parameter type I would like to support in SupportedParameterTypes
type as defined above.
My idea was to define boost::mpl::vector constaining all the Parameter types I would like to support:
typedef boost::mpl::vector<si::dimensionless, si::length> ParameterTypes;
And all the possible Parameter data types being supported on the other hand:
typedef boost::mpl::vector<short, int, float, double> ParameterDataTypes;
There comes my troubles:
typedef typename boost::make_variant_over<ParameterTypes>::type ParameterTypeVariants;
typedef typename boost::make_variant_over<ParameterDataTypes>::type ParameterDataVariants;
typedef boost::variant<Parameter<ParameterTypeVariants, ParameterDataVariants> > SupportedParameterTypes;
But to define boost::variant
of something (Parameter
) which is defineed by some other boost::variant
seems not to work :o(
QUESTION: How to define std::map
container holding all my Parameter
types defined in appropriate boost::mpl::vector
s?
I would like to kindly ask you for help solving this issue. Maybe it is not good idea/principle at all to code it as I wrote, who knows. My goal is to have a flexible storage by std::map to be capable to hold all my Parameters without having my code ambiguous. Looking for smart solution of course :o)
Many thanks in advance for any reply to my question / request for help
You may produce all your pairing with something like
template <typename Seq, typename T1, typename T2>
struct cartesian_parameters_helper;
template <std::size_t...Is, typename T1, typename T2>
struct cartesian_parameters_helper<std::index_sequence<Is...>, T1, T2>
{
static constexpr std::size_t size1 = std::tuple_size<T1>::value;
using type = boost::variant<
Parameter<
std::tuple_element_t<Is / size1, T1>,
std::tuple_element_t<Is % size1, T2>
>...>;
};
template <typename T1, typename T2>
struct cartesian_parameters
{
using type = typename cartesian_parameters_helper<
std::make_index_sequence<std::tuple_size<T1>::value
* std::tuple_size<T2>::value>,
T1, T2>::type;
};
And then use it as
using SupportedParameterTypes =
cartesian_parameters<std::tuple<si::dimensionless, si::length>,
std::tuple<short, int, float, double>>::type;
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With