Ticket #9294: flatten.patch

File flatten.patch, 39.7 KB (added by Jamboree <tongari95@…>, 9 years ago)
  • boost/fusion/algorithm/transformation.hpp

     
    2525#include <boost/fusion/algorithm/transformation/replace_if.hpp>
    2626#include <boost/fusion/algorithm/transformation/reverse.hpp>
    2727#include <boost/fusion/algorithm/transformation/transform.hpp>
    28 #include <boost/fusion/algorithm/transformation/zip.hpp>
     28#include <boost/fusion/algorithm/transformation/zip.hpp>
     29#include <boost/fusion/algorithm/transformation/flatten.hpp>
    2930
    3031#endif
  • boost/fusion/algorithm/transformation/flatten.hpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#ifndef BOOST_FUSION_ALGORITHM_FLATTEN_HPP_INCLUDED
     8#define BOOST_FUSION_ALGORITHM_FLATTEN_HPP_INCLUDED
     9
     10
     11#include <boost/fusion/view/flatten_view.hpp>
     12#include <boost/fusion/support/is_sequence.hpp>
     13#include <boost/utility/enable_if.hpp>
     14
     15
     16namespace boost { namespace fusion { namespace result_of
     17{
     18    template<typename Sequence>
     19    struct flatten
     20    {
     21        typedef flatten_view<Sequence> type;
     22    };
     23}}}
     24
     25namespace boost { namespace fusion
     26{
     27    template <typename Sequence>
     28    inline typename result_of::flatten<Sequence>::type
     29    flatten(Sequence& view)
     30    {
     31        return flatten_view<Sequence>(view);
     32    }
     33   
     34    template <typename Sequence>
     35    inline typename result_of::flatten<Sequence const>::type
     36    flatten(Sequence const& view)
     37    {
     38        return flatten_view<Sequence const>(view);
     39    }
     40}}
     41
     42
     43#endif
     44
  • boost/fusion/support.hpp

     
    2020#include <boost/fusion/support/deduce_sequence.hpp>
    2121#include <boost/fusion/support/unused.hpp>
    2222#include <boost/fusion/support/as_const.hpp>
     23#include <boost/fusion/support/ref.hpp>
    2324
    2425#endif
  • boost/fusion/support/ref.hpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#ifndef BOOST_FUSION_SUPPORT_REF_HPP_INCLUDED
     8#define BOOST_FUSION_SUPPORT_REF_HPP_INCLUDED
     9
     10
     11#include <boost/ref.hpp>
     12#include <boost/mpl/bool.hpp>
     13#include <boost/fusion/support/tag_of_fwd.hpp>
     14
     15
     16namespace boost { namespace fusion
     17{
     18    struct reference_wrapper_tag;
     19}}
     20
     21namespace boost { namespace fusion { namespace traits
     22{
     23    template<typename T>
     24    struct tag_of<reference_wrapper<T> >
     25    {
     26        typedef reference_wrapper_tag type;
     27    };
     28}}}
     29
     30namespace boost { namespace fusion { namespace extension
     31{
     32    template<typename Tag>
     33    struct category_of_impl;
     34   
     35    template<typename Tag>
     36    struct begin_impl;
     37
     38    template<typename Tag>
     39    struct end_impl;
     40
     41    template<typename Tag>
     42    struct at_impl;
     43
     44    template<typename Tag>
     45    struct value_at_impl;
     46
     47    template<typename Tag>
     48    struct size_impl;
     49
     50    template<typename Tag>
     51    struct at_key_impl;
     52
     53    template<typename Tag>
     54    struct value_at_key_impl;
     55
     56    template<typename Tag>
     57    struct has_key_impl;
     58
     59    template<typename Tag>
     60    struct is_sequence_impl;
     61
     62    template<typename Tag>
     63    struct is_view_impl;
     64
     65    template<typename Tag>
     66    struct is_segmented_impl;
     67   
     68    template<>
     69    struct category_of_impl<reference_wrapper_tag>
     70    {
     71        template<typename Sequence>
     72        struct apply
     73          : category_of_impl<typename traits::tag_of<typename Sequence::type>::type>::
     74                template apply<typename Sequence::type>
     75        {};
     76    };
     77   
     78    template<>
     79    struct begin_impl<reference_wrapper_tag>
     80    {
     81        template<typename Sequence>
     82        struct apply
     83          : begin_impl<typename traits::tag_of<typename Sequence::type>::type>::
     84                template apply<typename Sequence::type>
     85        {};
     86    };
     87   
     88    template<>
     89    struct end_impl<reference_wrapper_tag>
     90    {
     91        template<typename Sequence>
     92        struct apply
     93          : end_impl<typename traits::tag_of<typename Sequence::type>::type>::
     94                template apply<typename Sequence::type>
     95        {};
     96    };
     97
     98    template<>
     99    struct at_impl<reference_wrapper_tag>
     100    {
     101        template<typename Sequence, typename N>
     102        struct apply
     103          : at_impl<typename traits::tag_of<typename Sequence::type>::type>::
     104                template apply<typename Sequence::type, N>
     105        {};
     106    };
     107
     108    template<>
     109    struct value_at_impl<reference_wrapper_tag>
     110    {
     111        template<typename Sequence, typename N>
     112        struct apply
     113          : value_at_impl<typename traits::tag_of<typename Sequence::type>::type>::
     114                template apply<typename Sequence::type, N>
     115        {};
     116    };
     117
     118    template<>
     119    struct size_impl<reference_wrapper_tag>
     120    {
     121        template<typename Sequence>
     122        struct apply
     123          : size_impl<typename traits::tag_of<typename Sequence::type>::type>::
     124                template apply<typename Sequence::type>
     125        {};
     126    };
     127
     128    template<>
     129    struct value_at_key_impl<reference_wrapper_tag>
     130    {
     131        template<typename Sequence, typename Key>
     132        struct apply
     133          : value_at_key_impl<typename traits::tag_of<typename Sequence::type>::type>::
     134                template apply<typename Sequence::type, Key>
     135        {};
     136    };
     137
     138    template<>
     139    struct at_key_impl<reference_wrapper_tag>
     140    {
     141        template<typename Sequence, typename Key>
     142        struct apply
     143          : at_key_impl<typename traits::tag_of<typename Sequence::type>::type>::
     144                template apply<typename Sequence::type, Key>
     145        {};
     146    };
     147
     148    template<>
     149    struct has_key_impl<reference_wrapper_tag>
     150    {
     151        template<typename Sequence, typename Key>
     152        struct apply
     153          : has_key_impl<typename traits::tag_of<typename Sequence::type>::type>::
     154                template apply<typename Sequence::type, Key>
     155        {};
     156    };
     157
     158    template<>
     159    struct is_sequence_impl<reference_wrapper_tag>
     160    {
     161        template<typename T>
     162        struct apply
     163          : is_sequence_impl<typename traits::tag_of<typename T::type>::type>::
     164                template apply<typename T::type>
     165        {};
     166    };
     167
     168    template<>
     169    struct is_view_impl<reference_wrapper_tag>
     170      : is_sequence_impl<reference_wrapper_tag>
     171    {};
     172   
     173    template<>
     174    struct is_segmented_impl<reference_wrapper_tag>
     175    {
     176        template<typename T>
     177        struct apply
     178          : is_segmented_impl<typename traits::tag_of<typename T::type>::type>::
     179                template apply<typename T::type>
     180        {};
     181    };
     182}}}
     183
     184
     185#endif
     186
  • boost/fusion/view.hpp

     
    1515#include <boost/fusion/view/reverse_view.hpp>
    1616#include <boost/fusion/view/transform_view.hpp>
    1717#include <boost/fusion/view/zip_view.hpp>
     18#include <boost/fusion/view/flatten_view.hpp>
    1819
    1920#endif
  • boost/fusion/view/flatten_view/flatten_view.hpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#ifndef BOOST_FUSION_FLATTEN_VIEW_HPP_INCLUDED
     8#define BOOST_FUSION_FLATTEN_VIEW_HPP_INCLUDED
     9
     10
     11#include <boost/mpl/bool.hpp>
     12#include <boost/mpl/single_view.hpp>
     13#include <boost/fusion/support/detail/access.hpp>
     14#include <boost/fusion/support/is_view.hpp>
     15#include <boost/fusion/support/category_of.hpp>
     16#include <boost/fusion/support/sequence_base.hpp>
     17#include <boost/fusion/sequence/intrinsic/begin.hpp>
     18#include <boost/fusion/sequence/intrinsic/end.hpp>
     19#include <boost/fusion/view/flatten_view/flatten_view_iterator.hpp>
     20
     21
     22namespace boost { namespace fusion
     23{
     24    struct forward_traversal_tag;
     25    struct flatten_view_tag;
     26   
     27    template <typename Sequence>
     28    struct flatten_view
     29      : sequence_base<flatten_view<Sequence> >
     30    {
     31        typedef flatten_view_tag fusion_tag;
     32        typedef fusion_sequence_tag tag; // this gets picked up by MPL
     33        typedef mpl::true_ is_view;
     34        typedef forward_traversal_tag category;
     35       
     36        typedef Sequence sequence_type;
     37        typedef typename result_of::begin<Sequence>::type first_type;
     38        typedef typename result_of::end<Sequence>::type last_type;
     39       
     40        explicit flatten_view(Sequence& seq)
     41          : seq(seq)
     42        {}
     43       
     44        first_type first() const { return fusion::begin(seq); }
     45        last_type last() const { return fusion::end(seq); }
     46       
     47        typename mpl::if_<traits::is_view<Sequence>, Sequence, Sequence&>::type seq;
     48    };
     49}}
     50
     51namespace boost { namespace fusion { namespace extension
     52{
     53    template<>
     54    struct begin_impl<flatten_view_tag>
     55    {
     56        template<typename Sequence>
     57        struct apply
     58        {
     59            typedef typename Sequence::first_type first_type;
     60           
     61            typedef typename
     62                    result_of::begin<
     63                        mpl::single_view<
     64                            typename Sequence::sequence_type> >::type
     65            root_iterator;
     66           
     67            typedef
     68                detail::seek_descent<root_iterator, first_type>
     69            seek_descent;
     70           
     71            typedef typename seek_descent::type type;
     72
     73            static inline
     74            type call(Sequence& seq)
     75            {
     76                return seek_descent::apply(root_iterator(), seq.first());
     77            }
     78        };
     79    };
     80   
     81    template<>
     82    struct end_impl<flatten_view_tag>
     83    {
     84        template<typename Sequence>
     85        struct apply
     86        {
     87            typedef typename Sequence::last_type last_type;
     88           
     89            typedef typename
     90                    result_of::end<
     91                        mpl::single_view<
     92                            typename Sequence::sequence_type> >::type
     93            type;
     94
     95            static inline
     96            type call(Sequence&)
     97            {
     98                return type();
     99            }
     100        };
     101    };
     102
     103    template<>
     104    struct size_impl<flatten_view_tag>
     105    {
     106        template <typename Sequence>
     107        struct apply
     108          : result_of::distance
     109            <
     110                typename result_of::begin<Sequence>::type
     111              , typename result_of::end<Sequence>::type
     112            >
     113        {};
     114    };
     115
     116    template<>
     117    struct empty_impl<flatten_view_tag>
     118    {
     119        template <typename Sequence>
     120        struct apply
     121          : result_of::empty<typename Sequence::sequence_type>
     122        {};
     123    };
     124}}}
     125
     126
     127#endif
  • boost/fusion/view/flatten_view/flatten_view_iterator.hpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#ifndef BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
     8#define BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
     9
     10
     11#include <boost/mpl/bool.hpp>
     12#include <boost/mpl/eval_if.hpp>
     13#include <boost/type_traits/remove_reference.hpp>
     14#include <boost/fusion/container/list/cons.hpp>
     15#include <boost/fusion/support/unused.hpp>
     16#include <boost/fusion/include/equal_to.hpp>
     17#include <boost/fusion/iterator/next.hpp>
     18#include <boost/fusion/iterator/deref.hpp>
     19#include <boost/fusion/iterator/value_of.hpp>
     20
     21
     22namespace boost { namespace fusion
     23{
     24    struct forward_traversal_tag;
     25    struct flatten_view_iterator_tag;
     26   
     27    template<class First, class Base>
     28    struct flatten_view_iterator
     29      : iterator_base<flatten_view_iterator<First, Base> >
     30    {
     31        typedef flatten_view_iterator_tag fusion_tag;
     32        typedef forward_traversal_tag category;
     33       
     34        typedef convert_iterator<First> first_converter;
     35        typedef typename first_converter::type first_type;
     36        typedef Base base_type;
     37       
     38        flatten_view_iterator(First const& first, Base const& base)
     39          : first(first), base(base)
     40        {}
     41       
     42        first_type first;
     43        base_type base;
     44    };
     45}}
     46
     47namespace boost { namespace fusion { namespace detail
     48{
     49    template<class Iterator, class = void>
     50    struct make_descent_cons
     51    {
     52        typedef cons<Iterator> type;
     53       
     54        static inline type apply(Iterator const& it)
     55        {
     56            return type(it);
     57        }
     58    };
     59   
     60    template<class Iterator>
     61    struct make_descent_cons<Iterator,
     62        typename enable_if<traits::is_sequence<
     63            typename result_of::value_of<Iterator>::type> >::type>
     64    {
     65        // we use 'value_of' above for convenience, assuming the value won't be reference,
     66        // while we must use the regular 'deref' here for const issues...
     67        typedef typename
     68            remove_reference<typename result_of::deref<Iterator>::type>::type
     69        sub_sequence;
     70       
     71        typedef typename
     72            result_of::begin<sub_sequence>::type
     73        sub_begin;
     74           
     75        typedef cons<Iterator, typename make_descent_cons<sub_begin>::type> type;
     76       
     77        static inline type apply(Iterator const& it)
     78        {
     79            return type(it, make_descent_cons<sub_begin>::apply(
     80                fusion::begin(*it)));
     81        }
     82    };
     83   
     84    template<class Cons, class Base>
     85    struct build_flatten_view_iterator;
     86
     87    template<class Car, class Base>
     88    struct build_flatten_view_iterator<cons<Car>, Base>
     89    {
     90        typedef flatten_view_iterator<Car, Base> type;
     91       
     92        static inline type apply(cons<Car> const& cons, Base const& base)
     93        {
     94            return type(cons.car, base);
     95        }
     96    };
     97   
     98    template<class Car, class Cdr, class Base>
     99    struct build_flatten_view_iterator<cons<Car, Cdr>, Base>
     100    {
     101        typedef flatten_view_iterator<Car, Base> next_base;
     102        typedef build_flatten_view_iterator<Cdr, next_base> next;
     103        typedef typename next::type type;
     104       
     105        static inline type apply(cons<Car, Cdr> const& cons, Base const& base)
     106        {
     107            return next::apply(cons.cdr, next_base(cons.car, base));
     108        }
     109    };
     110   
     111    template<class Base, class Iterator, class = void>
     112    struct seek_descent
     113    {
     114        typedef make_descent_cons<Iterator> make_descent_cons_;
     115        typedef typename make_descent_cons_::type cons_type;
     116        typedef
     117            build_flatten_view_iterator<cons_type, Base>
     118        build_flatten_view_iterator_;
     119        typedef typename build_flatten_view_iterator_::type type;
     120       
     121        static inline type apply(Base const& base, Iterator const& it)
     122        {
     123            return build_flatten_view_iterator_::apply(
     124                make_descent_cons_::apply(it), base);
     125        }
     126    };
     127   
     128    template<class Base, class Iterator>
     129    struct seek_descent<Base, Iterator,
     130        typename enable_if<
     131            result_of::equal_to<Iterator, typename result_of::end<
     132                    typename result_of::value_of<Base>::type>::type> >::type>
     133    {
     134        typedef typename result_of::next<Base>::type type;
     135       
     136        static inline type apply(Base const& base, Iterator const&)
     137        {
     138            return fusion::next(base);
     139        }
     140    };
     141}}}
     142
     143namespace boost { namespace fusion { namespace extension
     144{
     145    template<>
     146    struct next_impl<flatten_view_iterator_tag>
     147    {
     148        template<typename Iterator>
     149        struct apply
     150        {
     151            typedef typename Iterator::first_type first_type;
     152            typedef typename Iterator::base_type base_type;
     153            typedef typename result_of::next<first_type>::type next_type;
     154           
     155            typedef detail::seek_descent<base_type, next_type> seek_descent;
     156            typedef typename seek_descent::type type;
     157
     158            static inline
     159            type call(Iterator const& it)
     160            {
     161                return seek_descent::apply(it.base, fusion::next(it.first));
     162            }
     163        };
     164    };
     165   
     166    template<>
     167    struct deref_impl<flatten_view_iterator_tag>
     168    {
     169        template<typename Iterator>
     170        struct apply
     171        {
     172            typedef typename
     173                result_of::deref<typename Iterator::first_type>::type
     174            type;
     175
     176            static inline
     177            type call(Iterator const& it)
     178            {
     179                return *it.first;
     180            }
     181        };
     182    };
     183   
     184    template<>
     185    struct value_of_impl<flatten_view_iterator_tag>
     186    {
     187        template<typename Iterator>
     188        struct apply
     189        {
     190            typedef typename
     191                result_of::value_of<typename Iterator::first_type>::type
     192            type;
     193        };
     194    };
     195}}}
     196
     197
     198#endif
     199
  • boost/fusion/view/flatten_view.hpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#ifndef BOOST_FUSION_SEQUENCE_FLATTEN_VIEW_HPP_INCLUDED
     8#define BOOST_FUSION_SEQUENCE_FLATTEN_VIEW_HPP_INCLUDED
     9
     10
     11#include <boost/fusion/view/flatten_view/flatten_view.hpp>
     12#include <boost/fusion/view/flatten_view/flatten_view_iterator.hpp>
     13
     14
     15#endif
  • boost/fusion/view/flatten_view/flatten_view.hpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#ifndef BOOST_FUSION_FLATTEN_VIEW_HPP_INCLUDED
     8#define BOOST_FUSION_FLATTEN_VIEW_HPP_INCLUDED
     9
     10
     11#include <boost/mpl/bool.hpp>
     12#include <boost/mpl/single_view.hpp>
     13#include <boost/fusion/support/detail/access.hpp>
     14#include <boost/fusion/support/is_view.hpp>
     15#include <boost/fusion/support/category_of.hpp>
     16#include <boost/fusion/support/sequence_base.hpp>
     17#include <boost/fusion/sequence/intrinsic/begin.hpp>
     18#include <boost/fusion/sequence/intrinsic/end.hpp>
     19#include <boost/fusion/view/flatten_view/flatten_view_iterator.hpp>
     20
     21
     22namespace boost { namespace fusion
     23{
     24    struct forward_traversal_tag;
     25    struct flatten_view_tag;
     26   
     27    template <typename Sequence>
     28    struct flatten_view
     29      : sequence_base<flatten_view<Sequence> >
     30    {
     31        typedef flatten_view_tag fusion_tag;
     32        typedef fusion_sequence_tag tag; // this gets picked up by MPL
     33        typedef mpl::true_ is_view;
     34        typedef forward_traversal_tag category;
     35       
     36        typedef Sequence sequence_type;
     37        typedef typename result_of::begin<Sequence>::type first_type;
     38        typedef typename result_of::end<Sequence>::type last_type;
     39       
     40        explicit flatten_view(Sequence& seq)
     41          : seq(seq)
     42        {}
     43       
     44        first_type first() const { return fusion::begin(seq); }
     45        last_type last() const { return fusion::end(seq); }
     46       
     47        typename mpl::if_<traits::is_view<Sequence>, Sequence, Sequence&>::type seq;
     48    };
     49}}
     50
     51namespace boost { namespace fusion { namespace extension
     52{
     53    template<>
     54    struct begin_impl<flatten_view_tag>
     55    {
     56        template<typename Sequence>
     57        struct apply
     58        {
     59            typedef typename Sequence::first_type first_type;
     60           
     61            typedef typename
     62                    result_of::begin<
     63                        mpl::single_view<
     64                            typename Sequence::sequence_type> >::type
     65            root_iterator;
     66           
     67            typedef
     68                detail::seek_descent<root_iterator, first_type>
     69            seek_descent;
     70           
     71            typedef typename seek_descent::type type;
     72
     73            static inline
     74            type call(Sequence& seq)
     75            {
     76                return seek_descent::apply(root_iterator(), seq.first());
     77            }
     78        };
     79    };
     80   
     81    template<>
     82    struct end_impl<flatten_view_tag>
     83    {
     84        template<typename Sequence>
     85        struct apply
     86        {
     87            typedef typename Sequence::last_type last_type;
     88           
     89            typedef typename
     90                    result_of::end<
     91                        mpl::single_view<
     92                            typename Sequence::sequence_type> >::type
     93            type;
     94
     95            static inline
     96            type call(Sequence&)
     97            {
     98                return type();
     99            }
     100        };
     101    };
     102
     103    template<>
     104    struct size_impl<flatten_view_tag>
     105    {
     106        template <typename Sequence>
     107        struct apply
     108          : result_of::distance
     109            <
     110                typename result_of::begin<Sequence>::type
     111              , typename result_of::end<Sequence>::type
     112            >
     113        {};
     114    };
     115
     116    template<>
     117    struct empty_impl<flatten_view_tag>
     118    {
     119        template <typename Sequence>
     120        struct apply
     121          : result_of::empty<typename Sequence::sequence_type>
     122        {};
     123    };
     124}}}
     125
     126
     127#endif
  • boost/fusion/view/flatten_view/flatten_view_iterator.hpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#ifndef BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
     8#define BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
     9
     10
     11#include <boost/mpl/bool.hpp>
     12#include <boost/mpl/eval_if.hpp>
     13#include <boost/type_traits/remove_reference.hpp>
     14#include <boost/fusion/container/list/cons.hpp>
     15#include <boost/fusion/support/unused.hpp>
     16#include <boost/fusion/include/equal_to.hpp>
     17#include <boost/fusion/iterator/next.hpp>
     18#include <boost/fusion/iterator/deref.hpp>
     19#include <boost/fusion/iterator/value_of.hpp>
     20
     21
     22namespace boost { namespace fusion
     23{
     24    struct forward_traversal_tag;
     25    struct flatten_view_iterator_tag;
     26   
     27    template<class First, class Base>
     28    struct flatten_view_iterator
     29      : iterator_base<flatten_view_iterator<First, Base> >
     30    {
     31        typedef flatten_view_iterator_tag fusion_tag;
     32        typedef forward_traversal_tag category;
     33       
     34        typedef convert_iterator<First> first_converter;
     35        typedef typename first_converter::type first_type;
     36        typedef Base base_type;
     37       
     38        flatten_view_iterator(First const& first, Base const& base)
     39          : first(first), base(base)
     40        {}
     41       
     42        first_type first;
     43        base_type base;
     44    };
     45}}
     46
     47namespace boost { namespace fusion { namespace detail
     48{
     49    template<class Iterator, class = void>
     50    struct make_descent_cons
     51    {
     52        typedef cons<Iterator> type;
     53       
     54        static inline type apply(Iterator const& it)
     55        {
     56            return type(it);
     57        }
     58    };
     59   
     60    template<class Iterator>
     61    struct make_descent_cons<Iterator,
     62        typename enable_if<traits::is_sequence<
     63            typename result_of::value_of<Iterator>::type> >::type>
     64    {
     65        // we use 'value_of' above for convenience, assuming the value won't be reference,
     66        // while we must use the regular 'deref' here for const issues...
     67        typedef typename
     68            remove_reference<typename result_of::deref<Iterator>::type>::type
     69        sub_sequence;
     70       
     71        typedef typename
     72            result_of::begin<sub_sequence>::type
     73        sub_begin;
     74           
     75        typedef cons<Iterator, typename make_descent_cons<sub_begin>::type> type;
     76       
     77        static inline type apply(Iterator const& it)
     78        {
     79            return type(it, make_descent_cons<sub_begin>::apply(
     80                fusion::begin(*it)));
     81        }
     82    };
     83   
     84    template<class Cons, class Base>
     85    struct build_flatten_view_iterator;
     86
     87    template<class Car, class Base>
     88    struct build_flatten_view_iterator<cons<Car>, Base>
     89    {
     90        typedef flatten_view_iterator<Car, Base> type;
     91       
     92        static inline type apply(cons<Car> const& cons, Base const& base)
     93        {
     94            return type(cons.car, base);
     95        }
     96    };
     97   
     98    template<class Car, class Cdr, class Base>
     99    struct build_flatten_view_iterator<cons<Car, Cdr>, Base>
     100    {
     101        typedef flatten_view_iterator<Car, Base> next_base;
     102        typedef build_flatten_view_iterator<Cdr, next_base> next;
     103        typedef typename next::type type;
     104       
     105        static inline type apply(cons<Car, Cdr> const& cons, Base const& base)
     106        {
     107            return next::apply(cons.cdr, next_base(cons.car, base));
     108        }
     109    };
     110   
     111    template<class Base, class Iterator, class = void>
     112    struct seek_descent
     113    {
     114        typedef make_descent_cons<Iterator> make_descent_cons_;
     115        typedef typename make_descent_cons_::type cons_type;
     116        typedef
     117            build_flatten_view_iterator<cons_type, Base>
     118        build_flatten_view_iterator_;
     119        typedef typename build_flatten_view_iterator_::type type;
     120       
     121        static inline type apply(Base const& base, Iterator const& it)
     122        {
     123            return build_flatten_view_iterator_::apply(
     124                make_descent_cons_::apply(it), base);
     125        }
     126    };
     127   
     128    template<class Base, class Iterator>
     129    struct seek_descent<Base, Iterator,
     130        typename enable_if<
     131            result_of::equal_to<Iterator, typename result_of::end<
     132                    typename result_of::value_of<Base>::type>::type> >::type>
     133    {
     134        typedef typename result_of::next<Base>::type type;
     135       
     136        static inline type apply(Base const& base, Iterator const&)
     137        {
     138            return fusion::next(base);
     139        }
     140    };
     141}}}
     142
     143namespace boost { namespace fusion { namespace extension
     144{
     145    template<>
     146    struct next_impl<flatten_view_iterator_tag>
     147    {
     148        template<typename Iterator>
     149        struct apply
     150        {
     151            typedef typename Iterator::first_type first_type;
     152            typedef typename Iterator::base_type base_type;
     153            typedef typename result_of::next<first_type>::type next_type;
     154           
     155            typedef detail::seek_descent<base_type, next_type> seek_descent;
     156            typedef typename seek_descent::type type;
     157
     158            static inline
     159            type call(Iterator const& it)
     160            {
     161                return seek_descent::apply(it.base, fusion::next(it.first));
     162            }
     163        };
     164    };
     165   
     166    template<>
     167    struct deref_impl<flatten_view_iterator_tag>
     168    {
     169        template<typename Iterator>
     170        struct apply
     171        {
     172            typedef typename
     173                result_of::deref<typename Iterator::first_type>::type
     174            type;
     175
     176            static inline
     177            type call(Iterator const& it)
     178            {
     179                return *it.first;
     180            }
     181        };
     182    };
     183   
     184    template<>
     185    struct value_of_impl<flatten_view_iterator_tag>
     186    {
     187        template<typename Iterator>
     188        struct apply
     189        {
     190            typedef typename
     191                result_of::value_of<typename Iterator::first_type>::type
     192            type;
     193        };
     194    };
     195}}}
     196
     197
     198#endif
     199
  • libs/fusion/doc/algorithm.qbk

     
    18411841
    18421842[endsect]
    18431843
     1844[section flatten]
     1845
     1846[heading Description]
     1847Returns a new sequence without nested sequences.
     1848
     1849[heading Synopsis]
     1850    template<
     1851        typename Sequence
     1852        >
     1853    typename __result_of_flatten__<Sequence>::type flatten(Sequence& seq);
     1854   
     1855    template<
     1856        typename Sequence
     1857        >
     1858    typename __result_of_flatten__<Sequence const>::type flatten(Sequence const& seq);
     1859
     1860[table Parameters
     1861    [[Parameter][Requirement][Description]]
     1862    [[`seq`][A model of __forward_sequence__][Operation's argument]]
     1863]
     1864
     1865[heading Expression Semantics]
     1866    __flatten__(seq);
     1867
     1868[*Return type]:
     1869
     1870* A model of __forward_sequence__.
     1871
     1872[*Semantics]: Returns a new sequence containing all the leaf elements of `seq`.
     1873
     1874[heading Complexity]
     1875Constant. Returns a view which is lazily evaluated.
     1876
     1877[heading Header]
     1878
     1879    #include <boost/fusion/algorithm/transformation/flatten.hpp>
     1880    #include <boost/fusion/include/flatten.hpp>
     1881
     1882[heading Example]
     1883    const __vector__<int, int, vector<int, int>, int> vec(1, 2, __make_vector__(3, 4), 5);
     1884    assert(__flatten__(vec) == __make_vector__(1, 2, 3, 4, 5)));
     1885
    18441886[endsect]
    18451887
     1888[endsect]
     1889
    18461890[section Metafunctions]
    18471891
    18481892[section filter]
     
    26332677
    26342678[endsect]
    26352679
     2680[section flatten]
     2681
     2682[heading Description]
     2683Returns the result type of __flatten__, given the input sequence type.
     2684
     2685[heading Synopsis]
     2686    template<
     2687        typename Sequence
     2688        >
     2689    struct flatten
     2690    {
     2691        typedef __unspecified__ type;
     2692    };
     2693
     2694[table Parameters
     2695    [[Parameter][Requirement][Description]]
     2696    [[`Sequence`][A model of __forward_sequence__][Operation's argument]]
     2697]
     2698
     2699[heading Expression Semantics]
     2700    __result_of_flatten__<Sequence>::type
     2701
     2702[*Return type]:
     2703
     2704* A model of __forward_sequence__.
     2705
     2706[*Semantics]: Returns a sequence with all the leaf elements of `Sequence`.
     2707
     2708[heading Complexity]
     2709Constant.
     2710
     2711[heading Header]
     2712
     2713    #include <boost/fusion/algorithm/transformation/flatten.hpp>
     2714    #include <boost/fusion/include/flatten.hpp>
     2715
    26362716[endsect]
    26372717
    26382718[endsect]
    26392719
    26402720[endsect]
     2721
     2722[endsect]
  • libs/fusion/doc/fusion.qbk

     
    288288[def __result_of_push_back__    [link fusion.algorithm.transformation.metafunctions.push_back `result_of::push_back`]]
    289289[def __push_front__             [link fusion.algorithm.transformation.functions.push_front `push_front`]]
    290290[def __result_of_push_front__   [link fusion.algorithm.transformation.metafunctions.push_front `result_of::push_front`]]
     291[def __flatten__                [link fusion.algorithm.transformation.functions.flatten `flatten`]]
     292[def __result_of_flatten__      [link fusion.algorithm.transformation.metafunctions.flatten `result_of::flatten`]]
    291293
    292294[def __tr1_tuple_pair__         [link fusion.tuple.pairs `TR1 and std::pair`]]
    293295[def __tuple_get__              [link fusion.tuple.class_template_tuple.element_access `get`]]
  • libs/fusion/test/algorithm/flatten.cpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#include <boost/detail/lightweight_test.hpp>
     8#include <boost/fusion/container/vector/vector.hpp>
     9#include <boost/fusion/sequence/io/out.hpp>
     10#include <boost/fusion/sequence/comparison/equal_to.hpp>
     11#include <boost/fusion/container/generation/make_vector.hpp>
     12#include <boost/fusion/sequence/intrinsic/begin.hpp>
     13#include <boost/fusion/sequence/intrinsic/end.hpp>
     14#include <boost/fusion/sequence/intrinsic/at.hpp>
     15#include <boost/fusion/sequence/intrinsic/size.hpp>
     16#include <boost/fusion/iterator/advance.hpp>
     17#include <boost/fusion/iterator/deref.hpp>
     18#include <boost/fusion/iterator/distance.hpp>
     19#include <boost/fusion/algorithm/auxiliary/copy.hpp>
     20#include <boost/fusion/algorithm/transformation/flatten.hpp>
     21
     22
     23int main()
     24{
     25    using namespace boost::fusion;
     26
     27    {
     28        typedef vector<int, int, vector<int, int>, int> sequence_type;
     29        sequence_type seq(1, 2, make_vector(3, 4), 5);
     30
     31        BOOST_TEST((boost::fusion::size(flatten(seq)) == 5));
     32    }
     33       
     34    {
     35        typedef vector<int, int, vector<int, int>, int> sequence_type;
     36        sequence_type seq(1, 2, make_vector(3, 4), 5);
     37        std::cout << flatten(seq) << std::endl;
     38        BOOST_TEST((flatten(seq) == make_vector(1, 2, 3, 4, 5)));
     39    }
     40
     41    {
     42        std::cout << flatten(make_vector(1, 2, make_vector(3, 4), 5)) << std::endl;
     43        BOOST_TEST((flatten(make_vector(1, 2, make_vector(3, 4), 5)) == make_vector(1, 2, 3, 4, 5)));
     44    }
     45   
     46    {
     47        typedef vector<int, int, vector<int, int>, int> sequence_type;
     48        sequence_type seq;
     49        result_of::flatten<sequence_type>::type flat(flatten(seq));
     50        copy(make_vector(1, 2, 3, 4, 5), flat);
     51        std::cout << seq << std::endl;
     52        BOOST_TEST((seq == make_vector(1, 2, make_vector(3, 4), 5)));
     53    }
     54   
     55    return boost::report_errors();
     56}
     57
  • libs/fusion/test/Jamfile

     
    5454    [ run algorithm/zip.cpp : : : : ]
    5555    [ run algorithm/zip2.cpp : : : : ]
    5656    [ run algorithm/zip_ignore.cpp : : : : ]
     57        [ run algorithm/flatten.cpp : : : : ]
    5758
    5859    [ run sequence/as_list.cpp :  :  :  : ]
    5960    [ run sequence/as_map.cpp :  :  :  : ]
     
    151152    [ run sequence/define_assoc_tpl_struct.cpp : : : : ]
    152153    [ run sequence/std_tuple_iterator.cpp : : : : ]
    153154    [ run sequence/ref_vector.cpp : : : : ]
     155        [ run sequence/flatten_view.cpp : : : : ]
    154156
    155157    [ run functional/fused.cpp : : : : ]
    156158    [ run functional/fused_function_object.cpp : : : : ]
  • libs/fusion/test/sequence/flatten_view.cpp

     
     1/*//////////////////////////////////////////////////////////////////////////////
     2    Copyright (c) 2013 Jamboree
     3
     4    Distributed under the Boost Software License, Version 1.0. (See accompanying
     5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6//////////////////////////////////////////////////////////////////////////////*/
     7#include <boost/detail/lightweight_test.hpp>
     8#include <boost/fusion/container/vector/vector.hpp>
     9#include <boost/fusion/view/flatten_view/flatten_view.hpp>
     10#include <boost/fusion/sequence/io/out.hpp>
     11#include <boost/fusion/sequence/comparison/equal_to.hpp>
     12#include <boost/fusion/container/generation/make_vector.hpp>
     13#include <boost/fusion/sequence/intrinsic/begin.hpp>
     14#include <boost/fusion/sequence/intrinsic/end.hpp>
     15#include <boost/fusion/sequence/intrinsic/at.hpp>
     16#include <boost/fusion/sequence/intrinsic/size.hpp>
     17#include <boost/fusion/iterator/advance.hpp>
     18#include <boost/fusion/iterator/deref.hpp>
     19#include <boost/fusion/iterator/distance.hpp>
     20#include <boost/fusion/algorithm/auxiliary/copy.hpp>
     21
     22
     23int main()
     24{
     25    using namespace boost::fusion;
     26
     27    {
     28        typedef vector<int, int, vector<int, int>, int> sequence_type;
     29        sequence_type seq(1, 2, make_vector(3, 4), 5);
     30        flatten_view<sequence_type> flatten(seq);
     31
     32        BOOST_TEST((boost::fusion::size(flatten) == 5));
     33        BOOST_TEST((boost::fusion::distance(boost::fusion::begin(flatten), boost::fusion::end(flatten)) == 5));
     34    }
     35       
     36    {
     37        typedef vector<int, int, vector<int, int>, int> sequence_type;
     38        sequence_type seq(1, 2, make_vector(3, 4), 5);
     39        flatten_view<sequence_type> flatten(seq);
     40        std::cout << flatten << std::endl;
     41        BOOST_TEST((flatten == make_vector(1, 2, 3, 4, 5)));
     42        BOOST_TEST((*advance_c<2>(boost::fusion::begin(flatten)) == 3));
     43    }
     44
     45    {
     46        typedef vector<int, int, vector<int, int>, int> sequence_type;
     47        sequence_type seq;
     48        flatten_view<sequence_type> flatten(seq);
     49        copy(make_vector(1, 2, 3, 4, 5), flatten);
     50        std::cout << seq << std::endl;
     51        BOOST_TEST((seq == make_vector(1, 2, make_vector(3, 4), 5)));
     52    }
     53   
     54    return boost::report_errors();
     55}
     56