1 /*
2  * kmp_utils.h -- Utilities that used internally
3  */
4 
5 //===----------------------------------------------------------------------===//
6 //
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef __KMP_UTILS_H__
13 #define __KMP_UTILS_H__
14 
15 #include <cstddef>
16 
17 #include "kmp.h"
18 
19 /// A simple pure header implementation of VLA that aims to replace uses of
20 /// actual VLA, which can cause compile warning. This class by default creates a
21 /// stack buffer that can accomodate \p N elements. If the number of elements is
22 /// greater than \p N, then a heap buffer will be allocated and used to
23 /// accomodate the elements. Similar to the actual VLA, we don't check boundary
24 /// (for now), so we will not store the number of elements. We can always revise
25 /// it later.
26 template <typename T, unsigned N = 8> class SimpleVLA final {
27   T StackBuffer[N];
28   T *HeapBuffer = nullptr;
29   T *Ptr = StackBuffer;
30 
31 public:
32   SimpleVLA() = delete;
33   SimpleVLA(const SimpleVLA &) = delete;
34   SimpleVLA(SimpleVLA &&) = delete;
35   SimpleVLA &operator=(const SimpleVLA &) = delete;
36   SimpleVLA &operator=(SimpleVLA &&) = delete;
37 
38   explicit SimpleVLA(unsigned NumOfElements) noexcept {
39     if (NumOfElements > N) {
40       HeapBuffer =
41           reinterpret_cast<T *>(__kmp_allocate(NumOfElements * sizeof(T)));
42       Ptr = HeapBuffer;
43     }
44   }
45 
46   ~SimpleVLA() {
47     if (HeapBuffer)
48       __kmp_free(HeapBuffer);
49   }
50 
51   operator T *() noexcept { return Ptr; }
52   operator const T *() const noexcept { return Ptr; }
53 };
54 
55 #endif
56