Virtual Testbed
Ship dynamics simulator for extreme conditions
face.hh
1 #ifndef VTESTBED_GEOMETRY_FACE_HH
2 #define VTESTBED_GEOMETRY_FACE_HH
3 
4 #include <algorithm>
5 #include <initializer_list>
6 #include <iosfwd>
7 #include <utility>
8 
9 #include <vtestbed/base/bstream.hh>
10 
11 namespace vtb {
12 
13  namespace geometry {
14 
15  template <int N>
16  class Face {
17 
18  static_assert(N >= 3, "bad N");
19 
20  public:
21  using value_type = unsigned int;
22  using size_type = int;
23  using iterator = value_type*;
24  using const_iterator = const value_type*;
25 
26  private:
27  value_type _indices[N] {};
28 
29  public:
30 
31  Face() = default;
32  Face(const Face&) = default;
33  Face& operator=(const Face&) = default;
34  ~Face() = default;
35 
36  inline
38  std::copy_n(list.begin(), N, this->_indices);
39  }
40 
41  template <class ... Args>
42  inline explicit
43  Face(Args ... indices): _indices{indices...} {}
44 
45  inline value_type
46  operator()(size_type i) const {
47  return this->_indices[i];
48  }
49 
50  inline value_type&
51  operator()(size_type i) {
52  return this->_indices[i];
53  }
54 
55  inline value_type
56  operator[](size_type i) const {
57  return this->_indices[i];
58  }
59 
60  inline value_type&
61  operator[](size_type i) {
62  return this->_indices[i];
63  }
64 
65  inline iterator begin() { return this->_indices; }
66  inline iterator end() { return this->_indices + N; }
67  inline const_iterator begin() const { return this->_indices; }
68  inline const_iterator end() const { return this->_indices + N; }
69 
70  inline value_type front() const { return this->_indices[0]; }
71  inline value_type back() const { return this->_indices[N-1]; }
72 
73  static constexpr inline size_type size() { return N; }
74 
75  inline size_type
76  index_of(value_type value) const {
77  for (size_type i=0; i<N; ++i) {
78  if (this->_indices[i] == value) {
79  return i;
80  }
81  }
82  return -1;
83  }
84 
85  inline bool
86  contains(value_type value) const {
87  for (size_type i=0; i<N; ++i) {
88  if (this->_indices[i] == value) {
89  return true;
90  }
91  }
92  return false;
93  }
94 
95  inline void
96  flip_winding() {
97  std::swap(this->_indices[0], this->_indices[1]);
98  }
99 
100  bool reorder(const Face<N>& rhs, value_type shared_vertex);
101  void sort();
102 
103  inline Face&
104  operator+=(value_type rhs) {
105  for (auto& idx : this->_indices) {
106  idx += rhs;
107  }
108  return *this;
109  }
110 
111  };
112 
113  template <int N>
114  inline bool
115  operator==(const Face<N>& lhs, const Face<N>& rhs) {
116  return std::equal(lhs.begin(), lhs.end(), rhs.begin());
117  }
118 
119  template <int N>
120  inline bool
121  operator!=(const Face<N>& lhs, const Face<N>& rhs) {
122  return !operator==(lhs, rhs);
123  }
124 
125  template <int N>
126  inline bool
127  operator<(const Face<N>& lhs, const Face<N>& rhs) {
128  return std::lexicographical_compare(
129  lhs.begin(), lhs.end(),
130  rhs.begin(), rhs.end()
131  );
132  }
133 
134  template <int N>
135  std::ostream&
136  operator<<(std::ostream& out, const Face<N>& rhs);
137 
138  template <int N>
139  std::istream&
140  operator>>(std::istream& in, Face<N>& rhs);
141 
142  template <int N>
144  operator<<(vtb::core::bstream& out, const Face<N>& rhs);
145 
146  template <int N>
148  operator>>(vtb::core::bstream& in, Face<N>& rhs);
149 
150  }
151 
152 }
153 
154 #endif // vim:filetype=cpp
Main namespace.
Definition: convert.hh:9