1 /*=============================================================================
2     Copyright (c) 2003 Joel de Guzman
3     Copyright (c) 2004 Peder Holt
4 
5     Use, modification and distribution is subject to the Boost Software
6     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7     http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #if !defined(FUSION_ALGORITHM_INSERT_HPP)
10 #define FUSION_ALGORITHM_INSERT_HPP
11 
12 #include <boost/spirit/fusion/sequence/single_view.hpp>
13 #include <boost/spirit/fusion/sequence/joint_view.hpp>
14 #include <boost/spirit/fusion/sequence/range.hpp>
15 #include <boost/spirit/fusion/sequence/begin.hpp>
16 #include <boost/spirit/fusion/sequence/end.hpp>
17 
18 namespace boost { namespace fusion
19 {
20     namespace meta
21     {
22         template <typename Sequence, typename Position, typename T>
23         struct insert
24         {
25             typedef typename meta::begin<Sequence>::type first_type;
26             typedef typename meta::end<Sequence>::type last_type;
27 
28             typedef single_view<T> insert_type;
29             typedef range<first_type, Position> left_type;
30             typedef range<Position, last_type> right_type;
31             typedef joint_view<left_type, insert_type> left_insert_type;
32             typedef joint_view<left_insert_type, right_type> type;
33         };
34     }
35 
36     namespace function
37     {
38         struct insert
39         {
40             template <typename Sequence, typename Position, typename T>
41             struct apply : meta::insert<Sequence, Position, T> {};
42 
43             template <typename Sequence, typename Position, typename T>
44             inline typename apply<Sequence const, Position, T>::type
operator ()boost::fusion::function::insert45             operator()(Sequence const& seq, Position const& pos, T const& x) const
46             {
47                 typedef apply<Sequence const, Position, T> meta;
48                 typedef typename meta::left_type left_type;
49                 typedef typename meta::right_type right_type;
50                 typedef typename meta::left_insert_type left_insert_type;
51                 typedef typename meta::insert_type insert_type;
52                 typedef typename meta::type result;
53 
54                 left_type left(fusion::begin(seq), pos);
55                 right_type right(pos, fusion::end(seq));
56                 insert_type ins(x);
57                 left_insert_type left_insert(left, ins);
58                 return result(left_insert, right);
59             }
60 
61             template <typename Sequence, typename Position, typename T>
62             inline typename apply<Sequence, Position, T>::type
operator ()boost::fusion::function::insert63             operator()(Sequence& seq, Position const& pos, T const& x) const
64             {
65                 typedef apply<Sequence, Position, T> meta_type;
66                 typedef typename meta_type::left_type left_type;
67                 typedef typename meta_type::right_type right_type;
68                 typedef typename meta_type::left_insert_type left_insert_type;
69                 typedef typename meta_type::insert_type insert_type;
70                 typedef typename meta_type::type result;
71 
72                 left_type left(fusion::begin(seq), pos);
73                 right_type right(pos, fusion::end(seq));
74                 insert_type ins(x);
75                 left_insert_type left_insert(left, ins);
76                 return result(left_insert, right);
77             }
78         };
79     }
80 
81     function::insert const insert = function::insert();
82 }}
83 
84 #endif
85 
86