Merge pull request #240 from denzor200/identity_view

Added boost::fusion::identity_view
This commit is contained in:
Joel de Guzman
2022-01-16 08:39:38 +08:00
committed by GitHub
11 changed files with 328 additions and 0 deletions

View File

@ -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`]]

View File

@ -163,6 +163,7 @@
<dt><span class="section"><a href="fusion/view/zip_view.html">zip_view</a></span></dt>
<dt><span class="section"><a href="fusion/view/transform_view.html">transform_view</a></span></dt>
<dt><span class="section"><a href="fusion/view/reverse_view.html">reverse_view</a></span></dt>
<dt><span class="section"><a href="fusion/view/identity_view.html">identity_view</a></span></dt>
<dt><span class="section"><a href="fusion/view/nview.html">nview</a></span></dt>
<dt><span class="section"><a href="fusion/view/repetitive_view.html">repetitive_view</a></span></dt>
<dt><span class="section"><a href="fusion/view/flatten_view.html">flatten_view</a></span></dt>

View File

@ -60,6 +60,7 @@ link against.
* single_view
* transform_view
* zip_view
* identity_view
* container
* deque
* list

View File

@ -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__<S, K>`.]
* __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]

View File

@ -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 <boost/fusion/view/identity_view.hpp>
#include <boost/fusion/include/identity_view.hpp>
[heading Synopsis]
template <typename Sequence>
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__<int, short, double> vector_type;
vector_type vec(2, 5, 3.3);
__identity_view__<vector_type> identity(vec);
std::cout << identity << std::endl; // (2 5 3.3)
[endsect]
[endsect]

View File

@ -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 <boost/fusion/support/config.hpp>
#include <boost/fusion/view/identity_view.hpp>
#endif

View File

@ -17,5 +17,6 @@
#include <boost/fusion/view/transform_view.hpp>
#include <boost/fusion/view/zip_view.hpp>
#include <boost/fusion/view/flatten_view.hpp>
#include <boost/fusion/view/identity_view.hpp>
#endif

View File

@ -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 <boost/fusion/support/config.hpp>
#include <boost/fusion/view/identity_view/identity_view.hpp>
#endif

View File

@ -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 <boost/fusion/support/config.hpp>
#include <boost/fusion/view/transform_view.hpp>
#include <boost/functional/identity.hpp>
#include <boost/utility/result_of.hpp>
namespace boost { namespace fusion {
namespace detail {
struct identity : boost::identity
{
};
}
}}
namespace boost {
template<typename T>
struct result_of<fusion::detail::identity(T)>
{
typedef T type;
};
}
namespace boost { namespace fusion {
template<typename Sequence> struct identity_view
: transform_view<Sequence, detail::identity>
{
typedef transform_view<Sequence, detail::identity> base_type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
identity_view(Sequence& in_seq)
: base_type(in_seq, detail::identity()) {}
};
}}
#endif

View File

@ -156,6 +156,7 @@ project
: <define>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 ]

View File

@ -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 <boost/detail/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/container/map/map.hpp>
#include <boost/fusion/container/generation/make_map.hpp>
#include <boost/fusion/algorithm/auxiliary/copy.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/fusion/sequence/comparison/equal_to.hpp>
#include <boost/fusion/view/identity_view/identity_view.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/at.hpp>
#include <boost/fusion/sequence/intrinsic/value_at.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/sequence/intrinsic/value_at_key.hpp>
#include <boost/fusion/sequence/intrinsic/has_key.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/prior.hpp>
#include <boost/fusion/iterator/advance.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/distance.hpp>
#include <boost/fusion/iterator/key_of.hpp>
#include <boost/fusion/iterator/deref_data.hpp>
#include <boost/fusion/iterator/value_of_data.hpp>
#include <boost/fusion/support/pair.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/map.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/remove_reference.hpp>
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<int, 5, 9> sequence_type;
sequence_type sequence;
typedef identity_view<sequence_type> 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<xform_type>::type first_type;
first_type first_it(boost::fusion::begin(xform));
typedef boost::fusion::result_of::next<first_type>::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<boost::fusion::result_of::value_at_c<xform_type, 0>::type, boost::mpl::integral_c<int, 5> >));
}
{
typedef vector<int, int, int, int, int> sequence_type;
sequence_type seq;
identity_view<sequence_type> 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<int, char>
, pair<double, std::string>
, pair<abstract, int> >
map_type;
typedef identity_view<map_type> transformed_type;
BOOST_MPL_ASSERT((traits::is_associative<transformed_type>));
BOOST_MPL_ASSERT((traits::is_random_access<transformed_type>));
map_type m(
make_pair<int>('X')
, make_pair<double>("Men")
, make_pair<abstract>(2));
transformed_type t(m);
std::cout << at_key<int>(t) << std::endl;
std::cout << at_key<double>(t) << std::endl;
std::cout << at_key<abstract>(t) << std::endl;
BOOST_TEST(at_key<int>(t) == 'X');
BOOST_TEST(at_key<double>(t) == "Men");
BOOST_TEST(at_key<abstract>(t) == 2);
BOOST_STATIC_ASSERT((
boost::is_same<boost::fusion::result_of::value_at_key<transformed_type, int>::type, char>::value));
BOOST_STATIC_ASSERT((
boost::is_same<boost::fusion::result_of::value_at_key<transformed_type, double>::type, std::string>::value));
BOOST_STATIC_ASSERT((
boost::is_same<boost::fusion::result_of::value_at_key<transformed_type, abstract>::type, int>::value));
std::cout << t << std::endl;
BOOST_STATIC_ASSERT((boost::fusion::result_of::has_key<transformed_type, int>::value));
BOOST_STATIC_ASSERT((boost::fusion::result_of::has_key<transformed_type, double>::value));
BOOST_STATIC_ASSERT((boost::fusion::result_of::has_key<transformed_type, abstract>::value));
BOOST_STATIC_ASSERT((!boost::fusion::result_of::has_key<transformed_type, std::string>::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<boost::fusion::result_of::key_of<boost::fusion::result_of::begin<transformed_type>::type>::type, int>::value));
BOOST_STATIC_ASSERT((boost::is_same<boost::fusion::result_of::key_of<boost::fusion::result_of::next<boost::fusion::result_of::begin<transformed_type>::type>::type>::type, double>::value));
BOOST_STATIC_ASSERT((boost::is_same<boost::fusion::result_of::key_of<boost::fusion::result_of::next<boost::fusion::result_of::next<boost::fusion::result_of::begin<transformed_type>::type>::type>::type>::type, abstract>::value));
BOOST_STATIC_ASSERT((boost::is_same<boost::fusion::result_of::value_of_data<boost::fusion::result_of::begin<transformed_type>::type>::type, char>::value));
BOOST_STATIC_ASSERT((boost::is_same<boost::fusion::result_of::value_of_data<boost::fusion::result_of::next<boost::fusion::result_of::begin<transformed_type>::type>::type>::type, std::string>::value));
BOOST_STATIC_ASSERT((boost::is_same<boost::fusion::result_of::value_of_data<boost::fusion::result_of::next<boost::fusion::result_of::next<boost::fusion::result_of::begin<transformed_type>::type>::type>::type>::type, int>::value));
// Test random access interface.
pair<int, char> a = at_c<0>(t); (void) a;
pair<double, std::string> b = at_c<1>(t);
pair<abstract, int> c = at_c<2>(t);
(void)c;
typedef boost::fusion::result_of::begin<transformed_type>::type first;
typedef boost::fusion::result_of::next<first>::type second;
typedef boost::fusion::result_of::next<second>::type third;
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_of<first>::type, boost::fusion::pair<int, char> >));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_of<second>::type, boost::fusion::pair<double, std::string> >));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_of<third>::type, boost::fusion::pair<abstract, int> >));
}
{
// compile test only
// make sure result_of::deref_data returns a reference
typedef map<pair<float, int> > map_type;
typedef identity_view<map_type> transformed_type;
typedef boost::fusion::result_of::begin<transformed_type>::type i_type;
typedef boost::fusion::result_of::deref_data<i_type>::type r_type;
BOOST_STATIC_ASSERT((boost::is_same<r_type, int&>::value));
}
{
// compile test only
// make sure result_of::deref_data is const correct
typedef map<pair<float, int> > const map_type;
typedef identity_view<map_type> transformed_type;
typedef boost::fusion::result_of::begin<transformed_type>::type i_type;
typedef boost::fusion::result_of::deref_data<i_type>::type r_type;
BOOST_STATIC_ASSERT((boost::is_same<r_type, int const&>::value));
}
{
// compile test only
// make sure result_of::deref_data will not const for non-constant references
typedef map<pair<float, int&> > const map_type;
typedef identity_view<map_type> transformed_type;
typedef boost::fusion::result_of::begin<transformed_type>::type i_type;
typedef boost::fusion::result_of::deref_data<i_type>::type r_type;
BOOST_STATIC_ASSERT((boost::is_same<r_type, int&>::value));
}
return boost::report_errors();
}