Skip to content

fogsong233/cpp-reflection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mini-Refl

A mini reflection library for cpp, extracted and re-composed from https://github.com/clice-project/clice.

Example:

enum class Nation {
    Yan,
    Laterano,
    Victoria,
    Ursus,
    Siracusa,
};

struct Info {
    int rank;
    int id;
};

struct Operator {
    Nation nation;
    int attack;
    int defense;
    std::string name;
    Info info;

    std::vector<std::string> tags;
    std::unordered_map<std::string, int> other_points;
    std::tuple<int, double, std::string> misc;
};

template <class T, int ident = 0, bool is_first = true>
void refl_print(const T& value) {
    constexpr bool needBlank = is_first;
    if constexpr(std::is_aggregate_v<T>) {
        std::println("{}{{", std::string(ident, ' '));
        using metainfo = refl::Struct<T>;
        [&]<std::size_t... Is>(std::index_sequence<Is...>) {
            ((std::print("{}{}: ", std::string(ident + 4, ' '), metainfo::fields[Is]),
              refl_print<decltype(refl::st::get<T, Is>(value)), ident + 4, false>(
                  refl::st::get<T, Is>(value))),
             ...);
        }(std::make_index_sequence<metainfo::member_count>{});
        std::println("{}}}{}", std::string(ident, ' '), ident == 0 ? "" : ",");
        return;
    } else if constexpr(std::is_enum_v<T>) {
        std::println("{}{},",
                     needBlank ? std::string(ident, ' ') : "",
                     refl::Enum<T>::fields[refl::impl::underlying_value(value)]);
        return;
    } else if constexpr(std::is_convertible_v<T, std::string_view>) {
        std::println("{}\"{}\",", needBlank ? std::string(ident, ' ') : "", value);
        return;
    } else if constexpr(refl::rg::map_range<T>) {
        std::println("{}({{", needBlank ? std::string(ident, ' ') : "");
        for(const auto& [k, v]: value) {
            std::print("{}{}: ", std::string(ident + 4, ' '), k);
            refl_print<decltype(v), ident + 4, false>(v);
        }
        std::println("{}}}),", std::string(ident, ' '));
        return;
    } else if constexpr(refl::rg::sequence_range<T>) {
        std::println("{}[", needBlank ? std::string(ident, ' ') : "");
        for(const auto& v: value) {
            refl_print<decltype(v), ident + 4, true>(v);
        }
        std::println("{}],", std::string(ident, ' '));
        return;

    } else {
        std::println("{}{},", needBlank ? std::string(ident, ' ') : "", value);
    }
};

int main(int argc, const char** argv) {
    Operator op = {
        .nation = Nation::Laterano,
        .attack = 1500,
        .defense = 800,
        .name = "Exusiai",
        .info =
            {
                   .rank = 5,
                   .id = 1001,
                   },
        .tags = {"DPS", "Ranged", "Physical"},
        .other_points = {{"DP", 50}, {"Cost", 18}},
        .misc = {42, 3.14, "Miscellaneous"},
    };
    refl_print(op);

    return 0;
}

output:

{
    nation: Laterano,
    attack: 1500,
    defense: 800,
    name: "Exusiai",
    info:     {
        rank: 5,
        id: 1001,
    },
    tags: [
        "DPS",
        "Ranged",
        "Physical",
    ],
    other_points: ({
        DP: 50,
        Cost: 18,
    }),
    misc: (42, 3.14, "Miscellaneous"),
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published