IMP logo
IMP Reference Guide  2.18.0
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 <boost/serialization/access.hpp>
17 #include <boost/serialization/split_member.hpp>
18 #include "hash.h"
19 
20 #if defined(_MSC_VER) && _MSC_VER == 1500
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 #ifndef SWIG
60  friend class boost::serialization::access;
61 
62  template<class Archive> void save(Archive &ar, const unsigned int) const {
63  size_t sz = V::size();
64  ar << sz;
65  auto it = V::begin();
66  while(sz-- > 0) {
67  ar << *it++;
68  }
69  }
70 
71  template<class Archive> void load(Archive &ar, const unsigned int) {
72  size_t sz;
73  ar >> sz;
74  V::resize(sz);
75  auto it = V::begin();
76  while(sz-- > 0) {
77  ar >> *it++;
78  }
79  }
80 
81  BOOST_SERIALIZATION_SPLIT_MEMBER()
82 #endif
83 
84  public:
85  Vector() {}
86  explicit Vector(unsigned int sz, const T &t = T()) : V(sz, t) {}
87 #if defined(_MSC_VER) && _MSC_VER == 1500
88  template <class It>
89  Vector(It b, It e,
90  typename boost::disable_if<boost::is_integral<It> >::type *t=0) {
91  for (It it = b; it != e; ++it) {
92  push_back(T(*it));
93  }
94  }
95  template <class VO>
96  explicit Vector(const std::vector<VO> &o) {
97  reserve(o.size());
98  for (std::vector<VO>::const_iterator it = o.begin();
99  it != o.end(); ++it) {
100  push_back(T(*it));
101  }
102  }
103 #else
104  template <class It>
105  Vector(It b, It e)
106  : V(b, e) {}
107  template <class VO>
108  explicit Vector(const std::vector<VO> &o)
109  : V(o.begin(), o.end()) {}
110 #endif
111  template <class O>
112  operator Vector<O>() const {
113  return Vector<O>(V::begin(), V::end());
114  }
115  template <class OV>
116  Vector<T> operator+=(const OV &o) {
117  V::insert(V::end(), o.begin(), o.end());
118  return *this;
119  }
120 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
121  void show(std::ostream &out = std::cout) const {
122  out << "[";
123  for (unsigned int i = 0; i < V::size(); ++i) {
124  if (i > 0) out << ", ";
125  if (i > 10) {
126  out << ",...";
127  break;
128  }
129  out << Showable(V::operator[](i));
130  }
131  out << "]";
132  }
133  operator Showable() const {
134  std::ostringstream oss;
135  show(oss);
136  return Showable(oss.str());
137  }
138  std::size_t __hash__() const {
139  return boost::hash_range(V::begin(), V::end());
140  }
141 #endif
142 };
143 
144 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
145 template <class T>
146 void swap(Vector<T> &a, Vector<T> &b) {
147  a.swap(b);
148 }
149 
150 template <class T>
151 inline Vector<T> operator+(Vector<T> ret, const Vector<T> &o) {
152  ret.insert(ret.end(), o.begin(), o.end());
153  return ret;
154 }
155 
156 #endif
157 
158 #if IMP_COMPILER_HAS_DEBUG_VECTOR &&IMP_HAS_CHECKS >= IMP_INTERNAL
159 template <class T>
160 inline std::size_t hash_value(const __gnu_debug::vector<T> &t) {
161  return boost::hash_range(t.begin(), t.end());
162 }
163 #endif
164 
165 IMPKERNEL_END_NAMESPACE
166 
167 #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