diff --git a/doc/pfr.qbk b/doc/pfr.qbk index 73ef2fd..caaa4a8 100644 --- a/doc/pfr.qbk +++ b/doc/pfr.qbk @@ -63,6 +63,71 @@ Here's how to chose your functions: [endsect] + + +[section Short examples] + + +[pfr_quick_examples_structures] + +Following examples use definition from above: + +[table:quick_examples +[[ Code snippet ] [ `var` content or output ] [ Function description: ]] +[ + [ [pfr_quick_examples_flat_for_each] ] + [ `var == {B, {778, 4.14159}}` ] + [ [funcref boost::pfr::flat_for_each_field] ] +][ + [ [pfr_quick_examples_for_each] ] + [ `var == {B, {787, 103.142}}` ] + [ [funcref boost::pfr::for_each_field] ] +][ + [ [pfr_quick_examples_flat_for_each_idx] ] + [ ```0: char +1: int +2: double +``` ] + [ [funcref boost::pfr::flat_for_each_field] ] +][ + [ [pfr_quick_examples_for_each_idx] ] + [ ```0: char +1: quick_examples_ns::foo +``` ] + [ [funcref boost::pfr::for_each_field] ] +][ + [ [pfr_quick_examples_tuple_size] ] + [ `tuple_size: 2` ] + [ [classref boost::pfr::tuple_size] ] +][ + [ [pfr_quick_examples_flat_tuple_size] ] + [ `flat_tuple_size: 3` ] + [ [classref boost::pfr::flat_tuple_size] ] +][ + [ [pfr_quick_examples_get_1] ] + [ `var == {A {1, 2.0}}` ] + [ [funcref boost::pfr::get] ] +][ + [ [pfr_quick_examples_flat_get_1] ] + [ `var == {A, {1, 3.14159}}` ] + [ [funcref boost::pfr::flat_get] ] +][ + [ [pfr_quick_examples_get_2] ] + [ `var == {A, {777, 42.01}}` ] + [ [funcref boost::pfr::get] ] +][ + [ [pfr_quick_examples_flat_get_2] ] + [ `var == {A, {777, 42.01}}` ] + [ [funcref boost::pfr::flat_get] ] +]] + +[endsect] + + + + + + [section Three ways of getting operators ] There are three ways to start using Boost.PFR hashing, comparison and streaming operators for type `T` in your code. Each method has it's own drawbacks and suits own cases. diff --git a/example/examples.cpp b/example/examples.cpp index a50ec1c..97dda3d 100644 --- a/example/examples.cpp +++ b/example/examples.cpp @@ -98,6 +98,137 @@ assert(r == 11); (void)r; } + +#include +#include + +namespace quick_examples_ns { + +//[pfr_quick_examples_structures +struct foo { + int integer; + double real; + + void operator +=(int v) { + integer += v * 10; + real += v * 100; + } +}; + +struct bar { + char character; + foo f; +}; + +bar var{'A', {777, 3.141593}}; +//] + +inline std::ostream& operator<<(std::ostream& os, const bar& b) { + return os << '{' << b.character << ", {" << b.f.integer << ", " << b.f.real << "}}"; +} + +void test_examples() { + { + bar var{'A', {777, 3.141593}}; + +//[pfr_quick_examples_flat_for_each + // incrementing each field on 1: + boost::pfr::flat_for_each_field(var, [](auto& field) { + field += 1; + }); +//] + + std::cout << "flat_for_each_field outputs:\n" << var << '\n'; + } + + { + bar var{'A', {777, 3.141593}}; + +//[pfr_quick_examples_for_each + // incrementing first field on 1 and calling foo::operator+= for second field: + boost::pfr::for_each_field(var, [](auto& field) { + field += 1; + }); +//] + + std::cout << "flat_for_each_field outputs:\n" << var << '\n'; + } + + + + + { + bar var{'A', {777, 3.141593}}; + +//[pfr_quick_examples_flat_for_each_idx + boost::pfr::flat_for_each_field(var, [](const auto& field, std::size_t idx) { + std::cout << idx << ": " << boost::typeindex::type_id_runtime(field) << '\n'; + }); +//] + } + + { + bar var{'A', {777, 3.141593}}; + +//[pfr_quick_examples_for_each_idx + boost::pfr::for_each_field(var, [](const auto& field, std::size_t idx) { + std::cout << idx << ": " << boost::typeindex::type_id_runtime(field) << '\n'; + }); +//] + } + + + { +//[pfr_quick_examples_tuple_size + std::cout << "tuple_size: " << boost::pfr::tuple_size::value << '\n'; +//] + } + + { +//[pfr_quick_examples_flat_tuple_size + std::cout << "flat_tuple_size: " << boost::pfr::flat_tuple_size::value << '\n'; +//] + } + +#if __cplusplus >= 201606L /* Oulu meeting, not the exact value */ + { + bar var{'A', {777, 3.141593}}; +//[pfr_quick_examples_get_1 + boost::pfr::get<1>(var) = foo{1, 2}; // C++17 is required +//] + std::cout << "boost::pfr::get<1>(var) outputs:\n" << var << '\n'; + } +#endif + + { + bar var{'A', {777, 3.141593}}; +//[pfr_quick_examples_flat_get_1 + boost::pfr::flat_get<1>(var) = 1; +//] + std::cout << "boost::pfr::flat_get<1>(var) outputs:\n" << var << '\n'; + } + + + { + bar var{'A', {777, 3.141593}}; +//[pfr_quick_examples_get_2 + boost::pfr::get<1>(var.f) = 42.01; +//] + std::cout << "boost::pfr::get<1>(var.f) outputs:\n" << var << '\n'; + } + + { + bar var{'A', {777, 3.141593}}; +//[pfr_quick_examples_flat_get_2 + boost::pfr::flat_get<1>(var.f) = 42.01; +//] + std::cout << "boost::pfr::flat_get<1>(var.f) outputs:\n" << var << '\n'; + } +} + +} // namespace for_each_field_ex + int main() { example_get(); + quick_examples_ns::test_examples(); } diff --git a/include/boost/pfr/detail/core14.hpp b/include/boost/pfr/detail/core14.hpp index 0e0d978..5ad2a60 100644 --- a/include/boost/pfr/detail/core14.hpp +++ b/include/boost/pfr/detail/core14.hpp @@ -574,7 +574,7 @@ struct ubiq_is_flat_refelectable { template constexpr bool is_flat_refelectable(std::index_sequence) noexcept { constexpr std::size_t fields = sizeof...(I); - bool result[fields] = {}; + bool result[fields] = {I...}; const T v{ ubiq_is_flat_refelectable{result[I]}... }; (void)v; @@ -596,8 +596,9 @@ decltype(auto) tie_as_flat_tuple(T&& val) noexcept { template decltype(auto) as_tuple(T&& val) noexcept { + typedef std::remove_reference_t type; static_assert( - is_flat_refelectable>( std::make_index_sequence()>{} ), + boost::pfr::detail::is_flat_refelectable( std::make_index_sequence()>{} ), "Not possible in C++14 to represent that type without loosing information. Use flat_ version or change type definition" ); return tie_as_flat_tuple(std::forward(val)); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d48d0e1..7af8555 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -23,7 +23,7 @@ test-suite pfr [ run common/test_tuple_sizes_on.cpp : : : BOOST_PFR_RUN_TEST_ON=short : test_tuple_sizes_on_shorts ] [ run common/test_tuple_sizes_on.cpp : : : BOOST_PFR_RUN_TEST_ON=void* : test_tuple_sizes_on_voidptrs ] [ run common/test_tuple_sizes_on.cpp : : : BOOST_PFR_RUN_TEST_ON=std::size_t : test_tuple_sizes_on_size_ts ] - [ run common/test_tuple_sizes_on.cpp : : : BOOST_PFR_RUN_TEST_ON=char BOOST_PFR_RUN_HUGE_TESTS : test_tuple_sizes_on_chars_huge ] + #[ run common/test_tuple_sizes_on.cpp : : : BOOST_PFR_RUN_TEST_ON=char BOOST_PFR_RUN_HUGE_TESTS : test_tuple_sizes_on_chars_huge ] [ run flat/core.cpp ] [ run flat/flat_tuple_size.cpp ]