1 // Boost string_algo library join.hpp header file ---------------------------// 2 3 // Copyright Pavol Droba 2002-2006. 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 // See http://www.boost.org/ for updates, documentation, and revision history. 10 11 #ifndef BOOST_STRING_JOIN_HPP 12 #define BOOST_STRING_JOIN_HPP 13 14 #include <boost/algorithm/string/config.hpp> 15 #include <boost/algorithm/string/detail/sequence.hpp> 16 #include <boost/range/value_type.hpp> 17 #include <boost/range/as_literal.hpp> 18 19 /*! \file 20 Defines join algorithm. 21 22 Join algorithm is a counterpart to split algorithms. 23 It joins strings from a 'list' by adding user defined separator. 24 Additionally there is a version that allows simple filtering 25 by providing a predicate. 26 */ 27 28 namespace boost { 29 namespace algorithm { 30 31 // join --------------------------------------------------------------// 32 33 //! Join algorithm 34 /*! 35 This algorithm joins all strings in a 'list' into one long string. 36 Segments are concatenated by given separator. 37 38 \param Input A container that holds the input strings. It must be a container-of-containers. 39 \param Separator A string that will separate the joined segments. 40 \return Concatenated string. 41 42 \note This function provides the strong exception-safety guarantee 43 */ 44 template< typename SequenceSequenceT, typename Range1T> 45 inline typename range_value<SequenceSequenceT>::type join(const SequenceSequenceT & Input,const Range1T & Separator)46 join( 47 const SequenceSequenceT& Input, 48 const Range1T& Separator) 49 { 50 // Define working types 51 typedef typename range_value<SequenceSequenceT>::type ResultT; 52 typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT; 53 54 // Parse input 55 InputIteratorT itBegin=::boost::begin(Input); 56 InputIteratorT itEnd=::boost::end(Input); 57 58 // Construct container to hold the result 59 ResultT Result; 60 61 // Append first element 62 if(itBegin!=itEnd) 63 { 64 detail::insert(Result, ::boost::end(Result), *itBegin); 65 ++itBegin; 66 } 67 68 for(;itBegin!=itEnd; ++itBegin) 69 { 70 // Add separator 71 detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator)); 72 // Add element 73 detail::insert(Result, ::boost::end(Result), *itBegin); 74 } 75 76 return Result; 77 } 78 79 // join_if ----------------------------------------------------------// 80 81 //! Conditional join algorithm 82 /*! 83 This algorithm joins all strings in a 'list' into one long string. 84 Segments are concatenated by given separator. Only segments that 85 satisfy the predicate will be added to the result. 86 87 \param Input A container that holds the input strings. It must be a container-of-containers. 88 \param Separator A string that will separate the joined segments. 89 \param Pred A segment selection predicate 90 \return Concatenated string. 91 92 \note This function provides the strong exception-safety guarantee 93 */ 94 template< typename SequenceSequenceT, typename Range1T, typename PredicateT> 95 inline typename range_value<SequenceSequenceT>::type join_if(const SequenceSequenceT & Input,const Range1T & Separator,PredicateT Pred)96 join_if( 97 const SequenceSequenceT& Input, 98 const Range1T& Separator, 99 PredicateT Pred) 100 { 101 // Define working types 102 typedef typename range_value<SequenceSequenceT>::type ResultT; 103 typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT; 104 105 // Parse input 106 InputIteratorT itBegin=::boost::begin(Input); 107 InputIteratorT itEnd=::boost::end(Input); 108 109 // Construct container to hold the result 110 ResultT Result; 111 112 // Roll to the first element that will be added 113 while(itBegin!=itEnd && !Pred(*itBegin)) ++itBegin; 114 // Add this element 115 if(itBegin!=itEnd) 116 { 117 detail::insert(Result, ::boost::end(Result), *itBegin); 118 ++itBegin; 119 } 120 121 for(;itBegin!=itEnd; ++itBegin) 122 { 123 if(Pred(*itBegin)) 124 { 125 // Add separator 126 detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator)); 127 // Add element 128 detail::insert(Result, ::boost::end(Result), *itBegin); 129 } 130 } 131 132 return Result; 133 } 134 135 } // namespace algorithm 136 137 // pull names to the boost namespace 138 using algorithm::join; 139 using algorithm::join_if; 140 141 } // namespace boost 142 143 144 #endif // BOOST_STRING_JOIN_HPP 145 146