1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2025 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/cppalliance/http
7  
// Official repository: https://github.com/cppalliance/http
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_HTTP_SERVER_DETAIL_STABLE_STRING_HPP
10  
#ifndef BOOST_HTTP_SERVER_DETAIL_STABLE_STRING_HPP
11  
#define BOOST_HTTP_SERVER_DETAIL_STABLE_STRING_HPP
11  
#define BOOST_HTTP_SERVER_DETAIL_STABLE_STRING_HPP
12  

12  

13  
#include <boost/http/detail/config.hpp>
13  
#include <boost/http/detail/config.hpp>
14  
#include <cstdint>
14  
#include <cstdint>
15  
#include <cstdlib>
15  
#include <cstdlib>
16  

16  

17  
namespace boost {
17  
namespace boost {
18  
namespace http {
18  
namespace http {
19  
namespace detail {
19  
namespace detail {
20  

20  

21  
// avoids SBO
21  
// avoids SBO
22  
class stable_string
22  
class stable_string
23  
{
23  
{
24  
    char const* p_ = 0;
24  
    char const* p_ = 0;
25  
    std::size_t n_ = 0;
25  
    std::size_t n_ = 0;
26  

26  

27  
public:
27  
public:
28  
    ~stable_string()
28  
    ~stable_string()
29  
    {
29  
    {
30  
        if(p_)
30  
        if(p_)
31  
            delete[] p_;
31  
            delete[] p_;
32  
    }
32  
    }
33  

33  

34  
    stable_string() = default;
34  
    stable_string() = default;
35  

35  

36  
    stable_string(
36  
    stable_string(
37  
        stable_string&& other) noexcept
37  
        stable_string&& other) noexcept
38  
        : p_(other.p_)
38  
        : p_(other.p_)
39  
        , n_(other.n_)
39  
        , n_(other.n_)
40  
    {
40  
    {
41  
        other.p_ = nullptr;
41  
        other.p_ = nullptr;
42  
        other.n_ = 0;
42  
        other.n_ = 0;
43  
    }
43  
    }
44  

44  

45  
    stable_string& operator=(
45  
    stable_string& operator=(
46  
        stable_string&& other) noexcept
46  
        stable_string&& other) noexcept
47  
    {
47  
    {
48  
        auto p = p_;
48  
        auto p = p_;
49  
        auto n = n_;
49  
        auto n = n_;
50  
        p_ = other.p_;
50  
        p_ = other.p_;
51  
        n_ = other.n_;
51  
        n_ = other.n_;
52  
        other.p_ = p;
52  
        other.p_ = p;
53  
        other.n_ = n;
53  
        other.n_ = n;
54  
        return *this;
54  
        return *this;
55  
    }
55  
    }
56  

56  

57  
    explicit
57  
    explicit
58  
    stable_string(
58  
    stable_string(
59  
        std::string_view s)
59  
        std::string_view s)
60  
        : p_(
60  
        : p_(
61  
            [&]
61  
            [&]
62  
            {
62  
            {
63  
                auto p =new char[s.size()];
63  
                auto p =new char[s.size()];
64  
                std::memcpy(p, s.data(), s.size());
64  
                std::memcpy(p, s.data(), s.size());
65  
                return p;
65  
                return p;
66  
            }())
66  
            }())
67  
        , n_(s.size())
67  
        , n_(s.size())
68  
    {
68  
    {
69  
    }
69  
    }
70  

70  

71  
    stable_string(
71  
    stable_string(
72  
        char const* it, char const* end)
72  
        char const* it, char const* end)
73  
        : stable_string(std::string_view(it, end))
73  
        : stable_string(std::string_view(it, end))
74  
    {
74  
    {
75  
    }
75  
    }
76  

76  

77  
    char const* data() const noexcept
77  
    char const* data() const noexcept
78  
    {
78  
    {
79  
        return p_;
79  
        return p_;
80  
    }
80  
    }
81  

81  

82  
    std::size_t size() const noexcept
82  
    std::size_t size() const noexcept
83  
    {
83  
    {
84  
        return n_;
84  
        return n_;
85  
    }
85  
    }
86  

86  

87  
    operator core::string_view() const noexcept
87  
    operator core::string_view() const noexcept
88  
    {
88  
    {
89  
        return { data(), size() };
89  
        return { data(), size() };
90  
    }
90  
    }
91  

91  

92  
    operator std::string_view() const noexcept
92  
    operator std::string_view() const noexcept
93  
    {
93  
    {
94  
        return { data(), size() };
94  
        return { data(), size() };
95  
    }
95  
    }
96  
};
96  
};
97  

97  

98  
} // detail
98  
} // detail
99  
} // http
99  
} // http
100  
} // boost
100  
} // boost
101  

101  

102  
#endif
102  
#endif