#pragma once /******************************************************************************* * * Copyright (c) 2019 AT&T Intellectual Property. * Copyright (c) 2018-2019 Nokia. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *******************************************************************************/ // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries #include #include //std::bad_alloc #include #include // Platform Includes: Platform specific classes, functions, and libraries // Local Includes: Application specific classes, functions, and libraries namespace asn { template class chunked_allocator { public: using allocator_t = ALLOC; chunked_allocator() { put_chunk(new_chunk()); } template decltype(auto) emplace_back(TSEQ& v) { try { return v.emplace_back(m_allocator); } catch (std::bad_alloc const&) { put_chunk(new_chunk()); return v.emplace_back(m_allocator); } } uint8_t* alloc_bytes(std::size_t sz) { //TODO: unify allocation: now it returns nullptr instead of throw! auto* ret = m_allocator.alloc_bytes(sz); if (!ret) { put_chunk(new_chunk()); ret = m_allocator.alloc_bytes(sz); } return ret; } private: static constexpr std::size_t CHUNK_SIZE = 32*1024; using chunk_t = std::array; using chunks_t = std::list; chunk_t& new_chunk() { return m_chunks.emplace_back(); } void put_chunk(chunk_t& c) { m_allocator.reset(c.data(), c.size()); } allocator_t m_allocator; chunks_t m_chunks; }; } //end: namespace asn