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