join.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Boost string_algo library join.hpp header file ---------------------------//
  2. // Copyright Pavol Droba 2002-2006.
  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_JOIN_HPP
  9. #define BOOST_STRING_JOIN_HPP
  10. #include <boost/algorithm/string/config.hpp>
  11. #include <boost/algorithm/string/detail/sequence.hpp>
  12. #include <boost/range/value_type.hpp>
  13. #include <boost/range/as_literal.hpp>
  14. /*! \file
  15. Defines join algorithm.
  16. Join algorithm is a counterpart to split algorithms.
  17. It joins strings from a 'list' by adding user defined separator.
  18. Additionally there is a version that allows simple filtering
  19. by providing a predicate.
  20. */
  21. namespace boost {
  22. namespace algorithm {
  23. // join --------------------------------------------------------------//
  24. //! Join algorithm
  25. /*!
  26. This algorithm joins all strings in a 'list' into one long string.
  27. Segments are concatenated by given separator.
  28. \param Input A container that holds the input strings. It must be a container-of-containers.
  29. \param Separator A string that will separate the joined segments.
  30. \return Concatenated string.
  31. \note This function provides the strong exception-safety guarantee
  32. */
  33. template< typename SequenceSequenceT, typename Range1T>
  34. inline typename range_value<SequenceSequenceT>::type
  35. join(
  36. const SequenceSequenceT& Input,
  37. const Range1T& Separator)
  38. {
  39. // Define working types
  40. typedef typename range_value<SequenceSequenceT>::type ResultT;
  41. typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
  42. // Parse input
  43. InputIteratorT itBegin=::boost::begin(Input);
  44. InputIteratorT itEnd=::boost::end(Input);
  45. // Construct container to hold the result
  46. ResultT Result;
  47. // Append first element
  48. if(itBegin!=itEnd)
  49. {
  50. detail::insert(Result, ::boost::end(Result), *itBegin);
  51. ++itBegin;
  52. }
  53. for(;itBegin!=itEnd; ++itBegin)
  54. {
  55. // Add separator
  56. detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
  57. // Add element
  58. detail::insert(Result, ::boost::end(Result), *itBegin);
  59. }
  60. return Result;
  61. }
  62. // join_if ----------------------------------------------------------//
  63. //! Conditional join algorithm
  64. /*!
  65. This algorithm joins all strings in a 'list' into one long string.
  66. Segments are concatenated by given separator. Only segments that
  67. satisfy the predicate will be added to the result.
  68. \param Input A container that holds the input strings. It must be a container-of-containers.
  69. \param Separator A string that will separate the joined segments.
  70. \param Pred A segment selection predicate
  71. \return Concatenated string.
  72. \note This function provides the strong exception-safety guarantee
  73. */
  74. template< typename SequenceSequenceT, typename Range1T, typename PredicateT>
  75. inline typename range_value<SequenceSequenceT>::type
  76. join_if(
  77. const SequenceSequenceT& Input,
  78. const Range1T& Separator,
  79. PredicateT Pred)
  80. {
  81. // Define working types
  82. typedef typename range_value<SequenceSequenceT>::type ResultT;
  83. typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
  84. // Parse input
  85. InputIteratorT itBegin=::boost::begin(Input);
  86. InputIteratorT itEnd=::boost::end(Input);
  87. // Construct container to hold the result
  88. ResultT Result;
  89. // Roll to the first element that will be added
  90. while(itBegin!=itEnd && !Pred(*itBegin)) ++itBegin;
  91. // Add this element
  92. if(itBegin!=itEnd)
  93. {
  94. detail::insert(Result, ::boost::end(Result), *itBegin);
  95. ++itBegin;
  96. }
  97. for(;itBegin!=itEnd; ++itBegin)
  98. {
  99. if(Pred(*itBegin))
  100. {
  101. // Add separator
  102. detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
  103. // Add element
  104. detail::insert(Result, ::boost::end(Result), *itBegin);
  105. }
  106. }
  107. return Result;
  108. }
  109. } // namespace algorithm
  110. // pull names to the boost namespace
  111. using algorithm::join;
  112. using algorithm::join_if;
  113. } // namespace boost
  114. #endif // BOOST_STRING_JOIN_HPP