C++ Essence Library 0.1.0
A Utility Library for Modern C++ Programming
Loading...
Searching...
No Matches
data_view.hpp
1/*
2 * Copyright (c) 2024 The RefValue Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include "type_identity.hpp"
26
27#include <array>
28#include <cstddef>
29#include <iterator>
30#include <type_traits>
31
32#if __has_include(<version>)
33#include <version>
34#endif
35
36#if __cpp_lib_span >= 202002L
37#include <span>
38#endif
39
40#if __cpp_lib_ranges >= 201911L
41#include <ranges>
42#endif
43
44namespace essence {
49 template <typename T>
50 class data_view {
51 public:
52 using element_type = T;
53 using value_type = std::remove_cv_t<T>;
54 using size_type = std::size_t;
55 using difference_type = std::ptrdiff_t;
56 using pointer = T*;
57 using const_pointer = const T*;
58 using reference = T&;
59 using const_reference = const T&;
60 using iterator = T*;
61 using reverse_iterator = std::reverse_iterator<iterator>;
62
63 constexpr data_view(T* ptr, size_type size) noexcept : ptr_{ptr}, size_{size} {}
64
65 template <std::size_t N>
66 constexpr data_view(type_identity_t<element_type> (&array)[N]) noexcept // NOLINT(*-explicit-constructor)
67 : ptr_{array}, size_{N} {}
68
69 template <typename U, std::size_t N>
70 constexpr data_view(std::array<U, N>& array) noexcept // NOLINT(*-explicit-constructor)
71 : ptr_{array.data()}, size_{array.size()} {}
72
73 template <typename U, std::size_t N>
74 constexpr data_view(const std::array<U, N>& array) noexcept // NOLINT(*-explicit-constructor)
75 : ptr_{array.data()}, size_{array.size()} {}
76
77#if __cpp_lib_ranges >= 201911L
78 template <typename Range>
79 constexpr data_view(Range&& range) // NOLINT(*-explicit-constructor, *-forwarding-reference-overload)
80 : ptr_{std::ranges::data(range)}, size_{std::ranges::size(range)} {}
81#endif
82
83#if __cpp_lib_span >= 202002L
84 template <typename U, std::size_t N>
85 constexpr data_view( // NOLINT(*-explicit-constructor, *-forwarding-reference-overload)
86 const std::span<U, N>& source) noexcept
87 : ptr_{source.data()}, size_{source.size()} {}
88#endif
89
90 constexpr data_view(const data_view&) noexcept = default;
91
92 constexpr data_view& operator=(const data_view&) noexcept = default;
93
94 constexpr reference operator[](size_type index) const noexcept {
95 return ptr_[index];
96 }
97
98#if __cpp_lib_span >= 202002L
99 constexpr operator std::span<T>() const noexcept { // NOLINT(*-explicit-constructor)
100 return std::span<T>{ptr_, size_};
101 }
102#endif
103
104 [[nodiscard]] constexpr iterator begin() const noexcept {
105 return ptr_;
106 }
107
108 [[nodiscard]] constexpr iterator end() const noexcept {
109 return ptr_ + size_;
110 }
111
112 [[nodiscard]] constexpr reverse_iterator rbegin() const noexcept {
113 return reverse_iterator{end()};
114 }
115
116 [[nodiscard]] constexpr reverse_iterator rend() const noexcept {
117 return reverse_iterator{begin()};
118 }
119
120 [[nodiscard]] constexpr pointer data() const noexcept {
121 return ptr_;
122 }
123
124 [[nodiscard]] constexpr size_type size() const noexcept {
125 return size_;
126 }
127
128 [[nodiscard]] constexpr bool empty() const noexcept {
129 return size_ == 0;
130 }
131
132 [[nodiscard]] constexpr size_type size_bytes() const noexcept {
133 return size_ * sizeof(T);
134 }
135
136 [[nodiscard]] constexpr reference front() const noexcept {
137 return ptr_[0];
138 }
139
140 [[nodiscard]] constexpr reference back() const noexcept {
141 return ptr_[size_ - 1];
142 }
143
144 [[nodiscard]] constexpr data_view subview(size_type index, size_type count) const noexcept {
145 return data_view{ptr_ + index, count};
146 }
147
148 private:
149 pointer ptr_;
150 size_type size_;
151 };
152
153 template <typename T>
154 data_view(T* ptr, std::size_t size) -> data_view<T>;
155
156 template <typename T, std::size_t N>
157 data_view(T (&)[N]) -> data_view<T>;
158
159 template <typename T, std::size_t N>
160 data_view(std::array<T, N>&) -> data_view<T>;
161
162 template <typename T, std::size_t N>
163 data_view(const std::array<T, N>&) -> data_view<const T>;
164
165#if __cpp_lib_ranges >= 201911L
166 template <typename Range>
168#endif
169} // namespace essence
A view of memory data, like std::span.
Definition data_view.hpp:50