mirror of
https://github.com/yuzu-emu/ext-boost.git
synced 2024-12-23 03:45:38 +00:00
160 lines
5.8 KiB
C++
160 lines
5.8 KiB
C++
// Boost string_algo library replace_storage.hpp header file ---------------------------//
|
|
|
|
// Copyright Pavol Droba 2002-2003.
|
|
//
|
|
// 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_REPLACE_STORAGE_DETAIL_HPP
|
|
#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
|
|
|
|
#include <boost/algorithm/string/config.hpp>
|
|
#include <algorithm>
|
|
#include <boost/mpl/bool.hpp>
|
|
#include <boost/algorithm/string/sequence_traits.hpp>
|
|
#include <boost/algorithm/string/detail/sequence.hpp>
|
|
|
|
namespace boost {
|
|
namespace algorithm {
|
|
namespace detail {
|
|
|
|
// storage handling routines -----------------------------------------------//
|
|
|
|
template< typename StorageT, typename OutputIteratorT >
|
|
inline OutputIteratorT move_from_storage(
|
|
StorageT& Storage,
|
|
OutputIteratorT DestBegin,
|
|
OutputIteratorT DestEnd )
|
|
{
|
|
OutputIteratorT OutputIt=DestBegin;
|
|
|
|
while( !Storage.empty() && OutputIt!=DestEnd )
|
|
{
|
|
*OutputIt=Storage.front();
|
|
Storage.pop_front();
|
|
++OutputIt;
|
|
}
|
|
|
|
return OutputIt;
|
|
}
|
|
|
|
template< typename StorageT, typename WhatT >
|
|
inline void copy_to_storage(
|
|
StorageT& Storage,
|
|
const WhatT& What )
|
|
{
|
|
Storage.insert( Storage.end(), ::boost::begin(What), ::boost::end(What) );
|
|
}
|
|
|
|
|
|
// process segment routine -----------------------------------------------//
|
|
|
|
template< bool HasStableIterators >
|
|
struct process_segment_helper
|
|
{
|
|
// Optimized version of process_segment for generic sequence
|
|
template<
|
|
typename StorageT,
|
|
typename InputT,
|
|
typename ForwardIteratorT >
|
|
ForwardIteratorT operator()(
|
|
StorageT& Storage,
|
|
InputT& /*Input*/,
|
|
ForwardIteratorT InsertIt,
|
|
ForwardIteratorT SegmentBegin,
|
|
ForwardIteratorT SegmentEnd )
|
|
{
|
|
// Copy data from the storage until the beginning of the segment
|
|
ForwardIteratorT It=::boost::algorithm::detail::move_from_storage( Storage, InsertIt, SegmentBegin );
|
|
|
|
// 3 cases are possible :
|
|
// a) Storage is empty, It==SegmentBegin
|
|
// b) Storage is empty, It!=SegmentBegin
|
|
// c) Storage is not empty
|
|
|
|
if( Storage.empty() )
|
|
{
|
|
if( It==SegmentBegin )
|
|
{
|
|
// Case a) everything is grand, just return end of segment
|
|
return SegmentEnd;
|
|
}
|
|
else
|
|
{
|
|
// Case b) move the segment backwards
|
|
return std::copy( SegmentBegin, SegmentEnd, It );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Case c) -> shift the segment to the left and keep the overlap in the storage
|
|
while( It!=SegmentEnd )
|
|
{
|
|
// Store value into storage
|
|
Storage.push_back( *It );
|
|
// Get the top from the storage and put it here
|
|
*It=Storage.front();
|
|
Storage.pop_front();
|
|
|
|
// Advance
|
|
++It;
|
|
}
|
|
|
|
return It;
|
|
}
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct process_segment_helper< true >
|
|
{
|
|
// Optimized version of process_segment for list-like sequence
|
|
template<
|
|
typename StorageT,
|
|
typename InputT,
|
|
typename ForwardIteratorT >
|
|
ForwardIteratorT operator()(
|
|
StorageT& Storage,
|
|
InputT& Input,
|
|
ForwardIteratorT InsertIt,
|
|
ForwardIteratorT SegmentBegin,
|
|
ForwardIteratorT SegmentEnd )
|
|
|
|
{
|
|
// Call replace to do the job
|
|
::boost::algorithm::detail::replace( Input, InsertIt, SegmentBegin, Storage );
|
|
// Empty the storage
|
|
Storage.clear();
|
|
// Iterators were not changed, simply return the end of segment
|
|
return SegmentEnd;
|
|
}
|
|
};
|
|
|
|
// Process one segment in the replace_all algorithm
|
|
template<
|
|
typename StorageT,
|
|
typename InputT,
|
|
typename ForwardIteratorT >
|
|
inline ForwardIteratorT process_segment(
|
|
StorageT& Storage,
|
|
InputT& Input,
|
|
ForwardIteratorT InsertIt,
|
|
ForwardIteratorT SegmentBegin,
|
|
ForwardIteratorT SegmentEnd )
|
|
{
|
|
return
|
|
process_segment_helper<
|
|
has_stable_iterators<InputT>::value>()(
|
|
Storage, Input, InsertIt, SegmentBegin, SegmentEnd );
|
|
}
|
|
|
|
|
|
} // namespace detail
|
|
} // namespace algorithm
|
|
} // namespace boost
|
|
|
|
#endif // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
|