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_REPLACE_HPP)
10 #define FUSION_ALGORITHM_REPLACE_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 #include <boost/spirit/fusion/iterator/equal_to.hpp>
18 
19 namespace boost { namespace fusion
20 {
21     namespace meta
22     {
23         template <typename Sequence, typename Position, typename T>
24         struct replace
25         {
26             typedef typename meta::begin<Sequence>::type first_type;
27             typedef typename meta::end<Sequence>::type last_type;
28             typedef typename meta::next<Position>::type next_type;
29 #if! BOOST_WORKAROUND(BOOST_MSVC,<=1300)
30             BOOST_STATIC_ASSERT((!meta::equal_to<Position, last_type>::value));
31 #endif
32             typedef single_view<T> insert_type;
33             typedef range<first_type, Position> left_type;
34             typedef range<next_type, last_type> right_type;
35             typedef joint_view<left_type, insert_type> left_replace_type;
36             typedef joint_view<left_replace_type, right_type> type;
37         };
38     }
39 
40     namespace function
41     {
42         struct replace
43         {
44             template <typename Sequence, typename Position, typename T>
45             struct apply : meta::replace<Sequence, Position, T> {};
46 
47             template <typename Sequence, typename Position, typename T>
48             typename apply<Sequence const, Position, T>::type
operator ()boost::fusion::function::replace49             operator()(Sequence const& seq, Position const& pos, T const& x) const
50             {
51                 typedef apply<Sequence const, Position, T> replacer;
52 
53                 typedef typename replacer::left_type left_type;
54                 typedef typename replacer::right_type right_type;
55                 typedef typename replacer::left_replace_type left_replace_type;
56                 typedef typename replacer::insert_type insert_type;
57                 typedef typename replacer::type result;
58 
59                 left_type left(fusion::begin(seq), pos);
60                 right_type right(fusion::next(pos), fusion::end(seq));
61                 insert_type ins(x);
62                 left_replace_type left_replace(left, ins);
63                 return result(left_replace, right);
64             }
65 
66             template <typename Sequence, typename Position, typename T>
67             typename apply<Sequence, Position, T>::type
operator ()boost::fusion::function::replace68             operator()(Sequence& seq, Position const& pos, T const& x) const
69             {
70                 typedef apply<Sequence, Position, T> replacer;
71 
72                 typedef typename replacer::left_type left_type;
73                 typedef typename replacer::right_type right_type;
74                 typedef typename replacer::left_replace_type left_replace_type;
75                 typedef typename replacer::insert_type insert_type;
76                 typedef typename replacer::type result;
77 
78                 left_type left(fusion::begin(seq), pos);
79                 right_type right(fusion::next(pos), fusion::end(seq));
80                 insert_type ins(x);
81                 left_replace_type left_replace(left, ins);
82                 return result(left_replace, right);
83             }
84         };
85     }
86 
87     function::replace const replace = function::replace();
88 }}
89 
90 #endif
91 
92