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 
50 public:
51  using iterator = T *;
52  using reverse_iterator = std::reverse_iterator< iterator >;
53 
54  size_t size() const
55  {
56  return m_size;
57  }
58 
59  inline T * data() const
60  {
61  return m_ptr;
62  }
63 
64  inline T & operator[]( size_t i ) const
65  {
66  return data()[ i ];
67  }
68 
69  inline iterator begin() const
70  {
71  return data();
72  }
73  inline iterator end() const
74  {
75  return data() + size();
76  }
77  inline reverse_iterator rbegin() const
78  {
79  // std::reverse_iterator does the -1 thing automatically
80  return reverse_iterator{ data() + size() };
81  }
82  inline reverse_iterator rend() const
83  {
84  return reverse_iterator{ data() };
85  }
86 };
87 
96 template< typename T >
97 class DynamicMemoryView
98 {
99  friend class RecordComponent;
100 
101 private:
102  using param_t = Parameter< Operation::GET_BUFFER_VIEW >;
103  param_t m_param;
104  size_t m_size;
105  RecordComponent m_recordComponent;
106 
107  DynamicMemoryView(
108  param_t param, size_t size, RecordComponent recordComponent )
109  : m_param( std::move( param ) )
110  , m_size( size )
111  , m_recordComponent( std::move( recordComponent ) )
112  {
113  m_param.update = true;
114  }
115 
116 public:
121  {
122  if( m_param.out->backendManagedBuffer )
123  {
124  // might need to update
125  m_recordComponent.IOHandler()->enqueue(
126  IOTask( &m_recordComponent, m_param ) );
127  m_recordComponent.IOHandler()->flush();
128  }
129  return Span< T >{ static_cast< T * >( m_param.out->ptr ), m_size };
130  }
131 };
132 }
openPMD::UnitDimension::T
@ T
time
openPMD
Public definitions of openPMD-api.
Definition: Date.cpp:29
openPMD::IOTask
Self-contained description of a single IO operation.
Definition: IOTask.hpp:589
openPMD::Span
Subset of C++20 std::span class template.
Definition: Writable.hpp:47
openPMD::DynamicMemoryView::currentBuffer
Span< T > currentBuffer()
Acquire the underlying buffer at its current position in memory.
Definition: Span.hpp:120