-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.h
147 lines (125 loc) · 2.99 KB
/
common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
* Just some definitions which can be used everywhere.
*/
#ifndef RECHTECKSPACKUNG_COMMON_H
#define RECHTECKSPACKUNG_COMMON_H
#include <list>
#include <cassert>
#include <string>
#include <iostream>
#include <stdexcept>
using pos = int;
using weight = int;
enum class rotation
{
rotated_0 = 0,
rotated_90 = 1,
rotated_180 = 2,
rotated_270 = 3,
count = 4
};
enum class dimension
{
x = 0,
y = 1
};
static auto all_dimensions = {dimension::x, dimension::y};
inline std::string to_string(dimension dim)
{
switch (dim)
{
case dimension::x:
return "x";
case dimension::y:
return "y";
}
}
struct certificate
{
bool valid;
int first;
int second;
certificate() :
valid(true)
{}
certificate(int first_, int second_) :
valid(false),
first(first_),
second(second_)
{}
};
struct point
{
pos x;
pos y;
// Sadly, std::optional is C++17, so we have to make do
bool set = false;
point() = default;
point(pos x_, pos y_, bool set_) : x(x_), y(y_), set(set_)
{}
void swap()
{
std::swap(x, y);
}
/**
* Returns the coordinate of the given dimension.
* @param dim The coordinate to be returned
* @param other Inverts the dimension (can be practical)
* @return x if dim is dimension::x, y if dim is dimension::y, if other is true the choice is inverted
*/
const pos &coord(dimension dim, bool other = false) const
{
switch (dim)
{
case dimension::x :
return other ? y : x;
case dimension::y :
return other ? x : y;
default:
throw std::invalid_argument("Invalid argurment: Unspecified value for dim");
}
}
/**
* Returns the coordinate of the given dimension.
* @param dim The coordinate to be returned
* @param other Inverts the dimension (can be practical)
* @return x if dim is dimension::x, y if dim is dimension::y, if other is true the choice is inverted
*/
pos &coord(dimension dim, bool other = false)
{
switch (dim)
{
case dimension::x :
return other ? y : x;
case dimension::y :
return other ? x : y;
default:
throw std::invalid_argument("Invalid argurment: Unspecified value for dim");
}
}
};
inline std::istream &operator>>(std::istream &in, point &p)
{
for (dimension dim : all_dimensions)
{
if (!(in >> p.coord(dim)))
{
if (!p.set)
{
return in;
}
else
{
throw std::runtime_error("Invalid format for point, only one value provided.");
}
}
p.set = true;
}
return in;
}
inline std::ostream &operator<<(std::ostream &out, const point &p)
{
out << p.x << " " << p.y;
return out;
}
#endif //RECHTECKSPACKUNG_COMMON_H