Line data Source code
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 :
10 : #ifndef BOOST_URL_DETAIL_MOVE_CHARS_HPP
11 : #define BOOST_URL_DETAIL_MOVE_CHARS_HPP
12 :
13 : #include <boost/core/detail/string_view.hpp>
14 : #include <boost/assert.hpp>
15 : #include <cstring>
16 : #include <functional>
17 :
18 : namespace boost {
19 : namespace urls {
20 : namespace detail {
21 :
22 : // Moves characters, and adjusts any passed
23 : // views if they point to any moved characters.
24 :
25 : // true if s completely overlapped by buf
26 : inline
27 : bool
28 1288 : is_overlapping(
29 : core::string_view buf,
30 : core::string_view s) noexcept
31 : {
32 1288 : auto const b0 = buf.data();
33 1288 : auto const e0 = b0 + buf.size();
34 1288 : auto const b1 = s.data();
35 1288 : auto const e1 = b1 + s.size();
36 : auto const less_equal =
37 : std::less_equal<char const*>();
38 1288 : if(less_equal(e0, b1))
39 88 : return false;
40 1200 : if(less_equal(e1, b0))
41 1198 : return false;
42 : // partial overlap is undefined
43 2 : BOOST_ASSERT(less_equal(e1, e0));
44 2 : BOOST_ASSERT(less_equal(b0, b1));
45 2 : return true;
46 : }
47 :
48 : inline
49 : void
50 1924 : move_chars_impl(
51 : std::ptrdiff_t,
52 : core::string_view const&) noexcept
53 : {
54 1924 : }
55 :
56 : template<class... Sn>
57 : void
58 1288 : move_chars_impl(
59 : std::ptrdiff_t d,
60 : core::string_view const& buf,
61 : core::string_view& s,
62 : Sn&... sn) noexcept
63 : {
64 1288 : if(is_overlapping(buf, s))
65 2 : s = {s.data() + d, s.size()};
66 1288 : move_chars_impl(d, buf, sn...);
67 1288 : }
68 :
69 : template<class... Args>
70 : void
71 1924 : move_chars(
72 : char* dest,
73 : char const* src,
74 : std::size_t n,
75 : Args&... args) noexcept
76 : {
77 1924 : move_chars_impl(
78 : dest - src,
79 1924 : core::string_view(src, n),
80 : args...);
81 1924 : std::memmove(
82 : dest, src, n);
83 1924 : }
84 :
85 : } // detail
86 : } // urls
87 : } // boost
88 :
89 : #endif
|