ADOL-C: Automatic Differentiation in C/C++ 2.7.3
Loading...
Searching...
No Matches
buffer_temp.h
Go to the documentation of this file.
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File: struct_buf.h
4 Revision: $Id$
5 Contents: - template class for linked list of Type buffers with constant length
6 per buffer
7 - intended to be used with structs
8
9 Copyright (c) Andreas Kowarz, Kshitij Kulshreshtha, Jean Utke
10
11 This file is part of ADOL-C. This software is provided as open source.
12 Any use, reproduction, or distribution of the software constitutes
13 recipient's acceptance of the terms of the accompanying license file.
14
15----------------------------------------------------------------------------*/
16
17#if !defined(ADOLC_STRUCT_BUF_H)
18#define ADOLC_STRUCT_BUF_H 1
19
21#include <array>
22#include <cstdlib>
23
24// check whether the type has an allmem storage
25template <typename T>
26concept AllMemType = requires(T t) {
27 { t.allmem } -> std::convertible_to<void *>;
28};
29
36template <AllMemType T, size_t buff_size> class Buffer {
37 using InitFunctionPointer = void (*)(T *subBufferElement);
38
40 struct SubBuffer {
41 std::array<T, buff_size> elements;
42 SubBuffer *nextSubBuffer{nullptr};
43 SubBuffer() = default;
44 };
45
46public:
47 Buffer() = default;
48 Buffer(InitFunctionPointer _initFunction) : initFunction(_initFunction) {}
50 Buffer(const Buffer &) = delete;
51 Buffer &operator=(const Buffer &) = delete;
52
53 Buffer(Buffer &&other) noexcept = default;
54
55 Buffer &operator=(Buffer &&other) noexcept;
56 inline void init(InitFunctionPointer _initFunction) {
57 initFunction = _initFunction;
58 }
59 T *append();
60 T *getElement(size_t index) const;
61
62private:
63 SubBuffer *firstSubBuffer{nullptr};
64 InitFunctionPointer initFunction{nullptr};
65 size_t numEntries{0};
66};
67
68template <AllMemType T, size_t buff_size>
71 if (this != &other) {
72 // Free current resources
73 SubBuffer *next = nullptr;
74 while (firstSubBuffer) {
75 next = firstSubBuffer->nextSubBuffer;
76 for (auto &ele : firstSubBuffer->elements)
77 if (ele.allmem)
78 free(ele.allmem);
79 delete firstSubBuffer;
80 firstSubBuffer = next;
81 }
82
83 // transfer resources
84 firstSubBuffer = other.firstSubBuffer;
85 numEntries = other.numEntries;
86 initFunction = other.initFunction;
87
88 // Leave other in a valid state
89 other.firstSubBuffer = nullptr;
90 other.numEntries = 0;
91 other.initFunction = nullptr;
92 }
93 return *this;
94}
95
96template <AllMemType T, size_t buff_size> Buffer<T, buff_size>::~Buffer() {
97 SubBuffer *next = nullptr;
98
99 // clean-up allmem and subBuffers
100 while (firstSubBuffer) {
101 next = firstSubBuffer->nextSubBuffer;
102 for (auto &ele : firstSubBuffer->elements)
103 if (ele.allmem)
104 free(ele.allmem);
105 delete firstSubBuffer;
106 firstSubBuffer = next;
107 }
108}
109
110template <AllMemType T, size_t buff_size> T *Buffer<T, buff_size>::append() {
111 SubBuffer *currentSubBuffer = firstSubBuffer, *previousSubBuffer = nullptr;
112 size_t tmp = numEntries;
113
114 while (tmp >= buff_size) {
115 previousSubBuffer = currentSubBuffer;
116 currentSubBuffer = currentSubBuffer->nextSubBuffer;
117 tmp -= buff_size;
118 }
119 if (currentSubBuffer == nullptr) {
120 currentSubBuffer = new SubBuffer;
121 if (firstSubBuffer == nullptr)
122 firstSubBuffer = currentSubBuffer;
123 else
124 previousSubBuffer->nextSubBuffer = currentSubBuffer;
125 currentSubBuffer->nextSubBuffer = nullptr;
126 }
127 const size_t index = tmp;
128
129 currentSubBuffer->elements[index].allmem = nullptr;
130 if (initFunction != nullptr)
131 initFunction(&(currentSubBuffer->elements[index]));
132
133 currentSubBuffer->elements[index].index = numEntries;
134 ++numEntries;
135
136 return &currentSubBuffer->elements[index];
137}
138
139template <AllMemType T, size_t buff_size>
140T *Buffer<T, buff_size>::getElement(size_t index) const {
141 if (index >= numEntries)
144
145 SubBuffer *currentSubBuffer = firstSubBuffer;
146 while (index >= buff_size) {
147 currentSubBuffer = currentSubBuffer->nextSubBuffer;
148 index -= buff_size;
149 }
150 return &currentSubBuffer->elements[index];
151}
152
153#endif /* ADOLC_STRUCT_BUF_H */
#define CURRENT_LOCATION
Definition adolcerror.h:26
Block-based storage for registered external-function descriptors.
Definition buffer_temp.h:36
T * append()
Definition buffer_temp.h:110
Buffer & operator=(const Buffer &)=delete
Buffer()=default
void init(InitFunctionPointer _initFunction)
Definition buffer_temp.h:56
T * getElement(size_t index) const
Definition buffer_temp.h:140
Buffer(InitFunctionPointer _initFunction)
Definition buffer_temp.h:48
Buffer & operator=(Buffer &&other) noexcept
Definition buffer_temp.h:70
Buffer(const Buffer &)=delete
~Buffer()
Definition buffer_temp.h:96
Buffer(Buffer &&other) noexcept=default
Definition buffer_temp.h:26
void ADOLC_API fail(ErrorType error, const source_location LocInfo, const FailInfo &failinfo=FailInfo())