Nektar++
ArrayPolicies.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: ArrayPolicies.hpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Scientific Computing and Imaging Institute,
10// University of Utah (USA) and Department of Aeronautics, Imperial
11// College London (UK).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Implementations of the array creation and destruction policies.
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_ARRAY_POLICIES_HPP
36#define NEKTAR_LIB_UTILITIES_BASIC_UTILS_ARRAY_POLICIES_HPP
37
38#include <memory>
39#include <type_traits>
40
43#include <boost/multi_array.hpp>
44
45namespace Nektar
46{
47template <typename ObjectType, typename enabled = void>
49
50/// \internal
51/// \brief Does nothing.
52template <typename ObjectType>
54 ObjectType,
55 typename std::enable_if<std::is_fundamental<ObjectType>::value>::type>
56{
57public:
58 static void Initialize([[maybe_unused]] ObjectType *data,
59 [[maybe_unused]] size_t itemsToCreate)
60 {
61 }
62
63 static void Initialize(ObjectType *data, size_t itemsToCreate,
64 const ObjectType &initValue)
65 {
66 std::fill_n(data, itemsToCreate, initValue);
67 }
68
69 static void Initialize(ObjectType *data, size_t itemsToCreate,
70 const ObjectType *initValue)
71 {
72 std::copy(initValue, initValue + itemsToCreate, data);
73 }
74};
75
76/// \internal
77/// \brief Default initializes all elements.
78///
79/// \internal
80/// The user calls Initialize, which immediately calls DoInitialization. There
81/// reason for this separation is because the code for creating an array of
82/// default initialized elements and an array of copy constructed elements is
83/// identical except for the actual call to placement new.
84///
85///
86template <typename ObjectType>
88 ObjectType,
89 typename std::enable_if<!std::is_fundamental<ObjectType>::value>::type>
90{
91public:
92 /// \brief Initalize each element in the array with ObjectType's default
93 /// constructor. \param data The array of values to populate. \param
94 /// itemsToCreate The size of data.
95 static void Initialize(ObjectType *data, size_t itemsToCreate)
96 {
97 DoInitialization(data, itemsToCreate,
98 [](ObjectType *element) { new (element) ObjectType; });
99 }
100
101 /// \brief Initalize each element in the array with ObjectType's copy
102 /// constructor. \param data The array of values to populate. \param
103 /// itemsToCreate The size of data. \param initValue The inital value each
104 /// element in data will have.
105 static void Initialize(ObjectType *data, size_t itemsToCreate,
106 const ObjectType &initValue)
107 {
108 DoInitialization(data, itemsToCreate, [&](ObjectType *element) {
109 new (element) ObjectType(initValue);
110 });
111 }
112
113 static void Initialize(ObjectType *data, size_t itemsToCreate,
114 const ObjectType *initValue)
115 {
116 DoInitialization(data, itemsToCreate, [&](ObjectType *element) {
117 new (element) ObjectType(*initValue);
118 initValue++;
119 });
120 }
121
122private:
123 template <typename CreateType>
124 static void DoInitialization(ObjectType *data, size_t itemsToCreate,
125 const CreateType &f)
126 {
127 size_t nextObjectToCreate = 0;
128 try
129 {
130 for (size_t i = 0; i < itemsToCreate; ++i)
131 {
132 ObjectType *memLocation = &data[i];
133 f(memLocation);
134 ++nextObjectToCreate;
135 }
136 }
137 catch (...)
138 {
139 for (size_t i = 0; i < nextObjectToCreate; ++i)
140 {
141 ObjectType *memLocation = &data[nextObjectToCreate - i - 1];
142 memLocation->~ObjectType();
143 }
144 throw;
145 }
146 }
147};
148
149template <typename ObjectType, typename enabled = void>
151
152template <typename ObjectType>
154 ObjectType,
155 typename std::enable_if<std::is_fundamental<ObjectType>::value>::type>
156{
157public:
158 static void Destroy([[maybe_unused]] ObjectType *data,
159 [[maybe_unused]] size_t itemsToDestroy)
160 {
161 }
162};
163
164template <typename ObjectType>
166 ObjectType,
167 typename std::enable_if<!std::is_fundamental<ObjectType>::value>::type>
168{
169public:
170 static void Destroy(ObjectType *data, size_t itemsToDestroy)
171 {
172 for (size_t i = 0; i < itemsToDestroy; ++i)
173 {
174 ObjectType *memLocation = &data[itemsToDestroy - i - 1];
175 memLocation->~ObjectType();
176 }
177 }
178};
179
180template <typename Dim, typename DataType, typename ExtentListType>
181std::shared_ptr<boost::multi_array_ref<DataType, Dim::Value>> CreateStorage(
182 const ExtentListType &extent)
183{
184 typedef boost::multi_array_ref<DataType, Dim::Value> ArrayType;
185 size_t size = std::accumulate(extent.begin(), extent.end(), 1,
186 std::multiplies<size_t>());
187 DataType *storage = MemoryManager<DataType>::RawAllocate(size);
189 [=]([[maybe_unused]] boost::multi_array_ref<DataType, Dim::Value>
190 *ptr) {
193 },
194 storage, extent);
195}
196
197template <typename DataType>
198std::shared_ptr<boost::multi_array_ref<DataType, 1>> CreateStorage(size_t d1)
199{
200 std::vector<size_t> extents = {d1};
201 return CreateStorage<OneD, DataType>(extents);
202}
203
204template <typename DataType>
205std::shared_ptr<boost::multi_array_ref<DataType, 2>> CreateStorage(size_t d1,
206 size_t d2)
207{
208 std::vector<size_t> extents = {d1, d2};
209 return CreateStorage<TwoD, DataType>(extents);
210}
211
212template <typename DataType>
213std::shared_ptr<boost::multi_array_ref<DataType, 3>> CreateStorage(size_t d1,
214 size_t d2,
215 size_t d3)
216{
217 std::vector<size_t> extents = {d1, d2, d3};
218 return CreateStorage<ThreeD, DataType>(extents);
219}
220} // namespace Nektar
221
222#endif // NEKTAR_LIB_UTILITIES_BASIC_UTILS_ARRAY_POLICIES_HPP
static void Initialize(ObjectType *data, size_t itemsToCreate, const ObjectType &initValue)
Initalize each element in the array with ObjectType's copy constructor.
static void Initialize(ObjectType *data, size_t itemsToCreate)
Initalize each element in the array with ObjectType's default constructor.
static void Initialize(ObjectType *data, size_t itemsToCreate, const ObjectType &initValue)
static void Initialize(ObjectType *data, size_t itemsToCreate, const ObjectType *initValue)
static DataType * RawAllocate(size_t NumberOfElements)
Allocates a chunk of raw, uninitialized memory, capable of holding NumberOfElements objects.
static void RawDeallocate(DataType *array, size_t NumberOfElements)
Deallocates memory allocated from RawAllocate.
static std::shared_ptr< DataType > AllocateSharedPtrD(const DeallocatorType &d, const Args &...args)
def copy(self)
Definition: pycml.py:2663
std::shared_ptr< boost::multi_array_ref< DataType, Dim::Value > > CreateStorage(const ExtentListType &extent)