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 
46 namespace Nektar
47 {
48 template <typename ObjectType, typename enabled = void>
50 
51 /// \internal
52 /// \brief Does nothing.
53 template <typename ObjectType>
55  ObjectType,
56  typename std::enable_if<std::is_fundamental<ObjectType>::value>::type>
57 {
58 public:
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 ///
87 template <typename ObjectType>
89  ObjectType,
90  typename std::enable_if<!std::is_fundamental<ObjectType>::value>::type>
91 {
92 public:
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 
123 private:
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 
150 template <typename ObjectType, typename enabled = void>
152 
153 template <typename ObjectType>
155  ObjectType,
156  typename std::enable_if<std::is_fundamental<ObjectType>::value>::type>
157 {
158 public:
159  static void Destroy(ObjectType *data, size_t itemsToDestroy)
160  {
161  boost::ignore_unused(data, itemsToDestroy);
162  }
163 };
164 
165 template <typename ObjectType>
167  ObjectType,
168  typename std::enable_if<!std::is_fundamental<ObjectType>::value>::type>
169 {
170 public:
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 
181 template <typename Dim, typename DataType, typename ExtentListType>
182 std::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 
198 template <typename DataType>
199 std::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 
205 template <typename DataType>
206 std::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 
213 template <typename DataType>
214 std::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 std::shared_ptr< DataType > AllocateSharedPtrD(const DeallocatorType &d, const Args &...args)
static void RawDeallocate(DataType *array, size_t NumberOfElements)
Deallocates memory allocated from RawAllocate.
static DataType * RawAllocate(size_t NumberOfElements)
Allocates a chunk of raw, uninitialized memory, capable of holding NumberOfElements objects.
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)