blob: 74961e3045c28bbff3bf2bc2542e7e1e3dcd0cf1 (
plain) (
blame)
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
|
#pragma once
#include <algorithm>
#include <cassert>
#include <string>
#include <string_view>
#include <ostream>
#include "openvic-simulation/types/Colour.hpp"
#include "openvic-simulation/utility/Getters.hpp"
namespace OpenVic {
constexpr bool valid_basic_identifier_char(char c) {
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_';
}
constexpr bool valid_basic_identifier(std::string_view identifier) {
return std::all_of(identifier.begin(), identifier.end(), valid_basic_identifier_char);
}
constexpr std::string_view extract_basic_identifier_prefix(std::string_view identifier) {
size_t len = 0;
while (len < identifier.size() && valid_basic_identifier_char(identifier[len])) {
++len;
}
return { identifier.data(), len };
}
/*
* Base class for objects with a non-empty string identifier. Uniquely named instances of a type derived from this class
* can be entered into an IdentifierRegistry instance.
*/
class HasIdentifier {
/* Not const so it can be moved rather than needing to be copied. */
std::string PROPERTY(identifier);
protected:
HasIdentifier(std::string_view new_identifier): identifier { new_identifier } {
assert(!identifier.empty());
}
HasIdentifier(HasIdentifier const&) = default;
public:
HasIdentifier(HasIdentifier&&) = default;
HasIdentifier& operator=(HasIdentifier const&) = delete;
HasIdentifier& operator=(HasIdentifier&&) = delete;
};
inline std::ostream& operator<<(std::ostream& stream, HasIdentifier const& obj) {
return stream << obj.get_identifier();
}
inline std::ostream& operator<<(std::ostream& stream, HasIdentifier const* obj) {
return obj != nullptr ? stream << *obj : stream << "<NULL>";
}
template<typename T>
concept HasGetIdentifier = requires(T const& t) {
{ t.get_identifier() } -> std::same_as<std::string_view>;
};
/*
* Base class for objects with associated colour information.
*/
template<IsColour ColourT>
class _HasColour {
const ColourT PROPERTY(colour);
protected:
_HasColour(ColourT new_colour, bool cannot_be_null): colour { new_colour } {
assert(!cannot_be_null || !colour.is_null());
}
_HasColour(_HasColour const&) = default;
public:
_HasColour(_HasColour&&) = default;
_HasColour& operator=(_HasColour const&) = delete;
_HasColour& operator=(_HasColour&&) = delete;
};
using HasColour = _HasColour<colour_t>;
using HasAlphaColour = _HasColour<colour_argb_t>;
template<typename T>
concept HasGetColour = requires(T const& t) {
{ t.get_colour() } -> IsColour;
};
/*
* Base class for objects with a unique string identifier and associated colour information.
*/
template<IsColour ColourT>
class _HasIdentifierAndColour : public HasIdentifier, public _HasColour<ColourT> {
protected:
_HasIdentifierAndColour(std::string_view new_identifier, ColourT new_colour, bool cannot_be_null)
: HasIdentifier { new_identifier }, _HasColour<ColourT> { new_colour, cannot_be_null } {}
_HasIdentifierAndColour(_HasIdentifierAndColour const&) = default;
public:
_HasIdentifierAndColour(_HasIdentifierAndColour&&) = default;
_HasIdentifierAndColour& operator=(_HasIdentifierAndColour const&) = delete;
_HasIdentifierAndColour& operator=(_HasIdentifierAndColour&&) = delete;
};
using HasIdentifierAndColour = _HasIdentifierAndColour<colour_t>;
using HasIdentifierAndAlphaColour = _HasIdentifierAndColour<colour_argb_t>;
template<std::unsigned_integral T = size_t>
class HasIndex {
public:
using index_t = T;
private:
const index_t PROPERTY(index);
protected:
HasIndex(index_t new_index) : index { new_index } {}
HasIndex(HasIndex const&) = default;
public:
HasIndex(HasIndex&&) = default;
HasIndex& operator=(HasIndex const&) = delete;
HasIndex& operator=(HasIndex&&) = delete;
};
template<typename T>
concept HasGetIndex = requires(T const& t) {
{ t.get_index() } -> std::unsigned_integral;
};
}
|