2
0
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:
Antony Polukhin
2017-09-16 21:19:41 +03:00
parent 14d59f5340
commit b67893d92e
4 changed files with 33 additions and 27 deletions

View File

@@ -15,7 +15,7 @@ Develop: | [![Build Status](https://travis-ci.org/apolukhin/magic_get.svg
Master: | [![Build Status](https://travis-ci.org/apolukhin/magic_get.svg?branch=master)](https://travis-ci.org/apolukhin/magic_get) <!-- [![Build status](https://ci.appveyor.com/api/projects/status/t6q6yhcabtk5b99l/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/boost-dll/branch/master) --> | [![Coverage Status](https://coveralls.io/repos/github/apolukhin/magic_get/badge.png?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).

View File

@@ -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]

View File

@@ -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

View File

@@ -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
///