pops-core  0.9
PoPS (Pest or Pathogen Spread) Model Core C++ library
utils.hpp
Go to the documentation of this file.
1 #ifndef POPS_UTILS_HPP
2 #define POPS_UTILS_HPP
3 
4 /*
5  * PoPS model - general utility functions (unrelated to the model)
6  *
7  * Copyright (C) 2020-2021 by the authors.
8  *
9  * Authors: Vaclav Petras <wenzeslaus gmail com>
10  *
11  * The code contained herein is licensed under the GNU General Public
12  * License. You may obtain a copy of the GNU General Public License
13  * Version 2 or later at the following locations:
14  *
15  * http://www.opensource.org/licenses/gpl-license.html
16  * http://www.gnu.org/copyleft/gpl.html
17  */
18 
33 #define UNUSED(expr) (void)(expr)
34 
35 #define M_PI 3.14159265358979323846
36 #define PI M_PI
37 
38 #include <algorithm>
39 #include <array>
40 #include <vector>
41 
45 template<typename Container, typename Value>
46 bool container_contains(const Container& container, const Value& value)
47 {
48  return container.find(value) != container.end();
49 }
50 
51 // Replace by ranges::shuffle in C++20.
55 template<typename Container, typename Generator>
56 void shuffle_container(Container& container, Generator& generator)
57 {
58  std::shuffle(container.begin(), container.end(), generator);
59 }
60 
61 typedef std::tuple<int, int, int, int> BBoxInt;
62 typedef std::tuple<double, double, double, double> BBoxFloat;
63 typedef std::tuple<bool, bool, bool, bool> BBoxBool;
64 
65 // C++20 NumericType
66 template<typename Number>
67 struct BBox
68 {
69  Number north;
70  Number south;
71  Number east;
72  Number west;
73 
74  BBox() : north(0), south(0), east(0), west(0) {}
75 };
76 
83 enum class Direction
84 {
85  N = 0,
86  NE = 45,
87  E = 90,
88  SE = 135,
89  S = 180,
90  SW = 225,
91  W = 270,
92  NW = 315,
93  None
94 };
95 
96 template<int... Indices>
97 struct indices
98 {
99  using next = indices<Indices..., sizeof...(Indices)>;
100 };
101 
102 template<int Size>
104 {
105  using type = typename build_indices<Size - 1>::type::next;
106 };
107 
108 template<>
109 struct build_indices<0>
110 {
111  using type = indices<>;
112 };
113 
114 template<typename T>
115 using Bare = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
116 
117 template<typename Tuple>
118 constexpr typename build_indices<std::tuple_size<Bare<Tuple>>::value>::type
120 {
121  return {};
122 }
123 
124 template<typename Tuple, int... Indices>
125 std::array<
126  typename std::tuple_element<0, Bare<Tuple>>::type,
127  std::tuple_size<Bare<Tuple>>::value>
129 {
130  using std::get;
131  return {{get<Indices>(std::forward<Tuple>(tuple))...}};
132 }
133 
134 template<typename Tuple>
135 auto to_array(Tuple&& tuple)
136  -> decltype(to_array(std::declval<Tuple>(), make_indices<Tuple>()))
137 {
138  return to_array(std::forward<Tuple>(tuple), make_indices<Tuple>());
139 }
140 
142 {
143  switch (type) {
144  case Direction::N:
145  return "N";
146  case Direction::S:
147  return "S";
148  case Direction::E:
149  return "E";
150  case Direction::W:
151  return "W";
152  case Direction::None:
153  return "None";
154  default:
155  return "Invalid direction";
156  }
157 }
158 
172 template<typename RasterIndex, typename RasterType>
173 std::vector<std::vector<RasterIndex>> find_suitable_cells(const RasterType& raster)
174 {
175  std::vector<std::vector<RasterIndex>> cells;
176  // The assumption is that the raster is sparse (otherwise we would not be doing
177  // this), so we have no number for the reserve method.
178  for (RasterIndex row = 0; row < raster.rows(); ++row) {
179  for (RasterIndex col = 0; col < raster.cols(); ++col) {
180  if (raster(row, col) > 0) {
181  cells.push_back({row, col});
182  }
183  }
184  }
185  return cells;
186 }
187 
188 #endif // POPS_UTILS_HPP
BBox::east
Number east
Definition: utils.hpp:71
quarantine_enum_to_string
std::string quarantine_enum_to_string(Direction type)
Definition: utils.hpp:141
Direction::NW
@ NW
Northwest.
BBoxFloat
std::tuple< double, double, double, double > BBoxFloat
Definition: utils.hpp:62
BBox::north
Number north
Definition: utils.hpp:69
BBoxInt
std::tuple< int, int, int, int > BBoxInt
Definition: utils.hpp:61
indices
Definition: utils.hpp:97
Direction::W
@ W
West.
container_contains
bool container_contains(const Container &container, const Value &value)
Return true if container contains value.
Definition: utils.hpp:46
Direction::SW
@ SW
Southwest.
build_indices
Definition: utils.hpp:103
BBox::BBox
BBox()
Definition: utils.hpp:74
build_indices::type
typename build_indices< Size - 1 >::type::next type
Definition: utils.hpp:105
to_array
std::array< typename std::tuple_element< 0, Bare< Tuple > >::type, std::tuple_size< Bare< Tuple > >::value > to_array(Tuple &&tuple, indices< Indices... >)
Definition: utils.hpp:128
BBoxBool
std::tuple< bool, bool, bool, bool > BBoxBool
Definition: utils.hpp:63
Direction::E
@ E
East.
Bare
typename std::remove_cv< typename std::remove_reference< T >::type >::type Bare
Definition: utils.hpp:115
find_suitable_cells
std::vector< std::vector< RasterIndex > > find_suitable_cells(const RasterType &raster)
Create a list of suitable cells in from a host raster.
Definition: utils.hpp:173
Direction::SE
@ SE
Southeast.
Direction::N
@ N
North.
shuffle_container
void shuffle_container(Container &container, Generator &generator)
Reorder items in container.
Definition: utils.hpp:56
BBox::west
Number west
Definition: utils.hpp:72
Direction::NE
@ NE
Northeast.
BBox::south
Number south
Definition: utils.hpp:70
Direction::None
@ None
No direction (non-directional)
Direction::S
@ S
South.
make_indices
constexpr build_indices< std::tuple_size< Bare< Tuple > >::value >::type make_indices()
Definition: utils.hpp:119
BBox
Definition: utils.hpp:67
Direction
Direction
Spread direction.
Definition: utils.hpp:83