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..e7efdb7a
--- /dev/null
+++ b/include/boost/fusion/view/identity_view/identity_view.hpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ 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
+#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
+ {
+ typedef transform_view base_type;
+
+ BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+ identity_view(Sequence& in_seq)
+ : base_type(in_seq, detail::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..e74f9294
--- /dev/null
+++ b/test/sequence/identity_view.cpp
@@ -0,0 +1,193 @@
+/*=============================================================================
+ 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
+#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 >));
+ }
+
+ {
+ 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<
+ 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;
+
+ 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();
+}
+