diff options
Diffstat (limited to 'boost/fusion')
19 files changed, 819 insertions, 115 deletions
diff --git a/boost/fusion/adapted/std_array.hpp b/boost/fusion/adapted/std_array.hpp new file mode 100644 index 0000000000..64ae6460c7 --- /dev/null +++ b/boost/fusion/adapted/std_array.hpp @@ -0,0 +1,23 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY__01062013_1700) +#define BOOST_FUSION_STD_ARRAY__01062013_1700 + +#include <boost/fusion/adapted/std_array/std_array_iterator.hpp> +#include <boost/fusion/adapted/std_array/tag_of.hpp> +#include <boost/fusion/adapted/std_array/detail/is_view_impl.hpp> +#include <boost/fusion/adapted/std_array/detail/is_sequence_impl.hpp> +#include <boost/fusion/adapted/std_array/detail/category_of_impl.hpp> +#include <boost/fusion/adapted/std_array/detail/begin_impl.hpp> +#include <boost/fusion/adapted/std_array/detail/end_impl.hpp> +#include <boost/fusion/adapted/std_array/detail/size_impl.hpp> +#include <boost/fusion/adapted/std_array/detail/at_impl.hpp> +#include <boost/fusion/adapted/std_array/detail/value_at_impl.hpp> + +#endif diff --git a/boost/fusion/adapted/std_array/detail/array_size.hpp b/boost/fusion/adapted/std_array/detail/array_size.hpp new file mode 100644 index 0000000000..2f83940465 --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/array_size.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_ARRAY_SIZE_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_ARRAY_SIZE_01062013_1700 + +#include <cstddef> +#include <type_traits> + +namespace boost { namespace fusion +{ + namespace extension + { + template<class T> + struct std_array_size; + + template<template<typename, std::size_t> class Array, typename T, std::size_t N> + struct std_array_size<Array<T, N>> : std::integral_constant<std::size_t, N> {}; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/at_impl.hpp b/boost/fusion/adapted/std_array/detail/at_impl.hpp new file mode 100644 index 0000000000..6086264a91 --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/at_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_AT_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_AT_IMPL_01062013_1700 + +#include <boost/type_traits/is_const.hpp> + +#include <boost/mpl/if.hpp> + +namespace boost { namespace fusion { + + struct std_array_tag; + + namespace extension + { + template<typename T> + struct at_impl; + + template<> + struct at_impl<std_array_tag> + { + template<typename Sequence, typename N> + struct apply + { + typedef typename mpl::if_< + is_const<Sequence>, + typename Sequence::const_reference, + typename Sequence::reference>::type type; + + static type + call(Sequence& seq) + { + return seq[N::value]; + } + }; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/begin_impl.hpp b/boost/fusion/adapted/std_array/detail/begin_impl.hpp new file mode 100644 index 0000000000..c84082e34e --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/begin_impl.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_BEGIN_OF_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_BEGIN_OF_IMPL_01062013_1700 + +#include <boost/fusion/adapted/std_array/std_array_iterator.hpp> + +namespace boost { namespace fusion { + + struct std_array_tag; + + namespace extension + { + template<typename T> + struct begin_impl; + + template <> + struct begin_impl<std_array_tag> + { + template <typename Sequence> + struct apply + { + typedef std_array_iterator<Sequence, 0> type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/category_of_impl.hpp b/boost/fusion/adapted/std_array/detail/category_of_impl.hpp new file mode 100644 index 0000000000..b5fa09350c --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/category_of_impl.hpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_CATEGORY_OF_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_CATEGORY_OF_IMPL_01062013_1700 + +#include <boost/config/no_tr1/utility.hpp> + +namespace boost { namespace fusion { + + struct std_array_tag; + struct random_access_traversal_tag; + + namespace extension + { + template<typename T> + struct category_of_impl; + + template<> + struct category_of_impl<std_array_tag> + { + template<typename T> + struct apply + { + typedef random_access_traversal_tag type; + }; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/end_impl.hpp b/boost/fusion/adapted/std_array/detail/end_impl.hpp new file mode 100644 index 0000000000..b7b789ef5c --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/end_impl.hpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_END_OF_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_END_OF_IMPL_01062013_1700 + +#include <boost/fusion/adapted/std_array/std_array_iterator.hpp> +#include <boost/fusion/adapted/std_array/detail/array_size.hpp> +#include <boost/type_traits/remove_const.hpp> + +namespace boost { namespace fusion { + + struct std_array_tag; + + namespace extension + { + template <typename Tag> + struct end_impl; + + template <> + struct end_impl<std_array_tag> + { + template <typename Sequence> + struct apply + { + typedef typename remove_const<Sequence>::type seq_type; + static int const size = std_array_size<seq_type>::value; + typedef std_array_iterator<Sequence, size> type; + + static type + call(Sequence& v) + { + return type(v); + } + }; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/is_sequence_impl.hpp b/boost/fusion/adapted/std_array/detail/is_sequence_impl.hpp new file mode 100644 index 0000000000..8308e838c3 --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/is_sequence_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_IS_SEQUENCE_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_IS_SEQUENCE_IMPL_01062013_1700 + +#include <boost/mpl/bool.hpp> + +namespace boost { namespace fusion { + + struct std_array_tag; + + namespace extension + { + template<typename Tag> + struct is_sequence_impl; + + template<> + struct is_sequence_impl<std_array_tag> + { + template<typename Sequence> + struct apply : mpl::true_ {}; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/is_view_impl.hpp b/boost/fusion/adapted/std_array/detail/is_view_impl.hpp new file mode 100644 index 0000000000..89cd04cf2b --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/is_view_impl.hpp @@ -0,0 +1,33 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_IS_VIEW_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_IS_VIEW_IMPL_01062013_1700 + +#include <boost/mpl/bool.hpp> + +namespace boost { namespace fusion +{ + struct std_array_tag; + + namespace extension + { + template<typename Tag> + struct is_view_impl; + + template<> + struct is_view_impl<std_array_tag> + { + template<typename T> + struct apply : mpl::false_ + {}; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/size_impl.hpp b/boost/fusion/adapted/std_array/detail/size_impl.hpp new file mode 100644 index 0000000000..7df51b2a5e --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/size_impl.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_SIZE_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_SIZE_IMPL_01062013_1700 + +#include <boost/fusion/adapted/std_array/detail/array_size.hpp> +#include <boost/type_traits/remove_const.hpp> + +namespace boost { namespace fusion { + + struct std_array_tag; + + namespace extension + { + template<typename T> + struct size_impl; + + template<> + struct size_impl<std_array_tag> + { + template<typename Sequence> + struct apply + : mpl::int_ + < + std_array_size + < + typename remove_const<Sequence>::type + >::value + > + {}; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/detail/value_at_impl.hpp b/boost/fusion/adapted/std_array/detail/value_at_impl.hpp new file mode 100644 index 0000000000..3d7871a7d2 --- /dev/null +++ b/boost/fusion/adapted/std_array/detail/value_at_impl.hpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_VALUE_AT_IMPL_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_VALUE_AT_IMPL_01062013_1700 + +namespace boost { namespace fusion { + + struct std_array_tag; + + namespace extension + { + template<typename T> + struct value_at_impl; + + template <> + struct value_at_impl<std_array_tag> + { + template <typename Sequence, typename N> + struct apply + { + typedef typename Sequence::value_type type; + }; + }; + } +}} + +#endif diff --git a/boost/fusion/adapted/std_array/std_array_iterator.hpp b/boost/fusion/adapted/std_array/std_array_iterator.hpp new file mode 100644 index 0000000000..29584512b0 --- /dev/null +++ b/boost/fusion/adapted/std_array/std_array_iterator.hpp @@ -0,0 +1,109 @@ +/*============================================================================= + Copyright (c) 2013 Mateusz Loskot + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_ARRAY_ITERATOR_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_ARRAY_ITERATOR_01062013_1700 + +#include <cstddef> +#include <boost/config.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/fusion/iterator/iterator_facade.hpp> +#include <boost/fusion/adapted/std_array/detail/array_size.hpp> + +namespace boost { namespace fusion +{ + struct random_access_traversal_tag; + + template <typename Array, int Pos> + struct std_array_iterator + : iterator_facade<std_array_iterator<Array, Pos>, random_access_traversal_tag> + { + BOOST_MPL_ASSERT_RELATION(Pos, >=, 0); + BOOST_MPL_ASSERT_RELATION(Pos, <=, std::tuple_size<Array>::value); + + typedef mpl::int_<Pos> index; + typedef Array array_type; + + std_array_iterator(Array& a) + : array(a) {} + + Array& array; + + template <typename Iterator> + struct value_of + { + typedef typename Iterator::array_type array_type; + typedef typename array_type::value_type type; + }; + + template <typename Iterator> + struct deref + { + typedef typename Iterator::array_type array_type; + typedef typename + mpl::if_< + is_const<array_type> + , typename array_type::const_reference + , typename array_type::reference + >::type + type; + + static type + call(Iterator const & it) + { + return it.array[Iterator::index::value]; + } + }; + + template <typename Iterator, typename N> + struct advance + { + typedef typename Iterator::index index; + typedef typename Iterator::array_type array_type; + typedef std_array_iterator<array_type, index::value + N::value> type; + + static type + call(Iterator const& i) + { + return type(i.array); + } + }; + + template <typename Iterator> + struct next : advance<Iterator, mpl::int_<1> > {}; + + template <typename Iterator> + struct prior : advance<Iterator, mpl::int_<-1> > {}; + + template <typename I1, typename I2> + struct distance : mpl::minus<typename I2::index, typename I1::index> + { + typedef typename + mpl::minus< + typename I2::index, typename I1::index + >::type + type; + + static type + call(I1 const&, I2 const&) + { + return type(); + } + }; + + private: + + std_array_iterator<Array, Pos>& operator=(std_array_iterator<Array, Pos> const&); + }; +}} + +#endif diff --git a/boost/fusion/adapted/std_array/tag_of.hpp b/boost/fusion/adapted/std_array/tag_of.hpp new file mode 100644 index 0000000000..543c5bb461 --- /dev/null +++ b/boost/fusion/adapted/std_array/tag_of.hpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2005-2006 Dan Marsden + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_FUSION_STD_ARRAY_TAG_OF_01062013_1700) +#define BOOST_FUSION_STD_ARRAY_TAG_OF_01062013_1700 + +#include <boost/fusion/support/tag_of_fwd.hpp> +#include <array> +#include <cstddef> + +namespace boost { namespace fusion +{ + struct std_array_tag; + struct fusion_sequence_tag; + + namespace traits + { + template<typename T, std::size_t N> +#if defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) + struct tag_of<std::array<T,N>, void > +#else + struct tag_of<std::array<T,N> > +#endif + { + typedef std_array_tag type; + }; + } +}} + +namespace boost { namespace mpl +{ + template<typename> + struct sequence_tag; + + template<typename T, std::size_t N> + struct sequence_tag<std::array<T,N> > + { + typedef fusion::fusion_sequence_tag type; + }; + + template<typename T, std::size_t N> + struct sequence_tag<std::array<T,N> const> + { + typedef fusion::fusion_sequence_tag type; + }; +}} + +#endif diff --git a/boost/fusion/adapted/struct/detail/define_struct.hpp b/boost/fusion/adapted/struct/detail/define_struct.hpp index ab483f0252..cb52ddff9f 100644 --- a/boost/fusion/adapted/struct/detail/define_struct.hpp +++ b/boost/fusion/adapted/struct/detail/define_struct.hpp @@ -10,6 +10,7 @@ #include <boost/fusion/support/config.hpp> #include <boost/config.hpp> +#include <boost/detail/workaround.hpp> #include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/iterator/deref.hpp> #include <boost/fusion/iterator/next.hpp> @@ -39,6 +40,8 @@ #define BOOST_FUSION_DEFINE_STRUCT_FILLER_0_END #define BOOST_FUSION_DEFINE_STRUCT_FILLER_1_END +#ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + #define BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR_FILLER_I( \ R, ATTRIBUTE_TUPLE_SIZE, I, ATTRIBUTE) \ \ @@ -46,6 +49,54 @@ BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE)( \ other_self.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE)) +#define BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED \ + NAME(self_type const& other_self) \ + : BOOST_PP_SEQ_FOR_EACH_I_R( \ + 1, \ + BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR_FILLER_I, \ + ATTRIBUTE_TUPLE_SIZE, \ + ATTRIBUTES_SEQ) \ + {} + +// Use templated version instead. +#define BOOST_FUSION_DEFINE_STRUCT_COPY_ASSIGN_FILLER_I( \ + R, ATTRIBUTE_TUPLE_SIZE, I_, ATTRIBUTE) \ + \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE)= \ + other.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE); + +#define BOOST_FUSION_DEFINE_STRUCT_COPY_ASSIGN_OP( \ + ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED \ + self_type& operator=(self_type const& other) \ + { \ + BOOST_PP_SEQ_FOR_EACH_I_R( \ + 1, \ + BOOST_FUSION_DEFINE_STRUCT_COPY_ASSIGN_FILLER_I, \ + ATTRIBUTE_TUPLE_SIZE, \ + ATTRIBUTES_SEQ) \ + \ + return *this; \ + } + +#else // BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + +#define BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED NAME(self_type const&) = default; + +#define BOOST_FUSION_DEFINE_STRUCT_COPY_ASSIGN_OP( \ + ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED self_type& operator=(self_type const&) = default; + +#endif // BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + #define BOOST_FUSION_DEFINE_STRUCT_ASSIGN_FILLER_I( \ R, ATTRIBUTE_TUPLE_SIZE, I_, ATTRIBUTE) \ \ @@ -85,6 +136,81 @@ return *this; \ } +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_CTOR(NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_ASSIGN_OP(ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) + +#else // BOOST_NO_CXX11_RVALUE_REFERENCES + +#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) \ + || BOOST_WORKAROUND(BOOST_GCC, < 40500) \ + || BOOST_WORKAROUND(BOOST_MSVC, == 1800) + +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_CTOR_FILLER_I( \ + R, ATTRIBUTE_TUPLE_SIZE, I, ATTRIBUTE) \ + \ + BOOST_PP_COMMA_IF(I) \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE)(std::move( \ + other_self.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE))) + +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_CTOR( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED \ + NAME(self_type&& other_self) \ + : BOOST_PP_SEQ_FOR_EACH_I_R( \ + 1, \ + BOOST_FUSION_DEFINE_STRUCT_MOVE_CTOR_FILLER_I, \ + ATTRIBUTE_TUPLE_SIZE, \ + ATTRIBUTES_SEQ) \ + {} + +#else // BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_CTOR( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED NAME(self_type&&) = default; + +#endif // BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + +#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) \ + || BOOST_WORKAROUND(BOOST_GCC, < 40600) \ + || BOOST_WORKAROUND(BOOST_MSVC, == 1800) + +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_ASSIGN_FILLER_I( \ + R, ATTRIBUTE_TUPLE_SIZE, I_, ATTRIBUTE) \ + \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE)=std::move( \ + other.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,1,ATTRIBUTE)); + +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_ASSIGN_OP( \ + ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED \ + self_type& operator=(self_type&& other) \ + { \ + BOOST_PP_SEQ_FOR_EACH_I_R( \ + 1, \ + BOOST_FUSION_DEFINE_STRUCT_MOVE_ASSIGN_FILLER_I, \ + ATTRIBUTE_TUPLE_SIZE, \ + ATTRIBUTES_SEQ) \ + \ + return *this; \ + } + +#else // BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + +#define BOOST_FUSION_DEFINE_STRUCT_MOVE_ASSIGN_OP( \ + ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + \ + BOOST_FUSION_GPU_ENABLED self_type& operator=(self_type&&) = default; + +#endif // BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + #define BOOST_FUSION_DEFINE_STRUCT_ATTR_I(R, ATTRIBUTE_TUPLE_SIZE, ATTRIBUTE) \ \ BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE,0,ATTRIBUTE) \ @@ -135,14 +261,10 @@ ATTRIBUTES_SEQ) \ {} \ \ - BOOST_FUSION_GPU_ENABLED \ - NAME(self_type const& other_self) \ - : BOOST_PP_SEQ_FOR_EACH_I_R( \ - 1, \ - BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR_FILLER_I, \ - ATTRIBUTE_TUPLE_SIZE, \ - ATTRIBUTES_SEQ) \ - {} \ + BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + BOOST_FUSION_DEFINE_STRUCT_MOVE_CTOR( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ \ template<typename Seq> \ BOOST_FUSION_GPU_ENABLED \ @@ -160,6 +282,10 @@ ATTRIBUTES_SEQ) \ {} \ \ + BOOST_FUSION_DEFINE_STRUCT_COPY_ASSIGN_OP( \ + ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ + BOOST_FUSION_DEFINE_STRUCT_MOVE_ASSIGN_OP( \ + ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ BOOST_FUSION_DEFINE_STRUCT_ASSIGN_OP(ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) #define BOOST_FUSION_DEFINE_STRUCT_CTOR_1( \ @@ -282,20 +408,7 @@ NAME, BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ), ATTRIBUTE_TUPLE_SIZE) #define BOOST_FUSION_DEFINE_EMPTY_STRUCT_IMPL( \ - NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ - \ - template<typename Seq> \ - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ - NAME(Seq const&) \ - {} \ - \ - template<typename Seq> \ - BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ - self_type& \ - operator=(Seq const& seq) \ - { \ - return *this; \ - } + NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) #define BOOST_FUSION_DEFINE_STRUCT_IMPL( \ NAMESPACE_SEQ, NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ @@ -327,10 +440,7 @@ ATTRIBUTE_TUPLE_SIZE) #define BOOST_FUSION_DEFINE_EMPTY_TPL_STRUCT_IMPL( \ - TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) \ - \ - BOOST_FUSION_DEFINE_EMPTY_STRUCT_IMPL( \ - NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) + TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES_SEQ, ATTRIBUTE_TUPLE_SIZE) #define BOOST_FUSION_DEFINE_TPL_STRUCT_IMPL( \ TEMPLATE_PARAMS_SEQ, \ diff --git a/boost/fusion/container/deque/detail/keyed_element.hpp b/boost/fusion/container/deque/detail/keyed_element.hpp index 24b5979d2d..15b686671d 100644 --- a/boost/fusion/container/deque/detail/keyed_element.hpp +++ b/boost/fusion/container/deque/detail/keyed_element.hpp @@ -59,7 +59,7 @@ namespace boost { namespace fusion { namespace detail #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_element(keyed_element&& rhs) - : Rest(BOOST_FUSION_FWD_ELEM(Rest, rhs.forward_base())) + : Rest(rhs.forward_base()) , value_(BOOST_FUSION_FWD_ELEM(Value, rhs.value_)) {} #endif @@ -90,7 +90,7 @@ namespace boost { namespace fusion { namespace detail BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED Rest&& forward_base() BOOST_NOEXCEPT { - return BOOST_FUSION_FWD_ELEM(Rest, *static_cast<Rest*>(this)); + return std::move(*static_cast<Rest*>(this)); } #endif @@ -116,7 +116,7 @@ namespace boost { namespace fusion { namespace detail #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_element(Value&& value, Rest&& rest) - : Rest(BOOST_FUSION_FWD_ELEM(Rest, rest)) + : Rest(std::move(rest)) , value_(BOOST_FUSION_FWD_ELEM(Value, value)) {} #endif @@ -147,8 +147,8 @@ namespace boost { namespace fusion { namespace detail BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_element& operator=(keyed_element&& rhs) { - base::operator=(std::forward<keyed_element>(rhs)); - value_ = BOOST_FUSION_FWD_ELEM(Value, rhs.value_); + base::operator=(rhs.forward_base()); + value_ = std::move(rhs.value_); return *this; } #endif diff --git a/boost/fusion/container/vector/detail/config.hpp b/boost/fusion/container/vector/detail/config.hpp index 84f4605d2e..2a7aea64a8 100644 --- a/boost/fusion/container/vector/detail/config.hpp +++ b/boost/fusion/container/vector/detail/config.hpp @@ -15,6 +15,8 @@ || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \ || defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) \ || defined(BOOST_NO_CXX11_DECLTYPE)) \ + || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) \ + || defined(BOOST_FUSION_DISABLE_VARIADIC_VECTOR) \ || (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) # if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) # undef BOOST_FUSION_HAS_VARIADIC_VECTOR diff --git a/boost/fusion/container/vector/vector.hpp b/boost/fusion/container/vector/vector.hpp index 65bffd0b69..62d2445eca 100644 --- a/boost/fusion/container/vector/vector.hpp +++ b/boost/fusion/container/vector/vector.hpp @@ -24,23 +24,21 @@ /////////////////////////////////////////////////////////////////////////////// #include <boost/fusion/support/sequence_base.hpp> #include <boost/fusion/support/is_sequence.hpp> -#include <boost/fusion/support/void.hpp> -#include <boost/fusion/support/detail/enabler.hpp> +#include <boost/fusion/support/detail/and.hpp> #include <boost/fusion/support/detail/index_sequence.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/begin_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/size.hpp> #include <boost/fusion/iterator/advance.hpp> #include <boost/fusion/iterator/deref.hpp> #include <boost/core/enable_if.hpp> #include <boost/mpl/int.hpp> -#include <boost/mpl/bool.hpp> -#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/type_traits/is_base_of.hpp> #include <boost/type_traits/is_convertible.hpp> -#include <boost/type_traits/remove_cv.hpp> #include <boost/type_traits/remove_reference.hpp> #include <cstddef> #include <utility> @@ -53,52 +51,48 @@ namespace boost { namespace fusion namespace vector_detail { struct each_elem {}; - struct copy_or_move {}; - template <typename I> struct from_sequence {}; - template <typename Sequence> - struct make_indices_from_seq - : detail::make_index_sequence< - fusion::result_of::size<typename remove_reference<Sequence>::type>::value + template < + typename This, typename T, typename T_, std::size_t Size, bool IsSeq + > + 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> - struct pure : remove_cv<typename remove_reference<T>::type> {}; - - template <typename Sequence, typename This, int = result_of::size<This>::value> - struct is_convertible_to_first - : boost::is_convertible<Sequence, typename result_of::value_at_c<This, 0>::type> - {}; - - template <typename Sequence, typename This> - struct is_convertible_to_first<Sequence, This, 0> - : mpl::false_ + template <typename This, typename T, typename T_, std::size_t Size> + struct can_convert + : can_convert_impl< + This, T, T_, Size, traits::is_sequence<T_>::value + > {}; - template <typename This, typename ...T> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - inline each_elem - dispatch(T const&...) BOOST_NOEXCEPT { return each_elem(); } - - template <typename This> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - inline copy_or_move - dispatch(This const&) BOOST_NOEXCEPT { return copy_or_move(); } + template <typename T, bool IsSeq, std::size_t Size> + struct is_longer_sequence_impl : false_type {}; - template <typename This, typename Sequence> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - inline from_sequence< - typename lazy_enable_if_c< - (traits::is_sequence<typename remove_reference<Sequence>::type>::value && - !is_same<This, typename pure<Sequence>::type>::value && - !is_convertible_to_first<Sequence, This>::value) - , make_indices_from_seq<Sequence> - >::type - > - dispatch(Sequence&&) BOOST_NOEXCEPT - { return from_sequence<typename make_indices_from_seq<Sequence>::type>(); } + template <typename Sequence, std::size_t Size> + struct is_longer_sequence_impl<Sequence, true, Size> + : integral_constant< + bool, (fusion::result_of::size<Sequence>::value >= Size) + > + {}; + 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 // since fusion::at_c requires RandomAccessSequence. @@ -163,22 +157,17 @@ namespace boost { namespace fusion 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 - store(U&& rhs - , typename disable_if<is_same<typename pure<U>::type, store>, detail::enabler_>::type = detail::enabler) + store(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 T & get() { return elem; } BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED @@ -206,21 +195,17 @@ namespace boost { namespace fusion vector_data() {} - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - vector_data(copy_or_move, vector_data const& rhs) - : store<I, T>(static_cast<store<I, T> const&>(rhs))... - {} - - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - vector_data(copy_or_move, vector_data&& rhs) - : store<I, T>(std::forward<store<I, T> >(rhs))... - {} - - template <typename Sequence> + template < + typename Sequence + , typename Sequence_ = typename remove_reference<Sequence>::type + , typename = typename boost::enable_if< + can_convert<vector_data, Sequence, Sequence_, sizeof...(I)> + >::type + > BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED explicit - vector_data(from_sequence<detail::index_sequence<I...> >, Sequence&& rhs) - : store<I, T>(forward_at_c<I>(rhs))... + vector_data(each_elem, Sequence&& rhs) + : store<I, T>(forward_at_c<I>(std::forward<Sequence>(rhs)))... {} template <typename ...U> @@ -233,6 +218,14 @@ namespace boost { namespace fusion 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> + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + void assign(Sequence&&, detail::index_sequence<>) {} template <typename Sequence, std::size_t N, std::size_t ...M> @@ -294,15 +287,36 @@ namespace boost { namespace fusion vector() {} - // rvalue-references is required here in order to forward any arguments to - // base: vector(T const&...) doesn't work with trailing void_ and - // vector(U const&...) cannot forward any arguments to base. - template <typename... U> + template < + typename... U + , typename = typename boost::enable_if_c<( + 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!! // In the (near) future release, should be fixed. /* BOOST_CONSTEXPR */ BOOST_FUSION_GPU_ENABLED - vector(U&&... u) - : base(vector_detail::dispatch<vector>(std::forward<U>(u)...), std::forward<U>(u)...) + explicit vector(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> @@ -310,10 +324,7 @@ namespace boost { namespace fusion vector& operator=(Sequence&& rhs) { - typedef typename - vector_detail::make_indices_from_seq<Sequence>::type - indices; - base::assign(std::forward<Sequence>(rhs), indices()); + base::assign_sequence(std::forward<Sequence>(rhs)); return *this; } }; diff --git a/boost/fusion/support/detail/and.hpp b/boost/fusion/support/detail/and.hpp new file mode 100644 index 0000000000..1b310dda36 --- /dev/null +++ b/boost/fusion/support/detail/and.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + 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) +==============================================================================*/ +#ifndef FUSION_AND_07152016_1625 +#define FUSION_AND_07152016_1625 + +#include <boost/config.hpp> +#include <boost/type_traits/integral_constant.hpp> + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#error fusion::detail::and_ requires variadic templates +#endif + +namespace boost { namespace fusion { namespace detail { + template<typename ...Cond> + struct and_impl : false_type {}; + + template<typename ...T> + struct and_impl<integral_constant<T, true>...> : true_type {}; + + // This specialization is necessary to avoid MSVC-12 variadics bug. + template<bool ...Cond> + struct and_impl1 : and_impl<integral_constant<bool, Cond>...> {}; + + /* fusion::detail::and_ differs from mpl::and_ in the following ways: + - The empty set is valid and returns true + - A single element set is valid and returns the identity + - There is no upper bound on the set size + - The conditions are evaluated at once, and are not short-circuited. This + reduces instantations when returning true; the implementation is not + recursive. */ + template<typename ...Cond> + struct and_ : and_impl1<Cond::value...> {}; +}}} + +#endif // FUSION_AND_07152016_1625 diff --git a/boost/fusion/tuple/tuple.hpp b/boost/fusion/tuple/tuple.hpp index 6ee21f56a0..07014c6c29 100644 --- a/boost/fusion/tuple/tuple.hpp +++ b/boost/fusion/tuple/tuple.hpp @@ -20,12 +20,15 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include <boost/core/enable_if.hpp> #include <boost/fusion/container/vector/vector.hpp> #include <boost/fusion/sequence/intrinsic/size.hpp> #include <boost/fusion/sequence/intrinsic/value_at.hpp> #include <boost/fusion/sequence/intrinsic/at.hpp> #include <boost/fusion/sequence/comparison.hpp> #include <boost/fusion/sequence/io.hpp> +#include <boost/fusion/support/detail/and.hpp> +#include <boost/type_traits/is_convertible.hpp> #include <utility> namespace boost { namespace fusion @@ -39,23 +42,49 @@ namespace boost { namespace fusion tuple() : 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 tuple(tuple<U...> const& 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 tuple(tuple<U...>&& other) : base_type(std::move(other)) {} - template <typename ...U> + template < + typename ...U + , typename = typename boost::enable_if_c<( + fusion::detail::and_<is_convertible<U, T>...>::value && + sizeof...(U) >= 1 + )>::type + > /*BOOST_CONSTEXPR*/ BOOST_FUSION_GPU_ENABLED explicit tuple(U&&... args) : base_type(std::forward<U>(args)...) {} - template <typename U> + template<typename U1, typename U2> + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + tuple(std::pair<U1, U2> const& other) + : base_type(other.first, other.second) {} + + template<typename U1, typename U2> + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + tuple(std::pair<U1, U2>&& other) + : base_type(std::move(other.first), std::move(other.second)) {} + + template<typename U> BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED tuple& operator=(U&& rhs) { diff --git a/boost/fusion/view/zip_view/zip_view.hpp b/boost/fusion/view/zip_view/zip_view.hpp index cf6f6d2716..b03272015d 100644 --- a/boost/fusion/view/zip_view/zip_view.hpp +++ b/boost/fusion/view/zip_view/zip_view.hpp @@ -126,7 +126,7 @@ namespace boost { namespace fusion { zip_view( const Sequences& seqs) : sequences_(seqs) - {}; + {} sequences sequences_; }; |