summaryrefslogtreecommitdiffstats
path: root/contrib/src/boost/algorithm/string/join.hpp
blob: cbc98d958299f76a31eadcc74af5c71ec6fe12fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//  Boost string_algo library join.hpp header file  ---------------------------//


//  Copyright Pavol Droba 2002-2006.

//

// Distributed under the Boost Software License, Version 1.0.

//    (See accompanying file LICENSE_1_0.txt or copy at

//          http://www.boost.org/LICENSE_1_0.txt)


//  See http://www.boost.org/ for updates, documentation, and revision history.


#ifndef BOOST_STRING_JOIN_HPP

#define BOOST_STRING_JOIN_HPP


#include <boost/algorithm/string/config.hpp>

#include <boost/algorithm/string/detail/sequence.hpp>

#include <boost/range/value_type.hpp>

#include <boost/range/as_literal.hpp>


/*! \file

    Defines join algorithm. 



    Join algorithm is a counterpart to split algorithms.

    It joins strings from a 'list' by adding user defined separator.

    Additionally there is a version that allows simple filtering

    by providing a predicate.

*/

namespace boost {
    namespace algorithm {

//  join --------------------------------------------------------------//


        //! Join algorithm

        /*!

            This algorithm joins all strings in a 'list' into one long string.

            Segments are concatenated by given separator.



            \param Input A container that holds the input strings. It must be a container-of-containers.

            \param Separator A string that will separate the joined segments.

            \return Concatenated string.



            \note This function provides the strong exception-safety guarantee

        */
        template< typename SequenceSequenceT, typename Range1T>
        inline typename range_value<SequenceSequenceT>::type 
        join(
            const SequenceSequenceT& Input,
            const Range1T& Separator)
        {
            // Define working types

            typedef typename range_value<SequenceSequenceT>::type ResultT;
            typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;

            // Parse input

            InputIteratorT itBegin=::boost::begin(Input);
            InputIteratorT itEnd=::boost::end(Input);

            // Construct container to hold the result

            ResultT Result;
            
            // Append first element

            if(itBegin!=itEnd)
            {
                detail::insert(Result, ::boost::end(Result), *itBegin);
                ++itBegin;
            }

            for(;itBegin!=itEnd; ++itBegin)
            {
                // Add separator

                detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
                // Add element

                detail::insert(Result, ::boost::end(Result), *itBegin);
            }

            return Result;
        }

// join_if ----------------------------------------------------------//


        //! Conditional join algorithm

        /*!

            This algorithm joins all strings in a 'list' into one long string.

            Segments are concatenated by given separator. Only segments that

            satisfy the predicate will be added to the result.



            \param Input A container that holds the input strings. It must be a container-of-containers.

            \param Separator A string that will separate the joined segments.

            \param Pred A segment selection predicate

            \return Concatenated string.



            \note This function provides the strong exception-safety guarantee

        */
        template< typename SequenceSequenceT, typename Range1T, typename PredicateT>
        inline typename range_value<SequenceSequenceT>::type 
        join_if(
            const SequenceSequenceT& Input,
            const Range1T& Separator,
            PredicateT Pred)
        {
            // Define working types

            typedef typename range_value<SequenceSequenceT>::type ResultT;
            typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;

            // Parse input

            InputIteratorT itBegin=::boost::begin(Input);
            InputIteratorT itEnd=::boost::end(Input);

            // Construct container to hold the result

            ResultT Result;

            // Roll to the first element that will be added

            while(itBegin!=itEnd && !Pred(*itBegin)) ++itBegin;
            // Add this element

            if(itBegin!=itEnd)
            {
                detail::insert(Result, ::boost::end(Result), *itBegin);
                ++itBegin;
            }

            for(;itBegin!=itEnd; ++itBegin)
            {
                if(Pred(*itBegin))
                {
                    // Add separator

                    detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
                    // Add element

                    detail::insert(Result, ::boost::end(Result), *itBegin);
                }
            }

            return Result;
        }

    } // namespace algorithm


    // pull names to the boost namespace

    using algorithm::join;
    using algorithm::join_if;

} // namespace boost



#endif  // BOOST_STRING_JOIN_HPP