Merge remote-tracking branch 'origin/develop' into denzor200-patch-3

This commit is contained in:
denzor200
2022-01-16 09:43:41 +04:00
18 changed files with 776 additions and 8 deletions

View File

@ -11,15 +11,19 @@ environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0
ADDRMD: 32
CXXSTD: latest # fake
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-10.0
ADDRMD: 32
CXXSTD: latest # fake
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-11.0
ADDRMD: 32
CXXSTD: latest # fake
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-12.0
ADDRMD: 32
CXXSTD: latest # fake
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
@ -88,4 +92,5 @@ install:
build: off
test_script:
- b2 -j%NUMBER_OF_PROCESSORS% --hash libs/fusion/test toolset=%TOOLSET% cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j%NUMBER_OF_PROCESSORS% --hash libs/fusion/test toolset=%TOOLSET% cxxstd=%CXXSTD% %ADDRMD%

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

@ -254,6 +254,7 @@ expressions must be valid:
* __iterator_range__ iterator (where adapted iterators are __associative_iterator__\ s)
* __joint_view__ iterator (where adapted sequences are __associative_sequence__\ s and __forward_sequence__\ s)
* __reverse_view__ iterator (where adapted sequence is an __associative_sequence__ and a __bidirectional_sequence__)
* __transform_view__ iterator (where adapted sequence is an __associative_sequence__ and a __forward_sequence__)
[endsect]

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]
@ -360,6 +363,8 @@ you can use `__result_of_value_at_key__<S, K>`.]
* __iterator_range__ (where adapted iterators are __associative_iterator__\ s)
* __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
@ -328,9 +329,7 @@ defined in __forward_sequence__.
The unary version of `transform_view` presents a view of its underlying
sequence given a unary function object or function pointer. The binary
version of `transform_view` presents a view of 2 underlying sequences,
given a binary function object or function pointer. The `transform_view`
inherits the traversal characteristics (see __traversal_concept__) of
its underlying sequence or sequences.
given a binary function object or function pointer.
[heading Header]
@ -364,7 +363,8 @@ its underlying sequence or sequences.
* __forward_sequence__, __bidirectional_sequence__ or
__random_access_sequence__ depending on the traversal characteristics (see
__traversal_concept__) of its underlying sequence.
__traversal_concept__) of its underlying sequence or sequences.
* __associative_sequence__ if underlying sequence implements the __associative_sequence__ model(available only with unary version of `transform_view`).
[variablelist Notation
[[`TV`] [A `transform_view` type]]
@ -381,9 +381,7 @@ __traversal_concept__) of its underlying sequence.
[heading Expression Semantics]
Semantics of an expression is defined only where it differs from, or is not
defined in __forward_sequence__, __bidirectional_sequence__ or
__random_access_sequence__ depending on the traversal characteristics (see
__traversal_concept__) of its underlying sequence or sequences.
defined in the implemented models.
[table
[[Expression] [Semantics]]
@ -667,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

@ -0,0 +1,66 @@
/*=============================================================================
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_TRANSFORM_VIEW_DEREF_DATA_IMPL_JAN_9_2022_0354PM)
#define BOOST_FUSION_TRANSFORM_VIEW_DEREF_DATA_IMPL_JAN_9_2022_0354PM
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/mpl/if.hpp>
namespace boost { namespace fusion
{
struct transform_view_iterator_tag;
struct transform_view_iterator2_tag;
namespace extension
{
template<typename Tag>
struct deref_data_impl;
// Unary Version
template<>
struct deref_data_impl<transform_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef typename
result_of::deref<typename Iterator::first_type>::type
value_type;
typedef typename Iterator::transform_type F;
typedef typename boost::result_of<F(value_type)>::type transformed_type;
typedef typename boost::remove_reference<transformed_type>::type transformed_type_unref;
typedef typename boost::remove_const<transformed_type_unref>::type transformed_type_unconst;
typedef typename transformed_type_unconst::second_type raw_type;
typedef typename
boost::mpl::if_<
is_reference<transformed_type>
, typename boost::mpl::if_<
is_const<transformed_type_unref>
, typename boost::add_reference<typename boost::add_const<raw_type>::type>::type
, typename boost::add_reference<raw_type>::type
>::type
, raw_type
>::type
type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static type
call(Iterator const& i)
{
return i.f(fusion::deref(i.first)).second;
}
};
};
// Binary Version is not supported with Associative Sequence
}
}}
#endif

View File

@ -0,0 +1,47 @@
/*=============================================================================
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_TRANSFORM_VIEW_KEY_OF_IMPL_JAN_9_2022_0354PM)
#define BOOST_FUSION_TRANSFORM_VIEW_KEY_OF_IMPL_JAN_9_2022_0354PM
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/utility/result_of.hpp>
namespace boost { namespace fusion
{
struct transform_view_iterator_tag;
struct transform_view_iterator2_tag;
namespace extension
{
template<typename Tag>
struct key_of_impl;
// Unary Version
template<>
struct key_of_impl<transform_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef typename
result_of::deref<typename Iterator::first_type>::type
value_type;
typedef typename Iterator::transform_type F;
typedef typename boost::result_of<F(value_type)>::type transformed_type;
typedef typename boost::remove_reference<transformed_type>::type transformed_type_unref;
typedef typename boost::remove_const<transformed_type_unref>::type transformed_type_unconst;
typedef typename transformed_type_unconst::first_type type;
};
};
// Binary Version is not supported with Associative Sequence
}
}}
#endif

View File

@ -0,0 +1,47 @@
/*=============================================================================
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_TRANSFORM_VIEW_VALUE_OF_IMPL_JAN_9_2022_0354PM)
#define BOOST_FUSION_TRANSFORM_VIEW_VALUE_OF_IMPL_JAN_9_2022_0354PM
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/utility/result_of.hpp>
namespace boost { namespace fusion
{
struct transform_view_iterator_tag;
struct transform_view_iterator2_tag;
namespace extension
{
template<typename Tag>
struct value_of_data_impl;
// Unary Version
template<>
struct value_of_data_impl<transform_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef typename
result_of::deref<typename Iterator::first_type>::type
value_type;
typedef typename Iterator::transform_type F;
typedef typename boost::result_of<F(value_type)>::type transformed_type;
typedef typename boost::remove_reference<transformed_type>::type transformed_type_unref;
typedef typename boost::remove_const<transformed_type_unref>::type transformed_type_unconst;
typedef typename transformed_type_unconst::second_type type;
};
};
// Binary Version is not supported with Associative Sequence
}
}}
#endif

View File

@ -19,6 +19,9 @@
#include <boost/fusion/view/transform_view/detail/advance_impl.hpp>
#include <boost/fusion/view/transform_view/detail/distance_impl.hpp>
#include <boost/fusion/view/transform_view/detail/equal_to_impl.hpp>
#include <boost/fusion/view/transform_view/detail/key_of_impl.hpp>
#include <boost/fusion/view/transform_view/detail/value_of_data_impl.hpp>
#include <boost/fusion/view/transform_view/detail/deref_data_impl.hpp>
namespace boost { namespace fusion
{

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();
}

View File

@ -1,11 +1,14 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
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/adapted/mpl.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
@ -14,15 +17,29 @@
#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 square
{
@ -60,6 +77,85 @@ struct add
}
};
struct abstract
{
virtual void foo() = 0;
};
struct functor
{
typedef boost::fusion::pair<short, char> pair_0;
typedef boost::fusion::pair<double, std::string> pair_1;
typedef boost::fusion::pair<abstract, long> pair_2;
typedef boost::mpl::map<
boost::mpl::pair< boost::fusion::pair<int, char> , pair_0>
, boost::mpl::pair< pair_1 , pair_1>
, boost::mpl::pair< boost::fusion::pair<abstract, int> , pair_2>
> m;
template<typename Sig>
struct result;
template<class F, class T>
struct result<F(T)>
: boost::mpl::at<
m,
typename boost::remove_reference<T>::type
>
{};
pair_0 operator() (const boost::fusion::pair<int, char>& arg) const
{
return pair_0(arg.second);
}
pair_1 operator() (const pair_1 & arg) const
{
return pair_1(arg.second + "_transformed");
}
pair_2 operator() (const boost::fusion::pair<abstract, int>& arg) const
{
return pair_2(arg.second);
}
};
struct simple_identity
{
template<typename Sig>
struct result;
template<typename U>
struct result<simple_identity(U)>
{
typedef U type;
};
template<typename T>
T& operator() (T& arg) const
{
return arg;
}
};
struct simple_identity_nonref
{
template<typename Sig>
struct result;
template<typename U>
struct result<simple_identity_nonref(U)>
: boost::remove_reference<U>
{};
template<typename T>
T operator() (T arg) const
{
return arg;
}
};
int
main()
{
@ -110,6 +206,183 @@ main()
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_c<xform_type, 0>::type, int>));
}
/// Associative
{
typedef map<
pair<int, char>
, pair<double, std::string>
, pair<abstract, int> >
map_type;
typedef transform_view<map_type, functor> 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, functor());
std::cout << at_key<short>(t) << std::endl;
std::cout << at_key<double>(t) << std::endl;
std::cout << at_key<abstract>(t) << std::endl;
BOOST_TEST(at_key<short>(t) == 'X');
BOOST_TEST(at_key<double>(t) == "Men_transformed");
BOOST_TEST(at_key<abstract>(t) == 2);
BOOST_STATIC_ASSERT((
boost::is_same<boost::fusion::result_of::value_at_key<transformed_type, short>::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, long>::value));
std::cout << t << std::endl;
BOOST_STATIC_ASSERT((boost::fusion::result_of::has_key<transformed_type, short>::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_transformed");
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, short>::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, long>::value));
// Test random access interface.
pair<short, 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<short, 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, long> >));
}
{
typedef map<
pair<int, char>
, pair<double, std::string>
, pair<abstract, int> >
map_type;
typedef transform_view<map_type, simple_identity> 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, simple_identity());
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 transform_view<map_type, simple_identity> 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 transform_view<map_type, simple_identity> 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 return a reference to temp object
typedef map<pair<float, int> > const map_type;
typedef transform_view<map_type, simple_identity_nonref> 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 will not const for non-constant references
typedef map<pair<float, int&> > const map_type;
typedef transform_view<map_type, simple_identity> 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();
}