DUNE-FEM (unstable)

stackallocator.hh
1#ifndef DUNE_FEM_COMMON_STACKALLOCATOR_HH
2#define DUNE_FEM_COMMON_STACKALLOCATOR_HH
3
4#include <cassert>
5#include <new>
6#include <stack>
7#include <utility>
8
9namespace Dune
10{
11
12 namespace Fem
13 {
14
15 // UninitializedObjectStack
16 // ------------------------
17
18 struct UninitializedObjectStack
19 : public std::stack< void * >
20 {
21 explicit UninitializedObjectStack ( std::size_t objectSize )
22 : objectSize_( objectSize )
23 {}
24
25 UninitializedObjectStack ( const UninitializedObjectStack &other )
26 : std::stack< void * >(),
27 objectSize_( other.objectSize_ )
28 {}
29
30 UninitializedObjectStack &operator= ( const UninitializedObjectStack &other )
31 {
32 if( objectSize_ != other.objectSize_ )
33 clear();
34 objectSize_ = other.objectSize_;
35 return *this;
36 }
37
38 ~UninitializedObjectStack () { clear(); }
39
40 void clear ()
41 {
42 for( ; !empty(); pop() )
43 ::operator delete( top() );
44 }
45
46 std::size_t objectSize () const { return objectSize_; }
47
48 void resize ( std::size_t newSize ) { clear(); objectSize_ = newSize; }
49
50 private:
51 std::size_t objectSize_;
52 };
53
54
55
56 // StackAllocator
57 // --------------
58
59 template< class T, class S = UninitializedObjectStack * >
60 struct StackAllocator
61 {
62 typedef T value_type;
63
64 typedef T *pointer;
65 typedef const T*const_pointer;
66
67 typedef T &reference;
68 typedef const T &const_reference;
69
70 typedef std::size_t size_type;
71 typedef std::ptrdiff_t difference_type;
72
73 template< class U >
74 struct rebind { typedef StackAllocator< U, S > other; };
75
76 typedef UninitializedObjectStack Stack;
77 typedef S StackPtr;
78
79 explicit StackAllocator ( StackPtr stack ) : stack_( stack ) {}
80
81 template< class U >
82 StackAllocator ( const StackAllocator< U, S > &other ) : stack_( other.stack_ ) {}
83
84 template< class U >
85 StackAllocator ( StackAllocator< U, S > &&other ) : stack_( std::move( other.stack_ ) ) {}
86
87 StackAllocator ( const StackAllocator &other ) : stack_( other.stack_ ) {}
88 StackAllocator ( StackAllocator && other ) : stack_( other.stack_ ) {}
89
90 pointer address ( reference x ) const { return &x; }
91 const_pointer address ( const_reference x ) const { return &x; }
92
93 pointer allocate ( size_type n, typename rebind< void >::other::const_pointer hint = nullptr )
94 {
95 assert( n <= max_size() );
96 if( !stack().empty() )
97 {
98 pointer p = (pointer) stack().top();
99 stack().pop();
100 return p;
101 }
102 else
103 return (pointer) ::operator new( stack().objectSize() );
104 }
105
106 void deallocate ( pointer p, size_type n )
107 {
108 assert( n <= max_size() );
109 stack().push( p );
110 }
111
112 size_type max_size () const { return stack().objectSize() / sizeof( T ); }
113
114 template< class... Args >
115 void construct ( pointer p, Args &&... args )
116 {
117 assert( p );
118 new( p ) T( std::forward< Args >( args )... );
119 }
120
121 void destroy ( pointer p ) { p->~T(); }
122
123 private:
124 template< class, class >
125 friend struct StackAllocator;
126
127 const Stack &stack () const { return *stack_; }
128 Stack &stack () { return *stack_; }
129
130 StackPtr stack_;
131 };
132
133
134 template<class S>
135 struct StackAllocator<void, S>
136 {
137 typedef void value_type;
138
139 typedef void *pointer;
140 typedef const void*const_pointer;
141
142 typedef std::size_t size_type;
143 typedef std::ptrdiff_t difference_type;
144
145 template< class U >
146 struct rebind { typedef StackAllocator< U, S > other; };
147
148 typedef UninitializedObjectStack Stack;
149 };
150
151 } // namespace
152
153} //namespace Dune
154
155#endif // #ifndef DUNE_FEM_COMMON_STACKALLOCATOR_HH
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::bool_constant<(sizeof...(II)==0)> empty(std::integer_sequence< T, II... >)
Checks whether the sequence is empty.
Definition: integersequence.hh:80
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)