-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContiguousContainer.h
More file actions
171 lines (131 loc) · 4.44 KB
/
Copy pathContiguousContainer.h
File metadata and controls
171 lines (131 loc) · 4.44 KB
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
#pragma once
#ifndef _NSTD_ARRAYUNDER_
#define _NSTD_ARRAYUNDER_
#include <xmemory>
#include "Defines.h"
#include "Pair.h"
_NSTD_BEGIN
template <typename _Ty, typename _Alloc>
class _Contiguous_container {
friend _STD _Tidy_deallocate_guard<_Contiguous_container>;
template <typename, typename> friend class _Contiguous_containter;
using _Alty = _STD _Rebind_alloc_t<_Alloc, _Ty>;
using _Alty_traits = _STD allocator_traits<_Alty>;
protected:
using value_type = typename _Alty_traits::value_type;
using allocator_type = _Alty;
using size_type = typename _Alty_traits::size_type;
using difference_type = typename _Alty_traits::difference_type;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = typename _Alty_traits::pointer;
using const_pointer = typename _Alty_traits::const_pointer;
// TODO
// using iterator =
// using const_iterator =
// using reverse_iterator =
// using const_reverse_iterator =
using pair_type = _NSTD pair<size_type, pointer>;
private:
static constexpr size_type _Mybytesize = sizeof(value_type);
static constexpr bool _Copyable = _STD is_trivially_copy_constructible_v<value_type>;
protected:
template <typename st1, typename st2>
_NODISCARD static constexpr auto const& _Min(const st1& first, const st2& second) {
return first > second ? second : first;
}
protected:
_Contiguous_container() : _Mypair({ 0, 0 }) {}
_Contiguous_container(const size_type& size) : _Mypair({ 0, 0 }) { _Grow(size); }
_Contiguous_container(const _Contiguous_container& other) : _Mypair({ 0, 0 }) { _Set(other); }
_Contiguous_container(const_pointer _Ref, size_type _Refsize) : _Mypair({ 0, 0 }) { _Grow(_Refsize, _Ref, _Refsize); }
~_Contiguous_container() { _Tidy_deallocate(); }
protected:
auto& operator[] (const size_type& index) const {
_NSTD_ASSERT(index < _Mysize(),
"index out of bounds");
return _Myarr()[index];
}
protected:
void _Grow(const size_type& _Newsize, const_pointer _Ref, size_type _Refsize) {
//_NSTD_ASSERT(_Newsize >= 0,
// "Allocating negative memory?");
// vvv
// Assume size_type is unsigned or _Alloc knows how to allocate negative memory
_Tidy_deallocate();
_Myarr() = _Alloc(_Newsize);
_Mysize() = _Newsize;
_Construct_default();
_Construct(_Ref, _Refsize);
}
// Forward _Alty::allocate(_Size)
pointer _Alloc(const size_type& _Size) {
_Alty alloc;
return alloc.allocate(_Size);
}
_STD enable_if_t<_Copyable> _Construct(const_pointer _Ref, size_type _Refsize) {
_NSTD_FOR_I(_Min(_Refsize, _Mysize()))
_Myarr()[_I] = _Ref[_I];
}
_STD enable_if_t<_Copyable, _Contiguous_container> _Copy() const {
_Contiguous_container c;
c._Grow(_Mysize(), _Myarr(), _Mysize());
return c;
}
void _Grow(const size_type& _Newsize) {
const_pointer p = _Myarr();
size_type s = _Mysize();
_Grow_RAWCOPY(_Newsize, p, s);
_Deallocate(p, s);
}
//_STD enable_if_t<!_Copyable> _Set(const _Contiguous_container&) = delete;
_STD enable_if_t<_Copyable> _Set(const _Contiguous_container& other) {
_Grow(other._Mysize(), other._Myarr(), other._Mysize());
}
void _Tidy_deallocate() {
_Deallocate(_Myarr(), _Mysize());
_Myarr() = nullptr;
_Mysize() = 0;
}
// Forward _Alty::deallocate
void _Deallocate(const_pointer p, size_type s) {
_Alty alloc;
alloc.deallocate(p, s);
}
size_type& _Mysize() {
return _Mypair.first;
}
const size_type& _Mysize() const {
return _Mypair.first;
}
// Unchecked
pointer& _Myarr() {
return _Mypair.second;
}
const pointer& _Myarr() const {
return _Mypair.second;
}
private:
//_STD enable_if_t<!_STD is_default_constructible_v<value_type>> _Construct_default() {}
_STD enable_if_t< _STD is_default_constructible_v<value_type>> _Construct_default() {
_Alty alloc;
_NSTD_FOR_I(_Mysize())
_Alty_traits::construct(alloc, (_Myarr() + _I), value_type());
}
void _Grow_RAWCOPY(const size_type& _Newsize, const_pointer _Ref, size_type _Refsize) {
_Tidy_deallocate();
_Myarr() = _Alloc(_Newsize);
_Mysize() = _Newsize;
_Construct_default();
_Construct_RAWCOPY(_Ref, _Refsize);
}
void _Construct_RAWCOPY(const_pointer _Ref, size_type _Refsize) {
_NSTD_FOR_I(_Min(_Refsize * _Mybytesize, _Mysize() * _Mybytesize))
reinterpret_cast<char*>(_Myarr())[_I] = reinterpret_cast<const char*>(_Ref)[_I];
}
pair_type _Mypair;
};
//template <typename T>
//using _ArrayUnder = _ArrayUnder<typename T::value_type, typename T::allocator_type>;
_NSTD_END
#endif // _NSTD_ARRAYUNDER_