Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / algorithm / string / detail / replace_storage.hpp
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
19 namespace 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