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