/type_utils

Type utilities for things like template packs, structs, functions, enums. Complex template pack manipulation.

Primary LanguageC++MIT LicenseMIT

Type Utils

Type utilities library for things like template packs, structs, functions, enums.

using namespace kaixo;

struct Struct {
    int a;
    double b;
    float c;
};

int my_fun(double, long, int, float) { return 1; }

enum my_enum { Value1, Value2 };

// boolean operations on type traits
template<require<is_integral || is_floating_point> Ty> 
struct my_type {};

int main() {

    // Simple type traits
    static_assert(info<int>::is_integral); 
    static_assert(info<double[3][5]>::extent<1> == 5);
    static_assert(info<double, long, int, float>::can_invoke<decltype(my_fun)>);
    
    // Query function information
    static_assert(info_v<my_fun>::arguments::size == 4); 
    static_assert(same_as<info_v<my_fun>::result::type, int>); 
    static_assert(same_as<info_v<my_fun>::pointer::type, int(*)(double, long, int, float)>);

    // Query struct member types
    static_assert(info<Struct>::members::size == 3);
    static_assert(same_as<info<Struct>::members::element<0>::type, int>);

    // Complex template pack manipulation
    static_assert(info<int, double, float>::filter<is_integral>::size == 1);
    static_assert(info<int, double, int>::indices<int>.size() == 2); // result: std::array{ 0ull, 2ull }
    static_assert(same_as<info<int, double, int, float>::unique, info<int, double, float>>);
    static_assert(info<int, unsigned, float, double>::count_filter<is_integral> == 2);

    // Enum value names
    static_assert(info<my_enum>::name<Value1> == "Value1");
    static_assert(info<my_enum>::name<1> == "Value2");
    static_assert(info<my_enum>::defined<0> == true);
    static_assert(info<my_enum>::defined<3> == false);

    // Type manipulation
    static_assert(same_as<info<int&>::add_cvref_from<const int>::type, const int&>);
    static_assert(same_as<info<const int&>::copy_ref_to<int>::type, int&>);

    // Sort types
    static_assert(same_as<
        info<uint16_t, uint64_t, uint8_t, uint32_t>::sort<type_sorters::size_desc>,
        info<uint64_t, uint32_t, uint16_t, uint8_t>
    >);

    // Transform pack of types
    static_assert(same_as<
        info<std::vector<int>, std::vector<double>>::transform<grab::reference>,
        info<int&, double&>
    >);

    return 0;
}