summaryrefslogtreecommitdiff
path: root/boost/beast/core/span.hpp
blob: e170729472b91026a39464e19cdcd0cb06d48d2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//

#ifndef BOOST_BEAST_CORE_SPAN_HPP
#define BOOST_BEAST_CORE_SPAN_HPP

#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/type_traits.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <type_traits>

namespace boost {
namespace beast {

/** A range of bytes expressed as a ContiguousContainer

    This class implements a non-owning reference to a storage
    area of a certain size and having an underlying integral
    type with size of 1.

    @tparam T The type pointed to by span iterators
*/
template<class T>
class span
{
    T* data_ = nullptr;
    std::size_t size_ = 0;

public:
    /// The type of value, including cv qualifiers
    using element_type = T;

    /// The type of value of each span element
    using value_type = typename std::remove_const<T>::type;

    /// The type of integer used to index the span
    using index_type = std::ptrdiff_t;

    /// A pointer to a span element
    using pointer = T*;

    /// A reference to a span element
    using reference = T&;

    /// The iterator used by the container
    using iterator = pointer;

    /// The const pointer used by the container
    using const_pointer = T const*;

    /// The const reference used by the container
    using const_reference = T const&;

    /// The const iterator used by the container
    using const_iterator = const_pointer;

    /// Constructor
    span() = default;

    /// Constructor
    span(span const&) = default;

    /// Assignment
    span& operator=(span const&) = default;

    /** Constructor

        @param data A pointer to the beginning of the range of elements

        @param size The number of elements pointed to by `data`
    */
    span(T* data, std::size_t size)
        : data_(data), size_(size)
    {
    }

    /** Constructor

        @param container The container to construct from
    */
    template<class ContiguousContainer
#if ! BOOST_BEAST_DOXYGEN
        , class = typename std::enable_if<
          detail::is_contiguous_container<
                ContiguousContainer, T>::value>::type
#endif
    >
    explicit
    span(ContiguousContainer&& container)
        : data_(container.data())
        , size_(container.size())
    {
    }

#if ! BOOST_BEAST_DOXYGEN
    template<class CharT, class Traits, class Allocator>
    explicit
    span(std::basic_string<CharT, Traits, Allocator>& s)
        : data_(&s[0])
        , size_(s.size())
    {
    }

    template<class CharT, class Traits, class Allocator>
    explicit
    span(std::basic_string<CharT, Traits, Allocator> const& s)
        : data_(s.data())
        , size_(s.size())
    {
    }
#endif

    /** Assignment

        @param container The container to assign from
    */
    template<class ContiguousContainer>
#if BOOST_BEAST_DOXYGEN
    span&
#else
    typename std::enable_if<detail::is_contiguous_container<
        ContiguousContainer, T>::value,
    span&>::type
#endif
    operator=(ContiguousContainer&& container)
    {
        data_ = container.data();
        size_ = container.size();
        return *this;
    }

#if ! BOOST_BEAST_DOXYGEN
    template<class CharT, class Traits, class Allocator>
    span&
    operator=(std::basic_string<
        CharT, Traits, Allocator>& s)
    {
        data_ = &s[0];
        size_ = s.size();
        return *this;
    }

    template<class CharT, class Traits, class Allocator>
    span&
    operator=(std::basic_string<
        CharT, Traits, Allocator> const& s)
    {
        data_ = s.data();
        size_ = s.size();
        return *this;
    }
#endif

    /// Returns `true` if the span is empty
    bool
    empty() const
    {
        return size_ == 0;
    }

    /// Returns a pointer to the beginning of the span
    T*
    data() const
    {
        return data_;
    }

    /// Returns the number of elements in the span
    std::size_t
    size() const
    {
        return size_;
    }

    /// Returns an iterator to the beginning of the span
    const_iterator
    begin() const
    {
        return data_;
    }
                
    /// Returns an iterator to the beginning of the span
    const_iterator
    cbegin() const
    {
        return data_;
    }
       
    /// Returns an iterator to one past the end of the span
    const_iterator
    end() const
    {
        return data_ + size_;
    }
        
    /// Returns an iterator to one past the end of the span
    const_iterator
    cend() const
    {
        return data_ + size_;
    }
};

} // beast
} // boost

#endif