move_chars.hpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/url
  8. //
  9. #ifndef BOOST_URL_DETAIL_MOVE_CHARS_HPP
  10. #define BOOST_URL_DETAIL_MOVE_CHARS_HPP
  11. #include <boost/core/detail/string_view.hpp>
  12. #include <boost/assert.hpp>
  13. #include <cstring>
  14. #include <functional>
  15. namespace boost {
  16. namespace urls {
  17. namespace detail {
  18. // Moves characters, and adjusts any passed
  19. // views if they point to any moved characters.
  20. // true if s completely overlapped by buf
  21. inline
  22. bool
  23. is_overlapping(
  24. core::string_view buf,
  25. core::string_view s) noexcept
  26. {
  27. auto const b0 = buf.data();
  28. auto const e0 = b0 + buf.size();
  29. auto const b1 = s.data();
  30. auto const e1 = b1 + s.size();
  31. auto const less_equal =
  32. std::less_equal<char const*>();
  33. if(less_equal(e0, b1))
  34. return false;
  35. if(less_equal(e1, b0))
  36. return false;
  37. // partial overlap is undefined
  38. BOOST_ASSERT(less_equal(e1, e0));
  39. BOOST_ASSERT(less_equal(b0, b1));
  40. return true;
  41. }
  42. inline
  43. void
  44. move_chars_impl(
  45. std::ptrdiff_t,
  46. core::string_view const&) noexcept
  47. {
  48. }
  49. template<class... Sn>
  50. void
  51. move_chars_impl(
  52. std::ptrdiff_t d,
  53. core::string_view const& buf,
  54. core::string_view& s,
  55. Sn&... sn) noexcept
  56. {
  57. if(is_overlapping(buf, s))
  58. s = {s.data() + d, s.size()};
  59. move_chars_impl(d, buf, sn...);
  60. }
  61. template<class... Args>
  62. void
  63. move_chars(
  64. char* dest,
  65. char const* src,
  66. std::size_t n,
  67. Args&... args) noexcept
  68. {
  69. core::string_view buf(src, n);
  70. move_chars_impl(
  71. dest - src,
  72. core::string_view(src, n),
  73. args...);
  74. std::memmove(
  75. dest, src, n);
  76. }
  77. } // detail
  78. } // urls
  79. } // boost
  80. #endif