Skip to content

voroncae/magic-cpp

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Magic Cpp

Header-only C++20 library provides static reflection for type, aggregate class and enum, no external dependencies, no registration, no macro, no code generation, just magic.

Documentation

type

just include magic/type.h to use these features

  • full name of type
struct Point{};
constexpr auto name = magic::full_name_of<Point>();
static_assert(name == "Point");

constexpr auto name2 = magic::full_name_of<std::vector<int>>();
static_assert(name2 == "std::vector<int, std::allocator<int>>");

constexpr auto name3 = magic::full_name_of<std::size_t>();
static_assert(name3 == "unsigned long long int");
  • display name of type
// specialization for type to get better readable
namespace magic
{
    template<>
    struct type_info<std::size_t>
    {
        constexpr static auto value = "std::size_t";
    };

    template<>
    struct type_info<std::string>
    {
        constexpr static auto value = "std::string";
    };
}

// use name_of to get the display name
constexpr auto name = magic::name_of<std::size_t>();
static_assert(name == "std::size_t");

constexpr auto name2 = magic::name_of<std::string>();
static_assert(name2 == "std::string");
  • visualize type
// for some complex type, it is hard to understand for human
// we can visualize it to a more readable form

using T = int (*(*(*)(int*))[4])(int*); // hard to understand
std::cout << magic::full_tree_of<T>() << std::endl;

Output:

ptr

using T = std::map<int, std::string>;
std::cout << magic::full_tree_of<T>() << std::endl;

Output:

map

you can also use tree_of to get a more compact form, more details see type.

just include magic/struct.h to use these features

struct Complex
{
    std::string name;
    std::vector<int> vec;
}; // Complex is an aggregate class
  • Retrieve field count of an aggregate class
static_assert(magic::field_count_of<Complex>() == 2);
  • Retrieve the field types for an aggregate class
using T = magic::field_types_of<Complex>;
static_assert(std::same_as<T, std::tuple<std::string, std::vector<int>>>);
  • Retrieve the field type at a given index for an aggregate class
static_assert(std::same_as<magic::field_type_of<Complex, 0>, std::string>);
static_assert(std::same_as<magic::field_type_of<Complex, 1>, std::vector<int>>);
  • Retrieve the field names for an aggregate class
constexpr auto names = magic::field_names_of<Complex>();
static_assert(names == std::array<std::string_view, 2>{"name", "vec"});
  • Retrieve the field name at a given index for an aggregate class
static_assert(magic::field_name_of<Complex>(0) == "name");
static_assert(magic::field_name_of<Complex>(1) == "vec");
  • Retrieve the field reference at a given index for an aggregate class
Complex c{"hello", {1, 2, 3}};
std::cout << magic::field_of<0>(c) << std::endl;
// output: hello

std::cout << magic::field_of<1>(c)[1] << std::endl;
// output: 2
  • Traverse all fields of an aggregate class
Complex c{"hello", {1, 2, 3}};
auto f = [](auto field)
{

};
magic::foreach(c, f);

enum

  • Retrieve the enum count

  • Retrieve the enum names

  • Retrieve the enum nam

  • Retrieve the bit field enum value

About

A C++20 header-only library that supports powerful reflection for C++

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 90.7%
  • Python 8.0%
  • Other 1.3%