IMP logo
IMP Reference Guide  2.18.0
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 <boost/serialization/access.hpp>
18 #include <boost/serialization/split_member.hpp>
19 #include <IMP/hash.h>
20 #include <iterator>
21 
22 IMPKERNEL_BEGIN_NAMESPACE
23 
24 //! Store an array of values of the same type.
25 /** Items must be comparable and hashable and the arrays
26  cannot be changed after creation.*/
27 template <class Data, class SwigData = Data>
28 class ConstVector : public Value {
29  boost::scoped_array<Data> v_;
30  unsigned int sz_;
31  int compare(const ConstVector &o) const {
32  if (size() < o.size())
33  return -1;
34  else if (size() > o.size())
35  return 1;
36  for (unsigned int i = 0; i < size(); ++i) {
37  if (v_[i] < o.v_[i])
38  return -1;
39  else if (v_[i] > o.v_[i])
40  return 1;
41  }
42  return 0;
43  }
44  void create(unsigned int sz) {
45  if (sz == 0) {
46  v_.reset(nullptr);
47  } else {
48  v_.reset(new Data[sz]);
49  }
50  sz_ = sz;
51  }
52  template <class It>
53  void copy_from(It b, It e) {
54  create(std::distance(b, e));
55  std::copy(b, e, v_.get());
56  }
57 
58 #ifndef SWIG
59  friend class boost::serialization::access;
60 
61  template<class Archive> void save(Archive &ar, const unsigned int) const {
62  ar << sz_;
63  for (unsigned int i = 0; i < sz_; ++i) {
64  ar << v_[i];
65  }
66  }
67 
68  template<class Archive> void load(Archive &ar, const unsigned int) {
69  ar >> sz_;
70  create(sz_);
71  for (unsigned int i = 0; i < sz_; ++i) {
72  ar >> v_[i];
73  }
74  }
75 
76  BOOST_SERIALIZATION_SPLIT_MEMBER()
77 #endif
78 
79  public:
80  ~ConstVector() {}
81  ConstVector(unsigned int sz, Data fill) {
82  create(sz);
83  std::fill(v_.get(), v_.get() + sz, fill);
84  }
85  ConstVector() : v_(0), sz_(0) {}
86  template <class It>
87  ConstVector(It b, It e) {
88  copy_from(b, e);
89  }
90  template <class Vector>
91  explicit ConstVector(const Vector &i) {
92  copy_from(i.begin(), i.end());
93  }
94 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
95  /* Add the arguments to attempt to make VC happy as it tries to
96  use the templated version instead.
97  */
98  ConstVector(const ConstVector<Data, SwigData> &o) : Value(), sz_(0) {
99  copy_from(o.begin(), o.end());
100  }
102  copy_from(o.begin(), o.end());
103  return *this;
104  }
105  ConstVector(int sz) { create(sz); }
106 #endif
108 #ifndef SWIG
109  Data operator[](unsigned int i) const {
110  IMP_USAGE_CHECK(i < sz_, "Out of range");
111  return v_[i];
112  }
113 #ifndef IMP_DOXYGEN
114  void set_item(unsigned int i, SwigData v) const {
115  IMP_USAGE_CHECK(i < sz_, "Out of range");
116  v_[i] = v;
117  ;
118  }
119 #endif
120 #endif
121 #ifndef IMP_DOXYGEN
122  SwigData __getitem__(unsigned int i) const {
123  if (i >= sz_)
124  IMP_THROW("Out of bound " << i << " vs " << sz_, IndexException);
125  return operator[](i);
126  }
127  unsigned int __len__() const { return sz_; }
128 #endif
129 #ifndef SWIG
130  unsigned int size() const { return sz_; }
131 #endif
133  out << "(";
134  for (unsigned int i = 0; i < size(); ++i) {
135  out << Showable(v_[i]);
136  if (i != size() - 1)
137  out << " ";
138  }
139  out << ")";
140  });
141 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
142  typedef const Data *const_iterator;
143  const_iterator begin() const { return v_.get(); }
144  const_iterator end() const { return v_.get() + size(); }
145  void swap_with(ConstVector &o) {
146  std::swap(sz_, o.sz_);
147  v_.swap(o.v_);
148  }
149 #endif
150  IMP_HASHABLE_INLINE(ConstVector, return boost::hash_range(begin(), end()););
151 };
152 
153 IMP_SWAP_1(ConstVector);
154 
155 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
156 template <class D>
157 inline std::size_t hash_value(const ConstVector<D> &t) {
158  return t.__hash__();
159 }
160 #endif
161 
162 IMPKERNEL_END_NAMESPACE
163 
164 #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:42
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:179
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:28
#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.