mirror of
https://github.com/boostorg/fusion.git
synced 2025-07-21 08:12:39 +02:00
Make C++11 fusion::vector more consistent with C++03 fusion::vector
- Construct from elements is enabled iff each argument is_convertible to corresponding element. - Construct from sequence is enabled iff the single argument is a fusion sequence. - C++11 vector and tuple also disable construct from sequence that are shorter than the destination. C++03 gives incorrect is_convertible responses in this situation and fails to compile if that constructor is used; C++11 can have instantation errors in and_<is_convertible<U, T>...> without the additional check. - C++11 tuple and vector support truncation conversion and assignment like all other sequences.
This commit is contained in:
@ -15,6 +15,7 @@
|
|||||||
|| defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \
|
|| defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \
|
||||||
|| defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) \
|
|| defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) \
|
||||||
|| defined(BOOST_NO_CXX11_DECLTYPE)) \
|
|| defined(BOOST_NO_CXX11_DECLTYPE)) \
|
||||||
|
|| defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) \
|
||||||
|| defined(BOOST_FUSION_DISABLE_VARIADIC_VECTOR) \
|
|| defined(BOOST_FUSION_DISABLE_VARIADIC_VECTOR) \
|
||||||
|| (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
|
|| (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
|
||||||
# if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
|
# if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
|
||||||
|
@ -24,24 +24,21 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#include <boost/fusion/support/sequence_base.hpp>
|
#include <boost/fusion/support/sequence_base.hpp>
|
||||||
#include <boost/fusion/support/is_sequence.hpp>
|
#include <boost/fusion/support/is_sequence.hpp>
|
||||||
#include <boost/fusion/support/void.hpp>
|
#include <boost/fusion/support/detail/and.hpp>
|
||||||
#include <boost/fusion/support/detail/enabler.hpp>
|
|
||||||
#include <boost/fusion/support/detail/index_sequence.hpp>
|
#include <boost/fusion/support/detail/index_sequence.hpp>
|
||||||
#include <boost/fusion/container/vector/detail/at_impl.hpp>
|
#include <boost/fusion/container/vector/detail/at_impl.hpp>
|
||||||
#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
|
#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
|
||||||
#include <boost/fusion/container/vector/detail/begin_impl.hpp>
|
#include <boost/fusion/container/vector/detail/begin_impl.hpp>
|
||||||
#include <boost/fusion/container/vector/detail/end_impl.hpp>
|
#include <boost/fusion/container/vector/detail/end_impl.hpp>
|
||||||
#include <boost/fusion/sequence/intrinsic/size.hpp>
|
|
||||||
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
||||||
#include <boost/fusion/sequence/intrinsic/size.hpp>
|
#include <boost/fusion/sequence/intrinsic/size.hpp>
|
||||||
#include <boost/fusion/iterator/advance.hpp>
|
#include <boost/fusion/iterator/advance.hpp>
|
||||||
#include <boost/fusion/iterator/deref.hpp>
|
#include <boost/fusion/iterator/deref.hpp>
|
||||||
#include <boost/core/enable_if.hpp>
|
#include <boost/core/enable_if.hpp>
|
||||||
#include <boost/mpl/bool.hpp>
|
|
||||||
#include <boost/mpl/equal_to.hpp>
|
|
||||||
#include <boost/mpl/int.hpp>
|
#include <boost/mpl/int.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
#include <boost/type_traits/remove_cv.hpp>
|
#include <boost/type_traits/is_base_of.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -54,56 +51,48 @@ namespace boost { namespace fusion
|
|||||||
namespace vector_detail
|
namespace vector_detail
|
||||||
{
|
{
|
||||||
struct each_elem {};
|
struct each_elem {};
|
||||||
struct copy_or_move {};
|
|
||||||
template <typename I> struct from_sequence {};
|
|
||||||
|
|
||||||
template <typename Sequence>
|
template <
|
||||||
struct make_indices_from_seq
|
typename This, typename T, typename T_, std::size_t Size, bool IsSeq
|
||||||
: detail::make_index_sequence<
|
>
|
||||||
fusion::result_of::size<typename remove_reference<Sequence>::type>::value
|
struct can_convert_impl : false_type {};
|
||||||
|
|
||||||
|
template <typename This, typename T, typename Sequence, std::size_t Size>
|
||||||
|
struct can_convert_impl<This, T, Sequence, Size, true> : true_type {};
|
||||||
|
|
||||||
|
template <typename This, typename Sequence, typename T>
|
||||||
|
struct can_convert_impl<This, Sequence, T, 1, true>
|
||||||
|
: integral_constant<
|
||||||
|
bool
|
||||||
|
, !is_convertible<
|
||||||
|
Sequence
|
||||||
|
, typename fusion::extension::value_at_impl<vector_tag>::
|
||||||
|
template apply< This, mpl::int_<0> >::type
|
||||||
|
>::value
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template <typename T>
|
template <typename This, typename T, typename T_, std::size_t Size>
|
||||||
struct pure : remove_cv<typename remove_reference<T>::type> {};
|
struct can_convert
|
||||||
|
: can_convert_impl<
|
||||||
template<typename Sequence, typename This, typename Enable = void>
|
This, T, T_, Size, traits::is_sequence<T_>::value
|
||||||
struct can_convert : mpl::false_ {};
|
|
||||||
|
|
||||||
template<typename Sequence, typename This>
|
|
||||||
struct can_convert<
|
|
||||||
Sequence
|
|
||||||
, This
|
|
||||||
, typename enable_if<traits::is_sequence<Sequence>>::type
|
|
||||||
> : mpl::equal_to<
|
|
||||||
fusion::result_of::size<Sequence>
|
|
||||||
, fusion::result_of::size<This>
|
|
||||||
>
|
>
|
||||||
{
|
{};
|
||||||
};
|
|
||||||
|
|
||||||
template <typename This, typename ...T>
|
template <typename T, bool IsSeq, std::size_t Size>
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
struct is_longer_sequence_impl : false_type {};
|
||||||
inline each_elem
|
|
||||||
dispatch(T const&...) BOOST_NOEXCEPT { return each_elem(); }
|
|
||||||
|
|
||||||
template <typename This>
|
template <typename Sequence, std::size_t Size>
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
struct is_longer_sequence_impl<Sequence, true, Size>
|
||||||
inline copy_or_move
|
: integral_constant<
|
||||||
dispatch(This const&) BOOST_NOEXCEPT { return copy_or_move(); }
|
bool, (fusion::result_of::size<Sequence>::value >= Size)
|
||||||
|
>
|
||||||
template <typename This, typename Sequence>
|
{};
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
|
||||||
inline from_sequence<
|
|
||||||
typename lazy_enable_if_c<
|
|
||||||
(!is_same<This, typename pure<Sequence>::type>::value &&
|
|
||||||
can_convert<typename pure<Sequence>::type, This>::value)
|
|
||||||
, make_indices_from_seq<Sequence>
|
|
||||||
>::type
|
|
||||||
>
|
|
||||||
dispatch(Sequence&&) BOOST_NOEXCEPT
|
|
||||||
{ return from_sequence<typename make_indices_from_seq<Sequence>::type>(); }
|
|
||||||
|
|
||||||
|
template<typename T, std::size_t Size>
|
||||||
|
struct is_longer_sequence
|
||||||
|
: is_longer_sequence_impl<T, traits::is_sequence<T>::value, Size>
|
||||||
|
{};
|
||||||
|
|
||||||
// forward_at_c allows to access Nth element even if ForwardSequence
|
// forward_at_c allows to access Nth element even if ForwardSequence
|
||||||
// since fusion::at_c requires RandomAccessSequence.
|
// since fusion::at_c requires RandomAccessSequence.
|
||||||
@ -168,22 +157,17 @@ namespace boost { namespace fusion
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <
|
||||||
|
typename U
|
||||||
|
, typename = typename boost::disable_if<
|
||||||
|
is_base_of<store, typename remove_reference<U>::type>
|
||||||
|
>::type
|
||||||
|
>
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
store(U&& rhs
|
store(U&& rhs)
|
||||||
, typename disable_if<is_same<typename pure<U>::type, store>, detail::enabler_>::type = detail::enabler)
|
|
||||||
: elem(std::forward<U>(rhs))
|
: elem(std::forward<U>(rhs))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
|
||||||
typename disable_if<is_same<typename pure<U>::type, store>, store&>::type
|
|
||||||
operator=(U&& rhs)
|
|
||||||
{
|
|
||||||
elem = std::forward<U>(rhs);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
T & get() { return elem; }
|
T & get() { return elem; }
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
@ -211,21 +195,17 @@ namespace boost { namespace fusion
|
|||||||
vector_data()
|
vector_data()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
template <
|
||||||
vector_data(copy_or_move, vector_data const& rhs)
|
typename Sequence
|
||||||
: store<I, T>(static_cast<store<I, T> const&>(rhs))...
|
, typename Sequence_ = typename remove_reference<Sequence>::type
|
||||||
{}
|
, typename = typename boost::enable_if<
|
||||||
|
can_convert<vector_data, Sequence, Sequence_, sizeof...(I)>
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
>::type
|
||||||
vector_data(copy_or_move, vector_data&& rhs)
|
>
|
||||||
: store<I, T>(std::forward<store<I, T> >(rhs))...
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename Sequence>
|
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
explicit
|
explicit
|
||||||
vector_data(from_sequence<detail::index_sequence<I...> >, Sequence&& rhs)
|
vector_data(each_elem, Sequence&& rhs)
|
||||||
: store<I, T>(forward_at_c<I>(rhs))...
|
: store<I, T>(forward_at_c<I>(std::forward<Sequence>(rhs)))...
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename ...U>
|
template <typename ...U>
|
||||||
@ -235,6 +215,14 @@ namespace boost { namespace fusion
|
|||||||
: store<I, T>(std::forward<U>(var))...
|
: store<I, T>(std::forward<U>(var))...
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
template <typename Sequence>
|
||||||
|
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
|
void
|
||||||
|
assign_sequence(Sequence&& seq)
|
||||||
|
{
|
||||||
|
assign(std::forward<Sequence>(seq), detail::index_sequence<I...>());
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Sequence>
|
template <typename Sequence>
|
||||||
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
void
|
void
|
||||||
@ -299,15 +287,36 @@ namespace boost { namespace fusion
|
|||||||
vector()
|
vector()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// rvalue-references is required here in order to forward any arguments to
|
template <
|
||||||
// base: vector(T const&...) doesn't work with trailing void_ and
|
typename... U
|
||||||
// vector(U const&...) cannot forward any arguments to base.
|
, typename = typename boost::enable_if_c<(
|
||||||
template <typename... U>
|
sizeof...(U) >= 1 &&
|
||||||
|
fusion::detail::and_<is_convertible<U, T>...>::value &&
|
||||||
|
!fusion::detail::and_<
|
||||||
|
is_base_of<vector, typename remove_reference<U>::type>...
|
||||||
|
>::value
|
||||||
|
)>::type
|
||||||
|
>
|
||||||
// XXX: constexpr become error due to pull-request #79, booooo!!
|
// XXX: constexpr become error due to pull-request #79, booooo!!
|
||||||
// In the (near) future release, should be fixed.
|
// In the (near) future release, should be fixed.
|
||||||
/* BOOST_CONSTEXPR */ BOOST_FUSION_GPU_ENABLED
|
/* BOOST_CONSTEXPR */ BOOST_FUSION_GPU_ENABLED
|
||||||
vector(U&&... u)
|
explicit vector(U&&... u)
|
||||||
: base(vector_detail::dispatch<vector>(std::forward<U>(u)...), std::forward<U>(u)...)
|
: base(vector_detail::each_elem(), std::forward<U>(u)...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Sequence
|
||||||
|
, typename Sequence_ = typename remove_reference<Sequence>::type
|
||||||
|
, typename = typename boost::enable_if_c<(
|
||||||
|
!is_base_of<vector, Sequence_>::value &&
|
||||||
|
vector_detail::is_longer_sequence<
|
||||||
|
Sequence_, sizeof...(T)
|
||||||
|
>::value
|
||||||
|
)>::type
|
||||||
|
>
|
||||||
|
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
|
vector(Sequence&& seq)
|
||||||
|
: base(vector_detail::each_elem(), std::forward<Sequence>(seq))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Sequence>
|
template <typename Sequence>
|
||||||
@ -315,10 +324,7 @@ namespace boost { namespace fusion
|
|||||||
vector&
|
vector&
|
||||||
operator=(Sequence&& rhs)
|
operator=(Sequence&& rhs)
|
||||||
{
|
{
|
||||||
typedef typename
|
base::assign_sequence(std::forward<Sequence>(rhs));
|
||||||
vector_detail::make_indices_from_seq<Sequence>::type
|
|
||||||
indices;
|
|
||||||
base::assign(std::forward<Sequence>(rhs), indices());
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -42,12 +42,22 @@ namespace boost { namespace fusion
|
|||||||
tuple()
|
tuple()
|
||||||
: base_type() {}
|
: base_type() {}
|
||||||
|
|
||||||
template <typename ...U>
|
template <
|
||||||
|
typename ...U
|
||||||
|
, typename = typename boost::enable_if_c<
|
||||||
|
sizeof...(U) >= sizeof...(T)
|
||||||
|
>::type
|
||||||
|
>
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
tuple(tuple<U...> const& other)
|
tuple(tuple<U...> const& other)
|
||||||
: base_type(other) {}
|
: base_type(other) {}
|
||||||
|
|
||||||
template <typename ...U>
|
template <
|
||||||
|
typename ...U
|
||||||
|
, typename = typename boost::enable_if_c<
|
||||||
|
sizeof...(U) >= sizeof...(T)
|
||||||
|
>::type
|
||||||
|
>
|
||||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||||
tuple(tuple<U...>&& other)
|
tuple(tuple<U...>&& other)
|
||||||
: base_type(std::move(other)) {}
|
: base_type(std::move(other)) {}
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <boost/fusion/container/vector/detail/config.hpp>
|
#include <boost/fusion/container/vector/detail/config.hpp>
|
||||||
|
|
||||||
#if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) \
|
#if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) \
|
||||||
|| defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) \
|
|
||||||
|| (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
|
|| (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
|
||||||
# if defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
|
# if defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
|
||||||
# undef BOOST_FUSION_HAS_VARIADIC_TUPLE
|
# undef BOOST_FUSION_HAS_VARIADIC_TUPLE
|
||||||
|
20
test/Jamfile
20
test/Jamfile
@ -123,6 +123,7 @@ project
|
|||||||
[ run sequence/array.cpp : : : : ]
|
[ run sequence/array.cpp : : : : ]
|
||||||
[ run sequence/tuple_comparison.cpp : : : : ]
|
[ run sequence/tuple_comparison.cpp : : : : ]
|
||||||
[ run sequence/tuple_construction.cpp : : : : ]
|
[ run sequence/tuple_construction.cpp : : : : ]
|
||||||
|
[ run sequence/tuple_conversion.cpp : : : : ]
|
||||||
[ run sequence/tuple_copy.cpp : : : : ]
|
[ run sequence/tuple_copy.cpp : : : : ]
|
||||||
[ run sequence/tuple_element.cpp : : : : ]
|
[ run sequence/tuple_element.cpp : : : : ]
|
||||||
[ run sequence/tuple_make.cpp : : : : ]
|
[ run sequence/tuple_make.cpp : : : : ]
|
||||||
@ -136,18 +137,19 @@ project
|
|||||||
:
|
:
|
||||||
:
|
:
|
||||||
:
|
:
|
||||||
: sequence/tuple_traits/maybe_variadic_vector
|
: sequence/tuple_traits/maybe_variadic_tuple
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
run sequence/tuple_traits.cpp
|
run sequence/tuple_traits.cpp
|
||||||
:
|
:
|
||||||
:
|
:
|
||||||
: <define>BOOST_FUSION_DISABLE_VARIADIC_VECTOR
|
: <define>BOOST_FUSION_DISABLE_VARIADIC_VECTOR
|
||||||
: sequence/tuple_traits/no_variadic_vector
|
: sequence/tuple_traits/no_variadic_tuple
|
||||||
]
|
]
|
||||||
[ run sequence/transform_view.cpp : : : : ]
|
[ run sequence/transform_view.cpp : : : : ]
|
||||||
[ run sequence/vector_comparison.cpp : : : : ]
|
[ run sequence/vector_comparison.cpp : : : : ]
|
||||||
[ run sequence/vector_construction.cpp : : : : ]
|
[ run sequence/vector_construction.cpp : : : : ]
|
||||||
|
[ run sequence/vector_conversion.cpp : : : : ]
|
||||||
[ run sequence/vector_copy.cpp : : : : ]
|
[ run sequence/vector_copy.cpp : : : : ]
|
||||||
[ run sequence/vector_iterator.cpp : : : : ]
|
[ run sequence/vector_iterator.cpp : : : : ]
|
||||||
[ run sequence/vector_make.cpp : : : : ]
|
[ run sequence/vector_make.cpp : : : : ]
|
||||||
@ -158,6 +160,20 @@ project
|
|||||||
[ run sequence/vector_nest.cpp : : : : ]
|
[ run sequence/vector_nest.cpp : : : : ]
|
||||||
[ run sequence/vector_hash.cpp : : : : ]
|
[ run sequence/vector_hash.cpp : : : : ]
|
||||||
[ run sequence/vector_tie.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/vector_value_at.cpp : : : : ]
|
||||||
[ run sequence/zip_view.cpp : : : : ]
|
[ run sequence/zip_view.cpp : : : : ]
|
||||||
[ run sequence/zip_view2.cpp : : : : ]
|
[ run sequence/zip_view2.cpp : : : : ]
|
||||||
|
320
test/sequence/conversion.hpp
Normal file
320
test/sequence/conversion.hpp
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
/*=============================================================================
|
||||||
|
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)
|
||||||
|
# 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)
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
@ -5,6 +5,8 @@
|
|||||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
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)
|
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/detail/lightweight_test.hpp>
|
||||||
#include <boost/fusion/sequence/intrinsic/at.hpp>
|
#include <boost/fusion/sequence/intrinsic/at.hpp>
|
||||||
#include <boost/fusion/mpl.hpp>
|
#include <boost/fusion/mpl.hpp>
|
||||||
@ -15,6 +17,8 @@
|
|||||||
#include <boost/mpl/equal.hpp>
|
#include <boost/mpl/equal.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
#include "fixture.hpp"
|
||||||
|
|
||||||
#if !defined(FUSION_AT)
|
#if !defined(FUSION_AT)
|
||||||
#define FUSION_AT at_c
|
#define FUSION_AT at_c
|
||||||
#endif
|
#endif
|
||||||
@ -36,12 +40,6 @@ namespace test_detail
|
|||||||
struct DD { operator CC() const { return CC(); }; };
|
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()
|
void test_mpl()
|
||||||
{
|
{
|
||||||
using namespace boost::fusion;
|
using namespace boost::fusion;
|
||||||
@ -60,6 +58,7 @@ void test_mpl()
|
|||||||
BOOST_STATIC_ASSERT(equal::value);
|
BOOST_STATIC_ASSERT(equal::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <template <typename> class Scenario>
|
||||||
void
|
void
|
||||||
test()
|
test()
|
||||||
{
|
{
|
||||||
@ -77,6 +76,9 @@ test()
|
|||||||
BOOST_TEST((double)FUSION_AT<0>(t1) == FUSION_AT<0>(t3));
|
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<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
|
// testing copy and assignment with implicit conversions
|
||||||
// between elements testing tie
|
// between elements testing tie
|
||||||
|
|
||||||
@ -91,8 +93,62 @@ test()
|
|||||||
BOOST_TEST(c=='a');
|
BOOST_TEST(c=='a');
|
||||||
BOOST_TEST(d>5.4 && d<5.6);
|
BOOST_TEST(d>5.4 && d<5.6);
|
||||||
|
|
||||||
// returning a tuple with conversion
|
|
||||||
foo(2);
|
|
||||||
|
|
||||||
test_mpl();
|
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)
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,30 @@
|
|||||||
#define FUSION_SEQUENCE deque
|
#define FUSION_SEQUENCE deque
|
||||||
#include "copy.hpp"
|
#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
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
#if defined(BOOST_FUSION_HAS_VARIADIC_DEQUE)
|
||||||
|
test<skip_const_lvalue_assignment>();
|
||||||
|
#else
|
||||||
|
test<can_copy>();
|
||||||
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,13 +7,37 @@
|
|||||||
#include <boost/fusion/container/deque/deque.hpp>
|
#include <boost/fusion/container/deque/deque.hpp>
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#define FUSION_SEQUENCE deque
|
#define FUSION_SEQUENCE boost::fusion::deque
|
||||||
#include "nest.hpp"
|
#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
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
test<skip_issues>();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
216
test/sequence/fixture.hpp
Normal file
216
test/sequence/fixture.hpp
Normal file
@ -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
|
@ -15,7 +15,7 @@
|
|||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
test<test_detail::can_copy>();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,13 +7,30 @@
|
|||||||
#include <boost/fusion/container/list/list.hpp>
|
#include <boost/fusion/container/list/list.hpp>
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#define FUSION_SEQUENCE list
|
#define FUSION_SEQUENCE boost::fusion::list
|
||||||
#include "nest.hpp"
|
#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
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
test<skip_issues>();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,111 +7,315 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
#include <boost/fusion/include/as_deque.hpp>
|
#include <boost/fusion/include/as_deque.hpp>
|
||||||
#include <boost/fusion/include/as_list.hpp>
|
#include <boost/fusion/include/as_list.hpp>
|
||||||
#include <boost/fusion/include/as_vector.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, template<typename> class As>
|
#include "fixture.hpp"
|
||||||
void test_from_sequence_rvalue()
|
|
||||||
|
namespace test_detail
|
||||||
{
|
{
|
||||||
typename As<C>::type dst((C()));
|
struct adapted_sequence
|
||||||
(void)dst;
|
{
|
||||||
}
|
adapted_sequence() : value_() {}
|
||||||
|
explicit adapted_sequence(int value) : value_(value) {}
|
||||||
|
int value_;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename C, template<typename> class As>
|
bool operator==(adapted_sequence const& lhs, adapted_sequence const& rhs)
|
||||||
void test_from_sequence_const_lvalue()
|
{
|
||||||
{
|
return lhs.value_ == rhs.value_;
|
||||||
C src;
|
}
|
||||||
typename As<C>::type dst(src);
|
|
||||||
(void)dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename C, template<typename> class As>
|
bool operator!=(adapted_sequence const& lhs, adapted_sequence const& rhs)
|
||||||
void test_from_sequence_lvalue()
|
{
|
||||||
{
|
return lhs.value_ != rhs.value_;
|
||||||
const C src;
|
}
|
||||||
typename As<C>::type dst(src);
|
|
||||||
(void)dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename C, template<typename> class As>
|
template <template <typename> class Scenario>
|
||||||
void test_from_sequence()
|
struct can_convert_using
|
||||||
{
|
{
|
||||||
// the following tests do not work in all cases for C++03
|
template <typename T>
|
||||||
#if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
|
struct to
|
||||||
test_from_sequence_rvalue<C, As>();
|
{
|
||||||
test_from_sequence_const_lvalue<C, As>();
|
static bool can_convert_(boost::true_type /* skip */)
|
||||||
test_from_sequence_lvalue<C, As>();
|
{
|
||||||
#endif
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C>
|
static bool can_convert_(boost::false_type /* skip */)
|
||||||
void test_copy()
|
{
|
||||||
{
|
using namespace boost::fusion;
|
||||||
C src;
|
return
|
||||||
C dst = src;
|
run<Scenario<T> >(typename result_of::as_deque<T>::type()) &&
|
||||||
(void)dst;
|
run<Scenario<T> >(typename result_of::as_list<T>::type()) &&
|
||||||
}
|
run<Scenario<T> >(typename result_of::as_vector<T>::type());
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
template <typename Source, typename Expected>
|
||||||
template <typename C>
|
bool operator()(Source const&, Expected const&) const
|
||||||
void test_move()
|
{
|
||||||
{
|
// bug when converting single element sequences in C++03 and
|
||||||
C src;
|
// C++11...
|
||||||
C dst = std::move(src);
|
// not_<not_<is_convertible<sequence<sequence<int>>, int >
|
||||||
(void)dst;
|
// is invalid check
|
||||||
}
|
typedef typename ::boost::fusion::result_of::size<T>::type seq_size;
|
||||||
#endif
|
return can_convert_(
|
||||||
|
boost::integral_constant<bool, seq_size::value == 1>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
template <typename C>
|
template <typename T>
|
||||||
void test_all()
|
struct can_construct_from_elements
|
||||||
{
|
{
|
||||||
// as_deque and as_list do not work in C++03 or C++11 mode
|
template <typename Source, typename Expected>
|
||||||
// test_from_sequence<C, boost::fusion::result_of::as_deque>();
|
bool operator()(Source const&, Expected const&) const
|
||||||
// test_from_sequence<C, boost::fusion::result_of::as_list>();
|
{
|
||||||
test_from_sequence<C, boost::fusion::result_of::as_vector>();
|
// constructing a nested sequence of one is the complicated case to
|
||||||
test_copy<C>();
|
// disambiguate from a conversion-copy, so focus on that
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
typedef typename boost::fusion::result_of::size<T>::type seq_size;
|
||||||
test_move<C>();
|
return can_construct_(
|
||||||
#endif
|
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
|
void
|
||||||
test()
|
test()
|
||||||
{
|
{
|
||||||
using namespace boost::fusion;
|
using namespace test_detail;
|
||||||
|
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<> > >();
|
BOOST_TEST(boost::fusion::traits::is_sequence<adapted_sequence>::value);
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<>, int> >();
|
BOOST_TEST(boost::fusion::size(adapted_sequence()) == 1);
|
||||||
test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<> > >();
|
|
||||||
test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<>, float> >();
|
|
||||||
|
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int> > >();
|
BOOST_TEST((
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int>, int> >();
|
run< Scenario< FUSION_SEQUENCE< FUSION_SEQUENCE<> > > >(
|
||||||
test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int> > >();
|
FUSION_SEQUENCE< FUSION_SEQUENCE<> >()
|
||||||
test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int>, float> >();
|
)
|
||||||
|
));
|
||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int, float> > >();
|
BOOST_TEST((
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int, float>, int> >();
|
run< Scenario< FUSION_SEQUENCE< FUSION_SEQUENCE<int> > > >(
|
||||||
test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int, float> > >();
|
FUSION_SEQUENCE< FUSION_SEQUENCE<int> >(FUSION_SEQUENCE<int>(400))
|
||||||
test_all<FUSION_SEQUENCE<int, FUSION_SEQUENCE<int, float>, float> >();
|
)
|
||||||
|
));
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<>, FUSION_SEQUENCE<> > >();
|
BOOST_TEST((
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<> > >();
|
run< Scenario< FUSION_SEQUENCE< FUSION_SEQUENCE<int, int> > > >(
|
||||||
test_all<FUSION_SEQUENCE<FUSION_SEQUENCE<>, FUSION_SEQUENCE<int> > >();
|
FUSION_SEQUENCE< FUSION_SEQUENCE<int, int> >(
|
||||||
test_all<
|
FUSION_SEQUENCE<int, int>(450, 500)
|
||||||
FUSION_SEQUENCE<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<float> >
|
)
|
||||||
>();
|
)
|
||||||
test_all<
|
));
|
||||||
FUSION_SEQUENCE<FUSION_SEQUENCE<int, float>, FUSION_SEQUENCE<float> >
|
BOOST_TEST((
|
||||||
>();
|
run< Scenario< FUSION_SEQUENCE<FUSION_SEQUENCE<int, int>, int> > >(
|
||||||
test_all<
|
FUSION_SEQUENCE<FUSION_SEQUENCE<int, int>, int>(
|
||||||
FUSION_SEQUENCE<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<float, int> >
|
FUSION_SEQUENCE<int, int>(450, 500), 150
|
||||||
>();
|
)
|
||||||
test_all<
|
)
|
||||||
FUSION_SEQUENCE<
|
));
|
||||||
FUSION_SEQUENCE<int, float>, FUSION_SEQUENCE<float, int>
|
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))
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
251
test/sequence/traits.hpp
Normal file
251
test/sequence/traits.hpp
Normal file
@ -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)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
51
test/sequence/tuple_conversion.cpp
Normal file
51
test/sequence/tuple_conversion.cpp
Normal file
@ -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();
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
test<test_detail::can_copy>();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,13 +7,29 @@
|
|||||||
#include <boost/fusion/tuple/tuple.hpp>
|
#include <boost/fusion/tuple/tuple.hpp>
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#define FUSION_SEQUENCE tuple
|
#define FUSION_SEQUENCE boost::fusion::tuple
|
||||||
#include "nest.hpp"
|
#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
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
test<skip_constructor_conversion>();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,15 +11,11 @@
|
|||||||
#include <boost/type_traits/is_constructible.hpp>
|
#include <boost/type_traits/is_constructible.hpp>
|
||||||
#include <boost/type_traits/is_convertible.hpp>
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
struct test_conversion
|
#define FUSION_SEQUENCE boost::fusion::tuple
|
||||||
{
|
#define FUSION_ALT_SEQUENCE boost::fusion::vector
|
||||||
test_conversion(int) {}
|
#include "traits.hpp"
|
||||||
};
|
|
||||||
|
|
||||||
struct test_no_conversion
|
struct not_convertible {};
|
||||||
{
|
|
||||||
explicit test_no_conversion(int) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Some construction differences in fusion::tuple from std::tuple:
|
/* Some construction differences in fusion::tuple from std::tuple:
|
||||||
- Construction from elements cannot call an explicit constructor.
|
- Construction from elements cannot call an explicit constructor.
|
||||||
@ -36,88 +32,55 @@ struct test_no_conversion
|
|||||||
could break existing code, however, switching to fusion::vector would
|
could break existing code, however, switching to fusion::vector would
|
||||||
restore the historical behavior. */
|
restore the historical behavior. */
|
||||||
int
|
int
|
||||||
main() {
|
main()
|
||||||
{
|
{
|
||||||
using namespace boost;
|
using namespace boost::fusion;
|
||||||
using namespace boost::fusion;
|
|
||||||
|
|
||||||
BOOST_TEST(!(is_convertible<int, tuple<> >::value));
|
test_convertible(false /* no conversion construction */ );
|
||||||
BOOST_TEST(!(is_convertible<int&, tuple<> >::value));
|
|
||||||
|
|
||||||
BOOST_TEST(!(is_convertible< int, tuple<int> >::value));
|
BOOST_TEST((is_convertible<std::pair<int, int>, tuple<int, int> >(true)));
|
||||||
BOOST_TEST(!(is_convertible< int&, tuple<int> >::value));
|
BOOST_TEST((
|
||||||
BOOST_TEST(!(is_convertible< vector<int>, tuple<int> >::value));
|
is_convertible<std::pair<int, int>, tuple<convertible, int> >(true)
|
||||||
BOOST_TEST(!(is_convertible< vector<int>&, tuple<int> >::value));
|
));
|
||||||
|
BOOST_TEST((
|
||||||
|
is_convertible<std::pair<int, int>, tuple<int, convertible> >(true)
|
||||||
|
));
|
||||||
|
BOOST_TEST((
|
||||||
|
is_convertible<
|
||||||
|
std::pair<int, int>, tuple<convertible, convertible>
|
||||||
|
>(true)
|
||||||
|
));
|
||||||
|
|
||||||
BOOST_TEST(!(is_convertible<int, tuple<int, int> >::value));
|
#if defined(FUSION_TEST_HAS_CONSTRUCTIBLE)
|
||||||
BOOST_TEST(!(is_convertible<int&, tuple<int, int> >::value));
|
test_constructible();
|
||||||
}
|
|
||||||
|
|
||||||
// is_constructible has some restrictions ...
|
BOOST_TEST((is_constructible< tuple<> >(true)));
|
||||||
#if !(defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_TEMPLATES) || \
|
BOOST_TEST((is_constructible<tuple<>, int>(false)));
|
||||||
defined(BOOST_NO_SFINAE_EXPR))
|
|
||||||
{
|
|
||||||
using namespace boost;
|
|
||||||
using namespace boost::fusion;
|
|
||||||
|
|
||||||
BOOST_TEST((is_constructible< tuple<> >::value));
|
BOOST_TEST((is_constructible< tuple<int> >(true)));
|
||||||
BOOST_TEST(!(is_constructible<tuple<>, int>::value));
|
BOOST_TEST((is_constructible<tuple<int>, int>(true)));
|
||||||
BOOST_TEST(!(is_constructible<tuple<>, int&>::value));
|
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> >::value));
|
BOOST_TEST((is_constructible< tuple<int, int> >(true)));
|
||||||
BOOST_TEST((is_constructible<tuple<int>, int>::value));
|
BOOST_TEST((is_constructible<tuple<int, int>, int, int>(true)));
|
||||||
BOOST_TEST((is_constructible<tuple<int>, int&>::value));
|
BOOST_TEST((
|
||||||
BOOST_TEST((is_constructible<tuple<test_conversion>, int>::value));
|
is_constructible<tuple<convertible, convertible>, int, int>(true)
|
||||||
BOOST_TEST((is_constructible<tuple<test_conversion>, int&>::value));
|
));
|
||||||
BOOST_TEST(!(is_constructible<tuple<test_no_conversion>, int>::value));
|
BOOST_TEST((is_constructible<tuple<int, not_convertible>, int, int>(false)));
|
||||||
BOOST_TEST(!(is_constructible<tuple<test_no_conversion>, int&>::value));
|
BOOST_TEST((is_constructible<tuple<not_convertible, int>, int, int>(false)));
|
||||||
BOOST_TEST(!(is_constructible< tuple<int>, vector<int> >::value));
|
BOOST_TEST((
|
||||||
BOOST_TEST(!(is_constructible<tuple<int>, vector<int>&>::value));
|
is_constructible<tuple<not_convertible, not_convertible>, int, int>(false)
|
||||||
BOOST_TEST(!(is_constructible<tuple<int>, int, int>::value));
|
));
|
||||||
BOOST_TEST(!(is_constructible<tuple<int>, int&, int&>::value));
|
|
||||||
|
|
||||||
BOOST_TEST((is_constructible< tuple<int, int> >::value));
|
|
||||||
BOOST_TEST((is_constructible<tuple<int, int>, int, int>::value));
|
|
||||||
BOOST_TEST((is_constructible<tuple<int, int>, int&, int&>::value));
|
|
||||||
BOOST_TEST((
|
|
||||||
is_constructible<
|
|
||||||
tuple<test_conversion, test_conversion>
|
|
||||||
, int
|
|
||||||
, int
|
|
||||||
>::value
|
|
||||||
));
|
|
||||||
BOOST_TEST((
|
|
||||||
is_constructible<
|
|
||||||
tuple<test_conversion, test_conversion>
|
|
||||||
, int&
|
|
||||||
, int&
|
|
||||||
>::value
|
|
||||||
));
|
|
||||||
BOOST_TEST(!(
|
|
||||||
is_constructible<
|
|
||||||
tuple<test_no_conversion, test_no_conversion>
|
|
||||||
, int
|
|
||||||
, int
|
|
||||||
>::value
|
|
||||||
));
|
|
||||||
BOOST_TEST(!(
|
|
||||||
is_constructible<
|
|
||||||
tuple<test_no_conversion, test_no_conversion>
|
|
||||||
, int&
|
|
||||||
, int&
|
|
||||||
>::value
|
|
||||||
));
|
|
||||||
#if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
|
#if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
|
||||||
// C++03 fusion::tuple has constructors that can never be used
|
// C++03 fusion::tuple has constructors that can never be used
|
||||||
BOOST_TEST(!(is_constructible<tuple<int, int>, int>::value));
|
BOOST_TEST((is_constructible<tuple<int, int>, int>(false)));
|
||||||
BOOST_TEST(!(is_constructible<tuple<int, int>, int&>::value));
|
|
||||||
#endif
|
|
||||||
BOOST_TEST(!(is_constructible<tuple<int, int>, int, int, int>::value));
|
|
||||||
BOOST_TEST(!(
|
|
||||||
is_constructible<tuple<int, int>, int&, int&, int&>::value
|
|
||||||
));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
BOOST_TEST((is_constructible<tuple<int, int>, int, int, int>(false)));
|
||||||
|
|
||||||
|
#endif // FUSION_TEST_HAS_CONSTRUCTIBLE
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
19
test/sequence/vector_conversion.cpp
Normal file
19
test/sequence/vector_conversion.cpp
Normal file
@ -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();
|
||||||
|
}
|
@ -15,7 +15,7 @@
|
|||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
test<test_detail::can_copy>();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,13 +7,13 @@
|
|||||||
#include <boost/fusion/container/vector/vector.hpp>
|
#include <boost/fusion/container/vector/vector.hpp>
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#define FUSION_SEQUENCE vector
|
#define FUSION_SEQUENCE boost::fusion::vector
|
||||||
#include "nest.hpp"
|
#include "nest.hpp"
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test();
|
test<test_detail::can_nest>();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
test/sequence/vector_traits.cpp
Normal file
32
test/sequence/vector_traits.cpp
Normal file
@ -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();
|
||||||
|
}
|
Reference in New Issue
Block a user