OpenSubdiv
Toggle main menu visibility
Loading...
Searching...
No Matches
stackBuffer.h
Go to the documentation of this file.
1
//
2
// Copyright 2015 DreamWorks Animation LLC.
3
//
4
// Licensed under the Apache License, Version 2.0 (the "Apache License")
5
// with the following modification; you may not use this file except in
6
// compliance with the Apache License and the following modification to it:
7
// Section 6. Trademarks. is deleted and replaced with:
8
//
9
// 6. Trademarks. This License does not grant permission to use the trade
10
// names, trademarks, service marks, or product names of the Licensor
11
// and its affiliates, except as required to comply with Section 4(c) of
12
// the License and to reproduce the content of the NOTICE file.
13
//
14
// You may obtain a copy of the Apache License at
15
//
16
// http://www.apache.org/licenses/LICENSE-2.0
17
//
18
// Unless required by applicable law or agreed to in writing, software
19
// distributed under the Apache License with the above modification is
20
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
// KIND, either express or implied. See the Apache License for the specific
22
// language governing permissions and limitations under the Apache License.
23
//
24
#ifndef OPENSUBDIV3_VTR_STACK_BUFFER_H
25
#define OPENSUBDIV3_VTR_STACK_BUFFER_H
26
27
#include "../version.h"
28
29
namespace
OpenSubdiv
{
30
namespace
OPENSUBDIV_VERSION
{
31
32
namespace
Vtr
{
33
namespace
internal
{
34
35
//
36
// The StackBuffer class is intended solely to take the place of VLAs (Variable
37
// Length Arrays) which most compilers support, but are not strictly standard C++.
38
// Portability concerns forces us to make use of either alloca() or some other
39
// mechanism to create small arrays on the stack that are typically based on the
40
// valence of a vertex -- small in general, but occasionally large.
41
//
42
// Note also that since the intent of this is to replace VLAs -- not general
43
// std::vectors -- support for std::vector functionality is intentionally limited
44
// and STL-like naming is avoided. Like a VLA there is no incremental growth.
45
// Support for resizing is available to reuse an instance at the beginning of a
46
// loop with a new size, but resizing in this case reinitializes all elements.
47
//
48
49
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE = false>
50
class
StackBuffer
51
{
52
public
:
53
typedef
unsigned
int
size_type
;
54
55
public
:
56
// Constructors and destructor -- declared inline below:
57
StackBuffer
();
58
StackBuffer
(
size_type
size);
59
~StackBuffer
();
60
61
public
:
62
// Note the reliance on implicit casting so that it can be used similar to
63
// a VLA. This removes the need for operator[] as the resulting TYPE* will
64
// natively support []. (The presence of both TYPE* and operator[] also
65
// causes an ambiguous overloading error with 32-bit MSVC builds.)
66
67
operator
TYPE
const
* ()
const
{
return
_data; }
68
operator
TYPE * () {
return
_data; }
69
70
size_type
GetSize
()
const
{
return
_size; }
71
72
void
SetSize
(
size_type
size);
73
void
Reserve
(
size_type
capacity);
74
75
private
:
76
// Non-copyable:
77
StackBuffer
(
const
StackBuffer<TYPE,SIZE,POD_TYPE>
&) { }
78
StackBuffer
& operator=(
const
StackBuffer<TYPE,SIZE,POD_TYPE>
&) {
return
*
this
; }
79
80
void
allocate(
size_type
capacity);
81
void
deallocate();
82
void
construct();
83
void
destruct();
84
85
private
:
86
TYPE * _data;
87
size_type
_size;
88
size_type
_capacity;
89
90
// Is alignment an issue here? The staticData arena will at least be double-word
91
// aligned within this struct, which meets current and most anticipated needs.
92
char
_staticData[SIZE *
sizeof
(TYPE)];
93
char
* _dynamicData;
94
};
95
96
97
//
98
// Core allocation/deallocation methods:
99
//
100
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
101
inline
void
102
StackBuffer<TYPE,SIZE,POD_TYPE>::allocate(size_type capacity) {
103
104
// Again, is alignment an issue here? C++ spec says new will return pointer
105
// "suitably aligned" for conversion to pointers of other types, which implies
106
// at least an alignment of 16.
107
_dynamicData =
static_cast<
char
*
>
(::operator
new
(capacity *
sizeof
(TYPE)));
108
109
_data =
reinterpret_cast<
TYPE*
>
(_dynamicData);
110
_capacity = capacity;
111
}
112
113
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
114
inline
void
115
StackBuffer<TYPE,SIZE,POD_TYPE>::deallocate() {
116
117
::operator
delete
(_dynamicData);
118
119
_data =
reinterpret_cast<
TYPE*
>
(_staticData);
120
_capacity = SIZE;
121
}
122
123
//
124
// Explicit element-wise construction and destruction within allocated memory.
125
// Compilers do not always optimize out the iteration here even when there is
126
// no construction or destruction, so the POD_TYPE arguement can be used to
127
// force this when/if it becomes an issue (and it has been in some cases).
128
//
129
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
130
inline
void
131
StackBuffer<TYPE,SIZE,POD_TYPE>::construct() {
132
133
for
(size_type i = 0; i < _size; ++i) {
134
(void)
new
(&_data[i]) TYPE;
135
}
136
}
137
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
138
inline
void
139
StackBuffer<TYPE,SIZE,POD_TYPE>::destruct() {
140
141
for
(size_type i = 0; i < _size; ++i) {
142
_data[i].~TYPE();
143
}
144
}
145
146
//
147
// Inline constructors and destructor:
148
//
149
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
150
inline
151
StackBuffer<TYPE,SIZE,POD_TYPE>::StackBuffer
() :
152
_data(reinterpret_cast<TYPE*>(_staticData)),
153
_size(0),
154
_capacity(SIZE),
155
_dynamicData(0) {
156
157
}
158
159
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
160
inline
161
StackBuffer<TYPE,SIZE,POD_TYPE>::StackBuffer
(
size_type
size) :
162
_data(reinterpret_cast<TYPE*>(_staticData)),
163
_size(size),
164
_capacity(SIZE),
165
_dynamicData(0) {
166
167
if
(size > SIZE) {
168
allocate(size);
169
}
170
if
(!POD_TYPE) {
171
construct();
172
}
173
}
174
175
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
176
inline
177
StackBuffer<TYPE,SIZE,POD_TYPE>::~StackBuffer
() {
178
179
if
(!POD_TYPE) {
180
destruct();
181
}
182
deallocate();
183
}
184
185
//
186
// Inline sizing methods:
187
//
188
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
189
inline
void
190
StackBuffer<TYPE,SIZE,POD_TYPE>::Reserve
(
size_type
capacity) {
191
192
if
(capacity > _capacity) {
193
if
(!POD_TYPE) {
194
destruct();
195
}
196
deallocate();
197
allocate(capacity);
198
}
199
}
200
201
template
<
typename
TYPE,
unsigned
int
SIZE,
bool
POD_TYPE>
202
inline
void
203
StackBuffer<TYPE,SIZE,POD_TYPE>::SetSize
(
size_type
size)
204
{
205
if
(!POD_TYPE) {
206
destruct();
207
}
208
if
(size == 0) {
209
deallocate();
210
}
else
if
(size > _capacity) {
211
deallocate();
212
allocate(size);
213
}
214
_size = size;
215
if
(!POD_TYPE) {
216
construct();
217
}
218
}
219
220
}
// end namespace internal
221
}
// end namespace Vtr
222
223
}
// end namespace OPENSUBDIV_VERSION
224
using namespace
OPENSUBDIV_VERSION
;
225
}
// end namespace OpenSubdiv
226
227
#endif
/* OPENSUBDIV3_VTR_STACK_BUFFER_H */
OpenSubdiv
Definition
error.h:30
OpenSubdiv::OPENSUBDIV_VERSION
Definition
error.h:31
OpenSubdiv::OPENSUBDIV_VERSION::Vtr
Definition
topologyRefiner.h:40
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal
Definition
topologyRefiner.h:40
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal::StackBuffer
Definition
stackBuffer.h:51
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal::StackBuffer::~StackBuffer
~StackBuffer()
Definition
stackBuffer.h:177
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal::StackBuffer::SetSize
void SetSize(size_type size)
Definition
stackBuffer.h:203
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal::StackBuffer::GetSize
size_type GetSize() const
Definition
stackBuffer.h:70
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal::StackBuffer::StackBuffer
StackBuffer()
Definition
stackBuffer.h:151
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal::StackBuffer::Reserve
void Reserve(size_type capacity)
Definition
stackBuffer.h:190
OpenSubdiv::OPENSUBDIV_VERSION::Vtr::internal::StackBuffer::size_type
unsigned int size_type
Definition
stackBuffer.h:53
opensubdiv
vtr
stackBuffer.h
Generated on
for OpenSubdiv by
1.18.0