Check if one set of types is a subset of the other

前端 未结 9 843
甜味超标
甜味超标 2021-01-01 17:54

How can one check if one parameter pack (interpreted as a set) is a subset of another one?

So far I only have the frame (using std::tuple), but no functionality.

9条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-01 18:38

    You can do that with a class like the following one:

    template
    struct Check {
        template
        static constexpr bool verify() {
            using accumulator_type = bool[];
            bool check = false;
            accumulator_type accumulator = { (check = check || std::is_same())... };
            (void)accumulator;
            return check;
        }
    
        template
        static constexpr bool contain() {
            using accumulator_type = bool[];
            bool check = true;
            accumulator_type accumulator = { (check = check && verify())... };
            (void)accumulator;
            return check;
        }
    };
    

    Turning it in an example based on function is straightforward.
    It follows a possible implementation adapted to your code:

    #include 
    #include 
    
    template
    struct Check {
        template
        static constexpr bool verify() {
            using accumulator_type = bool[];
            bool check = false;
            accumulator_type accumulator = { (check = check || std::is_same())... };
            (void)accumulator;
            return check;
        }
    
        template
        static constexpr bool contain() {
            using accumulator_type = bool[];
            bool check = true;
            accumulator_type accumulator = { (check = check && verify())... };
            (void)accumulator;
            return check;
        }
    };
    
    
    template 
    struct is_subset_of;
    
    template 
    struct is_subset_of, std::tuple> {
        static constexpr bool value = Check::template contain();
    };
    
    int main() {
        using t1 = std::tuple;
        using t2 = std::tuple;
        using t3 = std::tuple;
    
        static_assert(is_subset_of::value, "err");
        static_assert(is_subset_of::value, "err");
        static_assert(is_subset_of::value, "err");
        static_assert(is_subset_of::value, "err");
        static_assert(!is_subset_of::value, "err");
    }
    

    The work is done within the class Check and it's methods contain and verify.
    The contain member function is the entry point. It uses a common trick (while waiting for the fold expressions) to unpack the subset and requires an explicit check for each contained type. The member function verify does the rest, by matching the single type with the given set.

    Let me know if I can give you more details or it's clear enough as it stands.


    See it running on coliru.

提交回复
热议问题