mapbox / variant

C++11/C++14 Variant
BSD 3-Clause "New" or "Revised" License
371 stars 100 forks source link

avoid expensive instantiation of tuple constructor in noexcept #132

Closed lightmare closed 7 years ago

lightmare commented 7 years ago

I've recently been testing different variant implementations, and found out mapbox::variant cannot hold many alternatives. This is due to exception-specification using tuple's constructor for the test, which turns out to be much more complex than I thought. Try this:

template <size_t N, typename... Types>
struct make_crazy_variant
    : make_crazy_variant<N-1, std::integral_constant<size_t, N>, Types...> {};

template <typename... Types>
struct make_crazy_variant<0, Types...>
{
    using type = mapbox::util::variant<Types...>;
};

TEST_CASE("crazy variant")
{
    using VT = typename make_crazy_variant<20>::type;
    VT v = VT();
}

make_crazy_variant<N> constructs a variant type with N alternatives. clang with its default -ftemplate-depth=256 won't compile this for N=20, gcc with default depth=900 can go up N=60 or so.

With this patch, clang can go up to N=230 (still with the default template depth), gcc can go beyond N=350 (this takes ~5GB memory to compile; can't confirm higher N, not enough memory).

This could also improve (albeit only slightly) mapnik compiles. I measured clang 3.8 compilation of mapnik/src/**/*.cpp (188 sources): total time: 885s before, 870s after average RSS: 168MB before, 164MB after max RSS: 639MB before, 631MB after

artemp commented 7 years ago

@lightmare good patch thanks!