diff --git a/include/boost/fusion/container/generation/make_vector.hpp b/include/boost/fusion/container/generation/make_vector.hpp index 14ef323c..df63ded6 100644 --- a/include/boost/fusion/container/generation/make_vector.hpp +++ b/include/boost/fusion/container/generation/make_vector.hpp @@ -27,16 +27,38 @@ namespace boost { namespace fusion template struct make_vector { - typedef vector::type...> type; + // make `make_vector' into `make_vector' + template struct trim_void; + + template + struct trim_void > + { + typedef vector, U...> type; + }; + + template + struct trim_void, void_, Tail...> + : trim_void > { }; + + template + struct trim_void, Head, Tail...> + : trim_void, Tail...> { }; + + typedef + typename trim_void< + vector<> + , typename detail::as_fusion_element::type... + >::type + type; }; } template - BOOST_FUSION_GPU_ENABLED - inline vector::type...> + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline typename result_of::make_vector::type make_vector(T const&... arg) { - return vector::type...>(arg...); + return typename result_of::make_vector::type(arg...); } }} diff --git a/include/boost/fusion/container/generation/vector_tie.hpp b/include/boost/fusion/container/generation/vector_tie.hpp index dc820043..5d7cb98b 100644 --- a/include/boost/fusion/container/generation/vector_tie.hpp +++ b/include/boost/fusion/container/generation/vector_tie.hpp @@ -30,7 +30,7 @@ namespace boost { namespace fusion } template - BOOST_FUSION_GPU_ENABLED + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline vector vector_tie(T&... arg) { diff --git a/include/boost/fusion/container/vector/detail/as_vector.hpp b/include/boost/fusion/container/vector/detail/as_vector.hpp index 9fc38156..322f3dd6 100644 --- a/include/boost/fusion/container/vector/detail/as_vector.hpp +++ b/include/boost/fusion/container/vector/detail/as_vector.hpp @@ -20,6 +20,50 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace detail +{ +BOOST_FUSION_BARRIER_BEGIN + + template + struct as_vector_impl; + + template + struct as_vector_impl > + { + template + struct apply + { + typedef vector< + numbered_vector_tag + , typename result_of::value_of< + typename result_of::advance_c::type + >::type... + > type; + }; + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + static typename apply::type + call(Iterator i) + { + typedef typename apply::type result; + return result(*advance_c(i)...); + } + }; + + template + struct as_vector + : as_vector_impl::type> {}; + +BOOST_FUSION_BARRIER_END +}}} #endif #endif diff --git a/include/boost/fusion/container/vector/detail/at_impl.hpp b/include/boost/fusion/container/vector/detail/at_impl.hpp index cb98dd4a..a2900d79 100644 --- a/include/boost/fusion/container/vector/detail/at_impl.hpp +++ b/include/boost/fusion/container/vector/detail/at_impl.hpp @@ -9,9 +9,8 @@ #include #include -#include -#include -#include +#include +#include namespace boost { namespace fusion { @@ -28,7 +27,7 @@ namespace boost { namespace fusion template struct apply { - typedef typename mpl::at::type element; + typedef typename value_at_impl::template apply::type element; typedef typename detail::ref_result::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED @@ -43,7 +42,7 @@ namespace boost { namespace fusion template struct apply { - typedef typename mpl::at::type element; + typedef typename value_at_impl::template apply::type element; typedef typename detail::cref_result::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED diff --git a/include/boost/fusion/container/vector/detail/config.hpp b/include/boost/fusion/container/vector/detail/config.hpp index 380183b4..475fe641 100644 --- a/include/boost/fusion/container/vector/detail/config.hpp +++ b/include/boost/fusion/container/vector/detail/config.hpp @@ -1,5 +1,5 @@ /*============================================================================= - Copyright (c) 2014 Kohei Takahashi + Copyright (c) 2014-2015 Kohei Takahashi Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,10 +8,11 @@ #define FUSION_VECTOR_CONFIG_11052014_1720 #include +#include #include -/* #if (defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \ + || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \ || defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)) \ || (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) # if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) @@ -22,7 +23,13 @@ # define BOOST_FUSION_HAS_VARIADIC_VECTOR # endif #endif -*/ + +// Sometimes, MSVC 12 shows compile error with std::size_t of template parameter. +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) +# if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) +# undef BOOST_FUSION_HAS_VARIADIC_VECTOR +# endif +#endif #endif diff --git a/include/boost/fusion/container/vector/detail/deref_impl.hpp b/include/boost/fusion/container/vector/detail/deref_impl.hpp index 5186aa10..c85bb82b 100644 --- a/include/boost/fusion/container/vector/detail/deref_impl.hpp +++ b/include/boost/fusion/container/vector/detail/deref_impl.hpp @@ -8,8 +8,8 @@ #define FUSION_DEREF_IMPL_05042005_1037 #include -#include #include +#include #include #include @@ -30,9 +30,7 @@ namespace boost { namespace fusion { typedef typename Iterator::vector vector; typedef typename Iterator::index index; - typedef typename mpl::at< - typename vector::types, index>::type - element; + typedef typename value_at_impl::template apply::type element; typedef typename mpl::if_< diff --git a/include/boost/fusion/container/vector/detail/value_at_impl.hpp b/include/boost/fusion/container/vector/detail/value_at_impl.hpp index f71ca848..220807c7 100644 --- a/include/boost/fusion/container/vector/detail/value_at_impl.hpp +++ b/include/boost/fusion/container/vector/detail/value_at_impl.hpp @@ -9,11 +9,60 @@ #include #include +#include /////////////////////////////////////////////////////////////////////////////// // Without variadics, we will use the PP version /////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) # include +#else + +/////////////////////////////////////////////////////////////////////////////// +// C++11 interface +/////////////////////////////////////////////////////////////////////////////// +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + + namespace vector_detail + { + template + struct vector_data; + } + + namespace extension + { + template + struct value_at_impl; + + template <> + struct value_at_impl + { + template + struct apply_impl; + + template + struct apply_impl, 0> + { + typedef H type; + }; + + template + struct apply_impl, N> + : apply_impl, N - 1> + {}; + + template + struct apply : apply_impl + {}; + }; + } +}} #endif +#endif diff --git a/include/boost/fusion/container/vector/detail/value_of_impl.hpp b/include/boost/fusion/container/vector/detail/value_of_impl.hpp index 2a8acf91..d67ab3fc 100644 --- a/include/boost/fusion/container/vector/detail/value_of_impl.hpp +++ b/include/boost/fusion/container/vector/detail/value_of_impl.hpp @@ -8,7 +8,7 @@ #define FUSION_VALUE_OF_IMPL_05052005_1128 #include -#include +#include namespace boost { namespace fusion { @@ -27,9 +27,7 @@ namespace boost { namespace fusion { typedef typename Iterator::vector vector; typedef typename Iterator::index index; - typedef typename mpl::at< - typename vector::types, index>::type - type; + typedef typename value_at_impl::template apply::type type; }; }; } diff --git a/include/boost/fusion/container/vector/vector.hpp b/include/boost/fusion/container/vector/vector.hpp index db3a046e..3f9d52ec 100644 --- a/include/boost/fusion/container/vector/vector.hpp +++ b/include/boost/fusion/container/vector/vector.hpp @@ -1,5 +1,5 @@ /*============================================================================= - Copyright (c) 2014 Kohei Takahashi + Copyright (c) 2014-2015 Kohei Takahashi Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,6 +7,7 @@ #ifndef FUSION_VECTOR_11052014_1625 #define FUSION_VECTOR_11052014_1625 +#include #include #include #include @@ -21,6 +22,334 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct vector_tag; + struct random_access_traversal_tag; + + namespace vector_detail + { + struct each_elem {}; + struct copy_or_move {}; + template struct from_sequence {}; + + template + struct make_indices_from_seq + : detail::make_index_sequence< + fusion::result_of::size::type>::value + > + {}; + + template + struct pure : remove_cv::type> {}; + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline each_elem + dispatch( T const&... ) BOOST_NOEXCEPT { return each_elem(); } + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline copy_or_move + dispatch( This const& ) BOOST_NOEXCEPT { return copy_or_move(); } + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline from_sequence< + typename lazy_enable_if_c< + (traits::is_sequence::value && + !is_same::value) + , make_indices_from_seq + >::type + > + dispatch( Sequence const& ) BOOST_NOEXCEPT + { return from_sequence::type>(); } + + + // forward_at_c allows to access Nth element even if ForwardSequence + // since fusion::at_c requires RandomAccessSequence. + namespace result_of + { + template + struct forward_at_c + : fusion::result_of::deref< + typename fusion::result_of::advance_c< + typename fusion::result_of::begin< + typename remove_reference::type + >::type + , N + >::type + > + {}; + } + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline typename result_of::forward_at_c::type + forward_at_c(Sequence&& seq) + { + typedef typename + result_of::forward_at_c::type + result; + return std::forward(*advance_c(begin(seq))); + } + + // Object proxy since preserve object order + template + struct store + { + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + store() + : elem() // value-initialized explicitly + {} + + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + store(store const& rhs) + : elem(rhs.get()) + {} + + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + store& + operator=(store const& rhs) + { + elem = rhs.get(); + return *this; + } + + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + store(store&& rhs) + : elem(static_cast(rhs.get())) + {} + + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + store& + operator=(store&& rhs) + { + elem = static_cast(rhs.get()); + return *this; + } + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + store(U&& rhs + , typename disable_if::type, store> >::type* = 0) + : elem(std::forward(rhs)) + {} + + template + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + typename disable_if::type, store>, store&>::type + operator=(U&& rhs) + { + elem = std::forward(rhs); + return *this; + } + + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + T & get() { return elem; } + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + T const& get() const { return elem; } + + T elem; + }; + + template + struct vector_data; + + template + struct vector_data, T...> + : store... + , sequence_base, T...> > + { + typedef vector_tag fusion_tag; + typedef fusion_sequence_tag tag; // this gets picked up by MPL + typedef mpl::false_ is_view; + typedef random_access_traversal_tag category; + typedef mpl::int_ size; + typedef vector type_sequence; + + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + vector_data() + {} + + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + vector_data(copy_or_move, vector_data const& rhs) + : store(static_cast const&>(rhs))... + {} + + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + vector_data(copy_or_move, vector_data&& rhs) + : store(std::forward >(rhs))... + {} + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + explicit + vector_data(from_sequence >, Sequence&& rhs) + : store(forward_at_c(rhs))... + {} + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + explicit + vector_data(each_elem, U&&... var) + : store(std::forward(var))... + {} + + template + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + void + assign(Sequence&&, detail::index_sequence<>) {} + + template + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + void + assign(Sequence&& seq, detail::index_sequence) + { + at_impl(mpl::int_()) = vector_detail::forward_at_c(seq); + assign(std::forward(seq), detail::index_sequence()); + } + + typedef extension::value_at_impl value_at_impl; + + template + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + typename value_at_impl::template apply::type& + at_impl(J) + { + typedef typename value_at_impl::template apply::type U; + typedef store S; + return static_cast(this)->get(); + } + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + typename value_at_impl::template apply::type const& + at_impl(J) const + { + typedef typename value_at_impl::template apply::type U; + typedef store S; + return static_cast(this)->get(); + } + }; + + // Internal use only specialization for implementing vectorN. + // Simple aliasing (like a using vectorN = vector) will cause specialization confliction + // like following. + // + // template struct SomeClass; + // template struct SomeClass> { ... }; + // template + // struct SomeClass> // Error, since vector and vector1 are exact same type. + // { ... }; + // + // Introducing `numbered_vector_tag` will resolve such specialization error. + // + // template + // struct SomeClass> { ... }; + // template + // struct SomeClass> // OK + // { ... }; + // + // // Same meaning as above specialization. + // template + // struct SomeClass, T>> + // { ... }; + template + struct vector_data, numbered_vector_tag, T...> + : vector_data::type, T...> + { + typedef vector_data::type, T...> base; + + BOOST_STATIC_ASSERT((base::size::value == N)); + + template + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + vector_data(U&&... var) + : base(std::forward(var)...) + {} + }; + + template + struct construct_vector_; + + template + struct construct_vector_ > + { + typedef vector_data< + typename detail::make_index_sequence::type + , T... + > type; + }; + + template + struct construct_vector_, void_, Tail...> + : construct_vector_ > {}; + + template + struct construct_vector_, Head, Tail...> + : construct_vector_, Tail...> {}; + + template + struct construct_vector : construct_vector_, T...> {}; + } // namespace boost::fusion::vector_detail + + // This class provides backward compatibility: vector. + template + struct vector + : vector_detail::construct_vector::type + { + typedef typename vector_detail::construct_vector::type base; + + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + 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 + // 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(u...), std::forward(u)...) + {} + + template + BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED + vector& + operator=(Sequence&& rhs) + { + typedef typename + vector_detail::make_indices_from_seq::type + indices; + base::assign(std::forward(rhs), indices()); + return *this; + } + }; +}} #endif #endif diff --git a/include/boost/fusion/container/vector/vector10.hpp b/include/boost/fusion/container/vector/vector10.hpp index 86c58cc6..65722fe6 100644 --- a/include/boost/fusion/container/vector/vector10.hpp +++ b/include/boost/fusion/container/vector/vector10.hpp @@ -21,6 +21,8 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include #endif #endif diff --git a/include/boost/fusion/container/vector/vector20.hpp b/include/boost/fusion/container/vector/vector20.hpp index f0b4c47a..c36e50c7 100644 --- a/include/boost/fusion/container/vector/vector20.hpp +++ b/include/boost/fusion/container/vector/vector20.hpp @@ -21,6 +21,8 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include #endif #endif diff --git a/include/boost/fusion/container/vector/vector30.hpp b/include/boost/fusion/container/vector/vector30.hpp index 5ef2b90e..e9f891f2 100644 --- a/include/boost/fusion/container/vector/vector30.hpp +++ b/include/boost/fusion/container/vector/vector30.hpp @@ -21,6 +21,8 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include #endif #endif diff --git a/include/boost/fusion/container/vector/vector40.hpp b/include/boost/fusion/container/vector/vector40.hpp index 3625879b..4b753a08 100644 --- a/include/boost/fusion/container/vector/vector40.hpp +++ b/include/boost/fusion/container/vector/vector40.hpp @@ -21,6 +21,8 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include #endif #endif diff --git a/include/boost/fusion/container/vector/vector50.hpp b/include/boost/fusion/container/vector/vector50.hpp index 95d5d275..5d8d3563 100644 --- a/include/boost/fusion/container/vector/vector50.hpp +++ b/include/boost/fusion/container/vector/vector50.hpp @@ -21,6 +21,8 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include #endif #endif diff --git a/include/boost/fusion/container/vector/vector_fwd.hpp b/include/boost/fusion/container/vector/vector_fwd.hpp index 5b4fc749..641b19ef 100644 --- a/include/boost/fusion/container/vector/vector_fwd.hpp +++ b/include/boost/fusion/container/vector/vector_fwd.hpp @@ -21,10 +21,25 @@ /////////////////////////////////////////////////////////////////////////////// // C++11 interface /////////////////////////////////////////////////////////////////////////////// +#include +#include +#include + namespace boost { namespace fusion { template struct vector; + + template + struct numbered_vector_tag; + +#define FUSION_VECTOR_N_ALIASES(z, N, d) \ + template \ + using BOOST_PP_CAT(vector, N) = vector, T...>; + + BOOST_PP_REPEAT(51, FUSION_VECTOR_N_ALIASES, ~) + +#undef FUSION_VECTOR_N_ALIASES }} #endif