openPMD-api
Span.hpp
1 /* Copyright 2021 Franz Poeschel
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #pragma once
23 
24 #include "openPMD/RecordComponent.hpp"
25 
26 #include <iterator>
27 
28 namespace openPMD
29 {
36 template <typename T>
37 class Span
38 {
39  template <typename>
40  friend class DynamicMemoryView;
41 
42 private:
43  T *m_ptr;
44  size_t m_size;
45 
46  Span(T *ptr, size_t size) : m_ptr(ptr), m_size(size)
47  {}
48 
49 public:
50  using iterator = T *;
51  using reverse_iterator = std::reverse_iterator<iterator>;
52 
53  size_t size() const
54  {
55  return m_size;
56  }
57 
58  inline T *data() const
59  {
60  return m_ptr;
61  }
62 
63  inline T &operator[](size_t i) const
64  {
65  return data()[i];
66  }
67 
68  inline iterator begin() const
69  {
70  return data();
71  }
72  inline iterator end() const
73  {
74  return data() + size();
75  }
76  inline reverse_iterator rbegin() const
77  {
78  // std::reverse_iterator does the -1 thing automatically
79  return reverse_iterator{data() + size()};
80  }
81  inline reverse_iterator rend() const
82  {
83  return reverse_iterator{data()};
84  }
85 };
86 
95 template <typename T>
96 class DynamicMemoryView
97 {
98  friend class RecordComponent;
99 
100 private:
101  using param_t = Parameter<Operation::GET_BUFFER_VIEW>;
102  param_t m_param;
103  size_t m_size = 0;
104  RecordComponent m_recordComponent;
105 
106  DynamicMemoryView(
107  param_t param, size_t size, RecordComponent recordComponent)
108  : m_param(std::move(param))
109  , m_size(size)
110  , m_recordComponent(std::move(recordComponent))
111  {
112  m_param.update = true;
113  }
114 
115 public:
116  explicit DynamicMemoryView() = default;
117 
122  {
123  if (m_param.out->backendManagedBuffer)
124  {
125  // might need to update
126  m_recordComponent.IOHandler()->enqueue(
127  IOTask(&m_recordComponent, m_param));
128  m_recordComponent.IOHandler()->flush(internal::defaultFlushParams);
129  }
130  return Span<T>{static_cast<T *>(m_param.out->ptr), m_size};
131  }
132 };
133 } // namespace openPMD
Self-contained description of a single IO operation.
Definition: IOTask.hpp:695
STL namespace.
Public definitions of openPMD-api.
Subset of C++20 std::span class template.
Definition: Writable.hpp:46
Span< T > currentBuffer()
Acquire the underlying buffer at its current position in memory.
Definition: Span.hpp:121