refl-cpp |

README

Documentation

refl-cpp is a header-only library which provides compile-time reflection and introspection capabilities to C++. By encoding type metadata in the type system, refl-cpp allows you to process types and their fields and functions via constexpr and template metaprogramming.

Using refl-cpp in your project? I want to hear about it: contact me by email (see my profile), open an issue or add the #refl-cpp tag to your topics!

Have a question? Try asking in the Gitter channel.

Want to support refl-cpp? Consider making a donation.

# Table of Contents

- Introduction
  - Examples
  - Motivation
  - Performance
- Integration
  - Requirements
  - CMake
  - Packages
- Documentation
- Testing
- Contributors
- License

# Introduction

refl-cpp aims to provide a generic reflection system that is flexible enough to suit your needs while maintaining a relatively small API surface.

Some nice things refl-cpp supports out-of-the-box:

- custom attributes - constexpr `std::tuple`s associated with types and member descriptors
- proxy types - build generic `proxy<T>` types with the same members as `T` that can be used to wrap or extend functionality
- overloaded functions - you only declare your overloaded function once - refl-cpp knows how to work with it
- template types - use reflection with your containers and other templates; template types are perfectly-well supported
- template functions - refl-cpp also works with template functions, when the template parameters can be inferred from the function parameters

## Examples

- Implement a simple serialization system - example-serialization.cpp - View in Compiler Explorer Implements an efficient generic serialization procedure from scratch
- Simple SQL database abstraction - example-dao.cpp - View in Compiler Explorer Implements a basic ORM system which can generate SQL statements at compile-time from model classes using custom properties
- Iterate base classes with `bases<>` - example-inheritance.cpp - View in Compiler Explorer Uses the built-in `bases<>` attribute to iterate over a type's base classes
- Access reflection information at runtime - example-custom-rtti.cpp - View in Compiler Explorer Implements a basic runtime abstraction over refl-cpp which provides access to the reflection metadata at runtime via custom metadata objects
- XML-based GUI with strongly-types properties - example-binding.cpp - View in Compiler Explorer Implements a system for reading XML resources with refl-cpp, by building a custom runtime reflection layer on top of refl-cpp
- Implement a generic builder class factory - example-builders.cpp - View in Compiler Explorer Defines a generic `builder<T>` class, which implements the builder pattern for any type `T`.
- Convert fields to accessor methods - example-proxy.cpp - View in Compiler Explorer Uses the proxy feature to create a generic type `value_proxy<T>` which exposes all fields of `T` through accessors methods
- View an array of structs as a struct of arrays - example-struct-of-arrays.cpp - View in Compiler Explorer Uses the proxy feature to create a generic type `struct_of_arrays<T>` which stores all members of `T` in `std::vector`, but also has an `T operator[](int)` which constructs the individual objects on-demand
- Generate a struct of `std::optional` members - example-partials.cpp - View in Compiler Explorer Uses the proxy feature to create a generic type `partial<T>` which wraps all members of `T` in `std::optional`

## Motivation

I started developing refl-cpp during my final year in high-school. I was supposed to be studying for exams, but I had just read the original Static Reflection (2017) proposal, and after realising that it wasn't coming anytime soon, I decided that I had to try to cram as many of those features at possible into a compile-time library.

The library has grown and changed a lot since the early days, but even after several years, I still haven't seen another reflection library that supports constexpr and template metaprogramming. With other libraries, you often have to walk a metadata structure at runtime, invoke function pointers, and use type-erasure. With refl-cpp, you process the type metadata at compile-time, via `for_each` loops, all the types are there, and the compiler can often inline everything and generate the same code that you would have hand-written.

## Performance

All utility functions in refl-cpp are constexpr (except the ones in `refl::runtime`). Compilers will generally inline all loops and other constructs (when using `-O2`) and generate code that runs just as fast as if it was hand-written.

Thanks to some special compile-time optimisations, type metadata is generally not instantiated (no code-gen needs to happen) when the types themselves are not used in reflection. With 0.12.2, there have also been some major reductions in compilation time when using properties #60.

That being said, a word of caution: I have observed that after around the 250 reflected members mark, compilation times start to grow rapidly. If your codebase contains lots of huge classes (+250 functions), and you need to have all of them reflected with `refl-cpp`, this might be a deal breaker - benchmark before using.

# Integration

## Requirements

- Minimum language standard: C++17

## Single-header library

To use refl-cpp as a single-header library, copy `include/refl.hpp` to your include directory.

## CMake

You can also consume refl-cpp as a CMake dependecy (3.14+ required, thanks @friendlyanon).

## Packages

- `vcpkg install refl-cpp` (thanks @Vennor)
- `conan install refl-cpp`
- AUR (thanks @otreblan)

# Documentation

The online documentation is built with Doxygen. Run `doxygen Doxyfile` in `docs/` to update it.

# Testing

Run CMake with `-Drefl-cpp_DEVELOPER_MODE=ON` and make the `refl-cpp-tests` target.

# Contributors

Run CMake with `-Drefl-cpp_DEVELOPER_MODE=ON` flag. You may also want to setup a custom preset for a more convenient developer experience (see this comment on #44).

- Issue tracker - refl-cpp/issues
- Source code - refl-cpp
- Contributors - refl-cpp/contributors.md

# License

- MIT License (for more details, see the license file)