source: NonGTP/Boost/boost/algorithm/string/detail/replace_storage.hpp @ 857

Revision 857, 5.9 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  Boost string_algo library replace_storage.hpp header file  ---------------------------//
2
3//  Copyright Pavol Droba 2002-2003. Use, modification and
4//  distribution is subject to the Boost Software License, Version
5//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6//  http://www.boost.org/LICENSE_1_0.txt)
7
8//  See http://www.boost.org for updates, documentation, and revision history.
9
10#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
11#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
12
13#include <boost/algorithm/string/config.hpp>
14#include <algorithm>
15#include <boost/mpl/bool.hpp>
16#include <boost/algorithm/string/sequence_traits.hpp>
17#include <boost/algorithm/string/detail/sequence.hpp>
18
19namespace boost {
20    namespace algorithm {
21        namespace detail {
22
23//  storage handling routines -----------------------------------------------//
24           
25            template< typename StorageT, typename OutputIteratorT >
26            inline OutputIteratorT move_from_storage(
27                StorageT& Storage,
28                OutputIteratorT DestBegin,
29                OutputIteratorT DestEnd )
30            {
31                OutputIteratorT OutputIt=DestBegin;
32               
33                while( !Storage.empty() && OutputIt!=DestEnd )
34                {
35                    *OutputIt=Storage.front();
36                    Storage.pop_front();
37                    ++OutputIt;
38                }
39
40                return OutputIt;
41            }
42
43            template< typename StorageT, typename WhatT >
44            inline void copy_to_storage(
45                StorageT& Storage,
46                const WhatT& What )
47            {
48                Storage.insert( Storage.end(), begin(What), end(What) );
49            }
50
51
52//  process segment routine -----------------------------------------------//
53
54            template< bool HasStableIterators >
55            struct process_segment_helper
56            {
57                // Optimized version of process_segment for generic sequence
58                template<
59                    typename StorageT,
60                    typename InputT,
61                    typename ForwardIteratorT >
62                ForwardIteratorT operator()(
63                    StorageT& Storage,
64                    InputT& /*Input*/,
65                    ForwardIteratorT InsertIt,
66                    ForwardIteratorT SegmentBegin,
67                    ForwardIteratorT SegmentEnd )
68                {
69                    // Copy data from the storage until the beginning of the segment
70                    ForwardIteratorT It=move_from_storage( Storage, InsertIt, SegmentBegin );
71
72                    // 3 cases are possible :
73                    //   a) Storage is empty, It==SegmentBegin
74                    //   b) Storage is empty, It!=SegmentBegin
75                    //   c) Storage is not empty
76
77                    if( Storage.empty() )
78                    {
79                        if( It==SegmentBegin )
80                        {
81                            // Case a) everything is grand, just return end of segment
82                            return SegmentEnd;
83                        }
84                        else
85                        {
86                            // Case b) move the segment backwards
87                            return std::copy( SegmentBegin, SegmentEnd, It );
88                        }
89                    }
90                    else
91                    {
92                        // Case c) -> shift the segment to the left and keep the overlap in the storage
93                        while( It!=SegmentEnd )
94                        {
95                            // Store value into storage
96                            Storage.push_back( *It );
97                            // Get the top from the storage and put it here
98                            *It=Storage.front();
99                            Storage.pop_front();
100
101                            // Advance
102                            ++It;
103                        }
104
105                        return It;
106                    }
107                }
108            };
109
110            template<>
111            struct process_segment_helper< true >
112            {
113                // Optimized version of process_segment for list-like sequence
114                template<
115                    typename StorageT,
116                    typename InputT,
117                    typename ForwardIteratorT >
118                ForwardIteratorT operator()(
119                    StorageT& Storage,
120                    InputT& Input,
121                    ForwardIteratorT InsertIt,
122                    ForwardIteratorT SegmentBegin,
123                    ForwardIteratorT SegmentEnd )
124
125                {
126                    // Call replace to do the job
127                    replace( Input, InsertIt, SegmentBegin, Storage );
128                    // Empty the storage
129                    Storage.clear();
130                    // Iterators were not changed, simply return the end of segment
131                    return SegmentEnd;
132                }
133            };
134
135            // Process one segment in the replace_all algorithm
136            template<
137                typename StorageT,
138                typename InputT,
139                typename ForwardIteratorT >
140            inline ForwardIteratorT process_segment(
141                StorageT& Storage,
142                InputT& Input,
143                ForwardIteratorT InsertIt,
144                ForwardIteratorT SegmentBegin,
145                ForwardIteratorT SegmentEnd )
146            {
147                return
148                    process_segment_helper<
149                        has_stable_iterators<InputT>::value>()(
150                                Storage, Input, InsertIt, SegmentBegin, SegmentEnd );
151            }
152           
153
154        } // namespace detail
155    } // namespace algorithm
156} // namespace boost
157
158#endif  // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
Note: See TracBrowser for help on using the repository browser.