Pfr
std::tuple like methods for user defined types without any macro or boilerplate code
This C++14 library provides basic reflection capabilities, allowing access to structure elements by index, retrieval of aggregate field names, and `std::tuple`-like methods for user-defined types — all without macros or boilerplate code. The project is written primarily in C++, distributed under the Boost Software License 1.0 license, first published in 2016. It has gained significant community traction with 1,480 stars and 169 forks on GitHub. Key topics include: boost, clang, cplusplus, cplusplus-14, cpp.
Boost.PFR
This C++14 library provides basic reflection capabilities, allowing access to structure elements by index, retrieval of aggregate field names, and std::tuple-like methods for user-defined types — all without macros or boilerplate code.
Boost.PFR is a part of the Boost C++ Libraries. However, Boost.PFR is a header only library that does not depend on Boost. You can just copy the content of the "include" folder from the github into your project, and the library will work fine.
For a version of the library without boost:: namespace see PFR.
Test results
| Branches | Build | Tests coverage | More info |
|---|---|---|---|
| Develop: | ![]() | details... | |
| Master: | ![]() | details... |
Latest developer documentation
Motivating Example #0
c#include <iostream> #include <fstream> #include <string> #include "boost/pfr.hpp" struct some_person { std::string name; unsigned birth_year; }; int main(int argc, const char* argv[]) { some_person val{"Edgar Allan Poe", 1809}; std::cout << boost::pfr::get<0>(val) // No macros! << " was born in " << boost::pfr::get<1>(val); // Works with any aggregate type! if (argc > 1) { std::ofstream ofs(argv[1]); ofs << boost::pfr::io(val); // File now contains: {"Edgar Allan Poe", 1809} } }
Output:
Edgar Allan Poe was born in 1809
Motivating Example #1
c#include <iostream> #include "boost/pfr.hpp" struct my_struct { // no ostream operator defined! int i; char c; double d; }; int main() { my_struct s{100, 'H', 3.141593}; std::cout << "my_struct has " << boost::pfr::tuple_size<my_struct>::value << " fields: " << boost::pfr::io(s) << "\n"; }
Outputs:
my_struct has 3 fields: {100, H, 3.14159}
Motivating Example #2
c#include <iostream> #include "boost/pfr.hpp" struct my_struct { // no ostream operator defined! std::string s; int i; }; int main() { my_struct s{{"Das ist fantastisch!"}, 100}; std::cout << "my_struct has " << boost::pfr::tuple_size<my_struct>::value << " fields: " << boost::pfr::io(s) << "\n"; }
Outputs:
my_struct has 2 fields: {"Das ist fantastisch!", 100}
Motivating Example #3
c#include <iostream> #include <string> #include <boost/config/warning_disable.hpp> #include <boost/spirit/home/x3.hpp> #include <boost/fusion/include/adapt_boost_pfr.hpp> #include "boost/pfr/io.hpp" namespace x3 = boost::spirit::x3; struct ast_employee { // No BOOST_FUSION_ADAPT_STRUCT defined int age; std::string forename; std::string surname; double salary; }; auto const quoted_string = x3::lexeme['"' >> +(x3::ascii::char_ - '"') >> '"']; x3::rule<class employee, ast_employee> const employee = "employee"; auto const employee_def = x3::lit("employee") >> '{' >> x3::int_ >> ',' >> quoted_string >> ',' >> quoted_string >> ',' >> x3::double_ >> '}' ; BOOST_SPIRIT_DEFINE(employee); int main() { std::string str = R"(employee{34, "Chip", "Douglas", 2500.00})"; ast_employee emp; x3::phrase_parse(str.begin(), str.end(), employee, x3::ascii::space, emp); std::cout << boost::pfr::io(emp) << std::endl; }
Outputs:
(34 Chip Douglas 2500)
Requirements and Limitations
License
Distributed under the Boost Software License, Version 1.0.
Contributors
Showing top 12 contributors by commit count.


