Implement variadic templates based fusion::vector.

Thanks to Lee Clagett.
This commit is contained in:
Kohei Takahashi
2015-06-28 01:13:32 +09:00
parent c77f84749f
commit 969b475462
15 changed files with 493 additions and 22 deletions

View File

@@ -20,6 +20,50 @@
///////////////////////////////////////////////////////////////////////////////
// C++11 interface
///////////////////////////////////////////////////////////////////////////////
#include <boost/fusion/support/detail/index_sequence.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/iterator/value_of.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/advance.hpp>
#include <cstddef>
namespace boost { namespace fusion { namespace detail
{
BOOST_FUSION_BARRIER_BEGIN
template <typename Indices>
struct as_vector_impl;
template <std::size_t ...Indices>
struct as_vector_impl<index_sequence<Indices...> >
{
template <typename Iterator>
struct apply
{
typedef vector<
numbered_vector_tag<sizeof...(Indices)>
, typename result_of::value_of<
typename result_of::advance_c<Iterator, Indices>::type
>::type...
> type;
};
template <typename Iterator>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static typename apply<Iterator>::type
call(Iterator i)
{
typedef typename apply<Iterator>::type result;
return result(*advance_c<Indices>(i)...);
}
};
template <int size>
struct as_vector
: as_vector_impl<typename make_index_sequence<size>::type> {};
BOOST_FUSION_BARRIER_END
}}}
#endif
#endif

View File

@@ -9,9 +9,8 @@
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/support/detail/access.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
#include <boost/static_assert.hpp>
namespace boost { namespace fusion
{
@@ -28,7 +27,7 @@ namespace boost { namespace fusion
template <typename Sequence, typename N>
struct apply
{
typedef typename mpl::at<typename Sequence::types, N>::type element;
typedef typename value_at_impl<vector_tag>::template apply<Sequence, N>::type element;
typedef typename detail::ref_result<element>::type type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
@@ -43,7 +42,7 @@ namespace boost { namespace fusion
template <typename Sequence, typename N>
struct apply <Sequence const, N>
{
typedef typename mpl::at<typename Sequence::types, N>::type element;
typedef typename value_at_impl<vector_tag>::template apply<Sequence, N>::type element;
typedef typename detail::cref_result<element>::type type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED

View File

@@ -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 <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/fusion/support/config.hpp>
/*
#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

View File

@@ -8,8 +8,8 @@
#define FUSION_DEREF_IMPL_05042005_1037
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/at.hpp>
#include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
@@ -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<vector_tag>::template apply<vector, index>::type element;
typedef typename
mpl::if_<

View File

@@ -9,11 +9,60 @@
#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/vector/detail/config.hpp>
///////////////////////////////////////////////////////////////////////////////
// Without variadics, we will use the PP version
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
# include <boost/fusion/container/vector/detail/cpp03/value_at_impl.hpp>
#else
///////////////////////////////////////////////////////////////////////////////
// C++11 interface
///////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <boost/fusion/container/vector/vector_fwd.hpp>
namespace boost { namespace fusion
{
struct vector_tag;
namespace vector_detail
{
template <typename I, typename ...T>
struct vector_data;
}
namespace extension
{
template <typename Tag>
struct value_at_impl;
template <>
struct value_at_impl<vector_tag>
{
template <typename V, std::size_t N>
struct apply_impl;
template <typename H, typename ...T>
struct apply_impl<vector<H, T...>, 0>
{
typedef H type;
};
template <typename H, typename ...T, std::size_t N>
struct apply_impl<vector<H, T...>, N>
: apply_impl<vector<T...>, N - 1>
{};
template <typename Sequence, typename N>
struct apply : apply_impl<typename Sequence::type_sequence, N::value>
{};
};
}
}}
#endif
#endif

View File

@@ -8,7 +8,7 @@
#define FUSION_VALUE_OF_IMPL_05052005_1128
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/at.hpp>
#include <boost/fusion/container/vector/detail/value_at_impl.hpp>
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<vector_tag>::template apply<vector, index>::type type;
};
};
}