RMF
NodeConstHandle.h
Go to the documentation of this file.
1 /**
2  * \file RMF/NodeConstHandle.h
3  * \brief Declaration of NodeConstHandle.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef RMF_NODE_CONST_HANDLE_H
10 #define RMF_NODE_CONST_HANDLE_H
11 
12 #include <boost/any.hpp>
13 #include <boost/current_function.hpp>
14 #include <memory>
15 #include <iostream>
16 #include <string>
17 #include <vector>
18 
19 #include "RMF/ID.h"
20 #include "RMF/Nullable.h"
21 #include "RMF/config.h"
22 #include "RMF/exceptions.h"
24 #include "RMF/internal/SharedData.h"
25 #include "RMF/internal/errors.h"
26 #include "RMF/constants.h"
27 #include "RMF/enums.h"
28 #include "RMF/internal/SharedData.h"
29 #include "RMF/keys.h"
30 #include "RMF/traits.h"
31 #include "RMF/types.h"
32 
33 namespace RMF {
34 class NodeConstHandle;
35 } // namespace RMF
36 
37 RMF_ENABLE_WARNINGS
38 
39 #define RMF_NODE_CATCH(extra_info) \
40  catch (Exception& e) { \
41  RMF_RETHROW( \
42  File(get_file_name()) << Node(get_id()) \
43  << Frame(get_current_frame_id()) \
44  << Operation(BOOST_CURRENT_FUNCTION) extra_info, \
45  e); \
46  }
47 
48 #define RMF_NODE_CATCH_KEY(k, extra_info) \
49  RMF_NODE_CATCH(<< Key(get_name(k)) \
50  << Category(get_category_name(k)) extra_info)
51 
52 #ifndef SWIG
53 #define RMF_HDF5_NODE_CONST_KEY_TYPE_METHODS_DECL(Traits, UCName)
54 #else
55 #define RMF_HDF5_NODE_CONST_KEY_TYPE_METHODS_DECL(Traits, UCName) \
56  public: \
57  Nullable<UCName> get_value(UCName##Key k) const; \
58  bool get_has_value(UCName##Key k) const; \
59  Nullable<UCName> get_frame_value(UCName##Key k) const; \
60  Nullable<UCName> get_static_value(UCName##Key k) const;
61 #endif
62 namespace RMF {
63 
64 class FileConstHandle;
65 class NodeConstHandle;
66 class RootConstHandle;
67 
68 //! Pass a list of them
69 typedef std::vector<NodeConstHandle> NodeConstHandles;
70 
71 //! A handle for a particular node in a read-only hierarchy.
72 /** Use these handles to access parts of the
73  hierarchy.
74 
75  The get_value_always() methods return the appropriate
76  value or TypeTraits::get_null_value() if the node does
77  not have that attribute.
78 
79  See the NodeHandle for modifying the contents.
80  */
81 class RMFEXPORT NodeConstHandle
82 #ifdef SWIG
83  // get conversions right
84  : public NodeID
85 #endif
86  {
87  friend class FileHandle;
88  int compare(const NodeConstHandle& o) const {
89  if (node_ < o.node_)
90  return -1;
91  else if (node_ > o.node_)
92  return 1;
93  else if (shared_.get() < o.shared_.get())
94  return -1;
95  else if (shared_.get() > o.shared_.get())
96  return 1;
97  else
98  return 0;
99  }
100 
101  // hopefully get_value will be inlined...
102  template <class Tag>
103  Nullable<typename Tag::Type> get_value_impl(ID<Tag> k) const {
104  if (shared_->get_loaded_frame() != FrameID()) {
105  Nullable<typename Tag::Type> ret = get_frame_value(k);
106  if (!ret.get_is_null()) return ret;
107  }
108  return get_static_value(k);
109  }
110 
111  protected:
112  NodeID node_;
113  std::shared_ptr<internal::SharedData> shared_;
114  // for error messages
115  std::string get_file_name() const;
116  // for error messages
117  FrameID get_current_frame_id() const;
118 
119 #if !defined(SWIG) && !defined(RMF_DOXYGEN)
120  public:
121  NodeConstHandle(NodeID node, std::shared_ptr<internal::SharedData> shared);
122 #endif
123 
124  public:
125 #if !defined(RMF_DOXYGEN) && !defined(SWIG)
126  std::shared_ptr<internal::SharedData> get_shared_data() const {
127  return shared_;
128  }
129 #endif
130 #if !defined(SWIG)
131  operator NodeID() const { return node_; }
132 #endif
133 
134  /** Get the NodeID for this handle. */
135  NodeID get_id() const { return node_; }
137  RMF_HASHABLE(NodeConstHandle, return node_.get_index());
138  NodeConstHandle() {}
139 
140  /** The name of the node is not necessarily unique. */
141  std::string get_name() const { return shared_->get_name(node_); }
142  NodeConstHandles get_children() const;
143 
144  /** \name Functions to access attributes
145 
146  @{
147  */
148  template <class Tag>
149  Nullable<typename Tag::Type> get_value(ID<Tag> k) const {
150  return get_value_impl(k);
151  }
152  template <class Tag>
153  bool get_has_value(ID<Tag> k) const {
154  return !get_value(k).get_is_null();
155  }
156  template <class Tag>
157  Nullable<typename Tag::Type> get_frame_value(ID<Tag> k) const {
158  RMF_USAGE_CHECK(shared_->get_loaded_frame() != FrameID(),
159  "Need to set a current frame before getting frame values.");
160  return shared_->get_loaded_value(node_, k);
161  }
162  template <class Tag>
163  Nullable<typename Tag::Type> get_static_value(ID<Tag> k) const {
164  return shared_->get_static_value(node_, k);
165  }
166 /** @} */
167 
168 #ifndef SWIG
169  /** Each node can be associated at runtime with an
170  arbitrary piece of data to aid in maintaining the
171  relationship with application data structures. This
172  data type must be convertible to a void* pointer.
173  If direct casting does not work, you can implement
174  a function called \c get_void_pointer() that takes
175  the passed type and returns a \c void* pointer in
176  the namespace where the type is declared (so it is
177  found via Koenig lookup). Support has already been
178  added for std::shared_ptr.
179 
180  Either the association must not have been set before
181  or overwrite must be true. If overwrite is true,
182  the type must be the same as the old type.
183  */
184  template <class T>
185  void set_association(const T& v, bool overwrite = false) const {
186  shared_->set_association(node_, v, overwrite);
187  }
188 #else
189  void set_association(void* v, bool overwrite = false) const;
190 #endif
191  //! Return the associated pointer for this node
192  /** An exception will be thrown if it doesn't have one.*/
193  template <class T>
194  T get_association() const {
195  return boost::any_cast<T>(shared_->get_association(node_));
196  }
197 
198  bool get_has_association() const {
199  return shared_->get_has_association(node_);
200  }
201 
202  //! get the type of this node
203  NodeType get_type() const { return NodeType(shared_->get_type(node_)); }
204 
205  RMF_FOREACH_TYPE(RMF_HDF5_NODE_CONST_KEY_TYPE_METHODS_DECL);
206 
207  RMF_SHOWABLE(NodeConstHandle, get_name() << "(" << get_type() << ", " << node_
208  << ")");
209 
210  FileConstHandle get_file() const;
211 };
212 
213 //! Produce hash values for boost hash tables.
214 inline std::size_t hash_value(const NodeConstHandle& t) {
215  return t.__hash__();
216 }
217 
218 } /* namespace RMF */
219 
220 RMF_DISABLE_WARNINGS
221 
222 #endif /* RMF_NODE_CONST_HANDLE_H */
Declaration of RMF::ID.
Default implementation for types.h.
void set_association(const T &v, bool overwrite=false) const
NodeID get_id() const
NodeType get_type() const
get the type of this node
Various constants.
A handle for a particular node in a read-only hierarchy.
Handle read/write of Model data from/to files.
ID< FrameTag > FrameID
Definition: ID.h:108
A handle for a read-only RMF file.
std::size_t hash_value(const BufferConstHandle &t)
Produce hash values for boost hash tables.
Return a possibly null value.
Declarations of the various exception types.
A handle for an RMF file.
Definition: FileHandle.h:54
ID< NodeTag > NodeID
Definition: ID.h:106
#define RMF_COMPARISONS(Name)
Implement comparison in a class using field as the variable to compare.
A strong enum with an associated string name for each value.
Definition: Enum.h:46
The various enums used in RMF.
#define RMF_HASHABLE(name, hashret)
Implement a hash function for the class.
std::vector< NodeConstHandle > NodeConstHandles
Pass a list of them.
Declarations of the various key types.
#define RMF_FOREACH_TYPE(macroname)
A helper class for allowing nice return of possibly null values.
std::string get_name() const
T get_association() const
Return the associated pointer for this node.
Various general useful macros for IMP.
Enum< NodeTypeTag > NodeType
Definition: Enum.h:121