IMP logo
IMP Reference Guide  develop.1a86c4215a,2024/04/24
The Integrative Modeling Platform
ConstVector.h
Go to the documentation of this file.
1 /**
2  * \file IMP/ConstVector.h
3  * \brief Store an array of values of the same type.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_CONST_VECTOR_H
10 #define IMPKERNEL_CONST_VECTOR_H
11 
12 #include <IMP/kernel_config.h>
13 #include "base_macros.h"
14 #include "exception.h"
15 #include "Value.h"
16 #include <boost/scoped_array.hpp>
17 #include <cereal/access.hpp>
18 #include <IMP/hash.h>
19 #include <iterator>
20 
21 IMPKERNEL_BEGIN_NAMESPACE
22 
23 //! Store an array of values of the same type.
24 /** Items must be comparable and hashable and the arrays
25  cannot be changed after creation.*/
26 template <class Data, class SwigData = Data>
27 class ConstVector : public Value {
28  boost::scoped_array<Data> v_;
29  unsigned int sz_;
30  int compare(const ConstVector &o) const {
31  if (size() < o.size())
32  return -1;
33  else if (size() > o.size())
34  return 1;
35  for (unsigned int i = 0; i < size(); ++i) {
36  if (v_[i] < o.v_[i])
37  return -1;
38  else if (v_[i] > o.v_[i])
39  return 1;
40  }
41  return 0;
42  }
43  void create(unsigned int sz) {
44  if (sz == 0) {
45  v_.reset(nullptr);
46  } else {
47  v_.reset(new Data[sz]);
48  }
49  sz_ = sz;
50  }
51  template <class It>
52  void copy_from(It b, It e) {
53  create(std::distance(b, e));
54  std::copy(b, e, v_.get());
55  }
56 
57  friend class cereal::access;
58 
59  template<class Archive> void serialize(Archive &ar) {
60  ar(sz_);
61  if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
62  create(sz_);
63  }
64  for (unsigned int i = 0; i < sz_; ++i) {
65  ar(v_[i]);
66  }
67  }
68 
69  public:
70  ~ConstVector() {}
71  ConstVector(unsigned int sz, Data fill) {
72  create(sz);
73  std::fill(v_.get(), v_.get() + sz, fill);
74  }
75  ConstVector() : v_(0), sz_(0) {}
76  template <class It>
77  ConstVector(It b, It e) {
78  copy_from(b, e);
79  }
80  template <class Vector>
81  explicit ConstVector(const Vector &i) {
82  copy_from(i.begin(), i.end());
83  }
84 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
85  /* Add the arguments to attempt to make VC happy as it tries to
86  use the templated version instead.
87  */
88  ConstVector(const ConstVector<Data, SwigData> &o) : Value(), sz_(0) {
89  copy_from(o.begin(), o.end());
90  }
92  copy_from(o.begin(), o.end());
93  return *this;
94  }
95  ConstVector(int sz) { create(sz); }
96 #endif
98 #ifndef SWIG
99  Data operator[](unsigned int i) const {
100  IMP_USAGE_CHECK(i < sz_, "Out of range");
101  return v_[i];
102  }
103 #ifndef IMP_DOXYGEN
104  void set_item(unsigned int i, SwigData v) const {
105  IMP_USAGE_CHECK(i < sz_, "Out of range");
106  v_[i] = v;
107  ;
108  }
109 #endif
110 #endif
111 #ifndef IMP_DOXYGEN
112  SwigData __getitem__(unsigned int i) const {
113  if (i >= sz_)
114  IMP_THROW("Out of bound " << i << " vs " << sz_, IndexException);
115  return operator[](i);
116  }
117  unsigned int __len__() const { return sz_; }
118 #endif
119 #ifndef SWIG
120  unsigned int size() const { return sz_; }
121 #endif
123  out << "(";
124  for (unsigned int i = 0; i < size(); ++i) {
125  out << Showable(v_[i]);
126  if (i != size() - 1)
127  out << " ";
128  }
129  out << ")";
130  });
131 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
132  typedef const Data *const_iterator;
133  const_iterator begin() const { return v_.get(); }
134  const_iterator end() const { return v_.get() + size(); }
135  void swap_with(ConstVector &o) {
136  std::swap(sz_, o.sz_);
137  v_.swap(o.v_);
138  }
139 #endif
140  IMP_HASHABLE_INLINE(ConstVector, return boost::hash_range(begin(), end()););
141 };
142 
143 IMP_SWAP_1(ConstVector);
144 
145 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
146 template <class D>
147 inline std::size_t hash_value(const ConstVector<D> &t) {
148  return t.__hash__();
149 }
150 #endif
151 
152 IMPKERNEL_END_NAMESPACE
153 
154 #endif /* IMPKERNEL_CONST_VECTOR_H */
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
#define IMP_HASHABLE_INLINE(name, hashret)
Definition: hash_macros.h:18
Helper functions for implementing hashes.
#define IMP_COMPARISONS(Name)
Implement comparison in a class using a compare function.
Exception definitions and assertions.
A more IMP-like version of the std::vector.
Definition: Vector.h:50
Base class for a simple primitive-like type.
Definition: Value.h:23
int compare(const VectorD< D > &a, const VectorD< D > &b)
lexicographic comparison of two vectors
Definition: VectorD.h:166
An exception for a request for an invalid member of a container.
Definition: exception.h:156
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
Definition: check_macros.h:50
Base class for a simple primitive-like type.
Store an array of values of the same type.
Definition: ConstVector.h:27
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Helper class to aid in output of IMP classes to streams.
Definition: Showable.h:25
Various general useful macros for IMP.