From eed79cb557b2980992e2d13213b8258dbcde19da Mon Sep 17 00:00:00 2001 From: denzor200 Date: Mon, 10 Jan 2022 21:19:38 +0400 Subject: [PATCH 1/4] [identity_view] Added boost::fusion::identity_view --- doc/fusion.qbk | 1 + doc/html/index.html | 1 + doc/organization.qbk | 1 + doc/sequence.qbk | 4 + doc/view.qbk | 57 ++++++ .../boost/fusion/include/identity_view.hpp | 12 ++ include/boost/fusion/view.hpp | 1 + include/boost/fusion/view/identity_view.hpp | 14 ++ .../view/identity_view/identity_view.hpp | 27 +++ test/Jamfile | 1 + test/sequence/identity_view.cpp | 184 ++++++++++++++++++ 11 files changed, 303 insertions(+) create mode 100644 include/boost/fusion/include/identity_view.hpp create mode 100644 include/boost/fusion/view/identity_view.hpp create mode 100644 include/boost/fusion/view/identity_view/identity_view.hpp create mode 100644 test/sequence/identity_view.cpp diff --git a/doc/fusion.qbk b/doc/fusion.qbk index 6d6987d5..f7a5bf76 100644 --- a/doc/fusion.qbk +++ b/doc/fusion.qbk @@ -130,6 +130,7 @@ [def __reverse_view__ [link fusion.view.reverse_view `reverse_view`]] [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 __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 957609a9..9f0f14da 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -163,6 +163,7 @@
zip_view
transform_view
reverse_view
+
identity_view
nview
repetitive_view
flatten_view
diff --git a/doc/organization.qbk b/doc/organization.qbk index b7166f5d..b062e6ed 100644 --- a/doc/organization.qbk +++ b/doc/organization.qbk @@ -60,6 +60,7 @@ link against. * single_view * transform_view * zip_view + * identity_view * container * deque * list diff --git a/doc/sequence.qbk b/doc/sequence.qbk index b193b8e9..554d951f 100644 --- a/doc/sequence.qbk +++ b/doc/sequence.qbk @@ -133,6 +133,7 @@ For any Forward Sequence s the following invariants always hold: * __transform_view__ * __reverse_view__ * __zip_view__ +* __identity_view__ [endsect] @@ -201,6 +202,7 @@ are not defined in __forward_sequence__. * __iterator_range__ (where adapted sequence is a Bidirectional 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) [endsect] @@ -289,6 +291,7 @@ are not defined in __bidirectional_sequence__. * __iterator_range__ (where adapted sequence is a Random Access 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) [endsect] @@ -361,6 +364,7 @@ you can use `__result_of_value_at_key__`.] * __joint_view__ (where adapted sequences are __associative_sequence__\ s and __forward_sequence__\ s) * __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__) [endsect] diff --git a/doc/view.qbk b/doc/view.qbk index d99b325f..a3ad4d09 100644 --- a/doc/view.qbk +++ b/doc/view.qbk @@ -1,6 +1,7 @@ [/============================================================================== Copyright (C) 2001-2011 Joel de Guzman Copyright (C) 2006 Dan Marsden + 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 @@ -664,4 +665,60 @@ defined in __forward_sequence__. [endsect] +[section identity_view] + +[heading Description] + +`identity_view` presents underlying sequence unchanged. + +[heading Header] + + #include + #include + +[heading Synopsis] + + template + struct identity_view; + +[heading Template parameters] + +[table + [[Parameter] [Description] [Default]] + [[`Sequence`] [A __forward_sequence__] []] +] + +[heading Model of] + +* A model of __forward_sequence__ if `Sequence` is a __forward_sequence__ else, __bidirectional_sequence__ if `Sequence` is a __bidirectional_sequence__ +else, __random_access_sequence__ if `Sequence` is a __random_access_sequence__. +* __associative_sequence__ if `Sequence` implements the __associative_sequence__ model. + +[variablelist Notation + [[`IV`] [An `identity_view` type]] + [[`s`] [An instance of `Sequence`]] + [[`iv`, `iv2`] [Instances of `identity_view`]] +] + +[heading Expression Semantics] + +Semantics of an expression is defined only where it differs from, or is not +defined in the implemented models. + +[table + [[Expression] [Semantics]] + [[`IV(s)`] [Creates an `identity_view` given sequence, `s`.]] + [[`IV(iv)`] [Copy constructs an `identity_view` from another `identity_view`, `iv`.]] + [[`iv = iv2`] [Assigns to an `identity_view`, `iv`, from another `identity_view`, `iv2`.]] +] + +[heading Example] + typedef __vector__ vector_type; + vector_type vec(2, 5, 3.3); + + __identity_view__ identity(vec); + std::cout << identity << std::endl; // (2 5 3.3) + +[endsect] + [endsect] diff --git a/include/boost/fusion/include/identity_view.hpp b/include/boost/fusion/include/identity_view.hpp new file mode 100644 index 00000000..bb27d27b --- /dev/null +++ b/include/boost/fusion/include/identity_view.hpp @@ -0,0 +1,12 @@ +/*============================================================================= + 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_IDENTITY_VIEW) +#define FUSION_INCLUDE_IDENTITY_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 4cb49122..0d8ded42 100644 --- a/include/boost/fusion/view.hpp +++ b/include/boost/fusion/view.hpp @@ -17,5 +17,6 @@ #include #include #include +#include #endif diff --git a/include/boost/fusion/view/identity_view.hpp b/include/boost/fusion/view/identity_view.hpp new file mode 100644 index 00000000..72414cbe --- /dev/null +++ b/include/boost/fusion/view/identity_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_SEQUENCE_IDENTITY_VIEW_HPP_INCLUDED) +#define BOOST_FUSION_SEQUENCE_IDENTITY_VIEW_HPP_INCLUDED + +#include +#include + + +#endif \ No newline at end of file diff --git a/include/boost/fusion/view/identity_view/identity_view.hpp b/include/boost/fusion/view/identity_view/identity_view.hpp new file mode 100644 index 00000000..f26f2bc7 --- /dev/null +++ b/include/boost/fusion/view/identity_view/identity_view.hpp @@ -0,0 +1,27 @@ +/*============================================================================= + 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_IDENTITY_VIEW_HPP_INCLUDED) +#define BOOST_FUSION_IDENTITY_VIEW_HPP_INCLUDED + +#include +#include +#include + +namespace boost { namespace fusion { + template struct identity_view + : transform_view + { + typedef transform_view base_type; + + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + identity_view(Sequence& in_seq) + : base_type(in_seq, boost::identity()) {} + }; + +}} + +#endif diff --git a/test/Jamfile b/test/Jamfile index e55b15ad..13dd35c5 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -156,6 +156,7 @@ project : BOOST_FUSION_DISABLE_VARIADIC_VECTOR : tuple_traits__no_variadic ] [ run sequence/transform_view.cpp ] + [ run sequence/identity_view.cpp ] [ run sequence/vector_comparison.cpp ] [ run sequence/vector_construction.cpp ] [ run sequence/vector_conversion.cpp ] diff --git a/test/sequence/identity_view.cpp b/test/sequence/identity_view.cpp new file mode 100644 index 00000000..285b17e2 --- /dev/null +++ b/test/sequence/identity_view.cpp @@ -0,0 +1,184 @@ +/*============================================================================= + 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 +#include +#include +#include +#include +#include + +struct abstract +{ + virtual void foo() = 0; +}; + +int +main() +{ + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + +/// Testing the identity_view + + { + typedef boost::mpl::range_c sequence_type; + sequence_type sequence; + typedef identity_view xform_type; + xform_type xform(sequence); + + std::cout << xform << std::endl; + BOOST_TEST((xform == make_vector(5, 6, 7, 8))); + + typedef boost::fusion::result_of::begin::type first_type; + first_type first_it(boost::fusion::begin(xform)); + + typedef boost::fusion::result_of::next::type next_type; + next_type next_it(boost::fusion::next(first_it)); + BOOST_TEST((*next_it == 6)); + BOOST_TEST((*boost::fusion::prior(next_it) == 5)); + BOOST_TEST((boost::fusion::distance(first_it, next_it) == 1)); + + BOOST_TEST((*boost::fusion::advance_c<3>(boost::fusion::begin(xform)) == 8)); + BOOST_TEST((boost::fusion::at_c<2>(xform) == 7)); + BOOST_MPL_ASSERT((boost::is_same::type, boost::mpl::integral_c&& >)); + } + + /// Associative + { + typedef map< + pair + , pair + , pair > + map_type; + typedef identity_view transformed_type; + + BOOST_MPL_ASSERT((traits::is_associative)); + BOOST_MPL_ASSERT((traits::is_random_access)); + + map_type m( + make_pair('X') + , make_pair("Men") + , make_pair(2)); + transformed_type t(m); + + std::cout << at_key(t) << std::endl; + std::cout << at_key(t) << std::endl; + std::cout << at_key(t) << std::endl; + + BOOST_TEST(at_key(t) == 'X'); + BOOST_TEST(at_key(t) == "Men"); + BOOST_TEST(at_key(t) == 2); + + BOOST_STATIC_ASSERT(( + boost::is_same::type, char>::value)); + BOOST_STATIC_ASSERT(( + boost::is_same::type, std::string>::value)); + BOOST_STATIC_ASSERT(( + boost::is_same::type, int>::value)); + + std::cout << t << std::endl; + + BOOST_STATIC_ASSERT((boost::fusion::result_of::has_key::value)); + BOOST_STATIC_ASSERT((boost::fusion::result_of::has_key::value)); + BOOST_STATIC_ASSERT((boost::fusion::result_of::has_key::value)); + BOOST_STATIC_ASSERT((!boost::fusion::result_of::has_key::value)); + + std::cout << deref_data(begin(t)) << std::endl; + std::cout << deref_data(boost::fusion::next(begin(t))) << std::endl; + + BOOST_TEST(deref_data(begin(t)) == 'X'); + BOOST_TEST(deref_data(boost::fusion::next(begin(t))) == "Men"); + BOOST_TEST(deref_data(boost::fusion::next(next(begin(t)))) == 2); + + BOOST_STATIC_ASSERT((boost::is_same::type>::type, int>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type>::type>::type, double>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type>::type>::type>::type, abstract>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type>::type, char>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type>::type>::type, std::string>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type>::type>::type>::type, int>::value)); + + // Test random access interface. + pair a = at_c<0>(t); (void) a; + pair b = at_c<1>(t); + pair c = at_c<2>(t); + (void)c; + + typedef boost::fusion::result_of::begin::type first; + typedef boost::fusion::result_of::next::type second; + typedef boost::fusion::result_of::next::type third; + + // TODO: why is a boost::fusion::pair&& ?? + BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair&& >)); + BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair&& >)); + BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair&& >)); + } + + { + // compile test only + // make sure result_of::deref_data returns a reference + typedef map > map_type; + typedef identity_view transformed_type; + typedef boost::fusion::result_of::begin::type i_type; + typedef boost::fusion::result_of::deref_data::type r_type; + BOOST_STATIC_ASSERT((boost::is_same::value)); + } + + { + // compile test only + // make sure result_of::deref_data is const correct + typedef map > const map_type; + typedef identity_view transformed_type; + typedef boost::fusion::result_of::begin::type i_type; + typedef boost::fusion::result_of::deref_data::type r_type; + BOOST_STATIC_ASSERT((boost::is_same::value)); + } + + { + // compile test only + // make sure result_of::deref_data will not const for non-constant references + typedef map > const map_type; + typedef identity_view transformed_type; + typedef boost::fusion::result_of::begin::type i_type; + typedef boost::fusion::result_of::deref_data::type r_type; + BOOST_STATIC_ASSERT((boost::is_same::value)); + } + + return boost::report_errors(); +} + From b0f60d59332adf6d90d96645d8d5ba3a10f7fbb8 Mon Sep 17 00:00:00 2001 From: Denis Mikhailov Date: Wed, 12 Jan 2022 09:48:26 +0400 Subject: [PATCH 2/4] Update identity_view.cpp --- test/sequence/identity_view.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/sequence/identity_view.cpp b/test/sequence/identity_view.cpp index 285b17e2..0ad33277 100644 --- a/test/sequence/identity_view.cpp +++ b/test/sequence/identity_view.cpp @@ -79,6 +79,15 @@ main() BOOST_MPL_ASSERT((boost::is_same::type, boost::mpl::integral_c&& >)); } + { + typedef vector sequence_type; + sequence_type seq; + identity_view ident(seq); + copy(make_vector(1, 2, 3, 4, 5), ident); + std::cout << seq << std::endl; + BOOST_TEST((seq == make_vector(1, 2, 3, 4, 5))); + } + /// Associative { typedef map< From d26c2e421281a9667bb81581978aa46507a8aa5e Mon Sep 17 00:00:00 2001 From: Denis Mikhailov Date: Wed, 12 Jan 2022 10:14:07 +0400 Subject: [PATCH 3/4] Update identity_view.cpp --- test/sequence/identity_view.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/sequence/identity_view.cpp b/test/sequence/identity_view.cpp index 0ad33277..1f8c3de2 100644 --- a/test/sequence/identity_view.cpp +++ b/test/sequence/identity_view.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include From 21a449ae469a5c8cf4656ee7fec334075bf0e820 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Sat, 15 Jan 2022 22:22:46 +0400 Subject: [PATCH 4/4] [identity_view] Fix for spoiled prvalue --- .../view/identity_view/identity_view.hpp | 24 +++++++++++++++---- test/sequence/identity_view.cpp | 9 ++++--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/include/boost/fusion/view/identity_view/identity_view.hpp b/include/boost/fusion/view/identity_view/identity_view.hpp index f26f2bc7..e7efdb7a 100644 --- a/include/boost/fusion/view/identity_view/identity_view.hpp +++ b/include/boost/fusion/view/identity_view/identity_view.hpp @@ -10,18 +10,34 @@ #include #include #include +#include + +namespace boost { namespace fusion { + namespace detail { + struct identity : boost::identity + { + }; + } +}} + +namespace boost { + template + struct result_of + { + typedef T type; + }; +} namespace boost { namespace fusion { template struct identity_view - : transform_view + : transform_view { - typedef transform_view base_type; + typedef transform_view base_type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED identity_view(Sequence& in_seq) - : base_type(in_seq, boost::identity()) {} + : base_type(in_seq, detail::identity()) {} }; - }} #endif diff --git a/test/sequence/identity_view.cpp b/test/sequence/identity_view.cpp index 1f8c3de2..e74f9294 100644 --- a/test/sequence/identity_view.cpp +++ b/test/sequence/identity_view.cpp @@ -77,7 +77,7 @@ main() BOOST_TEST((*boost::fusion::advance_c<3>(boost::fusion::begin(xform)) == 8)); BOOST_TEST((boost::fusion::at_c<2>(xform) == 7)); - BOOST_MPL_ASSERT((boost::is_same::type, boost::mpl::integral_c&& >)); + BOOST_MPL_ASSERT((boost::is_same::type, boost::mpl::integral_c >)); } { @@ -153,10 +153,9 @@ main() typedef boost::fusion::result_of::next::type second; typedef boost::fusion::result_of::next::type third; - // TODO: why is a boost::fusion::pair&& ?? - BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair&& >)); - BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair&& >)); - BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair&& >)); + BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair >)); + BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair >)); + BOOST_MPL_ASSERT((boost::is_same::type, boost::fusion::pair >)); } {