This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: c++ compiler results
- From: Plinky Dermis <plinkydermis at hotmail dot com>
- To: Plinky Dermis <plinkydermis at hotmail dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Mon, 28 Apr 2014 17:45:51 +0100
- Subject: Re: c++ compiler results
- Authentication-results: sourceware.org; auth=none
#include <exception>
#include <iostream>
#include <string>
#include <tuple>
#include <typeinfo>
// goal: make this code work with constexpr, tested on g++ 4.7.2 (-std=c++11)
//#define constexpr
std::string operator"" _s(const char *literal_string, size_t chars)
{
return std::string(literal_string, chars);
}
template <typename T,typename U>
constexpr bool typematch(const T& a, const U& b)
{
return typeid(a) == typeid(b);
}
template <size_t N>
struct MatchTypes_t
{
MatchTypes_t() = default;
template<typename M,typename ...T>
constexpr const void *matchType(const M& match, const std::tuple<T...>& t) const
{
const size_t tsize = std::tuple_size<std::tuple<T...>>::value;
if (typematch(std::get<tsize-N>(t), match)) {
constexpr auto find = MatchTypes_t<N-1>();
return find.matchType(match, t)
? nullptr : static_cast<const void*>(&(std::get<tsize-N>(t)));
} else {
constexpr auto find = MatchTypes_t<N-1>();
return find.matchType(match, t);
}
}
};
template <>
struct MatchTypes_t<0>
{
template<typename M,typename ...T>
constexpr const void *matchType(const M& match, const std::tuple<T...>& t) const
{
return nullptr;
}
};
namespace std {
template <typename M,typename ...T>
const M& get(std::tuple<T...>& t, std::exception e = std::bad_typeid(), M dummy = M()) throw(std::exception)
{
const size_t tsize = std::tuple_size<std::tuple<T...>>::value;
constexpr auto find = MatchTypes_t<tsize>();
constexpr const void *ptr = find.matchType(dummy, t);
if (!ptr) { // static_assert(ptr, "bad_typeid or more than one of that type");
throw e;
}
return *(static_cast<const M*>(ptr));
}
} // namespace std
int main()
{
auto vary = std::make_tuple('A', "mixed set of"_s, -1.2, 2);
const auto &s = std::get<std::string>(vary);
const auto d = std::get<double>(vary);
return ((s == "mixed set of") && (d == -1.2)) ? 0 : 1;
}