Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / src / ASN1 / asn / utility.hpp
1 #pragma once
2
3 /******************************************************************************
4 *
5 *   Copyright (c) 2019 AT&T Intellectual Property.
6 *   Copyright (c) 2018-2019 Nokia.
7 *
8 *   Licensed under the Apache License, Version 2.0 (the "License");
9 *   you may not use this file except in compliance with the License.
10 *   You may obtain a copy of the License at
11 *
12 *       http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *   Unless required by applicable law or agreed to in writing, software
15 *   distributed under the License is distributed on an "AS IS" BASIS,
16 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 *   See the License for the specific language governing permissions and
18 *   limitations under the License.
19 *
20 ******************************************************************************/
21
22 // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
23 #include <new>
24 #include <memory>
25
26 // Local Includes: Application specific classes, functions, and libraries
27
28 namespace asn
29 {
30
31 struct allocator
32 {
33         allocator() = default;
34
35         allocator(void* data, size_t size) { reset(data, size); }
36
37         template <typename T, std::size_t SZ>
38         explicit allocator(T (&buf)[SZ]) : allocator(buf, SZ * sizeof(T)) { }
39
40         void reset(void* data, size_t size)
41         {
42                 std::size_t space = size;
43                 m_begin = static_cast<uint8_t*>(std::align(alignment, size, data, space));
44                 m_end = m_begin ? m_begin + space : nullptr;
45                 m_current = m_begin;
46                 m_ref_counter = 0;
47         }
48
49         uint8_t* alloc_bytes(std::size_t size)
50         {
51                 std::size_t const esize = (size + alignment - 1) & -alignment;
52                 if (m_current + esize > m_end) { return nullptr; } //throw std::bad_alloc();
53
54                 uint8_t* const rval = m_current;
55                 m_current += esize;
56                 return rval;
57         }
58
59         size_t add_ref() { return ++m_ref_counter; }
60         size_t release()
61         {
62                 if (m_ref_counter) --m_ref_counter;
63                 if (m_ref_counter == 0) reset();
64                 return m_ref_counter;
65         }
66         size_t ref_counter() const { return m_ref_counter; }
67 private:
68         //called by last release() when m_ref_counter becomes 0
69         void reset()
70         {
71                 m_current = m_begin;
72         }
73
74
75         enum : std::size_t
76         {
77                 alignment = alignof(std::size_t)
78         };
79
80         uint8_t* m_begin { nullptr };           //set in reset()
81         uint8_t* m_current { nullptr };         //changed by alloc_bytes
82         uint8_t* m_end { nullptr };
83
84         size_t m_ref_counter {0};
85 };
86
87 } //namespace asn
88