IMP logo
IMP Reference Guide  2.20.1
The Integrative Modeling Platform
Vector.h
Go to the documentation of this file.
1 /**
2  * \file IMP/Vector.h
3  * \brief A class for storing lists of IMP items.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_CONVERTIBLE_VECTOR_H
10 #define IMPKERNEL_CONVERTIBLE_VECTOR_H
11 #include <IMP/kernel_config.h>
12 // do not include anything more from base
13 #include "Showable.h"
14 #include "Value.h"
15 #include <sstream>
16 #include <cereal/access.hpp>
17 #include "hash.h"
18 
19 #if defined(_MSC_VER) && _MSC_VER == 1500
20 # include <type_traits>
21 # include <boost/type_traits.hpp>
22 # include <boost/utility.hpp>
23 #endif
24 
25 #if IMP_COMPILER_HAS_DEBUG_VECTOR &&IMP_HAS_CHECKS >= IMP_INTERNAL
26 #include <debug/vector>
27 #else
28 #include <vector>
29 #endif
30 
31 IMPKERNEL_BEGIN_NAMESPACE
32 
33 //! A more \imp-like version of the \c std::vector.
34 /** Specifically this class adds functionality from \c Python arrays such as
35  - hashing
36  - output to streams
37  - use of \c +=es
38  - implicit conversion when the contents are implicitly convertible
39  - bounds checking in debug mode
40  */
41 template <class T>
42 class Vector : public Value
43 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
44 #if IMP_COMPILER_HAS_DEBUG_VECTOR &&IMP_HAS_CHECKS >= IMP_INTERNAL
45  ,
46  public __gnu_debug::vector<T>
47 #else
48  ,
49  public std::vector<T>
50 #endif
51 #endif
52  {
53 #if IMP_COMPILER_HAS_DEBUG_VECTOR &&IMP_HAS_CHECKS >= IMP_INTERNAL
54  typedef __gnu_debug::vector<T> V;
55 #else
56  typedef std::vector<T> V;
57 #endif
58 
59  friend class cereal::access;
60 
61  template<class Archive> void save(Archive &ar) const {
62  size_t sz = V::size();
63  ar(sz);
64  auto it = V::begin();
65  while(sz-- > 0) {
66  ar(*it++);
67  }
68  }
69 
70  template<class Archive> void load(Archive &ar) {
71  size_t sz;
72  ar(sz);
73  V::resize(sz);
74  auto it = V::begin();
75  while(sz-- > 0) {
76  ar(*it++);
77  }
78  }
79 
80  public:
81  Vector() {}
82  explicit Vector(unsigned int sz, const T &t = T()) : V(sz, t) {}
83 #if defined(_MSC_VER) && _MSC_VER == 1500
84  template <class It>
85  Vector(It b, It e,
86  typename boost::disable_if<std::is_integral<It>::value>::type *t=0) {
87  for (It it = b; it != e; ++it) {
88  push_back(T(*it));
89  }
90  }
91  template <class VO>
92  explicit Vector(const std::vector<VO> &o) {
93  reserve(o.size());
94  for (std::vector<VO>::const_iterator it = o.begin();
95  it != o.end(); ++it) {
96  push_back(T(*it));
97  }
98  }
99 #else
100  template <class It>
101  Vector(It b, It e)
102  : V(b, e) {}
103  template <class VO>
104  explicit Vector(const std::vector<VO> &o)
105  : V(o.begin(), o.end()) {}
106 #endif
107  template <class O>
108  operator Vector<O>() const {
109  return Vector<O>(V::begin(), V::end());
110  }
111  template <class OV>
112  Vector<T> operator+=(const OV &o) {
113  V::insert(V::end(), o.begin(), o.end());
114  return *this;
115  }
116 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
117  void show(std::ostream &out = std::cout) const {
118  out << "[";
119  for (unsigned int i = 0; i < V::size(); ++i) {
120  if (i > 0) out << ", ";
121  if (i > 10) {
122  out << ",...";
123  break;
124  }
125  out << Showable(V::operator[](i));
126  }
127  out << "]";
128  }
129  operator Showable() const {
130  std::ostringstream oss;
131  show(oss);
132  return Showable(oss.str());
133  }
134  std::size_t __hash__() const {
135  return boost::hash_range(V::begin(), V::end());
136  }
137 #endif
138 };
139 
140 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
141 template <class T>
142 void swap(Vector<T> &a, Vector<T> &b) {
143  a.swap(b);
144 }
145 
146 template <class T>
147 inline Vector<T> operator+(Vector<T> ret, const Vector<T> &o) {
148  ret.insert(ret.end(), o.begin(), o.end());
149  return ret;
150 }
151 
152 #endif
153 
154 #if IMP_COMPILER_HAS_DEBUG_VECTOR &&IMP_HAS_CHECKS >= IMP_INTERNAL
155 template <class T>
156 inline std::size_t hash_value(const __gnu_debug::vector<T> &t) {
157  return boost::hash_range(t.begin(), t.end());
158 }
159 #endif
160 
161 IMPKERNEL_END_NAMESPACE
162 
163 namespace cereal {
164  template <class Archive, class T>
165  struct specialize<Archive, IMP::Vector<T>,
166  cereal::specialization::member_load_save> {};
167 }
168 
169 #endif /* IMPKERNEL_CONVERTIBLE_VECTOR_H */
Helper functions for implementing hashes.
Helper class to aid in output of IMP classes to streams.
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
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)
Print the hierarchy using a given decorator to display each node.
Base class for a simple primitive-like type.
Helper class to aid in output of IMP classes to streams.
Definition: Showable.h:25