Skip to content

mp::invoke causes the meta size to increase exponentially. #72

@TypeCombinator

Description

@TypeCombinator

Code: https://godbolt.org/z/WxGfz3so7

#define NTEST 1
#include <https://raw.githubusercontent.com/boost-ext/mp/main/mp>
#include <type_traits>

namespace mp::detail {

template <size_t left = 0u, size_t right = MP_SIZE - 1u, auto = [](){}>
static constexpr auto meta_size() -> size_t {
    if constexpr (left >= right) {
        return left + requires { get(info<mp::info{left}>{}); };
    } else if constexpr (constexpr auto mid = left + (right - left) / 2u;
                         requires { get(info<mp::info{mid}>{}); }) {
        return meta_size<mid + 1u, right>();
    } else {
        return meta_size<left, mid - 1u>();
    }
}

} // namespace mp::detail

int main() {
    static_assert(static_cast<std::size_t>(mp::meta<char>) == 0);
    static_assert(static_cast<std::size_t>(mp::meta<unsigned char>) == 1);
    static_assert(static_cast<std::size_t>(mp::meta<int>) == 2);

    static_assert(mp::detail::meta_size() == 3);
    {
        constexpr auto m = mp::invoke<std::add_const>(mp::meta<char*>);
        static_assert(std::is_same_v<mp::type_of<m>, char* const>);
        static_assert(mp::detail::meta_size() == 9);
    }
    {
        constexpr auto m = mp::invoke<std::add_volatile>(mp::meta<char*>);
        static_assert(std::is_same_v<mp::type_of<m>, char* volatile>);
        static_assert(mp::detail::meta_size() == 19);
    }
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions