Implement C++11 variadic templates based fusion::set

This commit is contained in:
Kohei Takahashi
2014-11-29 23:04:29 +09:00
parent 7739e4026d
commit b4133761e8
4 changed files with 188 additions and 2 deletions

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)
@ -13,7 +13,55 @@
///////////////////////////////////////////////////////////////////////////////
// Without variadics, we will use the PP version
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_FUSION_HAS_VARIADIC_SET)
# include <boost/fusion/container/set/detail/cpp03/as_set.hpp>
#else
///////////////////////////////////////////////////////////////////////////////
// C++11 interface
///////////////////////////////////////////////////////////////////////////////
#include <boost/fusion/support/detail/index_sequence.hpp>
#include <boost/fusion/container/set/set.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 <int size
, typename = typename detail::make_index_sequence<size>::type>
struct as_set;
template <int size, std::size_t ...Indices>
struct as_set<size, detail::index_sequence<Indices...> >
{
template <typename I>
struct apply
{
typedef set<
typename result_of::value_of<
typename result_of::advance_c<I, Indices>::type
>::type...
> type;
};
template <typename Iterator>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static typename apply<Iterator>::type
call(Iterator const& i)
{
typedef apply<Iterator> gen;
typedef typename gen::type result;
return result(*advance_c<Indices>(i)...);
}
};
BOOST_FUSION_BARRIER_END
}}}
#endif
#endif

View File

@ -29,7 +29,7 @@ namespace boost { namespace fusion
template <typename Sequence>
struct apply
{
typedef typename detail::as_set<result_of::size<Sequence>::value> gen;
typedef detail::as_set<result_of::size<Sequence>::value> gen;
typedef typename gen::
template apply<typename result_of::begin<Sequence>::type>::type
type;

View File

@ -13,8 +13,119 @@
///////////////////////////////////////////////////////////////////////////////
// Without variadics, we will use the PP version
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_FUSION_HAS_VARIADIC_SET)
# include <boost/fusion/container/set/detail/cpp03/set.hpp>
#else
///////////////////////////////////////////////////////////////////////////////
// C++11 interface
///////////////////////////////////////////////////////////////////////////////
#include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/container/set/detail/begin_impl.hpp>
#include <boost/fusion/container/set/detail/end_impl.hpp>
#include <boost/fusion/container/set/detail/value_of_impl.hpp>
#include <boost/fusion/container/set/detail/deref_data_impl.hpp>
#include <boost/fusion/container/set/detail/deref_impl.hpp>
#include <boost/fusion/container/set/detail/key_of_impl.hpp>
#include <boost/fusion/container/set/detail/value_of_data_impl.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace fusion
{
struct fusion_sequence_tag;
template <>
struct set<> : sequence_base<set<> >
{
struct category : forward_traversal_tag, associative_tag {};
typedef set_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef mpl::false_ is_view;
typedef vector<> storage_type;
typedef storage_type::size size;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
set()
: data() {}
template <typename Sequence>
BOOST_FUSION_GPU_ENABLED
set(Sequence const& rhs)
: data(rhs) {}
template <typename T>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
set&
operator=(T const& rhs)
{
data = rhs;
return *this;
}
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
storage_type& get_data() { return data; }
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
storage_type const& get_data() const { return data; }
private:
storage_type data;
};
template <typename ...T>
struct set : sequence_base<set<T...> >
{
struct category : forward_traversal_tag, associative_tag {};
typedef set_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef mpl::false_ is_view;
typedef vector<T...> storage_type;
typedef typename storage_type::size size;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
set()
: data() {}
template <typename Sequence>
BOOST_FUSION_GPU_ENABLED
set(Sequence const& rhs)
: data(rhs) {}
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
explicit
set(typename detail::call_param<T>::type ...args)
: data(args...) {}
template <typename U>
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
set&
operator=(U const& rhs)
{
data = rhs;
return *this;
}
BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
storage_type& get_data() { return data; }
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
storage_type const& get_data() const { return data; }
private:
storage_type data;
};
}}
#endif
#endif

View File

@ -9,11 +9,38 @@
#include <boost/config.hpp>
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/vector/detail/config.hpp>
#if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) \
|| (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
# if defined(BOOST_FUSION_HAS_VARIADIC_SET)
# undef BOOST_FUSION_HAS_VARIADIC_SET
# endif
#else
# if !defined(BOOST_FUSION_HAS_VARIADIC_SET)
# define BOOST_FUSION_HAS_VARIADIC_SET
# endif
#endif
///////////////////////////////////////////////////////////////////////////////
// With no variadics, we will use the C++03 version
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_FUSION_HAS_VARIADIC_SET)
# include <boost/fusion/container/set/detail/cpp03/set_fwd.hpp>
#else
///////////////////////////////////////////////////////////////////////////////
// C++11 interface
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace fusion
{
struct set_tag;
struct set_iterator_tag;
template <typename ...T>
struct set;
}}
#endif
#endif