1
// Boost string_algo library replace_storage.hpp header file ---------------------------//
3
// Copyright Pavol Droba 2002-2003.
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)
9
// See http://www.boost.org/ for updates, documentation, and revision history.
11
#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
12
#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
14
#include <boost/algorithm/string/config.hpp>
16
#include <boost/mpl/bool.hpp>
17
#include <boost/algorithm/string/sequence_traits.hpp>
18
#include <boost/algorithm/string/detail/sequence.hpp>
24
// storage handling routines -----------------------------------------------//
26
template< typename StorageT, typename OutputIteratorT >
27
inline OutputIteratorT move_from_storage(
29
OutputIteratorT DestBegin,
30
OutputIteratorT DestEnd )
32
OutputIteratorT OutputIt=DestBegin;
34
while( !Storage.empty() && OutputIt!=DestEnd )
36
*OutputIt=Storage.front();
44
template< typename StorageT, typename WhatT >
45
inline void copy_to_storage(
49
Storage.insert( Storage.end(), ::boost::begin(What), ::boost::end(What) );
53
// process segment routine -----------------------------------------------//
55
template< bool HasStableIterators >
56
struct process_segment_helper
58
// Optimized version of process_segment for generic sequence
62
typename ForwardIteratorT >
63
ForwardIteratorT operator()(
66
ForwardIteratorT InsertIt,
67
ForwardIteratorT SegmentBegin,
68
ForwardIteratorT SegmentEnd )
70
// Copy data from the storage until the beginning of the segment
71
ForwardIteratorT It=move_from_storage( Storage, InsertIt, SegmentBegin );
73
// 3 cases are possible :
74
// a) Storage is empty, It==SegmentBegin
75
// b) Storage is empty, It!=SegmentBegin
76
// c) Storage is not empty
80
if( It==SegmentBegin )
82
// Case a) everything is grand, just return end of segment
87
// Case b) move the segment backwards
88
return std::copy( SegmentBegin, SegmentEnd, It );
93
// Case c) -> shift the segment to the left and keep the overlap in the storage
94
while( It!=SegmentEnd )
96
// Store value into storage
97
Storage.push_back( *It );
98
// Get the top from the storage and put it here
112
struct process_segment_helper< true >
114
// Optimized version of process_segment for list-like sequence
118
typename ForwardIteratorT >
119
ForwardIteratorT operator()(
122
ForwardIteratorT InsertIt,
123
ForwardIteratorT SegmentBegin,
124
ForwardIteratorT SegmentEnd )
127
// Call replace to do the job
128
replace( Input, InsertIt, SegmentBegin, Storage );
131
// Iterators were not changed, simply return the end of segment
136
// Process one segment in the replace_all algorithm
140
typename ForwardIteratorT >
141
inline ForwardIteratorT process_segment(
144
ForwardIteratorT InsertIt,
145
ForwardIteratorT SegmentBegin,
146
ForwardIteratorT SegmentEnd )
149
process_segment_helper<
150
has_stable_iterators<InputT>::value>()(
151
Storage, Input, InsertIt, SegmentBegin, SegmentEnd );
155
} // namespace detail
156
} // namespace algorithm
159
#endif // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP