OpenTTD Source: src/core/span_type.hpp Source File

OpenTTD Source 13.1

span_type.hpp
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #ifndef CORE_SPAN_TYPE_HPP
11 #define CORE_SPAN_TYPE_HPP
12
13 /* This is a partial copy/paste from https://github.com/gsl-lite/gsl-lite/blob/master/include/gsl/gsl-lite.hpp */
14
15 /* Template to check if a template variable defines size() and data(). */
16 template <class, class = void>
17 struct has_size_and_data : std::false_type{};
18 template <class C>
19 struct has_size_and_data
20 <
21 C, std::void_t<
22 decltype(std::size(std::declval<C>())),
23 decltype(std::data(std::declval<C>()))>
24 > : std::true_type{};
25
26 /* Template to check if two elements are compatible. */
27 template <class, class, class = void>
28 struct is_compatible_element : std::false_type {};
29 template <class C, class E>
30 struct is_compatible_element
31 <
32 C, E, std::void_t<
33 decltype(std::data(std::declval<C>())),
34 typename std::remove_pointer_t<decltype(std::data( std::declval<C&>()))>(*)[]>
35 > : std::is_convertible<typename std::remove_pointer_t<decltype(std::data(std::declval<C&>()))>(*)[], E(*)[]>{};
36
37 /* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */
38 template <class C, class E>
39 struct is_compatible_container : std::bool_constant
40 <
41 has_size_and_data<C>::value
42 && is_compatible_element<C,E>::value
43 >{};
44
59 template<class T>
60 class span {
61 public:
62 typedef T element_type;
63 typedef typename std::remove_cv< T >::type value_type;
64
65 typedef T &reference;
66 typedef T *pointer;
67 typedef const T &const_reference;
68 typedef const T *const_pointer;
69
70 typedef pointer iterator;
71 typedef const_pointer const_iterator;
72
73 typedef size_t size_type;
74 typedef std::ptrdiff_t difference_type;
75
76 constexpr span() noexcept : first(nullptr), last(nullptr) {}
77
78 constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {}
79
80 template<class Container, typename std::enable_if<(is_compatible_container<Container, element_type>::value), int>::type = 0>
81 constexpr span(Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
82 template<class Container, typename std::enable_if<(std::is_const<element_type>::value && is_compatible_container<Container, element_type>::value), int>::type = 0>
83 constexpr span(const Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
84
85 constexpr size_t size() const noexcept { return static_cast<size_t>( last - first ); }
86 constexpr std::ptrdiff_t ssize() const noexcept { return static_cast<std::ptrdiff_t>( last - first ); }
87 constexpr bool empty() const noexcept { return size() == 0; }
88
89 constexpr iterator begin() const noexcept { return iterator(first); }
90 constexpr iterator end() const noexcept { return iterator(last); }
91
92 constexpr const_iterator cbegin() const noexcept { return const_iterator(first); }
93 constexpr const_iterator cend() const noexcept { return const_iterator(last); }
94
95 constexpr reference operator[](size_type idx) const { return first[idx]; }
96
97 private:
98 pointer first;
99 pointer last;
100 };
101
102 #endif /* CORE_SPAN_TYPE_HPP */
has_size_and_data
Definition: span_type.hpp:17
is_compatible_container
Definition: span_type.hpp:39
is_compatible_element
Definition: span_type.hpp:28
span
A trimmed down version of what std::span will be in C++20.
Definition: span_type.hpp:60