diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 884233ce5..9648b81ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -344,6 +344,8 @@ 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/mp11 git submodule init libs/headers tools/boost_install tools/build git submodule update rm -rf libs/fusion @@ -452,6 +454,8 @@ 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/mp11 git submodule init libs/headers tools/boost_install tools/build git submodule update rm -rf libs/fusion @@ -464,4 +468,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 diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 index 9dd1d3ee7..04883f449 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,5 +23,7 @@ target_link_libraries(boost_fusion Boost::type_traits Boost::typeof Boost::utility + Boost::pfr + Boost::mp11 Boost::functional ) diff --git a/appveyor.yml b/appveyor.yml index debd336bb..d58b3b94d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -82,6 +82,8 @@ 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/mp11 - git submodule init libs/headers tools/boost_install tools/build - git submodule update diff --git a/doc/algorithm.qbk b/doc/algorithm.qbk old mode 100644 new mode 100755 index 3bda204dd..bcd361a90 --- 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,91 @@ Linear, exactly `__result_of_size__::value`. [endsect] +[section pfr_fields] + +[caution This function requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] + +[heading Description] +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 Aggregate + > + typename __result_of_pfr_fields__::type pfr_fields( + Aggregate& agg); + + template< + typename Aggregate + > + typename __result_of_pfr_fields__::type pfr_fields( + Aggregate const& agg); + +[table Parameters + [[Parameter][Requirement][Description]] + [[`agg`][A model of __simple_aggregate__][Operation's argument]] +] + +[heading Expression Semantics] + __pfr_fields__(agg); + +[*Return type]: A model of __random_access_sequence__ + +[*Semantics]: Returns a sequence with all elements from user defined structure. + +[heading Complexity] +Constant. + +[heading Header] + + #include + #include + +[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 = 0; + }; + + 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 because of inheritance + std::string name; + int age = 0; + 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 +301,48 @@ Constant. [endsect] +[section pfr_fields] + +[caution This metafunction requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] + +[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]] + [[`Aggregate`] [A model of __simple_aggregate__] [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 from user defined structure. + +[heading Complexity] +Constant. + +[heading Header] + + #include + #include + +[note This algorithm won't be defined by inclusion of 'boost/fusion/algorithm/auxiliary.hpp' or 'boost/fusion/algorithm.hpp'. ] + +[heading See also] + +__boost_pfr__ + +[endsect] + [endsect] [endsect] diff --git a/doc/fusion.qbk b/doc/fusion.qbk old mode 100644 new mode 100755 index f7a5bf766..6c5e821ef --- a/doc/fusion.qbk +++ b/doc/fusion.qbk @@ -48,6 +48,9 @@ [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 __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`]] @@ -131,12 +134,14 @@ [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`]] [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`]] @@ -229,6 +234,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`]] 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 old mode 100644 new mode 100755 index a3ad4d09c..0d1031673 --- a/doc/view.qbk +++ b/doc/view.qbk @@ -721,4 +721,96 @@ defined in the implemented models. [endsect] +[section pfr_fields_view] + +[caution This view requires at least C++14! Pre C++14 compilers (C++11, C++03...) are not supported.] + +[heading Description] + +`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 be defined by inclusion of 'boost/fusion/view.hpp'. ] + +[heading Synopsis] + + template + struct pfr_fields_view; + +[heading Template parameters] + +[table + [[Parameter] [Description] [Default]] + [[`Aggregate`] [An user defined structure, satisfying __simple_aggregate__ 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 __simple_aggregate__]] +] + +[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 = 0; + }; + + 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 because of inheritance + std::string name; + int age = 0; + 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] 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..f2b85f382 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/at_impl.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + 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::is_const, std::remove_const_t +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_tag; + + namespace extension + { + template + struct at_impl; + + template <> + struct at_impl + { + template + struct apply + { + 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 + 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..69710f719 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/deref_impl.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + 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::is_const, std::remove_const_t +#include +#include + +namespace boost { namespace fusion { + struct pfr_fields_view_iterator_tag; + + namespace extension + { + template + struct deref_impl; + + template<> + struct deref_impl + { + template + struct apply + { + 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 + 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..ff7edabf5 --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/detail/end_impl.hpp @@ -0,0 +1,50 @@ +/*============================================================================= + 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 +#include // for std::remove_const_t + +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 aggregate_type = std::remove_const_t; + + 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..ba0bd214b --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view.hpp @@ -0,0 +1,57 @@ +/*============================================================================= + 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 +#include // for std::remove_const_t + +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_< + boost::pfr::tuple_size< + std::remove_const_t + >::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..d2b0894ff --- /dev/null +++ b/include/boost/fusion/view/pfr_fields_view/pfr_fields_view_iterator.hpp @@ -0,0 +1,57 @@ +/*============================================================================= + 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 +#include // for std::remove_const_t + +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..b4a2b6162 --- /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 100755 index 000000000..fcdd7dda9 --- /dev/null +++ b/test/sequence/pfr_fields_view.cpp @@ -0,0 +1,164 @@ +/*============================================================================= + 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; + }; + + struct guaranteed_nonconstexpr_string { + std::string 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 { + guaranteed_nonconstexpr_string name; + guaranteed_nonconstexpr_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{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( + ns::guaranteed_nonconstexpr_string("John Doe"), ns::guaranteed_nonconstexpr_string("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(); +}