From fb992677cf62b6aa982476538faae43e5bbbd87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Nusser?= Date: Sun, 12 Jan 2020 15:41:39 +0100 Subject: Introduce EventsDS to handle all the events and enable new features. Also: * Added an id.h class to make IDs with type * Added a range class to easily use range based for loops --- src/memory_heap.h | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/memory_heap.h (limited to 'src/memory_heap.h') diff --git a/src/memory_heap.h b/src/memory_heap.h new file mode 100644 index 0000000..e2901b8 --- /dev/null +++ b/src/memory_heap.h @@ -0,0 +1,113 @@ +/* -*- Mode: c++ -*- */ +/*************************************************************************** + * memory_heap.h + * + * Sun Jan 19 13:49:56 CET 2020 + * Copyright 2020 André Nusser + * andre.nusser@googlemail.com + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DrumGizmo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#pragma once + +#include + +// The purpose of this class is to have a heap for objects of a certain type. +// We want to avoid using the general "new"/"delete" memory allocation as this +// is problematic for real-time as well as slow. The underlying container still +// is a vector to handle the case when for some reason we need more memory +// than initially anticipated. Instead of throwing errors and giving up, we can +// then at least allocate new memory and just hope for the best. +template +class MemoryHeap +{ +public: + using Index = std::size_t; + using Indices = std::vector; + + MemoryHeap() = default; + MemoryHeap(std::size_t size) + { + memory.reserve(size); + free_indices.reserve(size); + } + + template + Index emplace(Args&&... args); + + Index add(T const& element); + T& get(Index index); + T const& get(Index index) const; + void remove(Index index); + +private: + std::vector memory; + Indices free_indices; +}; + +template +auto MemoryHeap::add(T const& element) -> Index +{ + if (free_indices.empty()) + { + memory.push_back(element); + return memory.size()-1; + } + + auto free_index = free_indices.back(); + free_indices.pop_back(); + memory[free_index] = element; + return free_index; +} + +template +template +auto MemoryHeap::emplace(Args&&... args) -> Index +{ + if (free_indices.empty()) + { + memory.emplace_back(std::forward(args)...); + return memory.size()-1; + } + + auto free_index = free_indices.back(); + free_indices.pop_back(); + memory[free_index] = T(std::forward(args)...); + return free_index; +} + +template +T& MemoryHeap::get(Index index) +{ + assert(index < memory.size()); + return memory[index]; +} + +template +T const& MemoryHeap::get(Index index) const +{ + assert(index < memory.size()); + return memory[index]; +} + +template +void MemoryHeap::remove(Index index) +{ + free_indices.push_back(index); +} -- cgit v1.2.3