Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

How it works

Fields count detection and getting references to members

Short description:

  1. at compile-time: use aggregate initialization to detect fields count in user-provided structure
    • BOOST_PFR_USE_CPP17 == 1:
      1. at compile-time: structured bindings are used to decompose a type T to known amount of fields
    • BOOST_PFR_USE_CPP17 == 0 && BOOST_PFR_USE_LOOPHOLE == 1:
      1. at compile-time: use aggregate initialization to detect fields count in user-provided structure
      2. at compile-time: make a structure that is convertible to anything and remember types it has been converted to during aggregate initialization of user-provided structure
      3. at compile-time: using knowledge from previous steps create a tuple with exactly the same layout as in user-provided structure
      4. at compile-time: find offsets for each field in user-provided structure using the tuple from previous step
      5. at run-time: get pointer to each field, knowing the structure address and each field offset
      6. at run-time: a tuple of references to fields is returned => all the tuple methods are available for the structure
    • BOOST_PFR_USE_CPP17 == 0 && BOOST_PFR_USE_LOOPHOLE == 0:
      1. at compile-time: let I be is an index of current field, it equals 0
      2. at run-time: T is constructed and field I is aggregate initialized using a separate instance of structure that is convertible to anything

        [Note] Note

        Additional care is taken to make sure that all the information about T is available to the compiler and that operations on T have no side effects, so the compiler can optimize away the unnecessary temporary objects.

      3. at compile-time: I += 1
      4. at compile-time: if I does not equal fields count goto step c. from inside of the conversion operator of the structure that is convertible to anything
      5. at compile-time: using knowledge from previous steps create a tuple with exactly the same layout as in user-provided structure
      6. at compile-time: find offsets for each field in user-provided structure using the tuple from previous step
      7. at run-time: get pointer to each field, knowing the structure address and each field offset
  2. at run-time: a tuple of references to fields is returned => all the tuple methods are available for the structure

Long description of some basics: Antony Polukhin: Better C++14 reflections. Long description of some basics of C++14 with BOOST_PFR_USE_LOOPHOLE == 0: Antony Polukhin: C++14 Reflections Without Macros, Markup nor External Tooling. Description of the BOOST_PFR_USE_LOOPHOLE == 1 technique by its inventor Alexandr Poltavsky in his blog.

Field name retrieval

  1. at compile-time:
    • Get references to members of an object of type T in constexpr function
    • Feed the reference from previous as a template parameter to a constexpr function with template <auto member_ptr>. That function returns __PRETTY_FUNCTION__ or some other vendor specific macro that prints the whole name of a function along with the template arguments.
    • The returned value from previous step contains the member name (godbolt example). Do some compiler specific parsing of the value and make a std::string_view that contains only the member name.
  2. at run-time: return the std::string_view with the member name.

PrevUpHomeNext