Line data Source code
1 : // Author(s): Maurice Laveaux 2 : // Copyright: see the accompanying file COPYING or copy at 3 : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING 4 : // 5 : // Distributed under the Boost Software License, Version 1.0. 6 : // (See accompanying file LICENSE_1_0.txt or copy at 7 : // http://www.boost.org/LICENSE_1_0.txt) 8 : // 9 : 10 : #ifndef MCRL2_UTILITIES_STACK_VECTOR_H 11 : #define MCRL2_UTILITIES_STACK_VECTOR_H 12 : 13 : #include "mcrl2/utilities/detail/memory_utility.h" 14 : #include "mcrl2/utilities/noncopyable.h" 15 : 16 : #include <cstddef> 17 : #include <iterator> 18 : 19 : namespace mcrl2 20 : { 21 : namespace utilities 22 : { 23 : 24 : /// \brief Provides (a subset of) the interface of std::array<T> for a portion of preallocated memory. Can be used to 25 : /// interface with a portion of memory allocated on the stack, \see MCRL2_DECLARE_STACK_ARRAY. The advantage over 26 : /// MCRL2_SPECIFIC_STACK_ALLOCATOR is that the lifetime of the underlying objects is bounded by the lifetime of the 27 : /// stack_array. 28 : template<typename T> 29 : class stack_array : public noncopyable 30 : { 31 : public: 32 : using iterator = T*; 33 : using const_iterator = const T*; 34 : using reverse_iterator = std::reverse_iterator<iterator>; 35 : using const_reverse_iterator = std::reverse_iterator<const_iterator>; 36 : 37 : /// \brief The given pointer should be able to hold N element of sizeof(T) bytes. 38 1167 : stack_array(T* reserved_memory, std::size_t N) 39 1167 : : m_reserved_memory(reserved_memory), 40 1167 : m_size(N) 41 : { 42 16979 : for (T& element : *this) 43 : { 44 15812 : new (&element) T(); 45 : } 46 1167 : } 47 : 48 1167 : ~stack_array() 49 : { 50 16979 : for (T& element : *this) 51 : { 52 15812 : element.~T(); 53 : } 54 1167 : } 55 : 56 : // The remaining interface of std::array 57 : 58 3501 : iterator begin() { return data(); } 59 : const_iterator begin() const { return data(); } 60 : 61 3501 : iterator end() { return data() + size(); } 62 : const_iterator end() const { return data() + size(); } 63 : 64 7002 : T* data() { return m_reserved_memory; } 65 : const T* data() const { return m_reserved_memory; } 66 : 67 : bool empty() const { return size() != 0; } 68 : 69 : reverse_iterator rbegin() { return reverse_iterator(data() + size()); } 70 : const_reverse_iterator rbegin() const { return const_reverse_iterator(data() + size()); } 71 : 72 : reverse_iterator rend() { return reverse_iterator(data()); } 73 : const_reverse_iterator rend() const { return const_reverse_iterator(data()); } 74 : 75 19313 : std::size_t size() const { return m_size; } 76 : 77 : std::size_t max_size() const { return m_size; } 78 : 79 15812 : T& operator[](std::size_t index) 80 : { 81 15812 : assert(index < size()); 82 15812 : return m_reserved_memory[index]; 83 : } 84 : 85 : private: 86 : T* m_reserved_memory; 87 : std::size_t m_size; 88 : }; 89 : 90 : } // namespace utilities 91 : } // namespace mcrl2 92 : 93 : /// \brief Define a (hopefully) unique name for the underlying reserved stack memory. 94 : #define MCRL2_STACK_ARRAY_NAME(NAME) \ 95 : NAME ## _reserved_stack_memory 96 : 97 : /// \brief Declares a stack_array<TYPE> with the specified NAME that stores SIZE elements type TYPE. 98 : #define MCRL2_DECLARE_STACK_ARRAY(NAME, TYPE, SIZE) \ 99 : TYPE* MCRL2_STACK_ARRAY_NAME(NAME) = MCRL2_SPECIFIC_STACK_ALLOCATOR(TYPE, SIZE); \ 100 : mcrl2::utilities::stack_array<TYPE> NAME (MCRL2_STACK_ARRAY_NAME(NAME), SIZE) 101 : 102 : #endif // MCRL2_UTILITIES_STACK_VECTOR_H