aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include/Span.h
blob: a43e8f9928699111135739f48a4b87169042ba0e (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
#pragma once

#include <array>
#include <cstddef>
#include <initializer_list>
#include <vector>

template<class T>
struct Span
{
public:
    using element_type = T;
    using pointer = T*;
    using reference = T&;
    using iterator = T*;

    constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {}
    constexpr Span(std::nullptr_t) noexcept : Span() {}
    constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {}
    constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {}
    constexpr Span(std::initializer_list<T> l) noexcept : m_ptr(l.begin()), m_count(l.size()) {}

    template<size_t N>
    constexpr Span(T (&arr)[N]) noexcept : Span(arr, N)
    {
    }

    Span(std::vector<T>& v) noexcept : Span(v.data(), v.size()) {}
    Span(const std::vector<std::remove_const_t<T>>& v) noexcept : Span(v.data(), v.size()) {}

    constexpr iterator begin() const { return m_ptr; }
    constexpr iterator end() const { return m_ptr + m_count; }

    constexpr reference operator[](size_t i) const { return m_ptr[i]; }
    constexpr size_t size() const { return m_count; }

private:
    pointer m_ptr;
    size_t m_count;
};

template<class T>
Span<T> make_span(std::vector<T>& v)
{
    return {v.data(), v.size()};
}

template<class T>
Span<const T> make_span(const std::vector<T>& v)
{
    return {v.data(), v.size()};
}