RMF
Vector.h
Go to the documentation of this file.
1 /**
2  * \file RMF/Vector.h
3  * \brief Represent coordinates.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef RMF_VECTOR_H
10 #define RMF_VECTOR_H
11 
12 #include "RMF/config.h"
13 #include "infrastructure_macros.h"
14 #include "exceptions.h"
15 #include <boost/range/begin.hpp>
16 #include <boost/range/end.hpp>
17 #include <type_traits>
18 #include <array>
19 #include <algorithm>
20 
21 RMF_ENABLE_WARNINGS
22 
23 namespace RMF {
24 
25 #ifndef SWIG
26 /** \brief Represent a point in some dimension.
27 
28  std::array provides `operator[]()` and `begin()`/`end()` in C++.
29  */
30 template <unsigned int D>
31 class Vector
32  : public std::array<float, D>
33  {
34  typedef std::array<float, D> P;
35  // work around swig
36  template <class R, class Enabled = void>
37  struct Convert {};
38 
39  template <class R>
40  struct Convert<R, typename std::enable_if<std::is_convertible<
41  R, std::array<float, D> >::value>::type> {
42  static void convert(const R& r, std::array<float, D>& d) { d = r; }
43  };
44 
45  template <class R>
46  struct Convert<R, typename std::enable_if<!std::is_convertible<
47  R, std::array<float, D> >::value>::type> {
48  static void convert(const R& r, std::array<float, D>& d) {
49  std::copy(boost::begin(r), boost::end(r), d.begin());
50  }
51  };
52  public:
53  Vector() {}
54  //#ifndef RMF_SWIG_WRAPPER
55  template <class Range>
56  explicit Vector(Range r) {
57  Convert<Range>::convert(r, *this);
58  }
59 
60  RMF_CXX11_DEFAULT_COPY_CONSTRUCTOR(Vector);
61 
62  Vector(float x, float y, float z) {
63  static_assert(D == 3, "Constructor only valid for Vector3");
64  P::operator[](0) = x;
65  P::operator[](1) = y;
66  P::operator[](2) = z;
67  }
68  Vector(float x, float y, float z, float q) {
69  static_assert(D == 4, "Constructor only valid for Vector4");
70  P::operator[](0) = x;
71  P::operator[](1) = y;
72  P::operator[](2) = z;
73  P::operator[](3) = q;
74  }
75  RMF_SHOWABLE(Vector, std::vector<float>(P::begin(), P::end()));
76 #if !defined(RMF_DOXYGEN)
77  float __getitem__(unsigned int i) const {
78  if (i >= D) throw IndexException();
79  return P::operator[](i);
80  }
81  unsigned int __len__() const { return D; }
82 #endif
83  static unsigned int get_dimension() { return D; }
84 };
85 
86 #else
87 template <unsigned int D>
88 class Vector {};
89 template <>
90 struct Vector<3U> {
91  Vector() {}
92  Vector(const Vector<3U> &o);
93  Vector(float x, float y, float z);
94  float __getitem__(unsigned int i) const;
95  unsigned int __len__() const;
96  static unsigned int get_dimension();
97 };
98 template <>
99 struct Vector<4U> {
100  Vector() {}
101  Vector(const Vector<4U> &o);
102  Vector(float w, float x, float y, float z);
103  float __getitem__(unsigned int i) const;
104  unsigned int __len__() const;
105  static unsigned int get_dimension();
106 };
107 #endif
108 
109 } /* namespace RMF */
110 
111 RMF_DISABLE_WARNINGS
112 
113 #endif /* RMF_VECTOR_H */
Represent a point in some dimension.
Definition: Vector.h:31
Declarations of the various exception types.
Various general useful macros for IMP.