1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/url
7  
// Official repository: https://github.com/boostorg/url
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_URL_DETAIL_MOVE_CHARS_HPP
10  
#ifndef BOOST_URL_DETAIL_MOVE_CHARS_HPP
11  
#define BOOST_URL_DETAIL_MOVE_CHARS_HPP
11  
#define BOOST_URL_DETAIL_MOVE_CHARS_HPP
12  

12  

13  
#include <boost/core/detail/string_view.hpp>
13  
#include <boost/core/detail/string_view.hpp>
14  
#include <boost/assert.hpp>
14  
#include <boost/assert.hpp>
15  
#include <cstring>
15  
#include <cstring>
16  
#include <functional>
16  
#include <functional>
17  

17  

18  
namespace boost {
18  
namespace boost {
19  
namespace urls {
19  
namespace urls {
20  
namespace detail {
20  
namespace detail {
21  

21  

22  
// Moves characters, and adjusts any passed
22  
// Moves characters, and adjusts any passed
23  
// views if they point to any moved characters.
23  
// views if they point to any moved characters.
24  

24  

25  
// true if s completely overlapped by buf
25  
// true if s completely overlapped by buf
26  
inline
26  
inline
27  
bool
27  
bool
28  
is_overlapping(
28  
is_overlapping(
29  
    core::string_view buf,
29  
    core::string_view buf,
30  
    core::string_view s) noexcept
30  
    core::string_view s) noexcept
31  
{
31  
{
32  
    auto const b0 = buf.data();
32  
    auto const b0 = buf.data();
33  
    auto const e0 = b0 + buf.size();
33  
    auto const e0 = b0 + buf.size();
34  
    auto const b1 = s.data();
34  
    auto const b1 = s.data();
35  
    auto const e1 = b1 + s.size();
35  
    auto const e1 = b1 + s.size();
36  
    auto const less_equal =
36  
    auto const less_equal =
37  
        std::less_equal<char const*>();
37  
        std::less_equal<char const*>();
38  
    if(less_equal(e0, b1))
38  
    if(less_equal(e0, b1))
39  
        return false;
39  
        return false;
40  
    if(less_equal(e1, b0))
40  
    if(less_equal(e1, b0))
41  
        return false;
41  
        return false;
42  
    // partial overlap is undefined
42  
    // partial overlap is undefined
43  
    BOOST_ASSERT(less_equal(e1, e0));
43  
    BOOST_ASSERT(less_equal(e1, e0));
44  
    BOOST_ASSERT(less_equal(b0, b1));
44  
    BOOST_ASSERT(less_equal(b0, b1));
45  
    return true;
45  
    return true;
46  
}
46  
}
47  

47  

48  
inline
48  
inline
49  
void
49  
void
50  
move_chars_impl(
50  
move_chars_impl(
51  
    std::ptrdiff_t,
51  
    std::ptrdiff_t,
52  
    core::string_view const&) noexcept
52  
    core::string_view const&) noexcept
53  
{
53  
{
54  
}
54  
}
55  

55  

56  
template<class... Sn>
56  
template<class... Sn>
57  
void
57  
void
58  
move_chars_impl(
58  
move_chars_impl(
59  
    std::ptrdiff_t d,
59  
    std::ptrdiff_t d,
60  
    core::string_view const& buf,
60  
    core::string_view const& buf,
61  
    core::string_view& s,
61  
    core::string_view& s,
62  
    Sn&... sn) noexcept
62  
    Sn&... sn) noexcept
63  
{
63  
{
64  
    if(is_overlapping(buf, s))
64  
    if(is_overlapping(buf, s))
65  
        s = {s.data() + d, s.size()};
65  
        s = {s.data() + d, s.size()};
66  
    move_chars_impl(d, buf, sn...);
66  
    move_chars_impl(d, buf, sn...);
67  
}
67  
}
68  

68  

69  
template<class... Args>
69  
template<class... Args>
70  
void
70  
void
71  
move_chars(
71  
move_chars(
72  
    char* dest,
72  
    char* dest,
73  
    char const* src,
73  
    char const* src,
74  
    std::size_t n,
74  
    std::size_t n,
75  
    Args&... args) noexcept
75  
    Args&... args) noexcept
76  
{
76  
{
77  
    move_chars_impl(
77  
    move_chars_impl(
78  
        dest - src,
78  
        dest - src,
79  
        core::string_view(src, n),
79  
        core::string_view(src, n),
80  
        args...);
80  
        args...);
81  
    std::memmove(
81  
    std::memmove(
82  
        dest, src, n);
82  
        dest, src, n);
83  
}
83  
}
84  

84  

85  
} // detail
85  
} // detail
86  
} // urls
86  
} // urls
87  
} // boost
87  
} // boost
88  

88  

89  
#endif
89  
#endif