added as_map

fixed bug: wrong iterator category for map_iterator

[SVN r82721]
This commit is contained in:
Joel de Guzman
2013-02-04 09:52:52 +00:00
parent 764a31e9f5
commit 85119dbd21
7 changed files with 156 additions and 25 deletions

View File

@ -41,7 +41,7 @@ namespace boost { namespace fusion
inline typename result_of::as_deque<Sequence>::type inline typename result_of::as_deque<Sequence>::type
as_deque(Sequence& seq) as_deque(Sequence& seq)
{ {
typedef typename result_of::as_deque<Sequence>::gen gen; typedef result_of::as_deque<Sequence> gen;
return gen::call(fusion::begin(seq), fusion::end(seq)); return gen::call(fusion::begin(seq), fusion::end(seq));
} }
@ -49,7 +49,7 @@ namespace boost { namespace fusion
inline typename result_of::as_deque<Sequence const>::type inline typename result_of::as_deque<Sequence const>::type
as_deque(Sequence const& seq) as_deque(Sequence const& seq)
{ {
typedef typename result_of::as_deque<Sequence const>::gen gen; typedef result_of::as_deque<Sequence const> gen;
return gen::call(fusion::begin(seq), fusion::end(seq)); return gen::call(fusion::begin(seq), fusion::end(seq));
} }
}} }}

View File

@ -7,6 +7,51 @@
#if !defined(FUSION_CONVERT_MAIN_09232005_1340) #if !defined(FUSION_CONVERT_MAIN_09232005_1340)
#define FUSION_CONVERT_MAIN_09232005_1340 #define FUSION_CONVERT_MAIN_09232005_1340
#include <boost/fusion/container/map/detail/cpp03/convert.hpp> #include <boost/fusion/container/map/map.hpp>
///////////////////////////////////////////////////////////////////////////////
// Without variadics, we will use the PP version
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_FUSION_HAS_VARIADIC_MAP)
# include <boost/fusion/container/map/detail/cpp03/convert.hpp>
#else
///////////////////////////////////////////////////////////////////////////////
// C++11 variadic implementation
///////////////////////////////////////////////////////////////////////////////
#include <boost/fusion/container/map/detail/build_map.hpp>
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence>
struct as_map :
detail::build_map<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type
>
{
};
}
template <typename Sequence>
inline typename result_of::as_map<Sequence>::type
as_map(Sequence& seq)
{
typedef result_of::as_map<Sequence> gen;
return gen::call(fusion::begin(seq), fusion::end(seq));
}
template <typename Sequence>
inline typename result_of::as_map<Sequence const>::type
as_map(Sequence const& seq)
{
typedef result_of::as_map<Sequence const> gen;
return gen::call(fusion::begin(seq), fusion::end(seq));
}
}}
#endif #endif
#endif

View File

@ -24,28 +24,30 @@ namespace boost { namespace fusion
template <typename Sequence, typename N> template <typename Sequence, typename N>
struct apply struct apply
{ {
typedef mpl::int_<N::value> index;
typedef typedef
decltype(std::declval<Sequence>().get(N())) decltype(std::declval<Sequence>().get(index()))
type; type;
static type static type
call(Sequence& m) call(Sequence& m)
{ {
return m.get(N()); return m.get(index());
} }
}; };
template <typename Sequence, typename N> template <typename Sequence, typename N>
struct apply<Sequence const, N> struct apply<Sequence const, N>
{ {
typedef mpl::int_<N::value> index;
typedef typedef
decltype(std::declval<Sequence const>().get(N())) decltype(std::declval<Sequence const>().get(index()))
type; type;
static type static type
call(Sequence const& m) call(Sequence const& m)
{ {
return m.get(N()); return m.get(index());
} }
}; };
}; };

View File

@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2005-2013 Joel de Guzman
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_BUILD_MAP_02042013_1448)
#define BOOST_FUSION_BUILD_MAP_02042013_1448
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/value_of.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/container/map/map.hpp>
#include <boost/fusion/algorithm/transformation/push_front.hpp>
namespace boost { namespace fusion { namespace detail
{
template <typename First, typename Last
, bool is_empty = result_of::equal_to<First, Last>::value>
struct build_map;
template <typename First, typename Last>
struct build_map<First, Last, true>
{
typedef map<> type;
static type
call(First const&, Last const&)
{
return type();
}
};
template <typename T, typename Rest>
struct push_front_map;
template <typename T, typename ...Rest>
struct push_front_map<T, map<Rest...>>
{
typedef map<T, Rest...> type;
static type
call(T const& first, map<Rest...> const& rest)
{
return type(push_front(rest, first));
}
};
template <typename First, typename Last>
struct build_map<First, Last, false>
{
typedef
build_map<typename result_of::next<First>::type, Last>
next_build_map;
typedef push_front_map<
typename result_of::value_of<First>::type
, typename next_build_map::type>
push_front;
typedef typename push_front::type type;
static type
call(First const& f, Last const& l)
{
typename result_of::value_of<First>::type v = *f;
return push_front::call(
v, next_build_map::call(fusion::next(f), l));
}
};
}}}
#endif

View File

@ -0,0 +1,19 @@
/*=============================================================================
Copyright (c) 2005-2013 Joel de Guzman
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_MAP_INDEX_02032013_2233)
#define BOOST_FUSION_MAP_INDEX_02032013_2233
namespace boost { namespace fusion { namespace detail
{
template <int N>
struct map_index
{
static int const value = N;
};
}}}
#endif

View File

@ -58,6 +58,12 @@ namespace boost { namespace fusion
: base_type(begin(seq), detail::map_impl_from_iterator()) : base_type(begin(seq), detail::map_impl_from_iterator())
{} {}
template <typename Sequence>
map(Sequence& seq
, typename enable_if<traits::is_sequence<Sequence>>::type* /*dummy*/ = 0)
: base_type(begin(seq), detail::map_impl_from_iterator())
{}
template <typename First, typename ...T_> template <typename First, typename ...T_>
map(First const& first, T_ const&... rest) map(First const& first, T_ const&... rest)
: base_type(first, rest...) : base_type(first, rest...)

View File

@ -20,7 +20,7 @@ namespace boost { namespace fusion
struct map_iterator struct map_iterator
: iterator_facade< : iterator_facade<
map_iterator<Seq, Pos> map_iterator<Seq, Pos>
, random_access_traversal_tag> , typename Seq::category>
{ {
typedef Seq sequence; typedef Seq sequence;
typedef mpl::int_<Pos> index; typedef mpl::int_<Pos> index;
@ -91,22 +91,6 @@ namespace boost { namespace fusion
} }
}; };
//~ template<typename Iterator>
//~ struct deref_data
//~ {
//~ typedef typename Iterator::sequence sequence;
//~ typedef typename Iterator::index index;
//~ typedef
//~ decltype(std::declval<sequence>().get(index()))
//~ type;
//~ static type
//~ call(Iterator const& it)
//~ {
//~ return it.seq_.get(typename Iterator::index());
//~ }
//~ };
template <typename Iterator, typename N> template <typename Iterator, typename N>
struct advance struct advance
{ {
@ -132,7 +116,7 @@ namespace boost { namespace fusion
{}; {};
template <typename I1, typename I2> template <typename I1, typename I2>
struct distance : mpl::minus<typename I2::index, typename I1::index> struct distance
{ {
typedef typename typedef typename
mpl::minus< mpl::minus<