mirror of
https://github.com/boostorg/pfr.git
synced 2026-01-19 04:22:13 +00:00
Updated docs and enabled Loophole by default
This commit is contained in:
13
README.md
13
README.md
@@ -15,7 +15,7 @@ Develop: | [](https://travis-ci.org/apolukhin/magic_get) <!-- [](https://ci.appveyor.com/project/apolukhin/boost-dll/branch/master) --> | [](https://coveralls.io/github/apolukhin/magic_get?branch=master) | <!-- [details...](http://www.boost.org/development/tests/master/developer/pfr.html)) -->
|
||||
|
||||
|
||||
### C++14 Motivating Example
|
||||
### Motivating Example #1
|
||||
```c++
|
||||
// requires: C++14
|
||||
#include <iostream>
|
||||
@@ -42,9 +42,10 @@ Outputs:
|
||||
my_struct has 3 fields: {100, H, 3.14159}
|
||||
```
|
||||
|
||||
### C++17 Motivating Example
|
||||
### Motivating Example #2
|
||||
|
||||
```c++
|
||||
// requires: C++14
|
||||
#include <iostream>
|
||||
#include "boost/pfr.hpp"
|
||||
|
||||
@@ -54,7 +55,7 @@ struct my_struct { // no ostream operator defined!
|
||||
};
|
||||
|
||||
int main() {
|
||||
using namespace boost::pfr::ops; // C++17 out-of-the-box ostream operators for aggregate initializables!
|
||||
using namespace boost::pfr::ops; // out-of-the-box ostream operators for aggregate initializables!
|
||||
|
||||
my_struct s{{"Das ist fantastisch!"}, 100};
|
||||
std::cout << "my_struct has " << boost::pfr::tuple_size<my_struct>::value
|
||||
@@ -74,14 +75,8 @@ my_struct has 2 fields: {"Das ist fantastisch!", 100}
|
||||
General:
|
||||
* C++14 compatible compiler (GCC-5.0+, Clang, ...)
|
||||
* Static variables are ignored
|
||||
|
||||
C++14 limitations:
|
||||
* T must be constexpr aggregate initializable and must not contain references nor bitfields
|
||||
|
||||
C++17 limitations:
|
||||
* T must be aggregate initializable and must not contain arrays (but may contain `std::array` like classes)
|
||||
|
||||
|
||||
### License
|
||||
|
||||
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
|
||||
|
||||
35
doc/pfr.qbk
35
doc/pfr.qbk
@@ -63,16 +63,9 @@ Boost.Precise and Flat Reflection (Boost.PFR) adds following out-of-the-box func
|
||||
[section Flat or Precise functions to chose]
|
||||
All the functions that have `flat_` prefix and are declared in `boost/pfr/flat/*` headers the [*flat] functions, other function are [*precise] and are declared in `boost/pfr/precise/*`. In previous example you've seen how the the flattening works.
|
||||
|
||||
Flat functions are more limited in their reflection capabilities, but guarantee to not affect debug and release builds in C++14 mode (no additional code would be produced).
|
||||
|
||||
Precise functions have almost unlimited reflection capabilities, but may produce additional code in C++14 mode in debug builds and even in release builds (on old compilers or compilers with bad optimizers).
|
||||
|
||||
Here's how to chose your functions:
|
||||
|
||||
* If you work only with POD types and wish them flattened - use [*flat] functions
|
||||
* If you use C++17 - use [*precise] functions
|
||||
* If you work only with flat POD types in C++14 - use [*flat] functions
|
||||
* If you have modern compiler in C++14 mode and work with non-POD literal types with some hierarchy - you are forced to use [*precise] functions
|
||||
* If you wish types flattened - use [*flat] functions
|
||||
* If you use types with C arrays - use [*flat] functions
|
||||
* Otherwise use [*precise] functions
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -289,6 +282,21 @@ Following examples use definition from above:
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Configuration Macro]
|
||||
|
||||
By default Boost.PFR [*auto-detects your compiler abilities] and automatically defines the configuration macro into appropriate values. If you wish to override that behavior, just define:
|
||||
[table:linkmacro Macros
|
||||
[[Macro name] [Effect]]
|
||||
[[*BOOST_PFR_USE_CPP17*] [Define to `1` if you wish to use structured bindings and other C++17 features for reflection. Define to `0` otherwize.]]
|
||||
[[*BOOST_PFR_USE_LOOPHOLE*] [Define to `1` if you wish to exploit [@http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118 CWG 2118] for reflection. Define to `0` otherwize.]]
|
||||
]
|
||||
|
||||
Note that disabling [*Loophole] in C++14 significantly limitates the reflection abilities of the library. See next section for more info.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Requirements and Limitations]
|
||||
|
||||
[note Boost.PFR does not depend on any Boost library. You may use it's headers even without Boost. ]
|
||||
@@ -300,11 +308,10 @@ Following examples use definition from above:
|
||||
[*Flat] functions limitations:
|
||||
|
||||
* T must be POD and must not contain references nor bitfields
|
||||
* T must not contain pointers to user defined types
|
||||
* Enums will be returned as their underlying type
|
||||
* All the methods that provide access to fields have a `reinterpret_cast` to an unrelated type. All the possible efforts and compiler specific tricks were used to avoid issues. But strictly speaking *this is an Undefined Behavior.
|
||||
|
||||
C++14 [*precise] functions limitations (C++17 fixes those):
|
||||
C++14 [*precise] functions limitations with manually disabled [*Loophole](C++17 or not disabling Loophole fixes those):
|
||||
|
||||
* T must be constexpr aggregate initializable and all it's fields must be constexpr default constructible
|
||||
* [funcref boost::pfr::get], [funcref boost::pfr::structure_to_tuple], [funcref boost::pfr::structure_tie], [headerref boost/pfr/precise/core.hpp boost::pfr::tuple_element] require T to be a flat POD type
|
||||
@@ -327,6 +334,8 @@ Short description:
|
||||
* C++17:
|
||||
# at compile-time: structured bindings are used to decompose a type `T` to known amount of fields fields
|
||||
* C++14:
|
||||
# Same approach as with [*flat] functions
|
||||
* C++14 with disabled [*Loophole]:
|
||||
# at compile-time: use flat reflection if it could precisely reflect the type. Otherwise:
|
||||
# at compile-time: let `I` be is an index of current field, it equals 0
|
||||
# at run-time: `T` is constructed and field `I` is aggregate initialized using a separate instance of structure that is convertible to anything [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.]
|
||||
@@ -343,6 +352,8 @@ Long description: [@https://www.youtube.com/watch?v=abdeAew3gmQ Antony Polukhin:
|
||||
|
||||
Great thanks to Bruno Dutra for showing the technique to precisely reflect aggregate initializable type in C++14 [@https://github.com/apolukhin/magic_get/issues/5 Manual type registering/structured bindings might be unnecessary].
|
||||
|
||||
Great thanks to Alexandr Poltavsky for initial implementation the [*Loophole] technique and for describing it [@http://alexpolt.github.io/type-loophole.html in his blog].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Reference]
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PFR_USE_LOOPHOLE
|
||||
# define BOOST_PFR_USE_LOOPHOLE 0
|
||||
# define BOOST_PFR_USE_LOOPHOLE 1
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PFR_USE_CPP17
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace boost { namespace pfr {
|
||||
|
||||
/// \brief Returns reference or const reference to a field with index `I` in aggregate T.
|
||||
///
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD}.
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
|
||||
///
|
||||
/// \rcast14
|
||||
///
|
||||
@@ -53,7 +53,7 @@ constexpr decltype(auto) get(T& val) noexcept {
|
||||
|
||||
/// \brief `tuple_element` has a `typedef type-of-a-field-with-index-I-in-aggregate-T type;`
|
||||
///
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD}.
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
@@ -65,7 +65,7 @@ using tuple_element = detail::sequence_tuple::tuple_element<I, decltype( ::boost
|
||||
|
||||
/// \brief Type of a field with index `I` in aggregate `T`.
|
||||
///
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD}.
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
@@ -77,7 +77,7 @@ using tuple_element_t = typename tuple_element<I, T>::type;
|
||||
|
||||
/// \brief Creates an `std::tuple` from an aggregate T.
|
||||
///
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD}.
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
|
||||
///
|
||||
/// \rcast14
|
||||
///
|
||||
@@ -99,7 +99,7 @@ constexpr auto structure_to_tuple(const T& val) noexcept {
|
||||
|
||||
/// \brief Creates an `std::tuple` with lvalue references to fields of an aggregate T.
|
||||
///
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD}.
|
||||
/// \b Requires: C++17 or \flatpod{C++14 flat POD or C++14 with not disabled Loophole}.
|
||||
///
|
||||
/// \rcast14
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user