tinyrefl

A work in progress minimal C++ static reflection API and codegen tool.

231
13
C++

tinyrefl pipeline status

A work in progress minimal C++ static reflection API and codegen tool.

Features

  • Reflection of classes and enums:

    • Class and enum names
    • User declared constructors
    • Public member functions
    • Public Member variables
    • Enumeration values
  • User defined attributes on all reflected entities

  • C++14 static reflection API: Convert enum values to strings, get the set of member
    functions of a class, check for attributes, visit object members…

    // foo.h
    
    namespace mylib {
    class [[interesting]] Foo {
        std::string str;
        void f() {}
        int i;
    
        enum class Enum
        {
            A, B, C
        };
    };
    }
    
    // main.cpp
    
    #include <tinyrefl/api.hpp>
    #include "foo.h"
    #include "foo.h.tinyrefl"
    
    int main()
    {
        static_assert(tinyrefl::has_attribute<mylib::Foo>("interesting"),
            "Wow, I thought your API was interesting...");
    
        static_assert(tinyrefl::metadata<mylib::Foo::Enum>().get_value(mylib::Foo::Enum::A).underlying_value() == 0,
            "Great, it seems to work");
    
        static_assert(tinyrefl::metadata<mylib::Foo::Enum>().get_value(mylib::Foo::Enum::A).name() == "A",
            "Once upon a time there was a proposal to make static_assert() accept constexpr strings as message");
    
        mylib::Foo foo{"hello", 42};
    
        tinyrefl::visit_object(foo, [](const std::string& name, auto depth, const auto& member, CTTI_STATIC_VALUE(tinyrefl::entity::MEMBER_VARIABLE))
        {
            std::cout << "Foo::" << name << ": " << member << "\n";
        });
    
        using base_classes = typename tinyrefl::metadata<mylib::Foo>::base_classes;
    }
    

    See the api.cpp example for a full example of usage.

  • API agnostic code generation: The tinyrefl-tool codegen tool included in the project is completely independent from the reflection API, generating
    macro based C/C++ code to allow users to write their own reflection API:

    #include <boost/fusion/adapted/struct/adapt_struct.hpp>
    
    // Write boost-adapt-struct compatible API:
    #define TINYREFL_STRING(...) # __VA_ARGS__
    #define TINYREFL_VALUE(...) __VA_ARGS__
    #define TINYREFL_SEQUENCE(...) __VA_ARGS__
    #define TINYREFL_TYPE(name, fullname) fullname
    #define TINYREFL_MEMBER(name, fullname, type, pointer) ((typename std::result_of<decltype(pointer), type>::type), (pointer))
    #define TINYREFL_REFLECT_CLASS(type, bases, members, classes, enums) BOOST_FUSION_ADAPT_STRUCT(type, members)
    
    #include "foo.h"
    #include "foo.h.tinyrefl"
    

    See examples/ for more backend examples.

  • CMake integration: Both the provided reflection API and codegen tool can be integrated in CMake based projects. To enable reflection,
    the library provides the tinyrefl_tool() function:

    
    # Include tinyrefl and its tooling
    add_subdirectory(thirdparty/tinyrefl)
    include(${TINYREFL_SOURCE_DIR}/tool/driver.cmake)
    
    # Declare your library
    add_library(mylib foo.h foo.cpp)
    
    # Enable code generation for foo.h of your library
    # The tool will be built and run before building your library
    tinyrefl_tool(TARGET mylib HEADERS foo.h)
    
  • Cross compilation supported: The CMake setup of tinyrefl detects whether your proyect is being
    cross compiled with a custom CMake toolchain file, and configures itself accordingly. No changes are needed
    in the tool integration as shown in the previous example.

Compiler support

The library has been testes against GCC >= 5.x and Clang >= 5.x.y. MSVC is not supported, but I have plans to make it work in the future.
See the CI build matrix for details.

Documentation

Docs available in the project wiki.

Acknowledgements

Many thanks to:

  • Jonathan “foonathan” Müller, for his awesome cppast library, feedback, and quick bugfixing.
  • My team lead at Bytech, for letting me integrate this for Qt QML C++ models (More about this soon).

License

This project is released under the MIT license. See LICENSE file for details.

Feedback and bug reporting

Feel free to open an issue in this repository. You can also send a mail to the project desk account incoming+Manu343726/[email protected].