updated licenses info
[platform/core/uifw/lottie-player.git] / src / vector / vstackallocator.h
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the LGPL License, Version 2.1 (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  *     https://www.gnu.org/licenses/
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 #ifndef VSTACK_ALLOCATOR_H
18 #define VSTACK_ALLOCATOR_H
19
20 #include <cstddef>
21 #include <cassert>
22
23 template <std::size_t N, std::size_t alignment = alignof(std::max_align_t)>
24 class arena
25 {
26     alignas(alignment) char buf_[N];
27     char* ptr_;
28
29 public:
30     ~arena() {ptr_ = nullptr;}
31     arena() noexcept : ptr_(buf_) {}
32     arena(const arena&) = delete;
33     arena& operator=(const arena&) = delete;
34
35     template <std::size_t ReqAlign> char* allocate(std::size_t n);
36     void deallocate(char* p, std::size_t n) noexcept;
37
38     static constexpr std::size_t size() noexcept {return N;}
39     std::size_t used() const noexcept {return static_cast<std::size_t>(ptr_ - buf_);}
40     void reset() noexcept {ptr_ = buf_;}
41
42 private:
43     static
44     std::size_t
45     align_up(std::size_t n) noexcept
46         {return (n + (alignment-1)) & ~(alignment-1);}
47
48     bool
49     pointer_in_buffer(char* p) noexcept
50         {return buf_ <= p && p <= buf_ + N;}
51 };
52
53 template <std::size_t N, std::size_t alignment>
54 template <std::size_t ReqAlign>
55 char*
56 arena<N, alignment>::allocate(std::size_t n)
57 {
58     static_assert(ReqAlign <= alignment, "alignment is too small for this arena");
59     assert(pointer_in_buffer(ptr_) && "stack_alloc has outlived arena");
60     auto const aligned_n = align_up(n);
61     if (static_cast<decltype(aligned_n)>(buf_ + N - ptr_) >= aligned_n)
62     {
63         char* r = ptr_;
64         ptr_ += aligned_n;
65         return r;
66     }
67
68     static_assert(alignment <= alignof(std::max_align_t), "you've chosen an "
69                   "alignment that is larger than alignof(std::max_align_t), and "
70                   "cannot be guaranteed by normal operator new");
71     return static_cast<char*>(::operator new(n));
72 }
73
74 template <std::size_t N, std::size_t alignment>
75 void
76 arena<N, alignment>::deallocate(char* p, std::size_t n) noexcept
77 {
78     assert(pointer_in_buffer(ptr_) && "stack_alloc has outlived arena");
79     if (pointer_in_buffer(p))
80     {
81         n = align_up(n);
82         if (p + n == ptr_)
83             ptr_ = p;
84     }
85     else
86         ::operator delete(p);
87 }
88
89 template <class T, std::size_t N, std::size_t Align = alignof(std::max_align_t)>
90 class stack_alloc
91 {
92 public:
93     using value_type = T;
94     static auto constexpr alignment = Align;
95     static auto constexpr size = N;
96     using arena_type = arena<size, alignment>;
97
98 private:
99     arena_type& a_;
100
101 public:
102     stack_alloc(const stack_alloc&) = default;
103     stack_alloc& operator=(const stack_alloc&) = delete;
104
105     stack_alloc(arena_type& a) noexcept : a_(a)
106     {
107         static_assert(size % alignment == 0,
108                       "size N needs to be a multiple of alignment Align");
109     }
110     template <class U>
111         stack_alloc(const stack_alloc<U, N, alignment>& a) noexcept
112             : a_(a.a_) {}
113
114     template <class _Up> struct rebind {using other = stack_alloc<_Up, N, alignment>;};
115
116     T* allocate(std::size_t n)
117     {
118         return reinterpret_cast<T*>(a_.template allocate<alignof(T)>(n*sizeof(T)));
119     }
120     void deallocate(T* p, std::size_t n) noexcept
121     {
122         a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
123     }
124
125     template <class T1, std::size_t N1, std::size_t A1,
126               class U, std::size_t M, std::size_t A2>
127     friend
128     bool
129     operator==(const stack_alloc<T1, N1, A1>& x, const stack_alloc<U, M, A2>& y) noexcept;
130
131     template <class U, std::size_t M, std::size_t A> friend class stack_alloc;
132 };
133
134 template <class T, std::size_t N, std::size_t A1, class U, std::size_t M, std::size_t A2>
135 inline
136 bool
137 operator==(const stack_alloc<T, N, A1>& x, const stack_alloc<U, M, A2>& y) noexcept
138 {
139     return N == M && A1 == A2 && &x.a_ == &y.a_;
140 }
141
142 template <class T, std::size_t N, std::size_t A1, class U, std::size_t M, std::size_t A2>
143 inline
144 bool
145 operator!=(const stack_alloc<T, N, A1>& x, const stack_alloc<U, M, A2>& y) noexcept
146 {
147     return !(x == y);
148 }
149
150 #endif  // VSTACK_ALLOCATOR_H