IMP  2.0.1
The Integrative Modeling Platform
Array.h
Go to the documentation of this file.
1 /**
2  * \file base/Array.h
3  * \brief Classes to handle static sized arrays of things.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBASE_ARRAY_H
10 #define IMPBASE_ARRAY_H
11 
12 #include <IMP/base/base_config.h>
13 #include "Value.h"
14 #include "comparison_macros.h"
15 #include "hash_macros.h"
16 #include "check_macros.h"
17 #include "showable_macros.h"
18 #include <boost/array.hpp>
19 
20 IMPBASE_BEGIN_NAMESPACE
21 
22 
23 //! A class to store an fixed array of same-typed values.
24 /** Only the constructor with the correct number of arguments for the
25  dimensionality can be used.
26 
27  \note These are mapped to/from python tuples, so there is
28  no need to use types that are typedefs of this on the python
29  side.
30 
31  \see ConstVector
32 */
33 template <unsigned int D, class Data, class SwigData=Data>
34 class Array:
35  public Value
36 {
37  typedef boost::array<Data, D> Storage;
38  Storage d_;
39  int compare(const Array<D, Data, SwigData> &o) const {
40  for (unsigned int i=0;i<D; ++i) {
41  if (d_[i] < o[i]) return -1;
42  else if (d_[i] > o[i]) return 1;
43  }
44  return 0;
45  }
46 public:
47 #ifndef IMP_DOXYGEN
48  typedef SwigData value_type;
49 #endif
50  unsigned int get_dimension() {return D;};
51  Array(){
52  }
53  Array(SwigData x, SwigData y) {
54  IMP_USAGE_CHECK(D==2, "Need " << D << " to construct a "
55  << D << "-tuple.");
56  d_[0] = x;
57  d_[1] = y;
58  }
59  Array(SwigData x, SwigData y, SwigData z) {
60  IMP_USAGE_CHECK(D==3, "Need " << D << " to construct a "
61  << D << "-tuple.");
62  d_[0] = x;
63  d_[1] = y;
64  d_[2] = z;
65  }
66  Array(SwigData x0, SwigData x1, SwigData x2, SwigData x3) {
67  IMP_USAGE_CHECK(D==4, "Need " << D << " to construct a "
68  << D << "-tuple.");
69  d_[0] = x0;
70  d_[1] = x1;
71  d_[2] = x2;
72  d_[3] = x3;
73  }
74  SwigData get(unsigned int i) const {
75  return d_[i];
76  }
77  IMP_HASHABLE_INLINE(Array, std::size_t seed = 0;
78  for (unsigned int i=0; i< D; ++i) {
79  boost::hash_combine(seed,
80  d_[i]);
81  }
82  return seed;);
84 #ifndef SWIG
85  const Data operator[](unsigned int i) const {
86  IMP_USAGE_CHECK(i < D, "Out of range");
87  return d_[i];
88  }
89  Data& operator[](unsigned int i) {
90  IMP_USAGE_CHECK(i < D, "Out of range");
91  return d_[i];
92  }
93 #ifndef IMP_DOXYGEN
94  void set_item(unsigned int i, SwigData v) const {
95  IMP_USAGE_CHECK(i < D, "Out of range");
96  d_[i]=v;
97  }
98 #endif
99 #endif
100 #ifndef IMP_DOXYGEN
101  SwigData __getitem__(unsigned int i) const {
102  if (i >= D) IMP_THROW("Out of bound " << i << " vs " << D,
104  return operator[](i);
105  }
106  unsigned int __len__() const {return D;}
107 #endif
108 #ifndef SWIG
109  unsigned int size() const {
110  return D;
111  }
112 #endif
113  std::string get_name() const {
114  std::ostringstream oss;
115  oss << "\"";
116  for (unsigned int i=0; i< D; ++i) {
117  if (i>0) {
118  oss << "\" and \"";
119  }
120  oss << d_[i];
121  }
122  oss << "\"";
123  return oss.str();
124  }
126  out << get_name();
127  });
128  typedef typename Storage::iterator iterator;
129  iterator begin() {
130  return d_.begin();
131  }
132  iterator end() {
133  return d_.end();
134  }
135  typedef typename Storage::const_iterator const_iterator;
136  const_iterator begin() const {
137  return d_.begin();
138  }
139  const_iterator end() const {
140  return d_.end();
141  }
142 };
143 
144 
145 IMPBASE_END_NAMESPACE
146 
147 #endif /* IMPBASE_ARRAY_H */