-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmemory.hpp
93 lines (85 loc) · 2.99 KB
/
memory.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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* memory.hpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: aisraely <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/01/01 20:51:47 by aisraely #+# #+# */
/* Updated: 2022/01/01 20:51:47 by aisraely ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MEMORY_HPP
# define MEMORY_HPP
# include <memory>
namespace ft
{
// addressof
// avoids calling object's operator&(); takes care of qualifiers
template <class T>
T *addressof(T &ref)
{
return (reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(ref))));
}
// destroy_a
// destroys elements in range with given allocator
template <typename ForwardIterator, typename Alloc>
void destroy_a(ForwardIterator first, ForwardIterator last, Alloc &alloc)
{
for (; first != last; ++first)
alloc.destroy(ft::addressof(*first));
}
// uninitialized_copy_a
// memory should be only allocated; objects shouldn't be constructed, because that's what this function does.
template <typename InputIterator, typename ForwardIterator, typename Alloc>
ForwardIterator uninitialized_copy_a(InputIterator first, InputIterator last, ForwardIterator result, Alloc &alloc)
{
ForwardIterator curr = result;
try
{
for (; first != last; ++first, ++curr)
alloc.construct(ft::addressof(*curr), *first);
return (curr);
}
catch (...)
{
destroy_a(result, curr, alloc);
throw ;
}
}
// uninitialized_fill_a
// constructs objects in the given range with the given alloc
template <typename ForwardIterator, typename T, typename Alloc>
void uninitialized_fill_a(ForwardIterator first, ForwardIterator last, const T &x, Alloc &alloc)
{
ForwardIterator curr = first;
try
{
for (; curr != last; ++curr)
alloc.construct(ft::addressof(*curr), x);
}
catch (...)
{
destroy_a(first, curr, alloc);
throw ;
}
}
// uninitialized_fill_n_a
// differs from its counterpart in that receives `first` and `n` instead of a full range
template <typename ForwardIterator, typename Size, typename T, typename Alloc>
void uninitialized_fill_n_a(ForwardIterator first, Size n, const T &x, Alloc &alloc)
{
ForwardIterator curr = first;
try
{
for (; n > 0; --n, ++curr)
alloc.construct(ft::addressof(*curr), x);
}
catch (...)
{
destroy_a(first, curr, alloc);
throw ;
}
}
}
#endif