1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <stdlib.h>
20 
21 #define array_copy(dest, src, count)                          \
22     do {                                                      \
23         STATIC_ASSERT(sizeof((dest)[0]) == sizeof((src)[0])); \
24         memcpy((dest), (src), sizeof((dest)[0]) * (count));   \
25     } while (false)
26 
27 #define array_shift(array, dest, src)                                          \
28     do {                                                                       \
29         assert(src <= countof((array)));                                       \
30         assert(dest <= countof((array)));                                      \
31         memmove((array) + (dest), (array) + (src),                             \
32                 sizeof((array)[0]) * (countof((array)) - MAX((src), (dest)))); \
33     } while (false)
34 
35 #define array_insert(array, index, value)           \
36     do {                                            \
37         array_shift((array), (index) + 1, (index)); \
38         (array)[(index)] = (value);                 \
39     } while (false)
40 
41 #define array_insert_overflow(array, index, value, overflow_value) \
42     do {                                                           \
43         if (index == countof((array))) {                           \
44             *overflow_value = value;                               \
45         } else {                                                   \
46             *overflow_value = (array)[countof((array)) - 1];       \
47             array_insert((array), (index), (value));               \
48         }                                                          \
49     } while (false)
50 
51 #define array_clear_end(array, start)                              \
52     do {                                                           \
53         memset((array) + (start), 0,                               \
54                sizeof((array)[0]) * (countof((array)) - (start))); \
55     } while (false)
56 
57 #define array_shift_down(array, dest, src)                             \
58     do {                                                               \
59         assert(src > dest);                                            \
60         assert(src <= countof((array)));                               \
61         array_shift((array), (dest), (src));                           \
62         array_clear_end((array), countof((array)) - ((src) - (dest))); \
63     } while (false)
64