forked from cataclysmbnteam/Cataclysm-BN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
int_id.h
131 lines (114 loc) · 3.68 KB
/
int_id.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
#pragma once
#ifndef CATA_SRC_INT_ID_H
#define CATA_SRC_INT_ID_H
#include <functional>
#include <string>
#include <type_traits>
template<typename T>
class string_id;
/**
* Just like the @ref string_id, this is a wrapper for int based identifiers.
* The template parameter T specifies what kind of object it identifies (e.g. a trap type, monster
* type, ...)
*
*/
template<typename T>
class int_id
{
public:
using This = int_id<T>;
/**
* Explicit constructor to make it stand out in the code, so one can easily search for all
* places that use it.
*/
explicit int_id( const int id )
: _id( id ) {
}
/**
* Prevent accidental construction from other int ids.
*/
template < typename S, typename std::enable_if_t < !std::is_same<S, T>::value, int > = 0 >
int_id( const int_id<S> &id ) = delete;
/**
* Default constructor constructs a 0-id. No id value is special to this class, 0 as id
* is just as normal as any other integer value.
*/
int_id()
: _id( 0 ) {
}
/**
* Construct an id from the matching string based id. This may show a debug message if the
* string id is invalid.
*/
int_id( const string_id<T> &id );
/**
* Forwarding constructor, forwards any parameter to the string_id
* constructor to create the int id. This allows plain C-strings,
* and std::strings to be used.
*/
template<typename S, class =
typename std::enable_if< std::is_convertible<S, std::string >::value>::type >
explicit int_id( S && id ) : int_id( string_id<T>( std::forward<S>( id ) ) ) {}
/**
* Comparison, only useful when the id is used in std::map or std::set as key.
*/
bool operator<( const This &rhs ) const {
return _id < rhs._id;
}
/**
* The usual comparator, compares the integer id as usual
*/
bool operator==( const This &rhs ) const {
return _id == rhs._id;
}
/**
* The usual comparator, compares the integer id as usual
*/
bool operator!=( const This &rhs ) const {
return _id != rhs._id;
}
/**
* Returns the identifier as plain int. Use with care, the plain int does not
* have any information as what type of object it refers to (the T template parameter of
* the class).
*/
int to_i() const {
return _id;
}
/**
* Conversion to int as with the @ref to_i function.
*/
explicit operator int() const {
return _id;
}
explicit operator bool() const {
return _id != 0;
}
// Those are optional, you need to implement them on your own if you want to use them.
// If you don't implement them, but use them, you'll get a linker error.
const string_id<T> &id() const;
const T &obj() const;
const T &operator*() const {
return obj();
}
const T *operator->() const {
return &obj();
}
/**
* Returns whether this id is valid, that means whether it refers to an existing object.
*/
bool is_valid() const;
private:
int _id;
};
// Support hashing of int based ids by forwarding the hash of the int.
namespace std
{
template<typename T>
struct hash< int_id<T> > {
std::size_t operator()( const int_id<T> &v ) const noexcept {
return hash<int>()( v.to_i() );
}
};
} // namespace std
#endif // CATA_SRC_INT_ID_H