From 58e9ffd9e1ccefc23c0da929d8b73e581fda7945 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Sun, 16 Jan 2022 21:38:32 +0400 Subject: [PATCH 01/10] [pfr_view] Just docs --- doc/algorithm.qbk | 122 ++++++++++++++++++++++++++++++++++++++++++- doc/fusion.qbk | 3 ++ doc/html/index.html | 1 + doc/organization.qbk | 1 + doc/sequence.qbk | 3 ++ doc/view.qbk | 90 +++++++++++++++++++++++++++++++ 6 files changed, 218 insertions(+), 2 deletions(-) diff --git a/doc/algorithm.qbk b/doc/algorithm.qbk index 3bda204dd..c92ad5bce 100644 --- a/doc/algorithm.qbk +++ b/doc/algorithm.qbk @@ -2,6 +2,7 @@ Copyright (C) 2001-2011 Joel de Guzman Copyright (C) 2006 Dan Marsden Copyright (C) 2010 Christopher Schmidt + Copyright (c) 2022 Denis Mikhailov Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -139,6 +140,89 @@ Linear, exactly `__result_of_size__::value`. [endsect] +[section pfr_fields] + +[important Please read __boost_pfr_lims__ before using this `pfr_fields`. Pay special attention to the SimpleAggregate concept.] + +[heading Description] +For a SimpleAggregate `agg`, `pfr_fields` returns a new sequence +with elements extracted by using __boost_pfr__. + +[heading Synopsis] + template< + typename SimpleAggregate + > + typename __result_of_pfr_fields__::type pfr_fields( + SimpleAggregate& agg); + + template< + typename SimpleAggregate + > + typename __result_of_pfr_fields__::type pfr_fields( + SimpleAggregate const& agg); + +[table Parameters + [[Parameter][Requirement][Description]] + [[`agg`][A model of SimpleAggregate][Operation's argument]] +] + +[heading Expression Semantics] + __pfr_fields__(agg); + +[*Return type]: A model of __random_access_sequence__ + +[*Semantics]: Returns a sequence with all elements of `SimpleAggregate`. + +[heading Complexity] +Constant. + +[heading Header] + + #include + #include + +[note This algorithm won't defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] + +[heading Example] + + struct some_person { // SimpleAggregate + std::string name; + unsigned birth_year; + }; + + some_person val{"Edgar Allan Poe", 1809}; + std::cout << __pfr_fields__(val) << std::endl; // (Edgar Allan Poe 1809) + +[heading Example] + + struct empty { // SimpleAggregate + }; + + struct aggregate : empty { // not a SimpleAggregate + std::string name; + int age; + boost::uuids::uuid uuid; + }; + + aggregate val{"Edgar Allan Poe", 1809, {}}; + __pfr_fields__(val); // non-portable behavior + +[heading Example] + + using some_person = __vector__< // not a SimpleAggregate + std::string + , unsigned + >; + + some_person val("Edgar Allan Poe", 1809); + __pfr_fields__(val); // won't compile + +[heading See also] + +__boost_pfr__ + +[endsect] + [endsect] [section Metafunctions] @@ -215,6 +299,42 @@ Constant. [endsect] +[section pfr_fields] + +[heading Description] +A metafunction returning the result type of applying __pfr_fields__. + +[heading Synopsis] + template + struct pfr_fields + { + typedef __unspecified__ type; + }; + +[table Parameters + [[Parameter] [Requirement] [Description]] + [[`SimpleAggregate`] [A model of SimpleAggregate from __boost_pfr__] [Operation's argument]] +] + +[heading Expression Semantics] + result_of::pfr_fields::type + +[*Return type]: A model of __random_access_sequence__ + +[*Semantics]: Returns a sequence with all elements of `SimpleAggregate`. + +[heading Complexity] +Constant. + +[heading Header] + + #include + #include + +[note This algorithm won't defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] + +[endsect] + [endsect] [endsect] @@ -2844,5 +2964,3 @@ Constant. [endsect] [endsect] - -[endsect] diff --git a/doc/fusion.qbk b/doc/fusion.qbk index f7a5bf766..61a1d1804 100644 --- a/doc/fusion.qbk +++ b/doc/fusion.qbk @@ -48,6 +48,8 @@ [def __boost_func_forward__ [@http://www.boost.org/libs/functional/forward Boost.Functional/Forward Library]] [def __boost_func_factory__ [@http://www.boost.org/libs/functional/factory Boost.Functional/Factory Library]] [def __boost_func_hash__ [@http://www.boost.org/doc/html/hash.html Boost.ContainerHash Library]] +[def __boost_pfr__ [@http://www.boost.org/doc/html/boost_pfr.html Boost.PFR Library]] +[def __boost_pfr_lims__ [@http://www.boost.org/doc/html/boost_pfr/limitations_and_configuration.html Boost.PFR Limitations and Configuration]] [def __std_pair_doc__ [@http://en.cppreference.com/w/cpp/utility/pair `std::pair`]] [def __std_tuple_doc__ [@http://en.cppreference.com/w/cpp/utility/tuple `std::tuple`]] [def __std_plus_doc__ [@http://en.cppreference.com/w/cpp/utility/functional/plus `std::plus`]] @@ -131,6 +133,7 @@ [def __zip_view__ [link fusion.view.zip_view `zip_view`]] [def __flatten_view__ [link fusion.view.flatten_view `flatten_view`]] [def __identity_view__ [link fusion.view.identity_view `identity_view`]] +[def __pfr_fields_view__ [link fusion.view.pfr_fields_view `pfr_fields_view`]] [def __array__ [link fusion.adapted.array array]] [def __std_pair__ [link fusion.adapted.std__pair `std::pair`]] diff --git a/doc/html/index.html b/doc/html/index.html index 9f0f14da5..3d53f1ffe 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -164,6 +164,7 @@
transform_view
reverse_view
identity_view
+
pfr_fields_view
nview
repetitive_view
flatten_view
diff --git a/doc/organization.qbk b/doc/organization.qbk index b062e6ed8..96111139e 100644 --- a/doc/organization.qbk +++ b/doc/organization.qbk @@ -61,6 +61,7 @@ link against. * transform_view * zip_view * identity_view + * pfr_fields_view * container * deque * list diff --git a/doc/sequence.qbk b/doc/sequence.qbk index 554d951fb..d4db89ebc 100644 --- a/doc/sequence.qbk +++ b/doc/sequence.qbk @@ -134,6 +134,7 @@ For any Forward Sequence s the following invariants always hold: * __reverse_view__ * __zip_view__ * __identity_view__ +* __pfr_fields_view__ [endsect] @@ -203,6 +204,7 @@ are not defined in __forward_sequence__. * __transform_view__ (where adapted sequence is a Bidirectional Sequence) * __zip_view__ (where adapted sequences are models of Bidirectional Sequence) * __identity_view__ (where adapted sequence is a Bidirectional Sequence) +* __pfr_fields_view__ [endsect] @@ -292,6 +294,7 @@ are not defined in __bidirectional_sequence__. * __transform_view__ (where adapted sequence is a Random Access Sequence) * __zip_view__ (where adapted sequences are models of Random Access Sequence) * __identity_view__ (where adapted sequence is a Random Access Sequence) +* __pfr_fields_view__ [endsect] diff --git a/doc/view.qbk b/doc/view.qbk index a3ad4d09c..f64b2f495 100644 --- a/doc/view.qbk +++ b/doc/view.qbk @@ -721,4 +721,94 @@ defined in the implemented models. [endsect] +[section pfr_fields_view] + +[important Please read __boost_pfr_lims__ before using this `pfr_fields_view`. Pay special attention to the SimpleAggregate concept.] + +[heading Description] + +`pfr_fields_view` is a view into a SimpleAggregate as a random access sequence. + +[heading Header] + + #include + #include + +[note This view won't defined by inclusion of 'boost/fusion/view.hpp'. ] + +[heading Synopsis] + + template + struct pfr_fields_view; + +[heading Template parameters] + +[table + [[Parameter] [Description] [Default]] + [[`SimpleAggregate`] [An user defined structure, satisfied 'SimpleAggregate' concept] []] +] + +[heading Model of] + +* __random_access_sequence__ + +[variablelist Notation + [[`P`] [A `pfr_fields_view` type]] + [[`p`, `p2`] [Instances of `pfr_fields_view`]] + [[`a`] [An instance of `SimpleAggregate`]] +] + +[heading Expression Semantics] + +Semantics of an expression is defined only where it differs from, or is not +defined in __random_access_sequence__. + +[table + [[Expression] [Semantics]] + [[`P(a)`] [Creates a `pfr_fields_view` from `a`.]] + [[`P(p)`] [Copy constructs a `pfr_fields_view` from another `pfr_fields_view`, `p`.]] + [[`p = p2`] [Assigns to a `pfr_fields_view`, `p`, from another `pfr_fields_view`, `p2`.]] +] + +[heading Example] + + struct some_person { // SimpleAggregate + std::string name; + unsigned birth_year; + }; + + some_person val{"Edgar Allan Poe", 1809}; + __pfr_fields_view__ view(val); + std::cout << view << std::endl; // (Edgar Allan Poe 1809) + +[heading Example] + + struct empty { // SimpleAggregate + }; + + struct aggregate : empty { // not a SimpleAggregate + std::string name; + int age; + boost::uuids::uuid uuid; + }; + + aggregate val{"Edgar Allan Poe", 1809, {}}; + __pfr_fields_view__ view(val); // non-portable behavior + +[heading Example] + + using some_person = __vector__< // not a SimpleAggregate + std::string + , unsigned + >; + + some_person val("Edgar Allan Poe", 1809); + __pfr_fields_view__ view(val); // won't compile + +[heading See also] + +__boost_pfr__ + +[endsect] + [endsect] From 5ba02db62783713647acadb83987359cb4b77bb7 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Mon, 17 Jan 2022 17:01:55 +0400 Subject: [PATCH 02/10] [pfr_view] Fixed docs --- doc/algorithm.qbk | 8 ++++++++ doc/fusion.qbk | 2 ++ 2 files changed, 10 insertions(+) diff --git a/doc/algorithm.qbk b/doc/algorithm.qbk index c92ad5bce..7f850f15f 100644 --- a/doc/algorithm.qbk +++ b/doc/algorithm.qbk @@ -301,6 +301,8 @@ Constant. [section pfr_fields] +[important Please read __boost_pfr_lims__ before using this `pfr_fields`. Pay special attention to the SimpleAggregate concept.] + [heading Description] A metafunction returning the result type of applying __pfr_fields__. @@ -333,6 +335,10 @@ Constant. [note This algorithm won't defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] +[heading See also] + +__boost_pfr__ + [endsect] [endsect] @@ -2964,3 +2970,5 @@ Constant. [endsect] [endsect] + +[endsect] diff --git a/doc/fusion.qbk b/doc/fusion.qbk index 61a1d1804..196c57f4d 100644 --- a/doc/fusion.qbk +++ b/doc/fusion.qbk @@ -232,6 +232,8 @@ [def __result_of_copy__ [link fusion.algorithm.auxiliary.metafunctions.copy `result_of::copy`]] [def __move__ [link fusion.algorithm.auxiliary.functions.move `move`]] [def __result_of_move__ [link fusion.algorithm.auxiliary.metafunctions.move `result_of::move`]] +[def __pfr_fields__ [link fusion.algorithm.auxiliary.functions.pfr_fields `pfr_fields`]] +[def __result_of_pfr_fields__ [link fusion.algorithm.auxiliary.metafunctions.pfr_fields `result_of::pfr_fields`]] [def __fold__ [link fusion.algorithm.iteration.functions.fold `fold`]] [def __result_of_fold__ [link fusion.algorithm.iteration.metafunctions.fold `result_of::fold`]] [def __reverse_fold__ [link fusion.algorithm.iteration.functions.reverse_fold `reverse_fold`]] From afaa50feaf26c96e24c915534ce24e2bbd690ec9 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Mon, 17 Jan 2022 21:43:42 +0400 Subject: [PATCH 03/10] [pfr_view] Implemented pfr_fields_view --- CMakeLists.txt | 1 + appveyor.yml | 1 + include/boost/fusion/algorithm/auxiliary.hpp | 8 + .../fusion/algorithm/auxiliary/pfr_fields.hpp | 41 ++++ include/boost/fusion/include/pfr_fields.hpp | 14 ++ .../boost/fusion/include/pfr_fields_view.hpp | 14 ++ include/boost/fusion/view.hpp | 8 + include/boost/fusion/view/pfr_fields_view.hpp | 14 ++ .../pfr_fields_view/detail/advance_impl.hpp | 46 +++++ .../view/pfr_fields_view/detail/at_impl.hpp | 41 ++++ .../pfr_fields_view/detail/begin_impl.hpp | 46 +++++ .../detail/deref_data_impl.hpp | 29 +++ .../pfr_fields_view/detail/deref_impl.hpp | 45 +++++ .../pfr_fields_view/detail/distance_impl.hpp | 40 ++++ .../view/pfr_fields_view/detail/end_impl.hpp | 49 +++++ .../view/pfr_fields_view/detail/next_impl.hpp | 46 +++++ .../pfr_fields_view/detail/prior_impl.hpp | 46 +++++ .../pfr_fields_view/detail/value_at_impl.hpp | 32 +++ .../detail/value_of_data_impl.hpp | 29 +++ .../pfr_fields_view/detail/value_of_impl.hpp | 32 +++ .../view/pfr_fields_view/pfr_fields_view.hpp | 52 +++++ .../pfr_fields_view_iterator.hpp | 56 ++++++ test/Jamfile | 11 ++ test/algorithm/pfr_fields.cpp | 187 ++++++++++++++++++ test/include/_pfr_fields.cpp | 13 ++ test/include/_pfr_fields_view.cpp | 13 ++ test/sequence/pfr_fields_view.cpp | 151 ++++++++++++++ test/sequence/pfr_fields_view_empty.cpp | 96 +++++++++ 28 files changed, 1161 insertions(+) create mode 100644 include/boost/fusion/algorithm/auxiliary/pfr_fields.hpp create mode 100644 include/boost/fusion/include/pfr_fields.hpp create mode 100644 include/boost/fusion/include/pfr_fields_view.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/advance_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/begin_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/deref_data_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/distance_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/next_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/prior_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/value_at_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/value_of_data_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/detail/value_of_impl.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp create mode 100644 include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp create mode 100644 test/algorithm/pfr_fields.cpp create mode 100644 test/include/_pfr_fields.cpp create mode 100644 test/include/_pfr_fields_view.cpp create mode 100644 test/sequence/pfr_fields_view.cpp create mode 100644 test/sequence/pfr_fields_view_empty.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 707b4f898..527d69400 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,4 +23,5 @@ target_link_libraries(boost_fusion Boost::type_traits Boost::typeof Boost::utility + Boost::pfr ) diff --git a/appveyor.yml b/appveyor.yml index debd336bb..539f1a331 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -82,6 +82,7 @@ install: - git submodule init libs/type_traits - git submodule init libs/typeof - git submodule init libs/utility + - git submodule init libs/pfr - git submodule init libs/headers tools/boost_install tools/build - git submodule update diff --git a/include/boost/fusion/algorithm/auxiliary.hpp b/include/boost/fusion/algorithm/auxiliary.hpp index 313c81f81..f300deb76 100644 --- a/include/boost/fusion/algorithm/auxiliary.hpp +++ b/include/boost/fusion/algorithm/auxiliary.hpp @@ -13,4 +13,12 @@ #include #endif +// Unfortunately, there is no way to determine the compatibility of the pfr library with the current compiler. +// The "boost/fusion/algorithm/auxiliary/pfr_fields.hpp" include has been commented out to ensure backward compatibility +// Please include it manually in your project + +// #if !defined(BOOST_FUSION_NO_PFR) +// #include +// #endif + #endif diff --git a/include/boost/fusion/algorithm/auxiliary/pfr_fields.hpp b/include/boost/fusion/algorithm/auxiliary/pfr_fields.hpp new file mode 100644 index 000000000..cbe6fb23b --- /dev/null +++ b/include/boost/fusion/algorithm/auxiliary/pfr_fields.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(FUSION_PFR_FIELDS_54763465_8735) +#define FUSION_PFR_FIELDS_54763465_8735 + +#include +#include + +namespace boost { namespace fusion { namespace result_of +{ + template + struct pfr_fields + { + typedef pfr_fields_view type; + }; +}}} + +namespace boost { namespace fusion +{ + template + constexpr BOOST_FUSION_GPU_ENABLED + auto pfr_fields(Aggregate& view) + { + using type = typename result_of::pfr_fields::type; + return type(view); + } + + template + constexpr BOOST_FUSION_GPU_ENABLED + auto pfr_fields(Aggregate const& view) + { + using type = typename result_of::pfr_fields::type; + return type(view); + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/include/pfr_fields.hpp b/include/boost/fusion/include/pfr_fields.hpp new file mode 100644 index 000000000..d53e8c5b6 --- /dev/null +++ b/include/boost/fusion/include/pfr_fields.hpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(FUSION_INCLUDE_PFR_FIELDS) +#define FUSION_INCLUDE_PFR_FIELDS + +#include +#include + + +#endif \ No newline at end of file diff --git a/include/boost/fusion/include/pfr_fields_view.hpp b/include/boost/fusion/include/pfr_fields_view.hpp new file mode 100644 index 000000000..b9bcf4eee --- /dev/null +++ b/include/boost/fusion/include/pfr_fields_view.hpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(FUSION_INCLUDE_PFR_FIELDS_VIEW) +#define FUSION_INCLUDE_PFR_FIELDS_VIEW + +#include +#include + + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view.hpp b/include/boost/fusion/view.hpp index 0d8ded42c..2d86941bc 100644 --- a/include/boost/fusion/view.hpp +++ b/include/boost/fusion/view.hpp @@ -19,4 +19,12 @@ #include #include +// Unfortunately, there is no way to determine the compatibility of the pfr library with the current compiler. +// The "boost/fusion/view/pfr_fields_view.hpp" include has been commented out to ensure backward compatibility +// Please include it manually in your project + +// #if !defined(BOOST_FUSION_NO_PFR) +// #include +// #endif + #endif diff --git a/include/boost/fusion/view/pfr_fields_view.hpp b/include/boost/fusion/view/pfr_fields_view.hpp new file mode 100644 index 000000000..5f868ddda --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view.hpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_JAN_17_2022_0726PM) +#define BOOST_FUSION_PFR_FIELDS_VIEW_JAN_17_2022_0726PM + +#include +#include +#include + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/advance_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/advance_impl.hpp new file mode 100644 index 000000000..802505ea0 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/advance_impl.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_ADVANCE_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_ADVANCE_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + template + struct pfr_fields_view_iterator; + + namespace extension + { + template + struct advance_impl; + + template<> + struct advance_impl + { + template + struct apply + { + using type = pfr_fields_view_iterator< + typename Iterator::aggregate_type + , mpl::int_ + >; + + constexpr BOOST_FUSION_GPU_ENABLED + static auto + call(Iterator const& it) + { + return type(it.agg); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp new file mode 100644 index 000000000..f55814e4b --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_AT_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_AT_IMPL_HPP_INCLUDED + +#include +#include +#include // for std::declval + +namespace boost { namespace fusion { + struct pfr_fields_view_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + using type = decltype(boost::pfr::get(std::declval().agg)); + + constexpr BOOST_FUSION_GPU_ENABLED + static decltype(auto) + call(Sequence& v) + { + return boost::pfr::get(v.agg); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/begin_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/begin_impl.hpp new file mode 100644 index 000000000..0af6dc610 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/begin_impl.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_BEGIN_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_BEGIN_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_tag; + + template + struct pfr_fields_view_iterator; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + using type = pfr_fields_view_iterator< + typename Sequence::aggregate_type + , mpl::int_<0> + >; + + constexpr BOOST_FUSION_GPU_ENABLED + static auto + call(Sequence& v) + { + return type(v.agg); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/deref_data_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/deref_data_impl.hpp new file mode 100644 index 000000000..43a898c66 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/deref_data_impl.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_DEREF_DATA_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_DEREF_DATA_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + namespace extension + { + template + struct deref_data_impl; + + template<> + struct deref_data_impl + : deref_impl + { + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp new file mode 100644 index 000000000..91141cb06 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_DEREF_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_DEREF_IMPL_HPP_INCLUDED + +#include +#include +#include // for std::declval + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template<> + struct deref_impl + { + template + struct apply + { + using type = decltype( + boost::pfr::get( + std::declval().agg + ) + ); + + constexpr BOOST_FUSION_GPU_ENABLED + static decltype(auto) + call(Iterator const& iter) + { + return boost::pfr::get(iter.agg); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/distance_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/distance_impl.hpp new file mode 100644 index 000000000..923819eaf --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/distance_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_DISTANCE_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_DISTANCE_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + namespace extension + { + template + struct distance_impl; + + template<> + struct distance_impl + { + template + struct apply + { + using type = mpl::int_; + + constexpr BOOST_FUSION_GPU_ENABLED + static auto + call(First const&, Last const&) + { + return type(); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp new file mode 100644 index 000000000..2f8d9147b --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_END_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_END_IMPL_HPP_INCLUDED + +#include +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_tag; + + template + struct pfr_fields_view_iterator; + + namespace extension + { + template + struct end_impl; + + template <> + struct end_impl + { + template + struct apply + { + using type = pfr_fields_view_iterator< + typename Sequence::aggregate_type + , mpl::int_::value> + >; + + constexpr BOOST_FUSION_GPU_ENABLED + static auto + call(Sequence& v) + { + return type(v.agg); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/next_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/next_impl.hpp new file mode 100644 index 000000000..badd6a0d6 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/next_impl.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_NEXT_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_NEXT_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + template + struct pfr_fields_view_iterator; + + namespace extension + { + template + struct next_impl; + + template<> + struct next_impl + { + template + struct apply + { + using type = pfr_fields_view_iterator< + typename Iterator::aggregate_type + , mpl::int_ + >; + + constexpr BOOST_FUSION_GPU_ENABLED + static auto + call(Iterator const& it) + { + return type(it.agg); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/prior_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/prior_impl.hpp new file mode 100644 index 000000000..17ccb5b2c --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/prior_impl.hpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_PRIOR_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_PRIOR_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + template + struct pfr_fields_view_iterator; + + namespace extension + { + template + struct prior_impl; + + template<> + struct prior_impl + { + template + struct apply + { + using type = pfr_fields_view_iterator< + typename Iterator::aggregate_type + , mpl::int_ + >; + + constexpr BOOST_FUSION_GPU_ENABLED + static auto + call(Iterator const& it) + { + return type(it.agg); + } + }; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/value_at_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/value_at_impl.hpp new file mode 100644 index 000000000..18b3e20a5 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/value_at_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_VALUE_AT_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_VALUE_AT_IMPL_HPP_INCLUDED + +#include +#include +#include // for std::remove_const_t + +namespace boost { namespace fusion { + struct pfr_fields_view_tag; + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply : boost::pfr::tuple_element> {}; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/value_of_data_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/value_of_data_impl.hpp new file mode 100644 index 000000000..72dd65caa --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/value_of_data_impl.hpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_VALUE_OF_DATA_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_VALUE_OF_DATA_IMPL_HPP_INCLUDED + +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + namespace extension + { + template + struct value_of_data_impl; + + template<> + struct value_of_data_impl + : value_of_impl + { + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/detail/value_of_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/value_of_impl.hpp new file mode 100644 index 000000000..b9e5ee3ae --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/value_of_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_VALUE_OF_IMPL_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_VALUE_OF_IMPL_HPP_INCLUDED + +#include +#include +#include // for std::remove_const_t + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + namespace extension + { + template + struct value_of_impl; + + template<> + struct value_of_impl + { + template + struct apply : boost::pfr::tuple_element> {}; + }; + } +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp new file mode 100644 index 000000000..9c3dd7d82 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_fields_view_tag; + struct random_access_traversal_tag; + struct fusion_sequence_tag; + + template + struct pfr_fields_view : sequence_base> + { + using fusion_tag = pfr_fields_view_tag; + using tag = fusion_sequence_tag; // this gets picked up by MPL + using category = random_access_traversal_tag; + using is_view = mpl::true_; + + using aggregate_type = Aggregate; + using size = mpl::int_::value>; + + constexpr BOOST_FUSION_GPU_ENABLED + explicit pfr_fields_view(Aggregate& in_agg) + : agg(in_agg) + {} + + constexpr BOOST_FUSION_GPU_ENABLED + pfr_fields_view(pfr_fields_view const& rhs) + : agg(rhs.agg) + {} + + Aggregate& agg; + }; +}} + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp new file mode 100644 index 000000000..fab602c8a --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_ITERATOR_HPP_INCLUDED) +#define BOOST_FUSION_PFR_FIELDS_VIEW_ITERATOR_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_fields_view_iterator_tag; + struct random_access_traversal_tag; + + template + struct pfr_fields_view_iterator + : iterator_base< pfr_fields_view_iterator > + { + static_assert(Pos::value >=0 && Pos::value <= boost::pfr::tuple_size::value, "out of range"); + using fusion_tag = pfr_fields_view_iterator_tag; + using category = random_access_traversal_tag; + + using aggregate_type = Aggregate; + using index = Pos; + + constexpr BOOST_FUSION_GPU_ENABLED + explicit pfr_fields_view_iterator(Aggregate& in_agg) + : agg(in_agg) + {} + + Aggregate& agg; + }; +}} + +#ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408 +namespace std +{ + template + struct iterator_traits< ::boost::fusion::pfr_fields_view_iterator > + { }; +} +#endif + +#endif \ No newline at end of file diff --git a/test/Jamfile b/test/Jamfile index 13dd35c55..b4780c985 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -66,8 +66,15 @@ project [ run algorithm/zip2.cpp ] [ run algorithm/zip_ignore.cpp ] [ run algorithm/flatten.cpp ] + [ run algorithm/pfr_fields.cpp : : + : [ requires cxx14_constexpr ] ] [ compile algorithm/ticket-5490.cpp ] + [ compile include/_pfr_fields.cpp + : [ requires cxx14_constexpr ] ] + [ compile include/_pfr_fields_view.cpp + : [ requires cxx14_constexpr ] ] + [ run sequence/as_deque.cpp ] [ run sequence/as_list.cpp ] [ run sequence/as_map.cpp ] @@ -157,6 +164,10 @@ project : tuple_traits__no_variadic ] [ run sequence/transform_view.cpp ] [ run sequence/identity_view.cpp ] + [ run sequence/pfr_fields_view.cpp : : + : [ requires cxx14_constexpr ] ] + [ run sequence/pfr_fields_view_empty.cpp : : + : [ requires cxx14_constexpr ] ] [ run sequence/vector_comparison.cpp ] [ run sequence/vector_construction.cpp ] [ run sequence/vector_conversion.cpp ] diff --git a/test/algorithm/pfr_fields.cpp b/test/algorithm/pfr_fields.cpp new file mode 100644 index 000000000..d2ccd0272 --- /dev/null +++ b/test/algorithm/pfr_fields.cpp @@ -0,0 +1,187 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +struct is_same_thernary + : std::integral_constant::value && std::is_same::value)> +{ +}; + + + +namespace namespaced_type { + typedef int integer; +} + +namespace ns { + struct point { + int x; + int y; + namespaced_type::integer z; + }; +} + +struct A +{ + int first; + int second; + int third; +}; + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + using ns::point; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + using pfr_t = boost::fusion::result_of::pfr_fields::type; + static_assert(traits::is_view< pfr_t >::value, ""); + point p = {123, 456, 789}; + + std::cout << at_c<0>(pfr_fields(p)) << std::endl; + std::cout << at_c<1>(pfr_fields(p)) << std::endl; + std::cout << at_c<2>(pfr_fields(p)) << std::endl; + std::cout << pfr_fields(p) << std::endl; + BOOST_TEST(pfr_fields(p) == make_vector(123, 456, 789)); + + at_c<0>(pfr_fields(p)) = 6; + at_c<1>(pfr_fields(p)) = 9; + at_c<2>(pfr_fields(p)) = 12; + BOOST_TEST(pfr_fields(p) == make_vector(6, 9, 12)); + + BOOST_STATIC_ASSERT(boost::fusion::result_of::size::value == 3); + BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty::value); + + BOOST_TEST(front(pfr_fields(p)) == 6); + BOOST_TEST(back(pfr_fields(p)) == 12); + } + + { + A a{100, 200, 300}; + auto view = boost::fusion::pfr_fields(a); + + using namespace boost::fusion; + + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::pfr_fields::type + , decltype(pfr_fields(a)) + , pfr_fields_view + >)); + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::prior< boost::fusion::result_of::end::type >::type + , std::remove_const_t + , pfr_fields_view_iterator > + >)); + + BOOST_TEST(*prior(end(view)) == 300); + BOOST_TEST(*next(begin(view)) == 200); + BOOST_TEST(distance(begin(view), end(view)) == 3); + BOOST_TEST(advance< boost::mpl::int_<3> >(begin(view)) == end(view)); + } + + { + A a; // it must be instead of std::declval + const A ca{800, 600, 500}; + + using namespace boost::fusion; + + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::deref::type + , decltype(deref(begin(pfr_fields(a)))) + , int& + >)); + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::deref::type + , decltype(deref(begin(pfr_fields(ca)))) + , const int& + >)); + + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::deref>(end(pfr_fields(a))) )>::type + , decltype(deref(advance>(end(pfr_fields(a))))) + , int& + >)); + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::deref>(end(pfr_fields(ca))) )>::type + , decltype(deref(advance>(end(pfr_fields(ca))))) + , const int& + >)); + } + + { + A a; // it must be instead of std::declval + const A ca{800, 600, 500}; + + using namespace boost::fusion; + + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::at_c::type + , decltype(at_c<0>(pfr_fields(a))) + , int& + >)); + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::at_c::type + , decltype(at_c<0>(pfr_fields(ca))) + , const int& + >)); + } + + { + A a{100, 200, 300}; + const A ca{800, 600, 500}; + + using namespace boost::fusion; + + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::value_of< boost::fusion::result_of::begin::type >::type + , boost::fusion::result_of::value_at< decltype(pfr_fields(a)), boost::mpl::int_<0> >::type + , int + >)); + + BOOST_MPL_ASSERT((is_same_thernary< + boost::fusion::result_of::value_of< boost::fusion::result_of::begin::type >::type + , boost::fusion::result_of::value_at< decltype(pfr_fields(ca)), boost::mpl::int_<0> >::type + , int + >)); + } + + return boost::report_errors(); +} \ No newline at end of file diff --git a/test/include/_pfr_fields.cpp b/test/include/_pfr_fields.cpp new file mode 100644 index 000000000..5d98803a9 --- /dev/null +++ b/test/include/_pfr_fields.cpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include +#include + +int +main() +{ + return boost::report_errors(); +} \ No newline at end of file diff --git a/test/include/_pfr_fields_view.cpp b/test/include/_pfr_fields_view.cpp new file mode 100644 index 000000000..4362941d9 --- /dev/null +++ b/test/include/_pfr_fields_view.cpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include +#include + +int +main() +{ + return boost::report_errors(); +} \ No newline at end of file diff --git a/test/sequence/pfr_fields_view.cpp b/test/sequence/pfr_fields_view.cpp new file mode 100644 index 000000000..f525edd3c --- /dev/null +++ b/test/sequence/pfr_fields_view.cpp @@ -0,0 +1,151 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace namespaced_type { + typedef int integer; +} + +namespace ns { + struct point { + int x; + int y; + namespaced_type::integer z; + }; + + // Testing non-constexpr compatible types +#if BOOST_PFR_USE_CPP17 != 0 + struct employee { + std::string name; + std::string nickname; + }; +#endif // BOOST_PFR_USE_CPP17 +} + +struct s { int m; }; + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + using ns::point; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + using view_t = pfr_fields_view; + static_assert(traits::is_view::value, ""); + point p = {123, 456, 789}; + pfr_fields_view view(p); + + std::cout << at_c<0>(view) << std::endl; + std::cout << at_c<1>(view) << std::endl; + std::cout << at_c<2>(view) << std::endl; + std::cout << view << std::endl; + BOOST_TEST(view == make_vector(123, 456, 789)); + + at_c<0>(view) = 6; + at_c<1>(view) = 9; + at_c<2>(view) = 12; + BOOST_TEST(view == make_vector(6, 9, 12)); + + static_assert(boost::fusion::result_of::size::value == 3, ""); + static_assert(!boost::fusion::result_of::empty::value, ""); + + BOOST_TEST(front(view) == 6); + BOOST_TEST( back(view) == 12); + } + + { + vector v1(4, 2.f, 2); + point v2 = {5, 3, 3}; + vector v3(5, 4., 4); + pfr_fields_view view(v2); + BOOST_TEST(v1 < view); + BOOST_TEST(v1 <= view); + BOOST_TEST(view > v1); + BOOST_TEST(view >= v1); + BOOST_TEST(view < v3); + BOOST_TEST(view <= v3); + BOOST_TEST(v3 > view); + BOOST_TEST(v3 >= view); + } + + { + // conversion from point to vector + point p = {5, 3, 3}; + pfr_fields_view view(p); + vector v(view); + v = view; + } + + { + // conversion from point to list + point p = {5, 3, 3}; + pfr_fields_view view(p); + list l(view); + l = view; + } + + { // begin/end + using namespace boost::fusion; + using boost::is_same; + using view_t = pfr_fields_view; + + typedef boost::fusion::result_of::begin::type b; + typedef boost::fusion::result_of::end::type e; + // this fails + static_assert(is_same::type, e>::value, ""); + } + + { + using view_t = pfr_fields_view; + static_assert(mpl::is_sequence::value, ""); + static_assert(boost::is_same< + boost::fusion::result_of::value_at_c::type + , mpl::front::type>::value, ""); + } + +#if BOOST_PFR_USE_CPP17 != 0 + { + ns::employee emp{"John Doe", "jdoe"}; + pfr_fields_view view(emp); + std::cout << at_c<0>(view) << std::endl; + std::cout << at_c<1>(view) << std::endl; + + fusion::vector v1("John Doe", "jdoe"); + BOOST_TEST(view == v1); + } +#endif // BOOST_PFR_USE_CPP17 + + return boost::report_errors(); +} \ No newline at end of file diff --git a/test/sequence/pfr_fields_view_empty.cpp b/test/sequence/pfr_fields_view_empty.cpp new file mode 100644 index 000000000..3f61c1e62 --- /dev/null +++ b/test/sequence/pfr_fields_view_empty.cpp @@ -0,0 +1,96 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct empty_struct {}; + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + using view_t = pfr_fields_view; + static_assert(traits::is_view::value, ""); + empty_struct e; + pfr_fields_view view(e); + + std::cout << view << std::endl; + BOOST_TEST(view == make_vector()); + + static_assert(fusion::result_of::size::value == 0, ""); + static_assert(fusion::result_of::empty::value, ""); + + static_assert(fusion::result_of::equal_to< + fusion::result_of::begin::type, + fusion::result_of::end::type>::value, ""); + } + + { + int counter = 0; + empty_struct empty; + pfr_fields_view view(empty); + boost::fusion::for_each(view, [&](){counter+=1;}); + BOOST_TEST(counter == 0); + } + + { + fusion::vector<> v; + empty_struct e; + pfr_fields_view view(e); + BOOST_TEST( v == view); + BOOST_TEST_NOT(view != v); + BOOST_TEST_NOT(v < view); + BOOST_TEST( v <= view); + BOOST_TEST_NOT(view > v); + BOOST_TEST( view >= v); + } + + { + empty_struct e; + pfr_fields_view view(e); + + // conversion from empty_struct to vector + fusion::vector<> v(view); + v = view; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(view); + //l = view; + } + + static_assert(mpl::is_sequence< pfr_fields_view >::value, ""); + + return boost::report_errors(); +} From 9932032740fe42f07c2e455f8dffbf62dad48c22 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Tue, 18 Jan 2022 21:02:33 +0400 Subject: [PATCH 04/10] [pfr_view] Update docs --- doc/algorithm.qbk | 6 ++++-- doc/view.qbk | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/algorithm.qbk b/doc/algorithm.qbk index 7f850f15f..1d6063617 100644 --- a/doc/algorithm.qbk +++ b/doc/algorithm.qbk @@ -142,7 +142,8 @@ Linear, exactly `__result_of_size__::value`. [section pfr_fields] -[important Please read __boost_pfr_lims__ before using this `pfr_fields`. Pay special attention to the SimpleAggregate concept.] +[caution This function requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] +[important Also, please read __boost_pfr_lims__ before using this function. Pay special attention to the SimpleAggregate concept.] [heading Description] For a SimpleAggregate `agg`, `pfr_fields` returns a new sequence @@ -301,7 +302,8 @@ Constant. [section pfr_fields] -[important Please read __boost_pfr_lims__ before using this `pfr_fields`. Pay special attention to the SimpleAggregate concept.] +[caution This metafunction requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] +[important Also, please read __boost_pfr_lims__ before using this metafunction. Pay special attention to the SimpleAggregate concept.] [heading Description] A metafunction returning the result type of applying __pfr_fields__. diff --git a/doc/view.qbk b/doc/view.qbk index f64b2f495..ed77f660a 100644 --- a/doc/view.qbk +++ b/doc/view.qbk @@ -723,7 +723,8 @@ defined in the implemented models. [section pfr_fields_view] -[important Please read __boost_pfr_lims__ before using this `pfr_fields_view`. Pay special attention to the SimpleAggregate concept.] +[caution This view requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] +[important Also, please read __boost_pfr_lims__ before using this view. Pay special attention to the SimpleAggregate concept.] [heading Description] From 0da3a417b14e06141dcff339f8da79b459253bd7 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Tue, 18 Jan 2022 21:06:11 +0400 Subject: [PATCH 05/10] [pfr_view] Fixed for MSVC building --- .../view/pfr_fields_view/detail/at_impl.hpp | 14 ++++++++++++-- .../view/pfr_fields_view/detail/deref_impl.hpp | 18 ++++++++++++------ test/algorithm/pfr_fields.cpp | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp index f55814e4b..5dec252be 100644 --- a/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp +++ b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp @@ -10,6 +10,7 @@ #include #include #include // for std::declval +#include // for std::is_const, std::remove_const namespace boost { namespace fusion { struct pfr_fields_view_tag; @@ -25,10 +26,19 @@ namespace boost { namespace fusion { template struct apply { - using type = decltype(boost::pfr::get(std::declval().agg)); + typedef typename std::remove_const::type aggregate_type; + typedef typename boost::pfr::tuple_element::type element; + + typedef typename + mpl::if_< + std::is_const + , typename fusion::detail::cref_result::type + , typename fusion::detail::ref_result::type + >::type + type; constexpr BOOST_FUSION_GPU_ENABLED - static decltype(auto) + static type call(Sequence& v) { return boost::pfr::get(v.agg); diff --git a/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp index 91141cb06..6d57dfd17 100644 --- a/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp +++ b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp @@ -10,6 +10,7 @@ #include #include #include // for std::declval +#include // for std::is_const, std::remove_const namespace boost { namespace fusion { struct pfr_fields_view_iterator_tag; @@ -25,14 +26,19 @@ namespace boost { namespace fusion { template struct apply { - using type = decltype( - boost::pfr::get( - std::declval().agg - ) - ); + typedef typename std::remove_const::type aggregate_type; + typedef typename Iterator::index index; + typedef typename boost::pfr::tuple_element::type element; + typedef typename + mpl::if_< + std::is_const + , typename fusion::detail::cref_result::type + , typename fusion::detail::ref_result::type + >::type + type; constexpr BOOST_FUSION_GPU_ENABLED - static decltype(auto) + static type call(Iterator const& iter) { return boost::pfr::get(iter.agg); diff --git a/test/algorithm/pfr_fields.cpp b/test/algorithm/pfr_fields.cpp index d2ccd0272..b4a2b6162 100644 --- a/test/algorithm/pfr_fields.cpp +++ b/test/algorithm/pfr_fields.cpp @@ -108,7 +108,7 @@ main() BOOST_MPL_ASSERT((is_same_thernary< boost::fusion::result_of::prior< boost::fusion::result_of::end::type >::type , std::remove_const_t - , pfr_fields_view_iterator > + , pfr_fields_view_iterator > >)); BOOST_TEST(*prior(end(view)) == 300); From 90ec956dfe90095a5b476deb61217f94efdcba02 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Wed, 19 Jan 2022 23:00:40 +0400 Subject: [PATCH 06/10] [pfr_view] Fixed at_impl && deref_impl --- .../view/pfr_fields_view/detail/at_impl.hpp | 15 ++++++++------- .../pfr_fields_view/detail/deref_impl.hpp | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp index 5dec252be..e9e90231f 100644 --- a/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp +++ b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp @@ -9,8 +9,9 @@ #include #include -#include // for std::declval #include // for std::is_const, std::remove_const +#include +#include namespace boost { namespace fusion { struct pfr_fields_view_tag; @@ -26,16 +27,16 @@ namespace boost { namespace fusion { template struct apply { - typedef typename std::remove_const::type aggregate_type; - typedef typename boost::pfr::tuple_element::type element; + using aggregate_type = typename std::remove_const::type; + using element = typename boost::pfr::tuple_element::type; - typedef typename - mpl::if_< + using type = typename + mpl::if_< std::is_const , typename fusion::detail::cref_result::type , typename fusion::detail::ref_result::type - >::type - type; + >::type + ; constexpr BOOST_FUSION_GPU_ENABLED static type diff --git a/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp index 6d57dfd17..cbe92b543 100644 --- a/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp +++ b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp @@ -9,8 +9,9 @@ #include #include -#include // for std::declval #include // for std::is_const, std::remove_const +#include +#include namespace boost { namespace fusion { struct pfr_fields_view_iterator_tag; @@ -26,16 +27,16 @@ namespace boost { namespace fusion { template struct apply { - typedef typename std::remove_const::type aggregate_type; - typedef typename Iterator::index index; - typedef typename boost::pfr::tuple_element::type element; - typedef typename + using aggregate_type = typename std::remove_const::type; + using index = typename Iterator::index; + using element = typename boost::pfr::tuple_element::type; + using type = typename mpl::if_< - std::is_const - , typename fusion::detail::cref_result::type - , typename fusion::detail::ref_result::type + std::is_const + , typename fusion::detail::cref_result::type + , typename fusion::detail::ref_result::type >::type - type; + ; constexpr BOOST_FUSION_GPU_ENABLED static type From 796eba43b088a95dde94c9eba81a4657f15d9b67 Mon Sep 17 00:00:00 2001 From: Denis Mikhailov Date: Tue, 25 Jan 2022 12:45:31 +0400 Subject: [PATCH 07/10] Update ci.yml --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 884233ce5..67b5a281b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -344,6 +344,7 @@ jobs: git submodule init libs/type_traits git submodule init libs/typeof git submodule init libs/utility + git submodule init libs/pfr git submodule init libs/headers tools/boost_install tools/build git submodule update rm -rf libs/fusion @@ -452,6 +453,7 @@ jobs: git submodule init libs/type_traits git submodule init libs/typeof git submodule init libs/utility + git submodule init libs/pfr git submodule init libs/headers tools/boost_install tools/build git submodule update rm -rf libs/fusion @@ -464,4 +466,4 @@ jobs: ./b2 -j`(nproc || sysctl -n hw.ncpu) 2> /dev/null` libs/fusion/test toolset=$TOOLSET cxxstd=$CXXSTD - fi \ No newline at end of file + fi From 68c58ec772257e422a095f261170f4dcda21ca3c Mon Sep 17 00:00:00 2001 From: denzor200 Date: Wed, 26 Jan 2022 19:12:18 +0400 Subject: [PATCH 08/10] [pfr_view] Modernized a lot && more remove_const --- .github/workflows/ci.yml | 2 ++ CMakeLists.txt | 1 + appveyor.yml | 1 + .../view/pfr_fields_view/detail/at_impl.hpp | 22 +++++++++---------- .../pfr_fields_view/detail/deref_impl.hpp | 22 +++++++++---------- .../view/pfr_fields_view/detail/end_impl.hpp | 7 +++--- .../view/pfr_fields_view/pfr_fields_view.hpp | 7 +++++- .../pfr_fields_view_iterator.hpp | 3 ++- 8 files changed, 36 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67b5a281b..9648b81ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -345,6 +345,7 @@ jobs: git submodule init libs/typeof git submodule init libs/utility git submodule init libs/pfr + git submodule init libs/mp11 git submodule init libs/headers tools/boost_install tools/build git submodule update rm -rf libs/fusion @@ -454,6 +455,7 @@ jobs: git submodule init libs/typeof git submodule init libs/utility git submodule init libs/pfr + git submodule init libs/mp11 git submodule init libs/headers tools/boost_install tools/build git submodule update rm -rf libs/fusion diff --git a/CMakeLists.txt b/CMakeLists.txt index 527d69400..456823d51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,4 +24,5 @@ target_link_libraries(boost_fusion Boost::typeof Boost::utility Boost::pfr + Boost::mp11 ) diff --git a/appveyor.yml b/appveyor.yml index 539f1a331..d58b3b94d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -83,6 +83,7 @@ install: - git submodule init libs/typeof - git submodule init libs/utility - git submodule init libs/pfr + - git submodule init libs/mp11 - git submodule init libs/headers tools/boost_install tools/build - git submodule update diff --git a/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp index e9e90231f..f2b85f382 100644 --- a/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp +++ b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp @@ -9,8 +9,8 @@ #include #include -#include // for std::is_const, std::remove_const -#include +#include // for std::is_const, std::remove_const_t +#include #include namespace boost { namespace fusion { @@ -27,16 +27,14 @@ namespace boost { namespace fusion { template struct apply { - using aggregate_type = typename std::remove_const::type; - using element = typename boost::pfr::tuple_element::type; - - using type = typename - mpl::if_< - std::is_const - , typename fusion::detail::cref_result::type - , typename fusion::detail::ref_result::type - >::type - ; + using aggregate_type = std::remove_const_t; + using element = boost::pfr::tuple_element_t; + + using type = mp11::mp_if< + std::is_const + , typename fusion::detail::cref_result::type + , typename fusion::detail::ref_result::type + >; constexpr BOOST_FUSION_GPU_ENABLED static type diff --git a/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp index cbe92b543..69710f719 100644 --- a/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp +++ b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp @@ -9,8 +9,8 @@ #include #include -#include // for std::is_const, std::remove_const -#include +#include // for std::is_const, std::remove_const_t +#include #include namespace boost { namespace fusion { @@ -27,16 +27,14 @@ namespace boost { namespace fusion { template struct apply { - using aggregate_type = typename std::remove_const::type; - using index = typename Iterator::index; - using element = typename boost::pfr::tuple_element::type; - using type = typename - mpl::if_< - std::is_const - , typename fusion::detail::cref_result::type - , typename fusion::detail::ref_result::type - >::type - ; + using aggregate_type = std::remove_const_t; + using element = boost::pfr::tuple_element_t; + + using type = mp11::mp_if< + std::is_const + , typename fusion::detail::cref_result::type + , typename fusion::detail::ref_result::type + >; constexpr BOOST_FUSION_GPU_ENABLED static type diff --git a/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp b/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp index 2f8d9147b..ff7edabf5 100644 --- a/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp +++ b/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp @@ -10,6 +10,7 @@ #include #include #include +#include // for std::remove_const_t namespace boost { namespace fusion { struct pfr_fields_view_tag; @@ -28,11 +29,11 @@ namespace boost { namespace fusion { template struct apply { + using aggregate_type = std::remove_const_t; + using type = pfr_fields_view_iterator< typename Sequence::aggregate_type - , mpl::int_::value> + , mpl::int_::value> >; constexpr BOOST_FUSION_GPU_ENABLED diff --git a/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp index 9c3dd7d82..ba0bd214b 100644 --- a/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp +++ b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp @@ -17,6 +17,7 @@ #include #include #include +#include // for std::remove_const_t namespace boost { namespace fusion { @@ -33,7 +34,11 @@ namespace boost { namespace fusion using is_view = mpl::true_; using aggregate_type = Aggregate; - using size = mpl::int_::value>; + using size = mpl::int_< + boost::pfr::tuple_size< + std::remove_const_t + >::value + >; constexpr BOOST_FUSION_GPU_ENABLED explicit pfr_fields_view(Aggregate& in_agg) diff --git a/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp index fab602c8a..d2b0894ff 100644 --- a/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp +++ b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp @@ -18,6 +18,7 @@ #include #include #include +#include // for std::remove_const_t namespace boost { namespace fusion { @@ -28,7 +29,7 @@ namespace boost { namespace fusion struct pfr_fields_view_iterator : iterator_base< pfr_fields_view_iterator > { - static_assert(Pos::value >=0 && Pos::value <= boost::pfr::tuple_size::value, "out of range"); + static_assert(Pos::value >=0 && Pos::value <= boost::pfr::tuple_size>::value, "out of range"); using fusion_tag = pfr_fields_view_iterator_tag; using category = random_access_traversal_tag; From cc82fb61399a12ff032e9747574c100ca80977df Mon Sep 17 00:00:00 2001 From: Denis Mikhaylov Date: Fri, 8 Jul 2022 17:25:59 +0600 Subject: [PATCH 09/10] [pfr_view] Fixed review issues --- doc/algorithm.qbk | 40 +++++++++++++++---------------- doc/fusion.qbk | 2 ++ doc/view.qbk | 21 ++++++++-------- test/sequence/pfr_fields_view.cpp | 18 ++++++++++---- 4 files changed, 46 insertions(+), 35 deletions(-) mode change 100644 => 100755 doc/algorithm.qbk mode change 100644 => 100755 doc/fusion.qbk mode change 100644 => 100755 doc/view.qbk mode change 100644 => 100755 test/sequence/pfr_fields_view.cpp diff --git a/doc/algorithm.qbk b/doc/algorithm.qbk old mode 100644 new mode 100755 index 1d6063617..bcd361a90 --- a/doc/algorithm.qbk +++ b/doc/algorithm.qbk @@ -143,28 +143,29 @@ Linear, exactly `__result_of_size__::value`. [section pfr_fields] [caution This function requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] -[important Also, please read __boost_pfr_lims__ before using this function. Pay special attention to the SimpleAggregate concept.] [heading Description] -For a SimpleAggregate `agg`, `pfr_fields` returns a new sequence +For an user defined structure `agg`, `pfr_fields` returns a new sequence with elements extracted by using __boost_pfr__. +This function does not require macro or boilerplate code from an user defined structure +, unlike __adapt_struct__, and can be used as a replacement for __adapt_struct__. [heading Synopsis] template< - typename SimpleAggregate + typename Aggregate > - typename __result_of_pfr_fields__::type pfr_fields( - SimpleAggregate& agg); + typename __result_of_pfr_fields__::type pfr_fields( + Aggregate& agg); template< - typename SimpleAggregate + typename Aggregate > - typename __result_of_pfr_fields__::type pfr_fields( - SimpleAggregate const& agg); + typename __result_of_pfr_fields__::type pfr_fields( + Aggregate const& agg); [table Parameters [[Parameter][Requirement][Description]] - [[`agg`][A model of SimpleAggregate][Operation's argument]] + [[`agg`][A model of __simple_aggregate__][Operation's argument]] ] [heading Expression Semantics] @@ -172,7 +173,7 @@ with elements extracted by using __boost_pfr__. [*Return type]: A model of __random_access_sequence__ -[*Semantics]: Returns a sequence with all elements of `SimpleAggregate`. +[*Semantics]: Returns a sequence with all elements from user defined structure. [heading Complexity] Constant. @@ -182,13 +183,13 @@ Constant. #include #include -[note This algorithm won't defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] +[note This algorithm won't be defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] [heading Example] struct some_person { // SimpleAggregate std::string name; - unsigned birth_year; + unsigned birth_year = 0; }; some_person val{"Edgar Allan Poe", 1809}; @@ -199,9 +200,9 @@ Constant. struct empty { // SimpleAggregate }; - struct aggregate : empty { // not a SimpleAggregate + struct aggregate : empty { // not a SimpleAggregate because of inheritance std::string name; - int age; + int age = 0; boost::uuids::uuid uuid; }; @@ -303,13 +304,12 @@ Constant. [section pfr_fields] [caution This metafunction requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] -[important Also, please read __boost_pfr_lims__ before using this metafunction. Pay special attention to the SimpleAggregate concept.] [heading Description] A metafunction returning the result type of applying __pfr_fields__. [heading Synopsis] - template + template struct pfr_fields { typedef __unspecified__ type; @@ -317,15 +317,15 @@ A metafunction returning the result type of applying __pfr_fields__. [table Parameters [[Parameter] [Requirement] [Description]] - [[`SimpleAggregate`] [A model of SimpleAggregate from __boost_pfr__] [Operation's argument]] + [[`Aggregate`] [A model of __simple_aggregate__] [Operation's argument]] ] [heading Expression Semantics] - result_of::pfr_fields::type + result_of::pfr_fields::type [*Return type]: A model of __random_access_sequence__ -[*Semantics]: Returns a sequence with all elements of `SimpleAggregate`. +[*Semantics]: Returns a sequence with all elements from user defined structure. [heading Complexity] Constant. @@ -335,7 +335,7 @@ Constant. #include #include -[note This algorithm won't defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] +[note This algorithm won't be defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] [heading See also] diff --git a/doc/fusion.qbk b/doc/fusion.qbk old mode 100644 new mode 100755 index 196c57f4d..6c5e821ef --- a/doc/fusion.qbk +++ b/doc/fusion.qbk @@ -50,6 +50,7 @@ [def __boost_func_hash__ [@http://www.boost.org/doc/html/hash.html Boost.ContainerHash Library]] [def __boost_pfr__ [@http://www.boost.org/doc/html/boost_pfr.html Boost.PFR Library]] [def __boost_pfr_lims__ [@http://www.boost.org/doc/html/boost_pfr/limitations_and_configuration.html Boost.PFR Limitations and Configuration]] +[def __simple_aggregate__ [@http://www.boost.org/doc/html/boost_pfr/limitations_and_configuration.html SimpleAggregate]] [def __std_pair_doc__ [@http://en.cppreference.com/w/cpp/utility/pair `std::pair`]] [def __std_tuple_doc__ [@http://en.cppreference.com/w/cpp/utility/tuple `std::tuple`]] [def __std_plus_doc__ [@http://en.cppreference.com/w/cpp/utility/functional/plus `std::plus`]] @@ -140,6 +141,7 @@ [def __boost_array__ [link fusion.adapted.boost__array `boost::array`]] [def __mpl_sequence__ [link fusion.adapted.mpl_sequence mpl sequence]] [def __adapt_tpl_struct__ [link fusion.adapted.adapt_tpl_struct `BOOST_FUSION_ADAPT_TPL_STRUCT`]] +[def __adapt_struct__ [link fusion.adapted.adapt_struct `BOOST_FUSION_ADAPT_STRUCT`]] [def __adapt_struct_named__ [link fusion.adapted.adapt_struct_named `BOOST_FUSION_ADAPT_STRUCT_NAMED`]] [def __adapt_struct_named_ns__ [link fusion.adapted.adapt_struct_named `BOOST_FUSION_ADAPT_STRUCT_NAMED_NS`]] [def __adapt_assoc_tpl_struct__ [link fusion.adapted.adapt_assoc_tpl_struct `BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT`]] diff --git a/doc/view.qbk b/doc/view.qbk old mode 100644 new mode 100755 index ed77f660a..0d1031673 --- a/doc/view.qbk +++ b/doc/view.qbk @@ -724,29 +724,30 @@ defined in the implemented models. [section pfr_fields_view] [caution This view requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] -[important Also, please read __boost_pfr_lims__ before using this view. Pay special attention to the SimpleAggregate concept.] [heading Description] -`pfr_fields_view` is a view into a SimpleAggregate as a random access sequence. +`pfr_fields_view` is a view into an user defined structure as a random access sequence. +This view does not require macro or boilerplate code from an user defined structure +, unlike __adapt_struct__, and can be used as a replacement for __adapt_struct__. [heading Header] #include #include -[note This view won't defined by inclusion of 'boost/fusion/view.hpp'. ] +[note This view won't be defined by inclusion of 'boost/fusion/view.hpp'. ] [heading Synopsis] - template + template struct pfr_fields_view; [heading Template parameters] [table - [[Parameter] [Description] [Default]] - [[`SimpleAggregate`] [An user defined structure, satisfied 'SimpleAggregate' concept] []] + [[Parameter] [Description] [Default]] + [[`Aggregate`] [An user defined structure, satisfying __simple_aggregate__ concept] []] ] [heading Model of] @@ -756,7 +757,7 @@ defined in the implemented models. [variablelist Notation [[`P`] [A `pfr_fields_view` type]] [[`p`, `p2`] [Instances of `pfr_fields_view`]] - [[`a`] [An instance of `SimpleAggregate`]] + [[`a`] [An instance of __simple_aggregate__]] ] [heading Expression Semantics] @@ -775,7 +776,7 @@ defined in __random_access_sequence__. struct some_person { // SimpleAggregate std::string name; - unsigned birth_year; + unsigned birth_year = 0; }; some_person val{"Edgar Allan Poe", 1809}; @@ -787,9 +788,9 @@ defined in __random_access_sequence__. struct empty { // SimpleAggregate }; - struct aggregate : empty { // not a SimpleAggregate + struct aggregate : empty { // not a SimpleAggregate because of inheritance std::string name; - int age; + int age = 0; boost::uuids::uuid uuid; }; diff --git a/test/sequence/pfr_fields_view.cpp b/test/sequence/pfr_fields_view.cpp old mode 100644 new mode 100755 index f525edd3c..9f67d70ad --- a/test/sequence/pfr_fields_view.cpp +++ b/test/sequence/pfr_fields_view.cpp @@ -39,11 +39,19 @@ namespace ns { namespaced_type::integer z; }; + struct guaranteed_nonconstexpr_string { + std::string value; + template + /*explicit*/ guaranteed_nonconstexpr_string(T value) : value(std::move(value)) { + std::cout << "mark to ensure nonconstexpr" << std::endl; + } + }; + // Testing non-constexpr compatible types #if BOOST_PFR_USE_CPP17 != 0 struct employee { - std::string name; - std::string nickname; + guaranteed_nonconstexpr_string name; + guaranteed_nonconstexpr_string nickname; }; #endif // BOOST_PFR_USE_CPP17 } @@ -139,10 +147,10 @@ main() { ns::employee emp{"John Doe", "jdoe"}; pfr_fields_view view(emp); - std::cout << at_c<0>(view) << std::endl; - std::cout << at_c<1>(view) << std::endl; + std::cout << at_c<0>(view).value << std::endl; + std::cout << at_c<1>(view).value << std::endl; - fusion::vector v1("John Doe", "jdoe"); + fusion::vector v1("John Doe", "jdoe"); BOOST_TEST(view == v1); } #endif // BOOST_PFR_USE_CPP17 From cbcbe1cf4a63e51af1220f620915bd31923e0e64 Mon Sep 17 00:00:00 2001 From: Denis Mikhaylov Date: Fri, 8 Jul 2022 17:56:52 +0600 Subject: [PATCH 10/10] [pfr_view] Fixed PFR limitation --- test/sequence/pfr_fields_view.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/sequence/pfr_fields_view.cpp b/test/sequence/pfr_fields_view.cpp index 9f67d70ad..fcdd7dda9 100755 --- a/test/sequence/pfr_fields_view.cpp +++ b/test/sequence/pfr_fields_view.cpp @@ -41,12 +41,15 @@ namespace ns { struct guaranteed_nonconstexpr_string { std::string value; - template - /*explicit*/ guaranteed_nonconstexpr_string(T value) : value(std::move(value)) { + explicit guaranteed_nonconstexpr_string(std::string value) : value(std::move(value)) { std::cout << "mark to ensure nonconstexpr" << std::endl; } }; + inline bool operator== (const guaranteed_nonconstexpr_string& rhs, const guaranteed_nonconstexpr_string& lhs) { + return (rhs.value == lhs.value); + } + // Testing non-constexpr compatible types #if BOOST_PFR_USE_CPP17 != 0 struct employee { @@ -145,12 +148,14 @@ main() #if BOOST_PFR_USE_CPP17 != 0 { - ns::employee emp{"John Doe", "jdoe"}; + ns::employee emp{ns::guaranteed_nonconstexpr_string("John Doe"), + ns::guaranteed_nonconstexpr_string("jdoe")}; pfr_fields_view view(emp); std::cout << at_c<0>(view).value << std::endl; std::cout << at_c<1>(view).value << std::endl; - fusion::vector v1("John Doe", "jdoe"); + fusion::vector v1( + ns::guaranteed_nonconstexpr_string("John Doe"), ns::guaranteed_nonconstexpr_string("jdoe")); BOOST_TEST(view == v1); } #endif // BOOST_PFR_USE_CPP17