diff --git a/CMakeLists.txt b/CMakeLists.txt index 707b4f898..456823d51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,4 +23,6 @@ target_link_libraries(boost_fusion Boost::type_traits Boost::typeof Boost::utility + Boost::pfr + Boost::mp11 ) 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 index 3bda204dd..b3e72ac9e 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,96 @@ Linear, exactly `__result_of_size__::value`. [endsect] +[section pfr] + +[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] + +`pfr` is a generic version of __pfr_fields__. For a `val` conforming Fusion __sequence__, `pfr` returns it sequence unchanged. +Otherwise, for a `val` like SimpleAggregate, `pfr` returns a new sequence with elements extracted by using __boost_pfr__. + +[heading Synopsis] + template< + typename SequenceOrSimpleAggregate + > + typename __result_of_pfr__::type pfr( + SequenceOrSimpleAggregate& val); + + template< + typename SequenceOrSimpleAggregate + > + typename __result_of_pfr__::type pfr( + SequenceOrSimpleAggregate const& val); + +[table Parameters + [[Parameter][Requirement][Description]] + [[`val`][A model of Sequence, or a model of SimpleAggregate][Operation's argument]] +] + +[heading Expression Semantics] + __pfr__(val); + +[*Return type]: + +* A model of __forward_sequence__ if `val` is a __forward_sequence__ +else, __bidirectional_sequence__ if `val` is a __bidirectional_sequence__ +else, __random_access_sequence__ if `val` is a __random_access_sequence__ or SimpleAggregate. +* A model of __associative_sequence__ if `val` implements the __associative_sequence__ model. + +[*Semantics]: Returns a sequence with all elements of `SequenceOrSimpleAggregate`. + +[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__(val) << std::endl; // (Edgar Allan Poe 1809) + +[heading Example] + + struct empty { // SimpleAggregate + }; + + struct aggregate : empty { // not a SimpleAggregate, not a Sequence + std::string name; + int age; + boost::uuids::uuid uuid; + }; + + aggregate val{"Edgar Allan Poe", 1809, {}}; + __pfr__(val); // non-portable behavior + +[heading Example] + + using some_person = __vector__< // not a SimpleAggregate, but Sequence + std::string + , unsigned + >; + + some_person val("Edgar Allan Poe", 1809); + std::cout << __pfr__(val) << std::endl; // (Edgar Allan Poe 1809) + +[heading See also] + +__boost_pfr__ + +[endsect] + [endsect] [section Metafunctions] @@ -215,6 +306,54 @@ Constant. [endsect] +[section pfr] + +[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__. + +[heading Synopsis] + template + struct pfr + { + typedef __unspecified__ type; + }; + +[table Parameters + [[Parameter] [Requirement] [Description]] + [[`SequenceOrSimpleAggregate`] [Model of Fusion __sequence__ or model of SimpleAggregate from __boost_pfr__] [Operation's argument]] +] + +[heading Expression Semantics] + result_of::pfr::type + +[*Return type]: + +* A model of __forward_sequence__ if `val` is a __forward_sequence__ +else, __bidirectional_sequence__ if `val` is a __bidirectional_sequence__ +else, __random_access_sequence__ if `val` is a __random_access_sequence__ or SimpleAggregate. +* A model of __associative_sequence__ if `val` implements the __associative_sequence__ model. + +[*Semantics]: Returns a sequence with all elements of `SequenceOrSimpleAggregate`. + +[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 See also] + +__boost_pfr__ + +[endsect] + [endsect] [endsect] diff --git a/doc/fusion.qbk b/doc/fusion.qbk index f7a5bf766..f3054e8d1 100644 --- 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 __boost_pfr_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,6 +134,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_view__ [link fusion.view.pfr_view `pfr_view`]] [def __array__ [link fusion.adapted.array array]] [def __std_pair__ [link fusion.adapted.std__pair `std::pair`]] @@ -229,6 +233,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__ [link fusion.algorithm.auxiliary.functions.pfr `pfr`]] +[def __result_of_pfr__ [link fusion.algorithm.auxiliary.metafunctions.pfr `result_of::pfr`]] [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..80a03a4f6 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -164,6 +164,7 @@
transform_view
reverse_view
identity_view
+
pfr_view
nview
repetitive_view
flatten_view
diff --git a/doc/organization.qbk b/doc/organization.qbk index b062e6ed8..b11dca93b 100644 --- a/doc/organization.qbk +++ b/doc/organization.qbk @@ -61,6 +61,7 @@ link against. * transform_view * zip_view * identity_view + * pfr_view * container * deque * list diff --git a/doc/sequence.qbk b/doc/sequence.qbk index 554d951fb..d9fd6ad9f 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_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_view__ (where adapted type is a Bidirectional Sequence or a __boost_pfr_simple_aggregate__) [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_view__ (where adapted type is a Random Access Sequence or a __boost_pfr_simple_aggregate__) [endsect] @@ -365,6 +368,7 @@ you can use `__result_of_value_at_key__`.] * __reverse_view__ (where adapted sequence is an __associative_sequence__ and a __bidirectional_sequence__) * __transform_view__ (where adapted sequence is an __associative_sequence__ and a __forward_sequence__) * __identity_view__ (where adapted sequence is an __associative_sequence__ and a __forward_sequence__) +* __pfr_view__ (where adapted type is an __associative_sequence__ and a __forward_sequence__) [endsect] diff --git a/doc/view.qbk b/doc/view.qbk index a3ad4d09c..1cb31fd43 100644 --- a/doc/view.qbk +++ b/doc/view.qbk @@ -721,4 +721,103 @@ defined in the implemented models. [endsect] +[section pfr_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_view` is a generic version of __pfr_fields_view__. If underlying type is a conforming Fusion __sequence__, then it type will be +presented unchanged. Otherwise, the underlying type must satisfy SimpleAggregate concept, because it type will be presented as a random +access sequence by using __boost_pfr__. + +[heading Header] + + #include + #include + +[note This view won't defined by inclusion of 'boost/fusion/view.hpp'. ] + +[heading Synopsis] + + template + struct pfr_view; + +[heading Template parameters] + +[table + [[Parameter] [Description] [Default]] + [[`SequenceOrSimpleAggregate`] [A fusion __sequence__ or an user defined structure, satisfied 'SimpleAggregate' concept] []] +] + +[heading Model of] + +* A model of __forward_sequence__ if underlying type is a __forward_sequence__ +else, __bidirectional_sequence__ if underlying type is a __bidirectional_sequence__ +else, __random_access_sequence__ if underlying type is a __random_access_sequence__ or SimpleAggregate. +* __associative_sequence__ if underlying type implements the __associative_sequence__ model. + +[variablelist Notation + [[`P`] [A `pfr_view` type]] + [[`p`, `p2`] [Instances of `pfr_view`]] + [[`a`] [An instance of `SimpleAggregate`]] + [[`s`] [An instance of `Sequence`]] +] + +[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_view` from simple aggregate `a`.]] + [[`P(s)`] [Creates a `pfr_view` from sequence `s`.]] + [[`P(p)`] [Copy constructs a `pfr_view` from another `pfr_view`, `p`.]] + [[`p = p2`] [Assigns to a `pfr_view`, `p`, from another `pfr_view`, `p2`.]] +] + +[heading Example] + + struct some_person { // SimpleAggregate + std::string name; + unsigned birth_year; + }; + + some_person val{"Edgar Allan Poe", 1809}; + __pfr_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_view__ view(val); // non-portable behavior + +[heading Example] + + using some_person = __vector__< // not a SimpleAggregate, but Sequence + std::string + , unsigned + >; + + some_person val("Edgar Allan Poe", 1809); + __pfr_view__ view(val); + std::cout << view << std::endl; // (Edgar Allan Poe 1809) + +[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..241c5adac 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.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.hpp b/include/boost/fusion/algorithm/auxiliary/pfr.hpp new file mode 100644 index 000000000..642abe5d3 --- /dev/null +++ b/include/boost/fusion/algorithm/auxiliary/pfr.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_98457698_34587) +#define FUSION_PFR_98457698_34587 + +#include +#include + +namespace boost { namespace fusion { namespace result_of +{ + template + struct pfr + { + typedef pfr_view type; + }; +}}} + +namespace boost { namespace fusion +{ + template + constexpr BOOST_FUSION_GPU_ENABLED + auto pfr(T& view) + { + using type = typename result_of::pfr::type; + return type(view); + } + + template + constexpr BOOST_FUSION_GPU_ENABLED + auto pfr(T const& view) + { + using type = typename result_of::pfr::type; + return type(view); + } +}} + +#endif diff --git a/include/boost/fusion/include/pfr.hpp b/include/boost/fusion/include/pfr.hpp new file mode 100644 index 000000000..86e70a35a --- /dev/null +++ b/include/boost/fusion/include/pfr.hpp @@ -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) +==============================================================================*/ + +#if !defined(FUSION_INCLUDE_PFR) +#define FUSION_INCLUDE_PFR + +#include +#include + +#endif diff --git a/include/boost/fusion/include/pfr_view.hpp b/include/boost/fusion/include/pfr_view.hpp new file mode 100644 index 000000000..00a9a1c01 --- /dev/null +++ b/include/boost/fusion/include/pfr_view.hpp @@ -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) +==============================================================================*/ + +#if !defined(FUSION_INCLUDE_PFR_VIEW) +#define FUSION_INCLUDE_PFR_VIEW + +#include +#include + +#endif diff --git a/include/boost/fusion/view.hpp b/include/boost/fusion/view.hpp index 0d8ded42c..d92ebe6a9 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_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_view.hpp b/include/boost/fusion/view/pfr_view.hpp new file mode 100644 index 000000000..7289ffb50 --- /dev/null +++ b/include/boost/fusion/view/pfr_view.hpp @@ -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) +==============================================================================*/ + +#if !defined(BOOST_FUSION_PFR_FIELDS_VIEW_JAN_24_2022_0035AM) +#define BOOST_FUSION_PFR_FIELDS_VIEW_JAN_24_2022_0035AM + +#include +#include + +#endif diff --git a/include/boost/fusion/view/pfr_view/pfr_view.hpp b/include/boost/fusion/view/pfr_view/pfr_view.hpp new file mode 100644 index 000000000..8b2d77e8c --- /dev/null +++ b/include/boost/fusion/view/pfr_view/pfr_view.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_VIEW_HPP_INCLUDED) +#define BOOST_FUSION_PFR_VIEW_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { + template struct pfr_view + : mp11::mp_eval_if< + traits::is_sequence + , mp11::mp_eval_if_not< + traits::is_sequence + , void + , identity_view, T + > + , pfr_fields_view, T + > + { + using base_type + = mp11::mp_eval_if< + traits::is_sequence + , mp11::mp_eval_if_not< + traits::is_sequence + , void + , identity_view, T + > + , pfr_fields_view, T + >; + using base_type::base_type; + }; +}} +#endif diff --git a/test/Jamfile b/test/Jamfile index 13dd35c55..ae666c0b3 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.cpp : : + : [ requires cxx14_constexpr ] ] [ compile algorithm/ticket-5490.cpp ] + [ compile include/_pfr.cpp + : [ requires cxx14_constexpr ] ] + [ compile include/_pfr_view.cpp + : [ requires cxx14_constexpr ] ] + [ run sequence/as_deque.cpp ] [ run sequence/as_list.cpp ] [ run sequence/as_map.cpp ] @@ -157,6 +164,8 @@ project : tuple_traits__no_variadic ] [ run sequence/transform_view.cpp ] [ run sequence/identity_view.cpp ] + [ run sequence/pfr_view.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.cpp b/test/algorithm/pfr.cpp new file mode 100644 index 000000000..b573988cd --- /dev/null +++ b/test/algorithm/pfr.cpp @@ -0,0 +1,84 @@ +/*============================================================================= + 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 + +namespace namespaced_type { + typedef int integer; +} + +namespace ns { + struct point { + int x; + int y; + namespaced_type::integer z; + }; +} + +template +void generic_test(T& t) { + using namespace boost::fusion; + + using pfr_t = typename boost::fusion::result_of::pfr::type; + static_assert(traits::is_view::value, ""); + + std::cout << at_c<0>(pfr(t)) << std::endl; + std::cout << at_c<1>(pfr(t)) << std::endl; + std::cout << at_c<2>(pfr(t)) << std::endl; + std::cout << pfr(t) << std::endl; + BOOST_TEST(pfr(t) == make_vector(123, 456, 789)); + + at_c<0>(pfr(t)) = 6; + at_c<1>(pfr(t)) = 9; + at_c<2>(pfr(t)) = 12; + BOOST_TEST(pfr(t) == 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(pfr(t)) == 6); + BOOST_TEST(back(pfr(t)) == 12); +} + + +int main() +{ + using namespace boost::fusion; + using namespace boost; + using ns::point; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + point p = {123, 456, 789}; + generic_test(p); + } + + { + vector seq (123, 456, 789); + generic_test(seq); + } + + return boost::report_errors(); +} diff --git a/test/include/_pfr.cpp b/test/include/_pfr.cpp new file mode 100644 index 000000000..18c329a98 --- /dev/null +++ b/test/include/_pfr.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_view.cpp b/test/include/_pfr_view.cpp new file mode 100644 index 000000000..08bc6a1cc --- /dev/null +++ b/test/include/_pfr_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_view.cpp b/test/sequence/pfr_view.cpp new file mode 100644 index 000000000..0bbc541e9 --- /dev/null +++ b/test/sequence/pfr_view.cpp @@ -0,0 +1,86 @@ +/*============================================================================= + 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 + +namespace namespaced_type { + typedef int integer; +} + +namespace ns { + struct point { + int x; + int y; + namespaced_type::integer z; + }; +} + +template +void generic_test(T& t) { + using namespace boost::fusion; + using namespace boost; + + using view_t = pfr_view; + static_assert(traits::is_view::value, ""); + + pfr_view view(t); + 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); +} + + +int main() +{ + using namespace boost::fusion; + using namespace boost; + using ns::point; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + point p = {123, 456, 789}; + generic_test(p); + } + + { + vector seq (123, 456, 789); + generic_test(seq); + } + + return boost::report_errors(); +}