This repository has been archived by the owner on Oct 7, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharray.hpp
114 lines (95 loc) · 4.6 KB
/
array.hpp
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
#ifndef MUSH_MARRAY_HEADER
#define MUSH_MARRAY_HEADER
#include <iterator>
#include <algorithm>
namespace mush
{
template<typename... Sizes>
constexpr inline size_t get_marray_size(Sizes... dim)
{
return (dim * ...) == 0 ? 1 : (dim * ...);
}
template<typename T, size_t... Dimensions>
struct Array
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
template <size_type Depth>
struct array_access_proxy
{
Array& ref;
size_type cindex;
constexpr explicit array_access_proxy(Array& arr, size_t cindex) : ref(arr), cindex(cindex) {}
constexpr auto operator[](size_type index)
{
if constexpr (Depth == sizeof...(Dimensions))
return ref.element_container[cindex * ref.dims[Depth - 1] + index];
else
return array_access_proxy<Depth+1>(ref, index + (cindex * ref.dims[Depth-1]));
}
};
value_type element_container[get_marray_size(Dimensions...)];
const size_type dims[sizeof...(Dimensions)];
Array() : dims{ Dimensions... } {}
template<typename... Args>
Array(Args... args) : element_container{ args... }, dims{ Dimensions... } {}
void fill(const value_type& f)
{ std::fill_n(element_container, get_marray_size(Dimensions...), f); }
void swap(Array& other)
{ std::swap(*this, other); }
// iterators
constexpr iterator begin() noexcept { return iterator(element_container); }
constexpr iterator end() noexcept
{ return iterator(element_container + get_marray_size(Dimensions...)); }
constexpr const_iterator begin() const noexcept { return iterator(element_container); }
constexpr const_iterator end() const noexcept
{ return iterator(element_container + get_marray_size(Dimensions...)); }
constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
constexpr const_iterator cbegin() const noexcept { return begin(); }
constexpr const_iterator cend() const noexcept { return end(); }
constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
constexpr const_reverse_iterator crend() const noexcept { return rend(); }
// capacity
constexpr size_type size() const noexcept { return get_marray_size(Dimensions...); }
constexpr size_type max_size() const noexcept { return get_marray_size(Dimensions...); }
constexpr bool empty() const noexcept { return false; }
// element access
template <size_type Depth = 1>
constexpr auto operator[](size_type index)
{
if constexpr (Depth == sizeof...(Dimensions))
return reference(element_container[index]);
else
return array_access_proxy<Depth+1>(*this, index);
}
constexpr reference front() { return element_container[0]; }
constexpr const_reference front() const { return element_container[0]; }
constexpr reference back()
{
return element_container[get_marray_size(Dimensions...) > 0 ?
get_marray_size(Dimensions...) - 1 : 0
];
}
constexpr const_reference back() const
{
return element_container[get_marray_size(Dimensions...) > 0 ?
get_marray_size(Dimensions...) - 1 : 0
];
}
constexpr pointer data() noexcept { return element_container; }
constexpr const pointer data() const noexcept { return element_container; }
};
}
#endif