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/core/ignore_unused.hpp>
44#include <boost/multi_array.hpp>
45
46namespace Nektar
47{
48template <typename ObjectType, typename enabled = void>
50
51/// \internal
52/// \brief Does nothing.
53template <typename ObjectType>
55 ObjectType,
56 typename std::enable_if<std::is_fundamental<ObjectType>::value>::type>
57{
58public:
59 static void Initialize(ObjectType *data, size_t itemsToCreate)
60 {
61 boost::ignore_unused(data, itemsToCreate);
62 }
63
64 static void Initialize(ObjectType *data, size_t itemsToCreate,
65 const ObjectType &initValue)
66 {
67 std::fill_n(data, itemsToCreate, initValue);
68 }
69
70 static void Initialize(ObjectType *data, size_t itemsToCreate,
71 const ObjectType *initValue)
72 {
73 std::copy(initValue, initValue + itemsToCreate, data);
74 }
75};
76
77/// \internal
78/// \brief Default initializes all elements.
79///
80/// \internal
81/// The user calls Initialize, which immediately calls DoInitialization. There
82/// reason for this separation is because the code for creating an array of
83/// default initialized elements and an array of copy constructed elements is
84/// identical except for the actual call to placement new.
85///
86///
87template <typename ObjectType>
89 ObjectType,
90 typename std::enable_if<!std::is_fundamental<ObjectType>::value>::type>
91{
92public:
93 /// \brief Initalize each element in the array with ObjectType's default
94 /// constructor. \param data The array of values to populate. \param
95 /// itemsToCreate The size of data.
96 static void Initialize(ObjectType *data, size_t itemsToCreate)
97 {
98 DoInitialization(data, itemsToCreate,
99 [](ObjectType *element) { new (element) ObjectType; });
100 }
101
102 /// \brief Initalize each element in the array with ObjectType's copy
103 /// constructor. \param data The array of values to populate. \param
104 /// itemsToCreate The size of data. \param initValue The inital value each
105 /// element in data will have.
106 static void Initialize(ObjectType *data, size_t itemsToCreate,
107 const ObjectType &initValue)
108 {
109 DoInitialization(data, itemsToCreate, [&](ObjectType *element) {
110 new (element) ObjectType(initValue);
111 });
112 }
113
114 static void Initialize(ObjectType *data, size_t itemsToCreate,
115 const ObjectType *initValue)
116 {
117 DoInitialization(data, itemsToCreate, [&](ObjectType *element) {
118 new (element) ObjectType(*initValue);
119 initValue++;
120 });
121 }
122
123private:
124 template <typename CreateType>
125 static void DoInitialization(ObjectType *data, size_t itemsToCreate,
126 const CreateType &f)
127 {
128 size_t nextObjectToCreate = 0;
129 try
130 {
131 for (size_t i = 0; i < itemsToCreate; ++i)
132 {
133 ObjectType *memLocation = &data[i];
134 f(memLocation);
135 ++nextObjectToCreate;
136 }
137 }
138 catch (...)
139 {
140 for (size_t i = 0; i < nextObjectToCreate; ++i)
141 {
142 ObjectType *memLocation = &data[nextObjectToCreate - i - 1];
143 memLocation->~ObjectType();
144 }
145 throw;
146 }
147 }
148};
149
150template <typename ObjectType, typename enabled = void>
152
153template <typename ObjectType>
155 ObjectType,
156 typename std::enable_if<std::is_fundamental<ObjectType>::value>::type>
157{
158public:
159 static void Destroy(ObjectType *data, size_t itemsToDestroy)
160 {
161 boost::ignore_unused(data, itemsToDestroy);
162 }
163};
164
165template <typename ObjectType>
167 ObjectType,
168 typename std::enable_if<!std::is_fundamental<ObjectType>::value>::type>
169{
170public:
171 static void Destroy(ObjectType *data, size_t itemsToDestroy)
172 {
173 for (size_t i = 0; i < itemsToDestroy; ++i)
174 {
175 ObjectType *memLocation = &data[itemsToDestroy - i - 1];
176 memLocation->~ObjectType();
177 }
178 }
179};
180
181template <typename Dim, typename DataType, typename ExtentListType>
182std::shared_ptr<boost::multi_array_ref<DataType, Dim::Value>> CreateStorage(
183 const ExtentListType &extent)
184{
185 typedef boost::multi_array_ref<DataType, Dim::Value> ArrayType;
186 size_t size = std::accumulate(extent.begin(), extent.end(), 1,
187 std::multiplies<size_t>());
188 DataType *storage = MemoryManager<DataType>::RawAllocate(size);
190 [=](boost::multi_array_ref<DataType, Dim::Value> *ptr) {
191 boost::ignore_unused(ptr);
194 },
195 storage, extent);
196}
197
198template <typename DataType>
199std::shared_ptr<boost::multi_array_ref<DataType, 1>> CreateStorage(size_t d1)
200{
201 std::vector<size_t> extents = {d1};
202 return CreateStorage<OneD, DataType>(extents);
203}
204
205template <typename DataType>
206std::shared_ptr<boost::multi_array_ref<DataType, 2>> CreateStorage(size_t d1,
207 size_t d2)
208{
209 std::vector<size_t> extents = {d1, d2};
210 return CreateStorage<TwoD, DataType>(extents);
211}
212
213template <typename DataType>
214std::shared_ptr<boost::multi_array_ref<DataType, 3>> CreateStorage(size_t d1,
215 size_t d2,
216 size_t d3)
217{
218 std::vector<size_t> extents = {d1, d2, d3};
219 return CreateStorage<ThreeD, DataType>(extents);
220}
221} // namespace Nektar
222
223#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
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
std::shared_ptr< boost::multi_array_ref< DataType, Dim::Value > > CreateStorage(const ExtentListType &extent)