Serenity Operating System
1/*
2 * Copyright (c) 2020, the SerenityOS developers.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Traits.h>
10
11namespace AK {
12
13template<typename T>
14class TypedTransfer {
15public:
16 static void move(T* destination, T* source, size_t count)
17 {
18 if (count == 0)
19 return;
20
21 if constexpr (Traits<T>::is_trivial()) {
22 __builtin_memmove(destination, source, count * sizeof(T));
23 return;
24 }
25
26 for (size_t i = 0; i < count; ++i) {
27 if (destination <= source)
28 new (&destination[i]) T(AK::move(source[i]));
29 else
30 new (&destination[count - i - 1]) T(AK::move(source[count - i - 1]));
31 }
32 }
33
34 static size_t copy(T* destination, T const* source, size_t count)
35 {
36 if (count == 0)
37 return 0;
38
39 if constexpr (Traits<T>::is_trivial()) {
40 if (count == 1)
41 *destination = *source;
42 else
43 __builtin_memmove(destination, source, count * sizeof(T));
44 return count;
45 }
46
47 for (size_t i = 0; i < count; ++i) {
48 if (destination <= source)
49 new (&destination[i]) T(source[i]);
50 else
51 new (&destination[count - i - 1]) T(source[count - i - 1]);
52 }
53
54 return count;
55 }
56
57 static bool compare(T const* a, T const* b, size_t count)
58 {
59 if (count == 0)
60 return true;
61
62 if constexpr (Traits<T>::is_trivial())
63 return !__builtin_memcmp(a, b, count * sizeof(T));
64
65 for (size_t i = 0; i < count; ++i) {
66 if (a[i] != b[i])
67 return false;
68 }
69
70 return true;
71 }
72
73 static void delete_(T* ptr, size_t count)
74 {
75 if (count == 0)
76 return;
77
78 if constexpr (Traits<T>::is_trivial()) {
79 return;
80 }
81
82 for (size_t i = 0; i < count; ++i)
83 ptr[i].~T();
84 }
85};
86
87}