openPMD-api
Attributable.hpp
1 /* Copyright 2017-2020 Fabian Koller
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 #pragma once
22 
23 #include "openPMD/IO/AbstractIOHandler.hpp"
24 #include "openPMD/backend/Attribute.hpp"
25 #include "openPMD/backend/Writable.hpp"
26 #include "openPMD/auxiliary/OutOfRangeMsg.hpp"
27 
28 #include <exception>
29 #include <map>
30 #include <memory>
31 #include <vector>
32 #include <string>
33 #include <cstddef>
34 
35 // expose private and protected members for invasive testing
36 #ifndef OPENPMD_protected
37 # define OPENPMD_protected protected
38 #endif
39 
40 
41 namespace openPMD
42 {
43 namespace traits
44 {
45  template< typename T >
47 } // traits
49 
50 class no_such_attribute_error : public std::runtime_error
51 {
52 public:
53  no_such_attribute_error(std::string const& what_arg)
54  : std::runtime_error(what_arg)
55  { }
56  virtual ~no_such_attribute_error() { }
57 };
58 
59 
66 {
67  using A_MAP = std::map< std::string, Attribute >;
68  friend Writable* getWritable(Attributable*);
69  template< typename T_elem >
70  friend class BaseRecord;
71  template<
72  typename T,
73  typename T_key,
74  typename T_container
75  >
76  friend class Container;
77  template< typename T >
78  friend struct traits::GenerationPolicy;
79  friend class Iteration;
80  friend class Series;
81 
82 public:
83  Attributable();
84  Attributable(Attributable const&);
85  Attributable(Attributable&&) = delete;
86  virtual ~Attributable() = default;
87 
88  Attributable& operator=(Attributable const&);
89  Attributable& operator=(Attributable&&) = delete;
90 
103  template< typename T >
104  bool setAttribute(std::string const& key, T const& value);
105  bool setAttribute(std::string const& key, char const value[]);
115  Attribute getAttribute(std::string const& key) const;
116 
122  bool deleteAttribute(std::string const& key);
123 
128  std::vector< std::string > attributes() const;
133  size_t numAttributes() const;
139  bool containsAttribute(std::string const& key) const;
140 
146  std::string comment() const;
152  Attributable& setComment(std::string const& comment);
153 
154 OPENPMD_protected:
155  void flushAttributes();
156  void readAttributes();
157 
172  template< typename T >
173  T readFloatingpoint(std::string const& key) const;
188  template< typename T >
189  std::vector< T > readVectorFloatingpoint(std::string const& key) const;
190 
191  std::shared_ptr< Writable > m_writable;
192  /* views into the resources held by m_writable
193  * purely for convenience so code that uses these does not have to go through m_writable-> */
194  AbstractFilePosition* abstractFilePosition;
195  AbstractIOHandler* IOHandler;
196  Writable* parent;
197  bool& dirty() const { return m_writable->dirty; }
198  bool& written() const { return m_writable->written; }
199 
200 private:
201  virtual void linkHierarchy(std::shared_ptr< Writable > const& w);
202 
203  std::shared_ptr< A_MAP > m_attributes;
204 }; // Attributable
205 
206 //TODO explicitly instantiate Attributable::setAttribute for all T in Datatype
207 template< typename T >
208 inline bool
209 Attributable::setAttribute(std::string const& key, T const& value)
210 {
211  if(IOHandler && Access::READ_ONLY == IOHandler->m_frontendAccess )
212  {
213  auxiliary::OutOfRangeMsg const out_of_range_msg(
214  "Attribute",
215  "can not be set (read-only)."
216  );
217  throw no_such_attribute_error(out_of_range_msg(key));
218  }
219 
220  dirty() = true;
221  auto it = m_attributes->lower_bound(key);
222  if( it != m_attributes->end() && !m_attributes->key_comp()(key, it->first) )
223  {
224  // key already exists in map, just replace the value
225  it->second = Attribute(value);
226  return true;
227  } else
228  {
229  // emplace a new map element for an unknown key
230  m_attributes->emplace_hint(it,
231  std::make_pair(key, Attribute(value)));
232  return false;
233  }
234 }
235 inline bool
236 Attributable::setAttribute(std::string const& key, char const value[])
237 {
238  return this->setAttribute(key, std::string(value));
239 }
240 
241 template< typename T >
242 inline T
243 Attributable::readFloatingpoint(std::string const& key) const
244 {
245  static_assert(std::is_floating_point< T >::value, "Type of attribute must be floating point");
246 
247  return getAttribute(key).get< T >();
248 }
249 
250 template< typename T >
251 inline std::vector< T >
252 Attributable::readVectorFloatingpoint(std::string const& key) const
253 {
254  static_assert(std::is_floating_point< T >::value, "Type of attribute must be floating point");
255 
256  return getAttribute(key).get< std::vector< T > >();
257 }
258 } // namespace openPMD
Return an error string for read-only access.
Definition: OutOfRangeMsg.hpp:37
Definition: Attributable.hpp:50
T readFloatingpoint(std::string const &key) const
Retrieve the value of a floating point Attribute of user-defined precision with ensured type-safety...
Definition: Attributable.hpp:243
Container Element Creation Policy.
Definition: Attributable.hpp:46
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:38
bool setAttribute(std::string const &key, T const &value)
Populate Attribute of provided name with provided value.
Definition: Attributable.hpp:209
std::vector< T > readVectorFloatingpoint(std::string const &key) const
Retrieve a vector of values of a floating point Attributes of user-defined precision with ensured typ...
Definition: Attributable.hpp:252
Root level of the openPMD hierarchy.
Definition: Series.hpp:64
Varidic datatype supporting at least all formats for attributes specified in the openPMD standard...
Definition: Attribute.hpp:50
Interface for communicating between logical and physically persistent data.
Definition: AbstractIOHandler.hpp:68
Public definitions of openPMD-api.
Definition: Date.cpp:29
Layer to mirror structure of logical data and persistent data in file.
Definition: Writable.hpp:55
Definition: BaseRecord.hpp:36
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:70
Definition: AbstractFilePosition.hpp:26
open series as read-only, fails if series is not found
Layer to manage storage of attributes associated with file objects.
Definition: Attributable.hpp:65