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
28namespace 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
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
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