blob: 53f8ed64208ca6ef94b9e817c24aea85e998628c [file] [log] [blame]
Kenton Vardaf9ee42c2013-05-30 03:57:48 -07001// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this
8// list of conditions and the following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24#include "array.h"
25
26namespace kj {
Kenton Varda8e1d1e52013-07-09 21:38:20 -070027
28void ExceptionSafeArrayUtil::construct(size_t count, void (*constructElement)(void*)) {
29 while (count > 0) {
30 constructElement(pos);
31 pos += elementSize;
32 ++constructedElementCount;
33 --count;
34 }
35}
36
37void ExceptionSafeArrayUtil::destroyAll() {
38 while (constructedElementCount > 0) {
39 pos -= elementSize;
40 --constructedElementCount;
41 destroyElement(pos);
42 }
43}
44
Kenton Varda719eb092013-07-17 15:58:30 -070045const DestructorOnlyArrayDisposer DestructorOnlyArrayDisposer::instance =
46 DestructorOnlyArrayDisposer();
47
48void DestructorOnlyArrayDisposer::disposeImpl(
49 void* firstElement, size_t elementSize, size_t elementCount,
50 size_t capacity, void (*destroyElement)(void*)) const {
51 if (destroyElement != nullptr) {
52 ExceptionSafeArrayUtil guard(firstElement, elementSize, elementCount, destroyElement);
53 guard.destroyAll();
54 }
55}
56
Kenton Vardade7f2662013-08-01 04:32:56 -070057const NullArrayDisposer NullArrayDisposer::instance = NullArrayDisposer();
58
59void NullArrayDisposer::disposeImpl(
60 void* firstElement, size_t elementSize, size_t elementCount,
61 size_t capacity, void (*destroyElement)(void*)) const {}
62
Kenton Vardaaa654992013-06-06 03:50:25 -070063namespace _ { // private
Kenton Varda4958d3a2013-05-30 21:12:54 -070064
Kenton Varda4958d3a2013-05-30 21:12:54 -070065void* HeapArrayDisposer::allocateImpl(size_t elementSize, size_t elementCount, size_t capacity,
66 void (*constructElement)(void*),
67 void (*destroyElement)(void*)) {
68 void* result = operator new(elementSize * capacity);
69
70 if (constructElement == nullptr) {
71 // Nothing to do.
72 } else if (destroyElement == nullptr) {
73 byte* pos = reinterpret_cast<byte*>(result);
74 while (elementCount > 0) {
75 constructElement(pos);
76 pos += elementSize;
77 --elementCount;
78 }
79 } else {
Kenton Varda8e1d1e52013-07-09 21:38:20 -070080 ExceptionSafeArrayUtil guard(result, elementSize, 0, destroyElement);
81 guard.construct(elementCount, constructElement);
82 guard.release();
Kenton Varda4958d3a2013-05-30 21:12:54 -070083 }
84
85 return result;
86}
87
88void HeapArrayDisposer::disposeImpl(
89 void* firstElement, size_t elementSize, size_t elementCount, size_t capacity,
90 void (*destroyElement)(void*)) const {
91 // Note that capacity is ignored since operator delete() doesn't care about it.
92
93 if (destroyElement == nullptr) {
94 operator delete(firstElement);
95 } else {
Kenton Varda8e1d1e52013-07-09 21:38:20 -070096 KJ_DEFER(operator delete(firstElement));
97 ExceptionSafeArrayUtil guard(firstElement, elementSize, elementCount, destroyElement);
Kenton Varda4958d3a2013-05-30 21:12:54 -070098 guard.destroyAll();
Kenton Varda4958d3a2013-05-30 21:12:54 -070099 }
100}
101
102const HeapArrayDisposer HeapArrayDisposer::instance = HeapArrayDisposer();
103
Kenton Vardaaa654992013-06-06 03:50:25 -0700104} // namespace _ (private)
Kenton Vardaf9ee42c2013-05-30 03:57:48 -0700105} // namespace kj