I found solution for getting index of type in boost::variant without boost::mpl if you are interested in.
#include <iostream>
#include <type_traits>
#include <boost/variant/variant.hpp>
using myvariant = boost::variant<int, bool, double, int>;
template <typename T, typename ... Ts>
struct type_index;
template <typename T, typename ... Ts>
struct type_index<T, T, Ts ...>
: std::integral_constant<std::size_t, 0>
{};
template <typename T, typename U, typename ... Ts>
struct type_index<T, U, Ts ...>
: std::integral_constant<std::size_t, 1 + type_index<T, Ts...>::value>
{};
template <typename T, typename ... Ts>
struct variant_first_same_type_idx;
template <typename T, typename Head, typename ... Tail>
struct variant_first_same_type_idx<T, boost::variant<Head, Tail ... >>
: type_index<T, Head, Tail ...>
{};
int main()
{
std::cout << variant_first_same_type_idx<int, myvariant>::value << std::endl;
std::cout << variant_first_same_type_idx<bool, myvariant>::value << std::endl;
std::cout << variant_first_same_type_idx<double, myvariant>::value << std::endl;
}
The output of this program is:
0
1
2
UPDATE FOR C++17:
#include <iostream>
#include <stdexcept>
#include <type_traits>
#include <boost/variant/variant.hpp>
using myvariant = boost::variant<int, bool, double, int>;
// std::type_identity in C++20
template <typename T>
struct type_identity
{
using type = T;
};
template <typename T, typename... Ts>
constexpr std::size_t get_same_type_idx(type_identity<boost::variant<Ts...>>)
{
const bool is_same[]{std::is_same_v<Ts, T>...};
// std::find in C++20
for (std::size_t i = 0; i < sizeof...(Ts); ++i)
{
if (is_same[i])
{
return i;
}
}
throw std::out_of_range("Type not found");
}
template <typename T, typename V>
constexpr std::size_t variant_first_same_type_idx = get_same_type_idx<T>(type_identity<V>{});
int main()
{
std::cout << variant_first_same_type_idx<int, myvariant> << std::endl;
std::cout << variant_first_same_type_idx<bool, myvariant> << std::endl;
std::cout << variant_first_same_type_idx<double, myvariant> << std::endl;
}
mpl::vector
it works like a charm, but withvariant
'stypes
it fails with missingpos
member for type iterator. Consider this (pastebin.com/Hd01nJQy) snippet, secondstatic_assert
fails.