diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:05:34 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:06:28 +0900 |
commit | 34bd32e225e2a8a94104489b31c42e5801cc1f4a (patch) | |
tree | d021b579a0c190354819974e1eaf0baa54b551f3 /libs/fusion | |
parent | f763a99a501650eff2c60288aa6f10ef916d769e (diff) | |
download | boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.tar.gz boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.tar.bz2 boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.zip |
Imported Upstream version 1.63.0upstream/1.63.0
Change-Id: Iac85556a04b7e58d63ba636dedb0986e3555714a
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'libs/fusion')
51 files changed, 3594 insertions, 64 deletions
diff --git a/libs/fusion/doc/Jamfile b/libs/fusion/doc/Jamfile index 8348f7ebed..04f9933ce0 100644 --- a/libs/fusion/doc/Jamfile +++ b/libs/fusion/doc/Jamfile @@ -25,4 +25,8 @@ boostbook quickbook <format>pdf:<xsl:param>img.src.path=$(images_location)/ ; - +############################################################################### +alias boostdoc ; +explicit boostdoc ; +alias boostrelease : quickbook ; +explicit boostrelease ; diff --git a/libs/fusion/doc/html/index.html b/libs/fusion/doc/html/index.html index daacb93e76..c91eafb78a 100644 --- a/libs/fusion/doc/html/index.html +++ b/libs/fusion/doc/html/index.html @@ -278,7 +278,7 @@ </div> </div> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> -<td align="left"><p><small>Last revised: September 21, 2016 at 14:45:48 GMT</small></p></td> +<td align="left"><p><small>Last revised: December 22, 2016 at 12:38:47 GMT</small></p></td> <td align="right"><div class="copyright-footer"></div></td> </tr></table> <hr> diff --git a/libs/fusion/test/Jamfile b/libs/fusion/test/Jamfile index 8f290165da..017e8922d5 100644 --- a/libs/fusion/test/Jamfile +++ b/libs/fusion/test/Jamfile @@ -1,5 +1,6 @@ ##============================================================================== # Copyright (c) 2003-2006 Joel de Guzman +# Copyright (c) 2013 Mateusz Loskot # # Use, modification and distribution is subject to the Boost Software # License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -121,8 +122,10 @@ project [ run sequence/std_pair.cpp : : : : ] [ run sequence/boost_array.cpp : : : : ] [ run sequence/array.cpp : : : : ] + [ run sequence/std_array.cpp : : : : ] [ run sequence/tuple_comparison.cpp : : : : ] [ run sequence/tuple_construction.cpp : : : : ] + [ run sequence/tuple_conversion.cpp : : : : ] [ run sequence/tuple_copy.cpp : : : : ] [ run sequence/tuple_element.cpp : : : : ] [ run sequence/tuple_make.cpp : : : : ] @@ -131,9 +134,24 @@ project [ run sequence/tuple_nest.cpp : : : : ] [ run sequence/tuple_hash.cpp : : : : ] [ run sequence/tuple_tie.cpp : : : : ] + [ + run sequence/tuple_traits.cpp + : + : + : + : sequence/tuple_traits/maybe_variadic_tuple + ] + [ + run sequence/tuple_traits.cpp + : + : + : <define>BOOST_FUSION_DISABLE_VARIADIC_VECTOR + : sequence/tuple_traits/no_variadic_tuple + ] [ run sequence/transform_view.cpp : : : : ] [ run sequence/vector_comparison.cpp : : : : ] [ run sequence/vector_construction.cpp : : : : ] + [ run sequence/vector_conversion.cpp : : : : ] [ run sequence/vector_copy.cpp : : : : ] [ run sequence/vector_iterator.cpp : : : : ] [ run sequence/vector_make.cpp : : : : ] @@ -144,6 +162,20 @@ project [ run sequence/vector_nest.cpp : : : : ] [ run sequence/vector_hash.cpp : : : : ] [ run sequence/vector_tie.cpp : : : : ] + [ + run sequence/vector_traits.cpp + : + : + : + : sequence/vector_traits/maybe_variadic_vector + ] + [ + run sequence/vector_traits.cpp + : + : + : <define>BOOST_FUSION_DISABLE_VARIADIC_VECTOR + : sequence/vector_traits/no_variadic_vector + ] [ run sequence/vector_value_at.cpp : : : : ] [ run sequence/zip_view.cpp : : : : ] [ run sequence/zip_view2.cpp : : : : ] @@ -151,24 +183,48 @@ project [ run sequence/repetitive_view.cpp : : : : ] [ run sequence/deduce_sequence.cpp : : : : ] [ run sequence/adapt_adt_named.cpp : : : : ] + [ run sequence/adapt_adt_named_empty.cpp : : : : ] [ run sequence/adapt_adt.cpp : : : : ] + [ run sequence/adapt_adt_empty.cpp : : : : ] [ run sequence/adapt_assoc_adt_named.cpp : : : : ] + [ run sequence/adapt_assoc_adt_named_empty.cpp : : : : ] [ run sequence/adapt_assoc_adt.cpp : : : : ] + [ run sequence/adapt_assoc_adt_empty.cpp : : : : ] [ run sequence/adapt_assoc_struct_named.cpp : : : : ] + [ run sequence/adapt_assoc_struct_named_empty.cpp : : : : ] [ run sequence/adapt_assoc_struct.cpp : : : : ] + [ run sequence/adapt_assoc_struct_empty.cpp : : : : ] [ run sequence/adapt_assoc_tpl_adt.cpp : : : : ] + [ run sequence/adapt_assoc_tpl_adt_empty.cpp : : : : ] [ run sequence/adapt_assoc_tpl_struct.cpp : : : : ] + [ run sequence/adapt_assoc_tpl_struct_empty.cpp : : : : ] [ run sequence/adapt_struct_named.cpp : : : : ] + [ run sequence/adapt_struct_named_empty.cpp : : : : ] [ run sequence/adapt_struct.cpp : : : : ] + [ run sequence/adapt_struct_empty.cpp : : : : ] [ run sequence/adapt_tpl_adt.cpp : : : : ] + [ run sequence/adapt_tpl_adt_empty.cpp : : : : ] [ run sequence/adapt_tpl_struct.cpp : : : : ] + [ run sequence/adapt_tpl_struct_empty.cpp : : : : ] [ run sequence/adt_attribute_proxy.cpp : : : : ] [ run sequence/define_struct.cpp : : : : ] + [ run sequence/define_struct_empty.cpp : : : : ] + [ run sequence/define_struct_move.cpp : : : : ] [ run sequence/define_struct_inline.cpp : : : : ] + [ run sequence/define_struct_inline_empty.cpp : : : : ] + [ run sequence/define_struct_inline_move.cpp : : : : ] [ run sequence/define_assoc_struct.cpp : : : : ] + [ run sequence/define_assoc_struct_empty.cpp : : : : ] + [ run sequence/define_assoc_struct_move.cpp : : : : ] [ run sequence/define_tpl_struct.cpp : : : : ] + [ run sequence/define_tpl_struct_empty.cpp : : : : ] + [ run sequence/define_tpl_struct_move.cpp : : : : ] [ run sequence/define_tpl_struct_inline.cpp : : : : ] + [ run sequence/define_tpl_struct_inline_empty.cpp : : : : ] + [ run sequence/define_tpl_struct_inline_move.cpp : : : : ] [ run sequence/define_assoc_tpl_struct.cpp : : : : ] + [ run sequence/define_assoc_tpl_struct_empty.cpp : : : : ] + [ run sequence/define_assoc_tpl_struct_move.cpp : : : : ] [ run sequence/std_tuple.cpp : : : : ] [ run sequence/std_tuple_iterator.cpp : : : : ] [ run sequence/ref_vector.cpp : : : : ] @@ -197,6 +253,7 @@ project [ compile support/pair_vector.cpp : : : : ] [ compile support/pair_nest.cpp : : : : ] [ compile support/index_sequence.cpp : : : : ] + [ compile support/and.cpp : : : : ] # [ compile-fail xxx.cpp : : : : ] diff --git a/libs/fusion/test/sequence/adapt_adt_empty.cpp b/libs/fusion/test/sequence/adapt_adt_empty.cpp new file mode 100644 index 0000000000..925cdce0d2 --- /dev/null +++ b/libs/fusion/test/sequence/adapt_adt_empty.cpp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/adt/adapt_adt.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_adt{}; +BOOST_FUSION_ADAPT_ADT(empty_adt,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_adt>)); + empty_adt e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_adt>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_adt>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_adt>::type, + fusion::result_of::end<empty_adt>::type>)); + } + + { + fusion::vector<> v; + empty_adt e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_adt e; + + // conversion from empty_adt to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_adt to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_adt>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_adt_named_empty.cpp b/libs/fusion/test/sequence/adapt_adt_named_empty.cpp new file mode 100644 index 0000000000..f750071dab --- /dev/null +++ b/libs/fusion/test/sequence/adapt_adt_named_empty.cpp @@ -0,0 +1,87 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/adt/adapt_adt_named.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_adt{}; +BOOST_FUSION_ADAPT_ADT_NAMED(::empty_adt,empty_adt,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + empty_adt empty; + { + BOOST_MPL_ASSERT((traits::is_view<adapted::empty_adt>)); + adapted::empty_adt e(empty); + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<adapted::empty_adt>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<adapted::empty_adt>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<adapted::empty_adt>::type, + fusion::result_of::end<adapted::empty_adt>::type>)); + } + + { + fusion::vector<> v; + adapted::empty_adt e(empty); + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + adapted::empty_adt e(empty); + + // conversion from empty_adt to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_adt to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<adapted::empty_adt>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_assoc_adt_empty.cpp b/libs/fusion/test/sequence/adapt_assoc_adt_empty.cpp new file mode 100644 index 0000000000..8d4d2a28c9 --- /dev/null +++ b/libs/fusion/test/sequence/adapt_assoc_adt_empty.cpp @@ -0,0 +1,88 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/adt/adapt_assoc_adt.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_adt{}; +BOOST_FUSION_ADAPT_ASSOC_ADT(empty_adt,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_adt>)); + empty_adt e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_adt>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_adt>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_adt>::type, + fusion::result_of::end<empty_adt>::type>)); + } + + { + fusion::vector<> v; + empty_adt e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(e != v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_adt e; + + // conversion from empty_adt to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_adt to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_adt>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_adt, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_adt, int>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_assoc_adt_named_empty.cpp b/libs/fusion/test/sequence/adapt_assoc_adt_named_empty.cpp new file mode 100644 index 0000000000..c8fa102afa --- /dev/null +++ b/libs/fusion/test/sequence/adapt_assoc_adt_named_empty.cpp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/adt/adapt_assoc_adt_named.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_adt{}; +BOOST_FUSION_ADAPT_ASSOC_ADT_NAMED(::empty_adt,empty_adt,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + empty_adt empty; + { + BOOST_MPL_ASSERT((traits::is_view<adapted::empty_adt>)); + adapted::empty_adt e(empty); + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<adapted::empty_adt>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<adapted::empty_adt>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<adapted::empty_adt>::type, + fusion::result_of::end<adapted::empty_adt>::type>)); + } + + { + fusion::vector<> v; + adapted::empty_adt e(empty); + BOOST_TEST(v == e); + BOOST_TEST_NOT(e != v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + adapted::empty_adt e(empty); + + // conversion from empty_adt to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_adt to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<adapted::empty_adt>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<adapted::empty_adt, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<adapted::empty_adt, int>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_assoc_struct_empty.cpp b/libs/fusion/test/sequence/adapt_assoc_struct_empty.cpp new file mode 100644 index 0000000000..aa75f87a18 --- /dev/null +++ b/libs/fusion/test/sequence/adapt_assoc_struct_empty.cpp @@ -0,0 +1,88 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/struct/adapt_assoc_struct.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_struct{}; +BOOST_FUSION_ADAPT_ASSOC_STRUCT(empty_struct,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct>)); + empty_struct e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_struct>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_struct>::type, + fusion::result_of::end<empty_struct>::type>)); + } + + { + fusion::vector<> v; + empty_struct e; + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_struct e; + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct, int>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_assoc_struct_named_empty.cpp b/libs/fusion/test/sequence/adapt_assoc_struct_named_empty.cpp new file mode 100644 index 0000000000..a744d6a440 --- /dev/null +++ b/libs/fusion/test/sequence/adapt_assoc_struct_named_empty.cpp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/struct/adapt_assoc_struct_named.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_struct{}; +BOOST_FUSION_ADAPT_ASSOC_STRUCT_NAMED(::empty_struct,empty_struct,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + empty_struct empty; + { + BOOST_MPL_ASSERT((traits::is_view<adapted::empty_struct>)); + adapted::empty_struct e(empty); + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<adapted::empty_struct>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<adapted::empty_struct>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<adapted::empty_struct>::type, + fusion::result_of::end<adapted::empty_struct>::type>)); + } + + { + fusion::vector<> v; + adapted::empty_struct e(empty); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + adapted::empty_struct e(empty); + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<adapted::empty_struct>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<adapted::empty_struct, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<adapted::empty_struct, int>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_assoc_tpl_adt_empty.cpp b/libs/fusion/test/sequence/adapt_assoc_tpl_adt_empty.cpp new file mode 100644 index 0000000000..f38ba7ac7f --- /dev/null +++ b/libs/fusion/test/sequence/adapt_assoc_tpl_adt_empty.cpp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/adt/adapt_assoc_adt.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +template <typename T> +class empty_adt{}; +BOOST_FUSION_ADAPT_ASSOC_TPL_ADT((T), (empty_adt)(T),) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_adt<void> >)); + empty_adt<void> e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_adt<void> >::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_adt<void> >)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_adt<void> >::type, + fusion::result_of::end<empty_adt<void> >::type>)); + } + + { + fusion::vector<> v; + empty_adt<void> e; + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_adt<void> e; + + // conversion from empty_adt to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_adt to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_adt<void> >)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_adt<void>, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_adt<void>, int>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_assoc_tpl_struct_empty.cpp b/libs/fusion/test/sequence/adapt_assoc_tpl_struct_empty.cpp new file mode 100644 index 0000000000..42795c4193 --- /dev/null +++ b/libs/fusion/test/sequence/adapt_assoc_tpl_struct_empty.cpp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/struct/adapt_assoc_struct.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +template <typename T> +class empty_struct{}; +BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT((T), (empty_struct)(T),) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct<void> >)); + empty_struct<void> e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct<void> >::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_struct<void> >)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_struct<void> >::type, + fusion::result_of::end<empty_struct<void> >::type>)); + } + + { + fusion::vector<> v; + empty_struct<void> e; + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_struct<void> e; + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct<void> >)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct<void>, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct<void>, int>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_struct_empty.cpp b/libs/fusion/test/sequence/adapt_struct_empty.cpp new file mode 100644 index 0000000000..f08dc98d8f --- /dev/null +++ b/libs/fusion/test/sequence/adapt_struct_empty.cpp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/struct/adapt_struct.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_struct{}; +BOOST_FUSION_ADAPT_STRUCT(empty_struct,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct>)); + empty_struct e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_struct>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_struct>::type, + fusion::result_of::end<empty_struct>::type>)); + } + + { + fusion::vector<> v; + empty_struct e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(e != v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_struct e; + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_struct_named_empty.cpp b/libs/fusion/test/sequence/adapt_struct_named_empty.cpp new file mode 100644 index 0000000000..8333f1304f --- /dev/null +++ b/libs/fusion/test/sequence/adapt_struct_named_empty.cpp @@ -0,0 +1,87 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/struct/adapt_struct_named.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +class empty_struct{}; +BOOST_FUSION_ADAPT_STRUCT_NAMED(::empty_struct,empty_struct,) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + empty_struct empty; + { + BOOST_MPL_ASSERT((traits::is_view<adapted::empty_struct>)); + adapted::empty_struct e(empty); + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<adapted::empty_struct>::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<adapted::empty_struct>)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<adapted::empty_struct>::type, + fusion::result_of::end<adapted::empty_struct>::type>)); + } + + { + fusion::vector<> v; + adapted::empty_struct e(empty); + BOOST_TEST(v == e); + BOOST_TEST_NOT(e != v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + adapted::empty_struct e(empty); + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<adapted::empty_struct>)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_tpl_adt_empty.cpp b/libs/fusion/test/sequence/adapt_tpl_adt_empty.cpp new file mode 100644 index 0000000000..82bf21214d --- /dev/null +++ b/libs/fusion/test/sequence/adapt_tpl_adt_empty.cpp @@ -0,0 +1,87 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/adt/adapt_adt.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +template <typename T> +class empty_adt{}; +BOOST_FUSION_ADAPT_TPL_ADT((T), (empty_adt)(T),) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_adt<void> >)); + empty_adt<void> e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_adt<void> >::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_adt<void> >)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_adt<void> >::type, + fusion::result_of::end<empty_adt<void> >::type>)); + } + + { + fusion::vector<> v; + empty_adt<void> e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_adt<void> e; + + // conversion from empty_adt to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_adt to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_adt<void> >)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/adapt_tpl_struct_empty.cpp b/libs/fusion/test/sequence/adapt_tpl_struct_empty.cpp new file mode 100644 index 0000000000..5cb1d442e5 --- /dev/null +++ b/libs/fusion/test/sequence/adapt_tpl_struct_empty.cpp @@ -0,0 +1,87 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/adapted/struct/adapt_struct.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/begin.hpp> +#include <boost/fusion/sequence/intrinsic/end.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/container/vector/vector.hpp> +#include <boost/fusion/container/list/list.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/sequence/comparison/equal_to.hpp> +#include <boost/fusion/sequence/comparison/not_equal_to.hpp> +#include <boost/fusion/sequence/comparison/less.hpp> +#include <boost/fusion/sequence/comparison/less_equal.hpp> +#include <boost/fusion/sequence/comparison/greater.hpp> +#include <boost/fusion/sequence/comparison/greater_equal.hpp> +#include <boost/fusion/mpl.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/assert.hpp> +#include <iostream> + +template <typename T> +class empty_struct{}; +BOOST_FUSION_ADAPT_TPL_STRUCT((T), (empty_struct)(T),) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct<void> >)); + empty_struct<void> e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct<void> >::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty<empty_struct<void> >)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin<empty_struct<void> >::type, + fusion::result_of::end<empty_struct<void> >::type>)); + } + + { + fusion::vector<> v; + empty_struct<void> e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct<void> e; + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct<void> >)); + + return boost::report_errors(); +} + diff --git a/libs/fusion/test/sequence/conversion.hpp b/libs/fusion/test/sequence/conversion.hpp new file mode 100644 index 0000000000..f572077620 --- /dev/null +++ b/libs/fusion/test/sequence/conversion.hpp @@ -0,0 +1,322 @@ +/*============================================================================= + Copyright (c) 2016 Lee Clagett + + Use modification and distribution are subject to the Boost Software + License, Version 1.0. (See accompanyintg file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt). +==============================================================================*/ + +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/adapted/boost_tuple.hpp> +#include <boost/fusion/adapted/std_pair.hpp> +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) \ + && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# include <boost/fusion/adapted/std_tuple.hpp> +#endif +#include <boost/fusion/container/deque.hpp> +#include <boost/fusion/container/list.hpp> +#include <boost/fusion/tuple.hpp> +#include <boost/fusion/container/vector.hpp> + +#include "fixture.hpp" + +template <template <typename> class Scenario> +void test() +{ + using namespace test_detail; + + // Note the trunction conversion tests from each containter + // ... bug or feature? + + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back(FUSION_SEQUENCE<int>(300), 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::push_back(FUSION_SEQUENCE<int>(200), 400) + , FUSION_SEQUENCE<convertible>(200) + ) + )); + + BOOST_TEST((run<Scenario<FUSION_SEQUENCE<> > >(boost::fusion::vector<>()))); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<> > >( + boost::fusion::vector<int>(100), boost::fusion::vector<>() + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::vector<int>(110) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::vector<int, int>(200, 100) + , boost::fusion::vector<convertible>(200) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::vector<int, int>(200, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::vector<int, int, int>(500, 400, 100) + , boost::fusion::vector<convertible, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::vector<int>(500), 400 + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::vector<int, int>(500, 400), 100 + ) + , boost::fusion::vector<convertible, int>(500, 400) + ) + )); + + BOOST_TEST((run<Scenario< FUSION_SEQUENCE<> > >(boost::fusion::deque<>()))); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<> > >( + boost::fusion::deque<int>(100), boost::fusion::deque<>() + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::deque<int>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::deque<int, int>(500, 100) + , boost::fusion::deque<convertible>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::deque<int, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::deque<int, int, int>(500, 400, 100) + , boost::fusion::deque<convertible, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::deque<int>(500), 400 + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::deque<int, int>(500, 400), 100 + ) + , boost::fusion::deque<convertible, int>(500, 400) + ) + )); + + BOOST_TEST((run< Scenario< FUSION_SEQUENCE<> > >(boost::fusion::list<>()))); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<> > >( + boost::fusion::list<int>(100), boost::fusion::list<>() + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::list<int>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::list<int, int>(500, 100) + , boost::fusion::list<convertible>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::list<int, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::list<int, int, int>(500, 400, 100) + , boost::fusion::list<convertible, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::list<int>(500), 400 + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::list<int, int>(500, 400), 100 + ) + , boost::fusion::list<convertible, int>(500, 400) + ) + )); + + BOOST_TEST((run<Scenario< FUSION_SEQUENCE<> > >(boost::fusion::tuple<>()))); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<> > >( + boost::fusion::tuple<int>(100), boost::fusion::tuple<>() + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::tuple<int>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::fusion::tuple<int, int>(500, 100) + , boost::fusion::tuple<convertible>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::tuple<int, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::tuple<int, int, int>(500, 400, 100) + , boost::fusion::tuple<convertible, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::tuple<int>(500), 400 + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::fusion::tuple<int, int>(500, 400), 100 + ) + , boost::fusion::tuple<convertible, int>(500, 400) + ) + )); + + BOOST_TEST((run< Scenario< FUSION_SEQUENCE<> > >(boost::tuple<>()))); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<> > >( + boost::tuple<int>(100), boost::tuple<>() + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::tuple<int>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + boost::tuple<int, int>(500, 100) + , boost::tuple<convertible>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::tuple<int, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::tuple<int, int, int>(500, 400, 100) + , boost::tuple<convertible, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back(boost::tuple<int>(500), 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + boost::tuple<int, int>(500, 400), 100 + ) + , boost::tuple<convertible, int>(500, 400) + ) + )); + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) \ + && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + BOOST_TEST((run< Scenario< FUSION_SEQUENCE<> > >(std::tuple<>()))); + BOOST_TEST(( + run<Scenario<FUSION_SEQUENCE<> > >(std::tuple<int>(100), std::tuple<>()) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + std::tuple<int>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + std::tuple<int, int>(500, 100) + , std::tuple<convertible>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + std::tuple<int, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + std::tuple<int, int, int>(500, 400, 100) + , std::tuple<convertible, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back(std::tuple<int>(500), 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + boost::fusion::push_back( + std::tuple<int, int>(500, 400), 100 + ) + , std::tuple<convertible, int>(500, 400) + ) + )); +#endif + + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + std::pair<int, int>(500, 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<> > >( + std::pair<int, int>(500, 400) + , boost::fusion::vector<>() + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + std::pair<int, int>(500, 400) + , boost::fusion::vector<convertible>(500) + ) + )); +} diff --git a/libs/fusion/test/sequence/copy.hpp b/libs/fusion/test/sequence/copy.hpp index cb9384abcc..566384cd67 100644 --- a/libs/fusion/test/sequence/copy.hpp +++ b/libs/fusion/test/sequence/copy.hpp @@ -5,6 +5,8 @@ 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 <string> + #include <boost/detail/lightweight_test.hpp> #include <boost/fusion/sequence/intrinsic/at.hpp> #include <boost/fusion/mpl.hpp> @@ -15,6 +17,8 @@ #include <boost/mpl/equal.hpp> #include <boost/static_assert.hpp> +#include "fixture.hpp" + #if !defined(FUSION_AT) #define FUSION_AT at_c #endif @@ -36,12 +40,6 @@ namespace test_detail struct DD { operator CC() const { return CC(); }; }; } -boost::fusion::FUSION_SEQUENCE<double, double, double, double> -foo(int i) -{ - return boost::fusion::FUSION_MAKE(i, i+1, i+2, i+3); -} - void test_mpl() { using namespace boost::fusion; @@ -60,6 +58,7 @@ void test_mpl() BOOST_STATIC_ASSERT(equal::value); } +template <template <typename> class Scenario> void test() { @@ -77,6 +76,9 @@ test() BOOST_TEST((double)FUSION_AT<0>(t1) == FUSION_AT<0>(t3)); BOOST_TEST(FUSION_AT<1>(t1) == FUSION_AT<1>(t3)[0]); + BOOST_TEST(FUSION_AT<0>(t1) == 4); + BOOST_TEST(FUSION_AT<1>(t1) == 'a'); + // testing copy and assignment with implicit conversions // between elements testing tie @@ -91,8 +93,62 @@ test() BOOST_TEST(c=='a'); BOOST_TEST(d>5.4 && d<5.6); - // returning a tuple with conversion - foo(2); - test_mpl(); + + + BOOST_TEST((run< Scenario< FUSION_SEQUENCE<> > >(FUSION_SEQUENCE<>()))); + + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int> > >(FUSION_SEQUENCE<int>(500)) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + FUSION_SEQUENCE<int>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int> > >( + FUSION_SEQUENCE<int, int>(500, 100) + , FUSION_SEQUENCE<int>(500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible> > >( + FUSION_SEQUENCE<int, int>(500, 100) + , FUSION_SEQUENCE<convertible>(500) + ) + )); + + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int, int> > >( + FUSION_SEQUENCE<int, int>(500, 600) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, int> > >( + FUSION_SEQUENCE<convertible, int>(100, 500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int, convertible> > >( + FUSION_SEQUENCE<int, convertible>(500, 600) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, convertible> > >( + FUSION_SEQUENCE<int, int>(400, 500) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int, int> > >( + FUSION_SEQUENCE<int, int, int>(500, 100, 323) + , FUSION_SEQUENCE<int, int>(500, 100) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<convertible, convertible> > >( + FUSION_SEQUENCE<int, int, int>(500, 600, 100) + , FUSION_SEQUENCE<convertible, convertible>(500, 600) + ) + )); } diff --git a/libs/fusion/test/sequence/define_assoc_struct.cpp b/libs/fusion/test/sequence/define_assoc_struct.cpp index c8caac1cf8..90608c4038 100644 --- a/libs/fusion/test/sequence/define_assoc_struct.cpp +++ b/libs/fusion/test/sequence/define_assoc_struct.cpp @@ -29,6 +29,8 @@ BOOST_FUSION_DEFINE_ASSOC_STRUCT( (int, y, ns::y_member) ) +BOOST_FUSION_DEFINE_ASSOC_STRUCT(BOOST_PP_EMPTY(), empty_struct, ) + int main() { diff --git a/libs/fusion/test/sequence/define_assoc_struct_empty.cpp b/libs/fusion/test/sequence/define_assoc_struct_empty.cpp new file mode 100644 index 0000000000..204eda8e1d --- /dev/null +++ b/libs/fusion/test/sequence/define_assoc_struct_empty.cpp @@ -0,0 +1,77 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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.hpp> +#include <boost/fusion/sequence.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/adapted/struct/define_assoc_struct.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/static_assert.hpp> +#include <iostream> + +BOOST_FUSION_DEFINE_ASSOC_STRUCT(BOOST_PP_EMPTY(), empty_struct, ) + +int +main() +{ + using namespace boost; + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct>)); + empty_struct e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct>::value == 0); + BOOST_STATIC_ASSERT(fusion::result_of::empty<empty_struct>::value); + } + + { + vector<> v; + empty_struct e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct e; + + // conversion from empty_struct to vector + vector<> v(e); + v = e; + + // conversion from empty_struct to list + //list<> l(e); + //l = e; + } + + { // begin/end + typedef fusion::result_of::begin<empty_struct>::type b; + typedef fusion::result_of::end<empty_struct>::type e; + + BOOST_MPL_ASSERT((fusion::result_of::equal_to<b, e>)); + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct, int>)); + + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/define_assoc_struct_move.cpp b/libs/fusion/test/sequence/define_assoc_struct_move.cpp new file mode 100644 index 0000000000..97c3d7ee2c --- /dev/null +++ b/libs/fusion/test/sequence/define_assoc_struct_move.cpp @@ -0,0 +1,78 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/config.hpp> +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/adapted/struct/define_assoc_struct.hpp> +#include <utility> + +struct key_type; +struct wrapper +{ + int value; + + wrapper() : value(42) {} + wrapper(wrapper&& other) : value(other.value) { other.value = 0; } + wrapper(wrapper const& other) : value(other.value) {} + + wrapper& operator=(wrapper&& other) { value = other.value; other.value = 0; return *this; } + wrapper& operator=(wrapper const& other) { value = other.value; return *this; } +}; +BOOST_FUSION_DEFINE_ASSOC_STRUCT((ns), value, (wrapper, w, key_type)) + +int main() +{ + using namespace boost::fusion; + + { + ns::value x; + ns::value y(x); // copy + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 43); + + y = x; // copy assign + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + } + + { + ns::value x; + ns::value y(std::move(x)); // move + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 43); + + y = std::move(x); // move assign + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 0); + } + + return boost::report_errors(); +} + +#else + +int main() +{ +} + +#endif diff --git a/libs/fusion/test/sequence/define_assoc_tpl_struct.cpp b/libs/fusion/test/sequence/define_assoc_tpl_struct.cpp index f7986395f2..00b3b1cee6 100644 --- a/libs/fusion/test/sequence/define_assoc_tpl_struct.cpp +++ b/libs/fusion/test/sequence/define_assoc_tpl_struct.cpp @@ -31,6 +31,8 @@ BOOST_FUSION_DEFINE_ASSOC_TPL_STRUCT( (int, y, ns::y_member) ) +BOOST_FUSION_DEFINE_ASSOC_TPL_STRUCT((M), BOOST_PP_EMPTY(), empty_struct, ) + int main() { diff --git a/libs/fusion/test/sequence/define_assoc_tpl_struct_empty.cpp b/libs/fusion/test/sequence/define_assoc_tpl_struct_empty.cpp new file mode 100644 index 0000000000..fc4ebd7fe7 --- /dev/null +++ b/libs/fusion/test/sequence/define_assoc_tpl_struct_empty.cpp @@ -0,0 +1,77 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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.hpp> +#include <boost/fusion/sequence.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/adapted/struct/define_assoc_struct.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/static_assert.hpp> +#include <iostream> + +BOOST_FUSION_DEFINE_ASSOC_TPL_STRUCT((M), BOOST_PP_EMPTY(), empty_struct, ) + +int +main() +{ + using namespace boost; + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct<void> >)); + empty_struct<void> e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct<void> >::value == 0); + BOOST_STATIC_ASSERT(fusion::result_of::empty<empty_struct<void> >::value); + } + + { + vector<> v; + empty_struct<void> e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct<void> e; + + // conversion from empty_struct to vector + vector<> v(e); + v = e; + + // conversion from empty_struct to list + //list<> l(e); + //l = e; + } + + { // begin/end + typedef fusion::result_of::begin<empty_struct<void> >::type b; + typedef fusion::result_of::end<empty_struct<void> >::type e; + + BOOST_MPL_ASSERT((fusion::result_of::equal_to<b, e>)); + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct<void> >)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct<void>, void>)); + BOOST_MPL_ASSERT_NOT((fusion::result_of::has_key<empty_struct<void>, int>)); + + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/define_assoc_tpl_struct_move.cpp b/libs/fusion/test/sequence/define_assoc_tpl_struct_move.cpp new file mode 100644 index 0000000000..dcffa5663c --- /dev/null +++ b/libs/fusion/test/sequence/define_assoc_tpl_struct_move.cpp @@ -0,0 +1,78 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/config.hpp> +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/adapted/struct/define_assoc_struct.hpp> +#include <utility> + +struct key_type; +struct wrapper +{ + int value; + + wrapper() : value(42) {} + wrapper(wrapper&& other) : value(other.value) { other.value = 0; } + wrapper(wrapper const& other) : value(other.value) {} + + wrapper& operator=(wrapper&& other) { value = other.value; other.value = 0; return *this; } + wrapper& operator=(wrapper const& other) { value = other.value; return *this; } +}; +BOOST_FUSION_DEFINE_ASSOC_TPL_STRUCT((W), (ns), value, (W, w, key_type)) + +int main() +{ + using namespace boost::fusion; + + { + ns::value<wrapper> x; + ns::value<wrapper> y(x); // copy + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 43); + + y = x; // copy assign + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + } + + { + ns::value<wrapper> x; + ns::value<wrapper> y(std::move(x)); // move + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 43); + + y = std::move(x); // move assign + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 0); + } + + return boost::report_errors(); +} + +#else + +int main() +{ +} + +#endif diff --git a/libs/fusion/test/sequence/define_struct.cpp b/libs/fusion/test/sequence/define_struct.cpp index f4862548a0..51a4056477 100644 --- a/libs/fusion/test/sequence/define_struct.cpp +++ b/libs/fusion/test/sequence/define_struct.cpp @@ -33,6 +33,8 @@ BOOST_FUSION_DEFINE_STRUCT( BOOST_FUSION_DEFINE_STRUCT(BOOST_PP_EMPTY(), s, (int, m)) +BOOST_FUSION_DEFINE_STRUCT(BOOST_PP_EMPTY(), empty_struct, ) + // Testing non-constexpr compatible types BOOST_FUSION_DEFINE_STRUCT( (ns), diff --git a/libs/fusion/test/sequence/define_struct_empty.cpp b/libs/fusion/test/sequence/define_struct_empty.cpp new file mode 100644 index 0000000000..893ed43681 --- /dev/null +++ b/libs/fusion/test/sequence/define_struct_empty.cpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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.hpp> +#include <boost/fusion/sequence.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/adapted/struct/define_struct.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/static_assert.hpp> +#include <iostream> + +BOOST_FUSION_DEFINE_STRUCT(BOOST_PP_EMPTY(), empty_struct, ) + +int +main() +{ + using namespace boost; + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct>)); + empty_struct e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct>::value == 0); + BOOST_STATIC_ASSERT(fusion::result_of::empty<empty_struct>::value); + } + + { + vector<> v; + empty_struct e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct e; + + // conversion from empty_struct to vector + vector<> v(e); + v = e; + + // conversion from empty_struct to list + //list<> l(e); + //l = e; + } + + { // begin/end + typedef fusion::result_of::begin<empty_struct>::type b; + typedef fusion::result_of::end<empty_struct>::type e; + + BOOST_MPL_ASSERT((fusion::result_of::equal_to<b, e>)); + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct>)); + + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/define_struct_inline_empty.cpp b/libs/fusion/test/sequence/define_struct_inline_empty.cpp new file mode 100644 index 0000000000..4524da1ba4 --- /dev/null +++ b/libs/fusion/test/sequence/define_struct_inline_empty.cpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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.hpp> +#include <boost/fusion/sequence.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/adapted/struct/define_struct_inline.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/static_assert.hpp> +#include <iostream> + +BOOST_FUSION_DEFINE_STRUCT_INLINE(empty_struct, ) + +int +main() +{ + using namespace boost; + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct>)); + empty_struct e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct>::value == 0); + BOOST_STATIC_ASSERT(fusion::result_of::empty<empty_struct>::value); + } + + { + vector<> v; + empty_struct e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct e; + + // conversion from empty_struct to vector + vector<> v(e); + v = e; + + // conversion from empty_struct to list + //list<> l(e); + //l = e; + } + + { // begin/end + typedef fusion::result_of::begin<empty_struct>::type b; + typedef fusion::result_of::end<empty_struct>::type e; + + BOOST_MPL_ASSERT((fusion::result_of::equal_to<b, e>)); + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct>)); + + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/define_struct_inline_move.cpp b/libs/fusion/test/sequence/define_struct_inline_move.cpp new file mode 100644 index 0000000000..13d3793192 --- /dev/null +++ b/libs/fusion/test/sequence/define_struct_inline_move.cpp @@ -0,0 +1,81 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/config.hpp> +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/adapted/struct/define_struct_inline.hpp> +#include <utility> + +struct wrapper +{ + int value; + + wrapper() : value(42) {} + wrapper(wrapper&& other) : value(other.value) { other.value = 0; } + wrapper(wrapper const& other) : value(other.value) {} + + wrapper& operator=(wrapper&& other) { value = other.value; other.value = 0; return *this; } + wrapper& operator=(wrapper const& other) { value = other.value; return *this; } +}; + +namespace ns +{ + BOOST_FUSION_DEFINE_STRUCT_INLINE(value, (wrapper, w)) +} + +int main() +{ + using namespace boost::fusion; + + { + ns::value x; + ns::value y(x); // copy + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 43); + + y = x; // copy assign + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + } + + { + ns::value x; + ns::value y(std::move(x)); // move + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 43); + + y = std::move(x); // move assign + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 0); + } + + return boost::report_errors(); +} + +#else + +int main() +{ +} + +#endif diff --git a/libs/fusion/test/sequence/define_struct_move.cpp b/libs/fusion/test/sequence/define_struct_move.cpp new file mode 100644 index 0000000000..9f9036bb51 --- /dev/null +++ b/libs/fusion/test/sequence/define_struct_move.cpp @@ -0,0 +1,77 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/config.hpp> +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/adapted/struct/define_struct.hpp> +#include <utility> + +struct wrapper +{ + int value; + + wrapper() : value(42) {} + wrapper(wrapper&& other) : value(other.value) { other.value = 0; } + wrapper(wrapper const& other) : value(other.value) {} + + wrapper& operator=(wrapper&& other) { value = other.value; other.value = 0; return *this; } + wrapper& operator=(wrapper const& other) { value = other.value; return *this; } +}; +BOOST_FUSION_DEFINE_STRUCT((ns), value, (wrapper, w)) + +int main() +{ + using namespace boost::fusion; + + { + ns::value x; + ns::value y(x); // copy + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 43); + + y = x; // copy assign + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + } + + { + ns::value x; + ns::value y(std::move(x)); // move + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 43); + + y = std::move(x); // move assign + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 0); + } + + return boost::report_errors(); +} + +#else + +int main() +{ +} + +#endif diff --git a/libs/fusion/test/sequence/define_tpl_struct.cpp b/libs/fusion/test/sequence/define_tpl_struct.cpp index 586e21cf38..bb5bf96ee1 100644 --- a/libs/fusion/test/sequence/define_tpl_struct.cpp +++ b/libs/fusion/test/sequence/define_tpl_struct.cpp @@ -27,6 +27,8 @@ BOOST_FUSION_DEFINE_TPL_STRUCT( BOOST_FUSION_DEFINE_TPL_STRUCT((M), BOOST_PP_EMPTY(), s, (M, m)) +BOOST_FUSION_DEFINE_TPL_STRUCT((M), BOOST_PP_EMPTY(), empty_struct, ) + int main() { diff --git a/libs/fusion/test/sequence/define_tpl_struct_empty.cpp b/libs/fusion/test/sequence/define_tpl_struct_empty.cpp new file mode 100644 index 0000000000..d8cf47dec9 --- /dev/null +++ b/libs/fusion/test/sequence/define_tpl_struct_empty.cpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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.hpp> +#include <boost/fusion/sequence.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/adapted/struct/define_struct.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/static_assert.hpp> +#include <iostream> + +BOOST_FUSION_DEFINE_TPL_STRUCT((M), BOOST_PP_EMPTY(), empty_struct, ) + +int +main() +{ + using namespace boost; + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct<void> >)); + empty_struct<void> e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct<void> >::value == 0); + BOOST_STATIC_ASSERT(fusion::result_of::empty<empty_struct<void> >::value); + } + + { + vector<> v; + empty_struct<void> e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct<void> e; + + // conversion from empty_struct to vector + vector<> v(e); + v = e; + + // conversion from empty_struct to list + //list<> l(e); + //l = e; + } + + { // begin/end + typedef fusion::result_of::begin<empty_struct<void> >::type b; + typedef fusion::result_of::end<empty_struct<void> >::type e; + + BOOST_MPL_ASSERT((fusion::result_of::equal_to<b, e>)); + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct<void> >)); + + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/define_tpl_struct_inline_empty.cpp b/libs/fusion/test/sequence/define_tpl_struct_inline_empty.cpp new file mode 100644 index 0000000000..5cc0163fe3 --- /dev/null +++ b/libs/fusion/test/sequence/define_tpl_struct_inline_empty.cpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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.hpp> +#include <boost/fusion/sequence.hpp> +#include <boost/fusion/sequence/io/out.hpp> +#include <boost/fusion/iterator/equal_to.hpp> +#include <boost/fusion/adapted/struct/define_struct_inline.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/static_assert.hpp> +#include <iostream> + +BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE((M), empty_struct, ) + +int +main() +{ + using namespace boost; + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view<empty_struct<void> >)); + empty_struct<void> e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size<empty_struct<void> >::value == 0); + BOOST_STATIC_ASSERT(fusion::result_of::empty<empty_struct<void> >::value); + } + + { + vector<> v; + empty_struct<void> e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct<void> e; + + // conversion from empty_struct to vector + vector<> v(e); + v = e; + + // conversion from empty_struct to list + //list<> l(e); + //l = e; + } + + { // begin/end + typedef fusion::result_of::begin<empty_struct<void> >::type b; + typedef fusion::result_of::end<empty_struct<void> >::type e; + + BOOST_MPL_ASSERT((fusion::result_of::equal_to<b, e>)); + } + + BOOST_MPL_ASSERT((mpl::is_sequence<empty_struct<void> >)); + + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/define_tpl_struct_inline_move.cpp b/libs/fusion/test/sequence/define_tpl_struct_inline_move.cpp new file mode 100644 index 0000000000..9917fea2bd --- /dev/null +++ b/libs/fusion/test/sequence/define_tpl_struct_inline_move.cpp @@ -0,0 +1,81 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/config.hpp> +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/adapted/struct/define_struct_inline.hpp> +#include <utility> + +struct wrapper +{ + int value; + + wrapper() : value(42) {} + wrapper(wrapper&& other) : value(other.value) { other.value = 0; } + wrapper(wrapper const& other) : value(other.value) {} + + wrapper& operator=(wrapper&& other) { value = other.value; other.value = 0; return *this; } + wrapper& operator=(wrapper const& other) { value = other.value; return *this; } +}; + +namespace ns +{ + BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE((W), value, (W, w)) +} + +int main() +{ + using namespace boost::fusion; + + { + ns::value<wrapper> x; + ns::value<wrapper> y(x); // copy + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 43); + + y = x; // copy assign + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + } + + { + ns::value<wrapper> x; + ns::value<wrapper> y(std::move(x)); // move + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 43); + + y = std::move(x); // move assign + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 0); + } + + return boost::report_errors(); +} + +#else + +int main() +{ +} + +#endif diff --git a/libs/fusion/test/sequence/define_tpl_struct_move.cpp b/libs/fusion/test/sequence/define_tpl_struct_move.cpp new file mode 100644 index 0000000000..127e5ce0fa --- /dev/null +++ b/libs/fusion/test/sequence/define_tpl_struct_move.cpp @@ -0,0 +1,77 @@ +/*============================================================================= + Copyright (c) 2016 Kohei Takahashi + + 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/config.hpp> +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/adapted/struct/define_struct.hpp> +#include <utility> + +struct wrapper +{ + int value; + + wrapper() : value(42) {} + wrapper(wrapper&& other) : value(other.value) { other.value = 0; } + wrapper(wrapper const& other) : value(other.value) {} + + wrapper& operator=(wrapper&& other) { value = other.value; other.value = 0; return *this; } + wrapper& operator=(wrapper const& other) { value = other.value; return *this; } +}; +BOOST_FUSION_DEFINE_TPL_STRUCT((W), (ns), value, (W, w)) + +int main() +{ + using namespace boost::fusion; + + { + ns::value<wrapper> x; + ns::value<wrapper> y(x); // copy + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 43); + + y = x; // copy assign + + BOOST_TEST(x.w.value == 42); + BOOST_TEST(y.w.value == 42); + } + + { + ns::value<wrapper> x; + ns::value<wrapper> y(std::move(x)); // move + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 42); + + ++y.w.value; + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 43); + + y = std::move(x); // move assign + + BOOST_TEST(x.w.value == 0); + BOOST_TEST(y.w.value == 0); + } + + return boost::report_errors(); +} + +#else + +int main() +{ +} + +#endif diff --git a/libs/fusion/test/sequence/deque_copy.cpp b/libs/fusion/test/sequence/deque_copy.cpp index e9f2b91fd8..5c48d5ecc6 100644 --- a/libs/fusion/test/sequence/deque_copy.cpp +++ b/libs/fusion/test/sequence/deque_copy.cpp @@ -13,10 +13,30 @@ #define FUSION_SEQUENCE deque #include "copy.hpp" +using namespace test_detail; + +// c++11 deque has bug, cannot properly copy-assign from a const value +template <typename T> +struct skip_const_lvalue_assignment +{ + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return + run< can_implicit_construct<T> >(source, expected) && + run< can_construct<T> >(source, expected) && + run< can_rvalue_assign<T> >(source, expected) && + run< can_lvalue_assign<T> >(source, expected); + } +}; + int main() { - test(); +#if defined(BOOST_FUSION_HAS_VARIADIC_DEQUE) + test<skip_const_lvalue_assignment>(); +#else + test<can_copy>(); +#endif return boost::report_errors(); } - diff --git a/libs/fusion/test/sequence/deque_nest.cpp b/libs/fusion/test/sequence/deque_nest.cpp index 6f70ee9ad0..fd69d151f6 100644 --- a/libs/fusion/test/sequence/deque_nest.cpp +++ b/libs/fusion/test/sequence/deque_nest.cpp @@ -7,13 +7,37 @@ #include <boost/fusion/container/deque/deque.hpp> #include <boost/core/lightweight_test.hpp> -#define FUSION_SEQUENCE deque +#define FUSION_SEQUENCE boost::fusion::deque #include "nest.hpp" +/* deque has a few issues: + - sequence conversion constructor is explicit + - assignment sequence conversion has bug in base class + - c++11 direct assignment from lvalue has bug */ +template <typename T> +struct skip_issues +{ + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + using namespace test_detail; + return +#if defined(BOOST_FUSION_HAS_VARIADIC_DEQUE) + run< can_construct<T> >(source, expected) && + run< can_implicit_construct<T> >(source, expected) && + run< can_rvalue_assign<T> >(source, expected) && + run< can_convert_using<can_construct>::to<T> >(source, expected) && +#else + run< can_copy<T> >(source, expected) && +#endif + run< can_construct_from_elements<T> >(source, expected); + } +}; + int main() { - test(); + test<skip_issues>(); return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/fixture.hpp b/libs/fusion/test/sequence/fixture.hpp new file mode 100644 index 0000000000..4cb05971ed --- /dev/null +++ b/libs/fusion/test/sequence/fixture.hpp @@ -0,0 +1,216 @@ +/*============================================================================= + Copyright (c) 2016 Lee Clagett + + 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/fusion/sequence/comparison.hpp> +#include <boost/mpl/identity.hpp> + +namespace test_detail +{ + struct convertible + { + convertible() : value_() {} + convertible(int value) : value_(value) {} + int value_; + }; + + bool operator==(convertible const& lhs, convertible const& rhs) + { + return lhs.value_ == rhs.value_; + } + + bool operator!=(convertible const& lhs, convertible const& rhs) + { + return lhs.value_ != rhs.value_; + } + + // Testing conversion at function call allows for testing mutable lvalue, + // const lvalue, and rvalue as the source. mpl::identity prevents deduction + template <typename T> + T implicit_construct(typename boost::mpl::identity<T>::type source) + { + return source; + } + + template <typename F, typename Source, typename Expected> + bool run(Source const& source, Expected const& expected) + { + return F()(source, expected); + } + + template <typename F, typename Source> + bool run(Source const& source) + { + return run<F>(source, source); + } + + template <typename T> + struct can_rvalue_implicit_construct + { + template<typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return expected == implicit_construct<T>(implicit_construct<Source>(source)); + } + }; + + template <typename T> + struct can_lvalue_implicit_construct + { + template <typename Source, typename Expected> + bool operator()(Source source, Expected const& expected) const + { + return expected == implicit_construct<T>(source); + } + }; + + template <typename T> + struct can_const_lvalue_implicit_construct + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return expected == implicit_construct<T>(source); + } + }; + + template <typename T> + struct can_implicit_construct + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return + run< can_rvalue_implicit_construct<T> >(source, expected) && + run< can_lvalue_implicit_construct<T> >(source, expected) && + run< can_const_lvalue_implicit_construct<T> >(source, expected); + } + }; + + template <typename T> + struct can_rvalue_construct + { + template<typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return expected == T(implicit_construct<Source>(source)); + } + }; + + template <typename T> + struct can_lvalue_construct + { + template <typename Source, typename Expected> + bool operator()(Source source, Expected const& expected) const + { + return expected == T(source); + } + }; + + template <typename T> + struct can_const_lvalue_construct + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return expected == T(source); + } + }; + + template <typename T> + struct can_construct + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return + run< can_rvalue_construct<T> >(source, expected) && + run< can_lvalue_construct<T> >(source, expected) && + run< can_const_lvalue_construct<T> >(source, expected); + } + }; + + template <typename T> + struct can_rvalue_assign + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + bool result = true; + { + T seq; + result &= (seq == expected || seq != expected); + + seq = implicit_construct<Source>(source); + result &= (seq == expected); + } + return result; + } + }; + + template <typename T> + struct can_lvalue_assign + { + + template <typename Source, typename Expected> + bool operator()(Source source, Expected const& expected) const + { + bool result = true; + { + T seq; + result &= (seq == expected || seq != expected); + + seq = source; + result &= (seq == expected); + } + return result; + } + }; + + template <typename T> + struct can_const_lvalue_assign + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + bool result = true; + { + T seq; + result &= (seq == expected || seq != expected); + + seq = source; + result &= (seq == expected); + } + return result; + } + }; + + template <typename T> + struct can_assign + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return + run< can_rvalue_assign<T> >(source, expected) && + run< can_lvalue_assign<T> >(source, expected) && + run< can_const_lvalue_assign<T> >(source, expected); + } + }; + + template <typename T> + struct can_copy + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + return + run< can_construct<T> >(source, expected) && + run< can_implicit_construct<T> >(source, expected) && + run< can_assign<T> >(source, expected); + } + }; +} // test_detail diff --git a/libs/fusion/test/sequence/list_copy.cpp b/libs/fusion/test/sequence/list_copy.cpp index adb5881411..797089e9cb 100644 --- a/libs/fusion/test/sequence/list_copy.cpp +++ b/libs/fusion/test/sequence/list_copy.cpp @@ -15,7 +15,7 @@ int main() { - test(); + test<test_detail::can_copy>(); return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/list_nest.cpp b/libs/fusion/test/sequence/list_nest.cpp index ff97b80737..82df4864f9 100644 --- a/libs/fusion/test/sequence/list_nest.cpp +++ b/libs/fusion/test/sequence/list_nest.cpp @@ -7,13 +7,30 @@ #include <boost/fusion/container/list/list.hpp> #include <boost/core/lightweight_test.hpp> -#define FUSION_SEQUENCE list +#define FUSION_SEQUENCE boost::fusion::list #include "nest.hpp" +/* list has a few issues: + - sequence conversion constructor has bug when first element is a sequence + - assignment sequence conversion has bug in base class */ +template <typename T> +struct skip_issues +{ + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + using namespace test_detail; + return + run< can_copy<T> >(source, expected) && + run< can_construct_from_elements<T> >(source, expected); + } +}; + + int main() { - test(); + test<skip_issues>(); return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/nest.hpp b/libs/fusion/test/sequence/nest.hpp index e8087320ff..9743b1d400 100644 --- a/libs/fusion/test/sequence/nest.hpp +++ b/libs/fusion/test/sequence/nest.hpp @@ -7,52 +7,315 @@ #include <utility> #include <boost/config.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/fusion/include/as_deque.hpp> +#include <boost/fusion/include/as_list.hpp> +#include <boost/fusion/include/as_vector.hpp> +#include <boost/fusion/include/begin.hpp> +#include <boost/fusion/include/is_sequence.hpp> +#include <boost/fusion/include/size.hpp> +#include <boost/fusion/include/value_of.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/type_traits/remove_reference.hpp> -template <typename C> -void test_copy() -{ - C src; - C dst = src; - (void)dst; -} +#include "fixture.hpp" -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -template <typename C> -void test_move() +namespace test_detail { - C src; - C dst = std::move(src); - (void)dst; -} -#endif + struct adapted_sequence + { + adapted_sequence() : value_() {} + explicit adapted_sequence(int value) : value_(value) {} + int value_; + }; -template <typename C> -void test_all() -{ - test_copy<C>(); -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - test_move<C>(); -#endif -} + bool operator==(adapted_sequence const& lhs, adapted_sequence const& rhs) + { + return lhs.value_ == rhs.value_; + } + + bool operator!=(adapted_sequence const& lhs, adapted_sequence const& rhs) + { + return lhs.value_ != rhs.value_; + } + + template <template <typename> class Scenario> + struct can_convert_using + { + template <typename T> + struct to + { + static bool can_convert_(boost::true_type /* skip */) + { + return true; + } + + static bool can_convert_(boost::false_type /* skip */) + { + using namespace boost::fusion; + return + run<Scenario<T> >(typename result_of::as_deque<T>::type()) && + run<Scenario<T> >(typename result_of::as_list<T>::type()) && + run<Scenario<T> >(typename result_of::as_vector<T>::type()); + } + + template <typename Source, typename Expected> + bool operator()(Source const&, Expected const&) const + { + // bug when converting single element sequences in C++03 and + // C++11... + // not_<not_<is_convertible<sequence<sequence<int>>, int > + // is invalid check + typedef typename ::boost::fusion::result_of::size<T>::type seq_size; + return can_convert_( + boost::integral_constant<bool, seq_size::value == 1>() + ); + } + }; + }; + + template <typename T> + struct can_construct_from_elements + { + template <typename Source, typename Expected> + bool operator()(Source const&, Expected const&) const + { + // constructing a nested sequence of one is the complicated case to + // disambiguate from a conversion-copy, so focus on that + typedef typename boost::fusion::result_of::size<T>::type seq_size; + return can_construct_( + boost::integral_constant<int, seq_size::value>() + ); + } + + template <int Size> + static bool can_construct_(boost::integral_constant<int, Size>) + { + return Size == 0 || Size == 2 || Size == 3; + } + + static bool can_construct_(boost::integral_constant<int, 1>) + { + typedef typename ::boost::remove_reference< + typename ::boost::remove_const< + typename ::boost::fusion::result_of::value_of< + typename ::boost::fusion::result_of::begin<T>::type + >::type + >::type + >::type element; + return run< can_construct<T> >(element(), T()); + } + }; + + template <typename T> + struct can_nest + { + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) + { + return + run< can_copy<T> >(source, expected); + run< can_convert_using<can_copy>::to<T> >(source, expected) && + run< can_construct_from_elements<T> >(source, expected); + } + }; +} // test_detail + + +BOOST_FUSION_ADAPT_STRUCT(test_detail::adapted_sequence, (int, data)) + +template <template <typename> class Scenario> void test() { - using namespace boost::fusion; - - test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<> > >(); - test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<>, int> >(); - test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<> > >(); - test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<>, float> >(); - - test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int> > >(); - test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int>, int> >(); - test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int> > >(); - test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int>, float> >(); - - test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int, float> > >(); - test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int, float>, int> >(); - test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int, float> > >(); - test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int, float>, float> >(); -} + using namespace test_detail; + + BOOST_TEST(boost::fusion::traits::is_sequence<adapted_sequence>::value); + BOOST_TEST(boost::fusion::size(adapted_sequence()) == 1); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE< FUSION_SEQUENCE<> > > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<> >() + ) + )); + BOOST_TEST(( + run< Scenario<FUSION_SEQUENCE<FUSION_SEQUENCE<>, int> > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<>, int>(FUSION_SEQUENCE<>(), 325) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int, FUSION_SEQUENCE<> > > >( + FUSION_SEQUENCE< int, FUSION_SEQUENCE<> >(325, FUSION_SEQUENCE<>()) + ) + )); + BOOST_TEST(( + run< Scenario<FUSION_SEQUENCE<int, FUSION_SEQUENCE<>, float> > >( + FUSION_SEQUENCE<int, FUSION_SEQUENCE<> , float>( + 325, FUSION_SEQUENCE<>(), 2.0f + ) + ) + )); + + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE< FUSION_SEQUENCE<int> > > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<int> >(FUSION_SEQUENCE<int>(400)) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<adapted_sequence> > >( + FUSION_SEQUENCE<adapted_sequence>(adapted_sequence(400)) + ) + )); + BOOST_TEST(( + run< Scenario<FUSION_SEQUENCE<FUSION_SEQUENCE<int>, int> > >( + FUSION_SEQUENCE<FUSION_SEQUENCE<int>, int>( + FUSION_SEQUENCE<int>(325), 400 + ) + ) + )); + BOOST_TEST(( + run< Scenario<FUSION_SEQUENCE<adapted_sequence, int> > >( + FUSION_SEQUENCE<adapted_sequence, int>(adapted_sequence(325), 400) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE< int, FUSION_SEQUENCE<int> > > >( + FUSION_SEQUENCE< int, FUSION_SEQUENCE<int> >( + 325, FUSION_SEQUENCE<int>(400) + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int, adapted_sequence> > >( + FUSION_SEQUENCE<int, adapted_sequence>(325, adapted_sequence(450)) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int, FUSION_SEQUENCE<int>, int> > >( + FUSION_SEQUENCE<int, FUSION_SEQUENCE<int>, int>( + 500, FUSION_SEQUENCE<int>(350), 200 + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<int, adapted_sequence, int> > >( + FUSION_SEQUENCE<int, adapted_sequence, int>( + 300, adapted_sequence(500), 400) + ) + )); + + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE< FUSION_SEQUENCE<int, int> > > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<int, int> >( + FUSION_SEQUENCE<int, int>(450, 500) + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE<FUSION_SEQUENCE<int, int>, int> > >( + FUSION_SEQUENCE<FUSION_SEQUENCE<int, int>, int>( + FUSION_SEQUENCE<int, int>(450, 500), 150 + ) + ) + )); + BOOST_TEST(( + run< Scenario< FUSION_SEQUENCE< int, FUSION_SEQUENCE<int, int> > > >( + FUSION_SEQUENCE< int, FUSION_SEQUENCE<int, int> >( + 450, FUSION_SEQUENCE<int, int>(500, 150) + ) + ) + )); + BOOST_TEST(( + run<Scenario< FUSION_SEQUENCE<int, FUSION_SEQUENCE<int, int>, int> > >( + FUSION_SEQUENCE<int, FUSION_SEQUENCE<int, int>, int>( + 150, FUSION_SEQUENCE<int, int>(250, 350), 450 + ) + ) + )); + + BOOST_TEST(( + run<Scenario<FUSION_SEQUENCE<FUSION_SEQUENCE<>, FUSION_SEQUENCE<> > > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<>, FUSION_SEQUENCE<> >( + FUSION_SEQUENCE<>(), FUSION_SEQUENCE<>() + ) + ) + )); + BOOST_TEST(( + run<Scenario<FUSION_SEQUENCE<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<> > > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<int>, FUSION_SEQUENCE<> >( + FUSION_SEQUENCE<int>(150), FUSION_SEQUENCE<>() + ) + ) + )); + BOOST_TEST(( + run<Scenario<FUSION_SEQUENCE<FUSION_SEQUENCE<>, FUSION_SEQUENCE<int> > > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<>, FUSION_SEQUENCE<int> >( + FUSION_SEQUENCE<>(), FUSION_SEQUENCE<int>(500) + ) + ) + )); + BOOST_TEST(( + run<Scenario<FUSION_SEQUENCE<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<int> > > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<int>, FUSION_SEQUENCE<int> >( + FUSION_SEQUENCE<int>(155), FUSION_SEQUENCE<int>(255) + ) + ) + )); + BOOST_TEST(( + run< Scenario< + FUSION_SEQUENCE< FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int> > + > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int> >( + FUSION_SEQUENCE<int, int>(222, 333), FUSION_SEQUENCE<int>(444) + ) + ) + )); + BOOST_TEST(( + run< Scenario< + FUSION_SEQUENCE< FUSION_SEQUENCE<int>, FUSION_SEQUENCE<int, int> > + > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<int>, FUSION_SEQUENCE<int, int> >( + FUSION_SEQUENCE<int>(100), FUSION_SEQUENCE<int, int>(300, 400) + ) + ) + )); + BOOST_TEST(( + run< Scenario< + FUSION_SEQUENCE< FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int> > + > >( + FUSION_SEQUENCE< FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int> >( + FUSION_SEQUENCE<int, int>(600, 700) + , FUSION_SEQUENCE<int, int>(800, 900) + ) + ) + )); + + + // Ignore desired scenario, and cheat to make these work + BOOST_TEST(( + run< can_lvalue_construct< FUSION_SEQUENCE<FUSION_SEQUENCE<>&> > >( + FUSION_SEQUENCE<>() + , FUSION_SEQUENCE< FUSION_SEQUENCE<> >() + ) + )); + BOOST_TEST(( + run< can_construct< FUSION_SEQUENCE<const FUSION_SEQUENCE<>&> > >( + FUSION_SEQUENCE<>() + , FUSION_SEQUENCE< FUSION_SEQUENCE<> >() + ) + )); + BOOST_TEST(( + run< can_lvalue_construct< FUSION_SEQUENCE<FUSION_SEQUENCE<int>&> > >( + FUSION_SEQUENCE<int>(300) + , FUSION_SEQUENCE< FUSION_SEQUENCE<int> >(FUSION_SEQUENCE<int>(300)) + ) + )); + BOOST_TEST(( + run< can_construct< FUSION_SEQUENCE<const FUSION_SEQUENCE<int>&> > >( + FUSION_SEQUENCE<int>(400) + , FUSION_SEQUENCE< FUSION_SEQUENCE<int> >(FUSION_SEQUENCE<int>(400)) + ) + )); +} diff --git a/libs/fusion/test/sequence/std_array.cpp b/libs/fusion/test/sequence/std_array.cpp new file mode 100644 index 0000000000..fdf761bffc --- /dev/null +++ b/libs/fusion/test/sequence/std_array.cpp @@ -0,0 +1,49 @@ +// +// Copyright (C) 2013 Mateusz Loskot <mateusz@loskot.net> +// +// 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/config.hpp> +#ifdef BOOST_NO_CXX11_HDR_ARRAY +int main() {} +#else + +#ifdef BOOST_MSVC +#pragma warning(disable:4180) +#endif +#include <boost/detail/lightweight_test.hpp> + +#include <boost/fusion/adapted/std_array.hpp> +#include <array> + +#include <boost/fusion/sequence/intrinsic.hpp> +#include <boost/fusion/support/is_sequence.hpp> +#include <boost/fusion/support/is_view.hpp> +#include <boost/fusion/iterator.hpp> + +#include <boost/mpl/assert.hpp> + +int main() +{ + using namespace boost::fusion; + typedef std::array<int,3> array_type; + + BOOST_MPL_ASSERT((traits::is_sequence<array_type>)); + BOOST_MPL_ASSERT_NOT((traits::is_view<array_type>)); + + array_type arr = {{1,2,3}}; + + BOOST_TEST(*boost::fusion::begin(arr) == 1); + BOOST_TEST(*boost::fusion::next(boost::fusion::begin(arr)) == 2); + BOOST_TEST(*advance_c<2>(boost::fusion::begin(arr)) == 3); + BOOST_TEST(prior(boost::fusion::next(boost::fusion::begin(arr))) == boost::fusion::begin(arr)); + BOOST_TEST(*prior(boost::fusion::end(arr)) == 3); + BOOST_TEST(at_c<2>(arr) == 3); + BOOST_TEST(boost::fusion::size(arr) == 3); + BOOST_TEST(distance(boost::fusion::begin(arr), boost::fusion::end(arr)) == 3); + + return boost::report_errors(); +} +#endif diff --git a/libs/fusion/test/sequence/traits.hpp b/libs/fusion/test/sequence/traits.hpp new file mode 100644 index 0000000000..b409936e51 --- /dev/null +++ b/libs/fusion/test/sequence/traits.hpp @@ -0,0 +1,251 @@ +/*============================================================================= + Copyright (C) 2016 Lee Clagett + + 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/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/container/list.hpp> +#include <boost/fusion/container/vector.hpp> +#include <boost/type_traits/add_const.hpp> +#include <boost/type_traits/add_reference.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/type_traits/is_constructible.hpp> +#include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/type_traits/remove_reference.hpp> + +struct convertible +{ + convertible(int) {} +}; + +template <typename From, typename To> +bool is_convertible(bool has_conversion) +{ + typedef typename boost::remove_reference< + typename boost::remove_const<From>::type + >::type from_rvalue; + typedef typename boost::add_reference<from_rvalue>::type from_lvalue; + typedef typename boost::add_const<from_lvalue>::type from_const_lvalue; + + return + boost::is_convertible<from_rvalue, To>::value == has_conversion && + boost::is_convertible<from_lvalue, To>::value == has_conversion && + boost::is_convertible<from_const_lvalue, To>::value == has_conversion; +} + +// is_constructible has a few requirements +#if !defined(BOOST_NO_CXX11_DECLTYPE) && \ + !defined(BOOST_NO_CXX11_TEMPLATES) && \ + !defined(BOOST_NO_SFINAE_EXPR) + +#define FUSION_TEST_HAS_CONSTRUCTIBLE + +template <typename To, typename... Args> +bool is_lvalue_constructible(bool has_constructor) +{ + return has_constructor == + boost::is_constructible< + To + , typename boost::add_reference<Args>::type... + >::value; +} + +template <typename To, typename... Args> +bool is_constructible_impl(bool has_constructor) +{ + return + boost::is_constructible<To, Args...>::value == has_constructor && + is_lvalue_constructible<To, Args...>(has_constructor) && + is_lvalue_constructible< + To, typename boost::add_const<Args>::type... + >(has_constructor); +} + +template <typename To, typename... Args> +bool is_constructible(bool has_constructor) +{ + return + is_constructible_impl< + To + , typename boost::remove_reference< + typename boost::remove_const<Args>::type + >::type... + >(has_constructor); +} + +void test_constructible() +{ + BOOST_TEST((is_constructible< FUSION_SEQUENCE<> >(true))); + + BOOST_TEST((is_constructible< FUSION_SEQUENCE<int> >(true))); + BOOST_TEST((is_constructible<FUSION_SEQUENCE<int>, int>(true))); + + BOOST_TEST((is_constructible<FUSION_SEQUENCE<convertible>, int>(true))); + BOOST_TEST(( + is_constructible<FUSION_SEQUENCE<convertible>, convertible>(true) + )); + + BOOST_TEST(( + is_constructible<FUSION_SEQUENCE<int, int>, int, int>(true) + )); + + BOOST_TEST(( + is_constructible<FUSION_SEQUENCE<convertible, int>, int, int>(true) + )); + BOOST_TEST(( + is_constructible< + FUSION_SEQUENCE<convertible, int>, convertible, int + >(true) + )); + + BOOST_TEST(( + is_constructible<FUSION_SEQUENCE<int, convertible>, int, int>(true) + )); + BOOST_TEST(( + is_constructible< + FUSION_SEQUENCE<int, convertible>, int, convertible + >(true) + )); + + BOOST_TEST(( + is_constructible< + FUSION_SEQUENCE<convertible, convertible>, int, int + >(true) + )); + BOOST_TEST(( + is_constructible< + FUSION_SEQUENCE<convertible, convertible>, convertible, int + >(true) + )); + BOOST_TEST(( + is_constructible< + FUSION_SEQUENCE<convertible, convertible>, int, convertible + >(true) + )); + BOOST_TEST(( + is_constructible< + FUSION_SEQUENCE<convertible, convertible>, convertible, convertible + >(true) + )); +} + +#endif // is_constructible is available + +void test_convertible(bool has_seq_conversion) +{ + BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<> >(false))); + BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int> >(false))); + BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<const int&> >(false))); + BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<convertible> >(false))); + BOOST_TEST(( + is_convertible<int, FUSION_SEQUENCE<const convertible&> >(false) + )); + BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int, int> >(false))); + BOOST_TEST(( + is_convertible<int, FUSION_SEQUENCE<const int&, const int&> >(false) + )); + BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<convertible, int> >(false))); + BOOST_TEST(( + is_convertible<int, FUSION_SEQUENCE<const convertible&, const int&> >(false) + )); + BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int, convertible> >(false))); + BOOST_TEST(( + is_convertible<int, FUSION_SEQUENCE<const int&, const convertible&> >(false) + )); + BOOST_TEST(( + is_convertible<int, FUSION_SEQUENCE<convertible, convertible> >(false) + )); + BOOST_TEST(( + is_convertible< + int, FUSION_SEQUENCE<const convertible&, const convertible&> + >(false) + )); + + BOOST_TEST((is_convertible<FUSION_SEQUENCE<>, FUSION_SEQUENCE<> >(true))); + BOOST_TEST(( + is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<int> >(true) + )); + BOOST_TEST(( + is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<const int&> >(true) + )); + BOOST_TEST(( + is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<convertible> >(true) + )); + BOOST_TEST(( + is_convertible<FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int> >(true) + )); + BOOST_TEST(( + is_convertible< + FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<const int&, const int&> + >(true) + )); + BOOST_TEST(( + is_convertible< + FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<convertible, int> + >(true) + )); + BOOST_TEST(( + is_convertible< + FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, convertible> + >(true) + )); + BOOST_TEST(( + is_convertible< + FUSION_SEQUENCE<int, int> + , FUSION_SEQUENCE<convertible, convertible> + >(true) + )); + + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<>, FUSION_SEQUENCE<> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<int> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<const int&> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<convertible> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int, int> + , FUSION_SEQUENCE<const int&, const int&> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<convertible, int> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<int, convertible> + >(has_seq_conversion) + )); + BOOST_TEST(( + is_convertible< + FUSION_ALT_SEQUENCE<int, int> + , FUSION_SEQUENCE<convertible, convertible> + >(has_seq_conversion) + )); +} + diff --git a/libs/fusion/test/sequence/tuple_construction.cpp b/libs/fusion/test/sequence/tuple_construction.cpp index 044701c407..1277202795 100644 --- a/libs/fusion/test/sequence/tuple_construction.cpp +++ b/libs/fusion/test/sequence/tuple_construction.cpp @@ -13,9 +13,37 @@ #define FUSION_AT get #include "construction.hpp" +// Bug in C++03 tuple? Cannot construct from a std::pair without including +// std::pair fusion adaption +#if !defined(BOOST_FUSION_HAS_VARIADIC_TUPLE) +# include <boost/fusion/adapted/std_pair.hpp> +#endif + +struct test_conversion +{ + test_conversion(int value) : value_(value) {} + + int value_; +}; + int main() { test(); + + { + using namespace boost::fusion; + const tuple<int, test_conversion> instance(std::pair<int, int>(1, 9)); + BOOST_TEST(boost::fusion::get<0>(instance) == 1); + BOOST_TEST(boost::fusion::get<1>(instance).value_ == 9); + } + { + using namespace boost::fusion; + const std::pair<int, int> init(16, 4); + const tuple<int, test_conversion> instance(init); + BOOST_TEST(boost::fusion::get<0>(instance) == 16); + BOOST_TEST(boost::fusion::get<1>(instance).value_ == 4); + } + return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/tuple_conversion.cpp b/libs/fusion/test/sequence/tuple_conversion.cpp new file mode 100644 index 0000000000..861365de46 --- /dev/null +++ b/libs/fusion/test/sequence/tuple_conversion.cpp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 2016 Lee Clagett + + Use modification and distribution are subject to 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/tuple.hpp> + +#define FUSION_SEQUENCE boost::fusion::tuple +#include "conversion.hpp" + +// Bug in C++03 tuple? Cannot construct from a std::pair without including +// std::pair fusion adaption +#if !defined(BOOST_FUSION_HAS_VARIADIC_TUPLE) +# include <boost/fusion/adapted/std_pair.hpp> +#endif + +using namespace test_detail; + +void test_tuple() +{ + BOOST_TEST(( + run< can_copy< boost::fusion::tuple<int, int> > >( + std::pair<int, int>(1, 9) + ) + )); + BOOST_TEST(( + run< can_copy< boost::fusion::tuple<int, convertible> > >( + std::pair<int, int>(1, 9) + ) + )); + BOOST_TEST(( + run< can_copy< boost::fusion::tuple<convertible, int> > >( + std::pair<int, int>(1, 9) + ) + )); + BOOST_TEST(( + run< can_copy< boost::fusion::tuple<convertible, convertible> > >( + std::pair<int, int>(1, 9) + ) + )); +} + +int main() +{ + test<can_assign>(); // conversion construction not supported + test_tuple(); + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/tuple_copy.cpp b/libs/fusion/test/sequence/tuple_copy.cpp index c41117e7a1..0129738768 100644 --- a/libs/fusion/test/sequence/tuple_copy.cpp +++ b/libs/fusion/test/sequence/tuple_copy.cpp @@ -16,7 +16,7 @@ int main() { - test(); + test<test_detail::can_copy>(); return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/tuple_nest.cpp b/libs/fusion/test/sequence/tuple_nest.cpp index 1d263da4ff..3344c5231b 100644 --- a/libs/fusion/test/sequence/tuple_nest.cpp +++ b/libs/fusion/test/sequence/tuple_nest.cpp @@ -7,13 +7,29 @@ #include <boost/fusion/tuple/tuple.hpp> #include <boost/core/lightweight_test.hpp> -#define FUSION_SEQUENCE tuple +#define FUSION_SEQUENCE boost::fusion::tuple #include "nest.hpp" + +// tuple does not support conversion construction from sequence by design +template <typename T> +struct skip_constructor_conversion +{ + template <typename Source, typename Expected> + bool operator()(Source const& source, Expected const& expected) const + { + using namespace test_detail; + return + run< can_copy<T> >(source, expected) && + run< can_convert_using<can_assign>::to<T> >(source, expected) && + run< can_construct_from_elements<T> >(source, expected); + } +}; + int main() { - test(); + test<skip_constructor_conversion>(); return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/tuple_traits.cpp b/libs/fusion/test/sequence/tuple_traits.cpp new file mode 100644 index 0000000000..6d18c231e6 --- /dev/null +++ b/libs/fusion/test/sequence/tuple_traits.cpp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 2016 Lee Clagett + + 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.hpp> +#include <boost/fusion/tuple/tuple.hpp> +#include <boost/config.hpp> +#include <boost/type_traits/is_constructible.hpp> +#include <boost/type_traits/is_convertible.hpp> + +#define FUSION_SEQUENCE boost::fusion::tuple +#define FUSION_ALT_SEQUENCE boost::fusion::vector +#include "traits.hpp" + +struct not_convertible {}; + +/* Some construction differences in fusion::tuple from std::tuple: + - Construction from elements cannot call an explicit constructor. + - There is no implicit construction from elements. + - Construction from std::pair is _enabled_ when tuple is not of size 2. + - Construction from tuple is _enabled_ when destination tuple is of + different size. + - Implicit construction from std::pair can call explicit constructors on + elements. + - Implicit construction from tuple can call explicit constructors on + elements. + + These differences are historical. Matching the behavior of std::tuple + could break existing code, however, switching to fusion::vector would + restore the historical behavior. */ +int +main() +{ + using namespace boost::fusion; + + test_convertible(false /* no conversion construction */ ); + + BOOST_TEST((is_convertible<std::pair<int, int>, tuple<int, int> >(true))); + BOOST_TEST(( + is_convertible<std::pair<int, int>, tuple<convertible, int> >(true) + )); + BOOST_TEST(( + is_convertible<std::pair<int, int>, tuple<int, convertible> >(true) + )); + BOOST_TEST(( + is_convertible< + std::pair<int, int>, tuple<convertible, convertible> + >(true) + )); + +#if defined(FUSION_TEST_HAS_CONSTRUCTIBLE) + test_constructible(); + + BOOST_TEST((is_constructible< tuple<> >(true))); + BOOST_TEST((is_constructible<tuple<>, int>(false))); + + BOOST_TEST((is_constructible< tuple<int> >(true))); + BOOST_TEST((is_constructible<tuple<int>, int>(true))); + BOOST_TEST((is_constructible<tuple<convertible>, int>(true))); + BOOST_TEST((is_constructible<tuple<not_convertible>, int>(false))); + BOOST_TEST((is_constructible< tuple<int>, vector<int> >(false))); + BOOST_TEST((is_constructible<tuple<int>, int, int>(false))); + + BOOST_TEST((is_constructible< tuple<int, int> >(true))); + BOOST_TEST((is_constructible<tuple<int, int>, int, int>(true))); + BOOST_TEST(( + is_constructible<tuple<convertible, convertible>, int, int>(true) + )); + BOOST_TEST((is_constructible<tuple<int, not_convertible>, int, int>(false))); + BOOST_TEST((is_constructible<tuple<not_convertible, int>, int, int>(false))); + BOOST_TEST(( + is_constructible<tuple<not_convertible, not_convertible>, int, int>(false) + )); +#if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) + // C++03 fusion::tuple has constructors that can never be used + BOOST_TEST((is_constructible<tuple<int, int>, int>(false))); +#endif + BOOST_TEST((is_constructible<tuple<int, int>, int, int, int>(false))); + +#endif // FUSION_TEST_HAS_CONSTRUCTIBLE + + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/vector_conversion.cpp b/libs/fusion/test/sequence/vector_conversion.cpp new file mode 100644 index 0000000000..1ffd77cc61 --- /dev/null +++ b/libs/fusion/test/sequence/vector_conversion.cpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2016 Lee Clagett + + Use modification and distribution are subject to 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.hpp> + +#define FUSION_SEQUENCE boost::fusion::vector +#include "conversion.hpp" + +int main() +{ + test<test_detail::can_copy>(); + return boost::report_errors(); +} diff --git a/libs/fusion/test/sequence/vector_copy.cpp b/libs/fusion/test/sequence/vector_copy.cpp index d21f5c9cb6..8a4d26ce9a 100644 --- a/libs/fusion/test/sequence/vector_copy.cpp +++ b/libs/fusion/test/sequence/vector_copy.cpp @@ -15,7 +15,7 @@ int main() { - test(); + test<test_detail::can_copy>(); return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/vector_nest.cpp b/libs/fusion/test/sequence/vector_nest.cpp index a0cb76c6af..2627b3d7c7 100644 --- a/libs/fusion/test/sequence/vector_nest.cpp +++ b/libs/fusion/test/sequence/vector_nest.cpp @@ -7,13 +7,13 @@ #include <boost/fusion/container/vector/vector.hpp> #include <boost/core/lightweight_test.hpp> -#define FUSION_SEQUENCE vector +#define FUSION_SEQUENCE boost::fusion::vector #include "nest.hpp" int main() { - test(); + test<test_detail::can_nest>(); return boost::report_errors(); } diff --git a/libs/fusion/test/sequence/vector_traits.cpp b/libs/fusion/test/sequence/vector_traits.cpp new file mode 100644 index 0000000000..470f11e699 --- /dev/null +++ b/libs/fusion/test/sequence/vector_traits.cpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (C) 2016 Lee Clagett + + 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/list.hpp> +#include <boost/fusion/container/vector.hpp> + +#define FUSION_SEQUENCE boost::fusion::vector +#define FUSION_ALT_SEQUENCE boost::fusion::list +#include "traits.hpp" + +int main() { + test_convertible(true /* has conversion construction */ ); + + // C++11 models overly aggressive (bug) implicit conversion from C++03 + BOOST_TEST(( + is_convertible< + boost::fusion::list<int> + , boost::fusion::vector< boost::fusion::list<int> > + >(true) + )); + +#if defined(FUSION_TEST_HAS_CONSTRUCTIBLE) + test_constructible(); +#endif + + return boost::report_errors(); +} diff --git a/libs/fusion/test/support/and.cpp b/libs/fusion/test/support/and.cpp new file mode 100644 index 0000000000..99ecd9f4ae --- /dev/null +++ b/libs/fusion/test/support/and.cpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2016 Lee Clagett + 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/config.hpp> + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include <boost/detail/lightweight_test.hpp> +#include <boost/fusion/support/detail/and.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/integral_constant.hpp> + +int main() { + using namespace boost; + using namespace boost::fusion::detail; + + BOOST_TEST((and_<>::value)); + BOOST_TEST(!(and_<false_type>::value)); + BOOST_TEST((and_<true_type>::value)); + BOOST_TEST(!(and_<true_type, false_type>::value)); + BOOST_TEST((and_<true_type, true_type>::value)); + BOOST_TEST(!(and_<true_type, true_type, false_type>::value)); + BOOST_TEST((and_<true_type, true_type, true_type>::value)); + BOOST_TEST((and_<true_type, mpl::true_>::value)); + + return boost::report_errors(); +} + +#endif + |