sequence.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // Boost string_algo library sequence.hpp header file ---------------------------//
  2. // Copyright Pavol Droba 2002-2003.
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org/ for updates, documentation, and revision history.
  8. #ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP
  9. #define BOOST_STRING_DETAIL_SEQUENCE_HPP
  10. #include <boost/algorithm/string/config.hpp>
  11. #include <boost/mpl/bool.hpp>
  12. #include <boost/mpl/logical.hpp>
  13. #include <boost/range/begin.hpp>
  14. #include <boost/range/end.hpp>
  15. #include <boost/algorithm/string/sequence_traits.hpp>
  16. namespace boost {
  17. namespace algorithm {
  18. namespace detail {
  19. // insert helpers -------------------------------------------------//
  20. template< typename InputT, typename ForwardIteratorT >
  21. inline void insert(
  22. InputT& Input,
  23. BOOST_STRING_TYPENAME InputT::iterator At,
  24. ForwardIteratorT Begin,
  25. ForwardIteratorT End )
  26. {
  27. Input.insert( At, Begin, End );
  28. }
  29. template< typename InputT, typename InsertT >
  30. inline void insert(
  31. InputT& Input,
  32. BOOST_STRING_TYPENAME InputT::iterator At,
  33. const InsertT& Insert )
  34. {
  35. ::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) );
  36. }
  37. // erase helper ---------------------------------------------------//
  38. // Erase a range in the sequence
  39. /*
  40. Returns the iterator pointing just after the erase subrange
  41. */
  42. template< typename InputT >
  43. inline typename InputT::iterator erase(
  44. InputT& Input,
  45. BOOST_STRING_TYPENAME InputT::iterator From,
  46. BOOST_STRING_TYPENAME InputT::iterator To )
  47. {
  48. return Input.erase( From, To );
  49. }
  50. // replace helper implementation ----------------------------------//
  51. // Optimized version of replace for generic sequence containers
  52. // Assumption: insert and erase are expensive
  53. template< bool HasConstTimeOperations >
  54. struct replace_const_time_helper
  55. {
  56. template< typename InputT, typename ForwardIteratorT >
  57. void operator()(
  58. InputT& Input,
  59. BOOST_STRING_TYPENAME InputT::iterator From,
  60. BOOST_STRING_TYPENAME InputT::iterator To,
  61. ForwardIteratorT Begin,
  62. ForwardIteratorT End )
  63. {
  64. // Copy data to the container ( as much as possible )
  65. ForwardIteratorT InsertIt=Begin;
  66. BOOST_STRING_TYPENAME InputT::iterator InputIt=From;
  67. for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ )
  68. {
  69. *InputIt=*InsertIt;
  70. }
  71. if ( InsertIt!=End )
  72. {
  73. // Replace sequence is longer, insert it
  74. Input.insert( InputIt, InsertIt, End );
  75. }
  76. else
  77. {
  78. if ( InputIt!=To )
  79. {
  80. // Replace sequence is shorter, erase the rest
  81. Input.erase( InputIt, To );
  82. }
  83. }
  84. }
  85. };
  86. template<>
  87. struct replace_const_time_helper< true >
  88. {
  89. // Const-time erase and insert methods -> use them
  90. template< typename InputT, typename ForwardIteratorT >
  91. void operator()(
  92. InputT& Input,
  93. BOOST_STRING_TYPENAME InputT::iterator From,
  94. BOOST_STRING_TYPENAME InputT::iterator To,
  95. ForwardIteratorT Begin,
  96. ForwardIteratorT End )
  97. {
  98. BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To );
  99. if ( Begin!=End )
  100. {
  101. if(!Input.empty())
  102. {
  103. Input.insert( At, Begin, End );
  104. }
  105. else
  106. {
  107. Input.insert( Input.begin(), Begin, End );
  108. }
  109. }
  110. }
  111. };
  112. // No native replace method
  113. template< bool HasNative >
  114. struct replace_native_helper
  115. {
  116. template< typename InputT, typename ForwardIteratorT >
  117. void operator()(
  118. InputT& Input,
  119. BOOST_STRING_TYPENAME InputT::iterator From,
  120. BOOST_STRING_TYPENAME InputT::iterator To,
  121. ForwardIteratorT Begin,
  122. ForwardIteratorT End )
  123. {
  124. replace_const_time_helper<
  125. boost::mpl::and_<
  126. has_const_time_insert<InputT>,
  127. has_const_time_erase<InputT> >::value >()(
  128. Input, From, To, Begin, End );
  129. }
  130. };
  131. // Container has native replace method
  132. template<>
  133. struct replace_native_helper< true >
  134. {
  135. template< typename InputT, typename ForwardIteratorT >
  136. void operator()(
  137. InputT& Input,
  138. BOOST_STRING_TYPENAME InputT::iterator From,
  139. BOOST_STRING_TYPENAME InputT::iterator To,
  140. ForwardIteratorT Begin,
  141. ForwardIteratorT End )
  142. {
  143. Input.replace( From, To, Begin, End );
  144. }
  145. };
  146. // replace helper -------------------------------------------------//
  147. template< typename InputT, typename ForwardIteratorT >
  148. inline void replace(
  149. InputT& Input,
  150. BOOST_STRING_TYPENAME InputT::iterator From,
  151. BOOST_STRING_TYPENAME InputT::iterator To,
  152. ForwardIteratorT Begin,
  153. ForwardIteratorT End )
  154. {
  155. replace_native_helper< has_native_replace<InputT>::value >()(
  156. Input, From, To, Begin, End );
  157. }
  158. template< typename InputT, typename InsertT >
  159. inline void replace(
  160. InputT& Input,
  161. BOOST_STRING_TYPENAME InputT::iterator From,
  162. BOOST_STRING_TYPENAME InputT::iterator To,
  163. const InsertT& Insert )
  164. {
  165. if(From!=To)
  166. {
  167. ::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) );
  168. }
  169. else
  170. {
  171. ::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) );
  172. }
  173. }
  174. } // namespace detail
  175. } // namespace algorithm
  176. } // namespace boost
  177. #endif // BOOST_STRING_DETAIL_SEQUENCE_HPP