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